AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / coding / Perguntas / 79079699
Accepted
fuz
fuz
Asked: 2024-10-12 04:56:19 +0800 CST2024-10-12 04:56:19 +0800 CST 2024-10-12 04:56:19 +0800 CST

Como preciso alterar meu código para torná-lo compatível com PAC/BTI?

  • 772

Eu escrevi algum código assembly arm64 seguindo a convenção de chamada AAPCS64.

Agora eu gostaria de integrar esse código em um projeto C/C++ construído com PAC e BTI habilitados. Eu notei o problema pela primeira vez quando o linker me disse que estava faltando a GNU_PROPERTY_AARCH64_FEATURE_1_BTIpropriedade:

ld: error: md5block_arm64.o: -z bti-report: file does not have GNU_PROPERTY_AARCH64_FEATURE_1_BTI property

Embora seja trivial apenas definir essa propriedade, estou ciente de que provavelmente preciso alterar partes do meu código para torná-las compatíveis com PAC/BTI. Quais são as alterações necessárias para isso? Estou interessado em uma resposta geral que possa ser usada como um guia para adaptar qualquer código, daí a falta de código a ser adaptado nesta questão.

assembly
  • 1 1 respostas
  • 55 Views

1 respostas

  • Voted
  1. Best Answer
    Siguza
    2024-10-12T07:28:41+08:002024-10-12T07:28:41+08:00

    O BTI é bem simples e não depende de ABI de software (além do BTI estar habilitado em primeiro lugar). Na versão atual ( K.a) do manual , o comportamento é documentado na seção "D8.4.5.3 PSTATE.BTYPE". Em essência:

    • As instruções de ramificação de borda para frente se dividem em duas categorias:

      • br, braa, braaz, brabebrabz
      • blr, blraa, blraaz, blrab,blrabz

      Usarei bre blrcomo uma abreviação para essas categorias.

    • Há três novas instruções: bti c, bti je bti jc.

    • blros ramos devem pousar em uma instrução bti cou bti jc.

    • brramificações que usam um registrador diferente de x16e x17para o endereço de destino devem pousar em uma instrução bti jou bti jc.

    • brramificações que usam x16ou x17para o endereço de destino podem pousar em qualquer btiinstrução.

    • paciaspe pacibspagir como bti cou bti jccom base em alguns bits SCTLR_ELnpara o regime de tradução relevante - apenas assuma bti cque está seguro.

    Então, para ser compatível com o código BTI, você precisa:

    • Prefixe todas as suas funções que podem ser invocadas via ramificação indireta com paciasp, pacibspou bti c.
    • Certifique-se de que todas as chamadas finais e importações (apenas aquelas usadas brpara chamar funções reais) usem x16or x17.
    • Adicione bti ja todos os alvos possíveis do estilo switch brs.

    PAC é uma fera completamente diferente. Isso depende do ABI exato de tudo em sua pilha - gnuvs musl, C vs C++, __attribute__especificadores em arquivos de cabeçalho, ...

    A especificação AAPCS64 não define uma ABI de autenticação de ponteiro. PAUTHELF64 tem algumas definições sobre como codificar coisas no formato de arquivo ELF, mas crucialmente não define como essas coisas devem ser escolhidas .

    Basicamente, qualquer síntese de ponteiro de código, qualquer ramificação indireta e potencialmente até mesmo cargas de memória podem precisar de instruções PAC, totalmente definidas pela implementação.

    Agora, para sua sorte, -mbranch-protection=standardparece usar PAC quase nada. Da documentação do flag :

    -mbranch-protection=none|standard|pac-ret[+leaf+b-key]|bti

    Selecione os recursos de proteção de ramificação a serem usados. noneé o padrão e desativa todos os tipos de proteção de ramificação. standardativa todos os tipos de recursos de proteção de ramificação. Se um recurso tiver opções de ajuste adicionais, standarddefina-o para seu nível padrão. pac-ret[+leaf]ativa a assinatura de endereço de retorno para seu nível padrão: funções de assinatura que salvam o endereço de retorno na memória (funções não-folha praticamente sempre farão isso) usando a tecla a. O argumento opcional leafpode ser usado para estender a assinatura para incluir funções folha. O argumento opcional b-keypode ser usado para assinar as funções com a tecla B em vez da tecla A. btiativa o mecanismo de identificação de alvo de ramificação.

    Basicamente, isso usa apenas PAC para proteger frames de pilha, o que não afeta o ABI entre diferentes unidades de compilação. Se você quiser manter as propriedades de segurança da opção, todas as suas funções que vazarem x30precisarão de um paciaspantes do vazamento e um autiaspentre o reload e o ret. (Se seu código não precisa ser capaz de rodar em hardware sem suporte a PAC, você pode combinar o autiasp+ retem um único retaa).

    • 5

relate perguntas

  • x86 - mudando de 32 bits para 64 bits via RETF

  • Opcode não reconhecido em instruções de montagem de ponto flutuante para Xiao ESP32-C3 (baseado em RISC-V)

  • Como usar o GNU Assembler (GAS) para criar um arquivo ELF escrito à mão a partir do arquivo .s correspondente

  • Não consigo ler o registro LY do gameboy

  • Obtenha o valor do parâmetro no Assembly

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Vue 3: Erro na criação "Identificador esperado, mas encontrado 'import'" [duplicado]

    • 1 respostas
  • Marko Smith

    Por que esse código Java simples e pequeno roda 30x mais rápido em todas as JVMs Graal, mas não em nenhuma JVM Oracle?

    • 1 respostas
  • Marko Smith

    Qual é o propósito de `enum class` com um tipo subjacente especificado, mas sem enumeradores?

    • 1 respostas
  • Marko Smith

    Como faço para corrigir um erro MODULE_NOT_FOUND para um módulo que não importei manualmente?

    • 6 respostas
  • Marko Smith

    `(expression, lvalue) = rvalue` é uma atribuição válida em C ou C++? Por que alguns compiladores aceitam/rejeitam isso?

    • 3 respostas
  • Marko Smith

    Quando devo usar um std::inplace_vector em vez de um std::vector?

    • 3 respostas
  • Marko Smith

    Um programa vazio que não faz nada em C++ precisa de um heap de 204 KB, mas não em C

    • 1 respostas
  • Marko Smith

    PowerBI atualmente quebrado com BigQuery: problema de driver Simba com atualização do Windows

    • 2 respostas
  • Marko Smith

    AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos

    • 1 respostas
  • Marko Smith

    Estou tentando fazer o jogo pacman usando apenas o módulo Turtle Random e Math

    • 1 respostas
  • Martin Hope
    Aleksandr Dubinsky Por que a correspondência de padrões com o switch no InetAddress falha com 'não cobre todos os valores de entrada possíveis'? 2024-12-23 06:56:21 +0800 CST
  • Martin Hope
    Phillip Borge Por que esse código Java simples e pequeno roda 30x mais rápido em todas as JVMs Graal, mas não em nenhuma JVM Oracle? 2024-12-12 20:46:46 +0800 CST
  • Martin Hope
    Oodini Qual é o propósito de `enum class` com um tipo subjacente especificado, mas sem enumeradores? 2024-12-12 06:27:11 +0800 CST
  • Martin Hope
    sleeptightAnsiC `(expression, lvalue) = rvalue` é uma atribuição válida em C ou C++? Por que alguns compiladores aceitam/rejeitam isso? 2024-11-09 07:18:53 +0800 CST
  • Martin Hope
    The Mad Gamer Quando devo usar um std::inplace_vector em vez de um std::vector? 2024-10-29 23:01:00 +0800 CST
  • Martin Hope
    Chad Feller O ponto e vírgula agora é opcional em condicionais bash com [[ .. ]] na versão 5.2? 2024-10-21 05:50:33 +0800 CST
  • Martin Hope
    Wrench Por que um traço duplo (--) faz com que esta cláusula MariaDB seja avaliada como verdadeira? 2024-05-05 13:37:20 +0800 CST
  • Martin Hope
    Waket Zheng Por que `dict(id=1, **{'id': 2})` às vezes gera `KeyError: 'id'` em vez de um TypeError? 2024-05-04 14:19:19 +0800 CST
  • Martin Hope
    user924 AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos 2024-03-20 03:12:31 +0800 CST
  • Martin Hope
    MarkB Por que o GCC gera código que executa condicionalmente uma implementação SIMD? 2024-02-17 06:17:14 +0800 CST

Hot tag

python javascript c++ c# java typescript sql reactjs html

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve