From e5d8ae6da351efe511ec13434dc19db7a31c67d3 Mon Sep 17 00:00:00 2001 From: Peter Smith Date: Fri, 13 Sep 2024 16:18:34 +0100 Subject: [PATCH 1/2] [sysvabi64] Document requirements for tools wrt BTI Add requirements for when a tool must generate a BTI instruction. This permits tools to elide BTI instructions when they can prove that no indirect branch to that location is possible from local information available to the tool. Static linkers are not allowed to assume that all direct branch targets have a BTI instruction. If a veneer is required then the static linker must generate additional BTI instructions if needed. A static linker is allowed to assume that a symbol that is exported to the dynamic symbol table has a BTI instruction. In practice this will permit compilers to remove BTI instructions from static functions that do not have their address taken and that address escapes the function. This matches the behavior of the GNU toolchain. Fixes https://github.com/ARM-software/abi-aa/issues/196 --- sysvabi64/sysvabi64.rst | 60 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 57 insertions(+), 3 deletions(-) diff --git a/sysvabi64/sysvabi64.rst b/sysvabi64/sysvabi64.rst index bf1315f..6ed8da4 100644 --- a/sysvabi64/sysvabi64.rst +++ b/sysvabi64/sysvabi64.rst @@ -1646,9 +1646,8 @@ The following bits are defined for GNU_PROPERTY_AARCH64_FEATURE_1_AND: +-----------------------------------------+------------+ ``GNU_PROPERTY_AARCH64_FEATURE_1_BTI`` This indicates that all executable -sections are compatible with Branch Target Identification mechanism. An -executable or shared object with this bit set is required to generate -`Custom PLTs`_ with BTI instruction. +sections are compatible with Branch Target Identification mechanism. See +`Tool requirements for generating BTI instructions`_. ``GNU_PROPERTY_AARCH64_FEATURE_1_PAC`` This indicates that all executable sections have been protected with Return Address Signing. @@ -1671,6 +1670,61 @@ include: * Any functions used by the program that manipulate the stack such as ``setjmp`` and ``longjmp``, must be aware of GCS. +Tool Requirements for generating BTI instructions +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +For an executable or shared library to set +``GNU_PROPERTY_AARCH64_FEATURE_1_BTI`` every indirect branch to a +location in a guarded page must target a BTI instruction that is +compatible with the PSTATE.BTYPE value. Indirect branches can come +from: + +* Relocatable object producers, such as a compiler or assembler. + +* Static linkers when generating PLT sequences or veneers. + +* Other executables and shared libraries via call from a PLT or a + function pointer. + +It is desirable to minimize the number of BTI instructions to limit +the number of indirect branch destinations in the program. The +following tool requirements determine which tool has the +responsibility of inserting the BTI instruction, permitting a tool to +elide the BTI instuction when it can prove that there are no indirect +calls to that location. + +A relocatable object producer is required to add a BTI instruction to +the destination of an indirect branch originating in the same +relocatable object. + +A relocatable object producer is required to add a BTI instruction to +a location when the address of that location escapes out of the +relocatable object. This includes the locations of all symbols that +can be exported into the dynamic symbol table by a static linker. + +A static linker is required to generate `Custom PLTs`_ with BTI +instructions. + +A static linker that uses indirect branches in veneers is required to +generate a BTI compatible landing pad if the target does not have a +compatible BTI instruction at the destination of the veneer. A BTI +compatible landing pad consists of a BTI instruction followed by a +direct branch. For example: + +.. code-block:: asm + + // Linker generated veneer using indirect bracnh + adrp x16, fn + add x16, :lo12: fn + br x16 + ... + // Linker generated BTI landing pad + bti c + b fn + ... + // Destination of veneer without a BTI instruction. + fn: + // a non BTI instruction. Program Loading --------------- From 7c89cc75ac4eacc694fa6bd199e2bcb053509758 Mon Sep 17 00:00:00 2001 From: Peter Smith Date: Wed, 25 Sep 2024 14:40:57 +0100 Subject: [PATCH 2/2] [sysvabi64] No BTI landing pads for absolute symbols. It is possible to provide a static linker with branch targets using absolute symbols. For example using --defsym. The static cannot disassemble the location of these symbols so it isn't possible to check whether A BTI landing pad is necessary, nor is it always possible to place a BTI landing pad within range of the absolute symbol address. A user providing the static linker with function addresses using absolute symbols is responsible for putting BTI compatible landing pads at the start of these addresses. --- sysvabi64/sysvabi64.rst | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/sysvabi64/sysvabi64.rst b/sysvabi64/sysvabi64.rst index 6ed8da4..d2e9a7d 100644 --- a/sysvabi64/sysvabi64.rst +++ b/sysvabi64/sysvabi64.rst @@ -1706,7 +1706,8 @@ A static linker is required to generate `Custom PLTs`_ with BTI instructions. A static linker that uses indirect branches in veneers is required to -generate a BTI compatible landing pad if the target does not have a +generate a BTI compatible landing pad if the target of the indirect +branch is defined within the same link unit and does not have a compatible BTI instruction at the destination of the veneer. A BTI compatible landing pad consists of a BTI instruction followed by a direct branch. For example: @@ -1726,6 +1727,9 @@ direct branch. For example: fn: // a non BTI instruction. +A static linker is not required to insert BTI compatible landing pads +for symbols with section index ``SHN_ABS``. + Program Loading ---------------