llvm-project/lld/test/ELF/aarch64-ifunc-bti.s

66 lines
2.5 KiB
ArmAsm
Raw Normal View History

[ELF][AArch64] Support for BTI and PAC Branch Target Identification (BTI) and Pointer Authentication (PAC) are architecture features introduced in v8.5a and 8.3a respectively. The new instructions have been added in the hint space so that binaries take advantage of support where it exists yet still run on older hardware. The impact of each feature is: BTI: For executable pages that have been guarded, all indirect branches must have a destination that is a BTI instruction of the appropriate type. For the static linker, this means that PLT entries must have a "BTI c" as the first instruction in the sequence. BTI is an all or nothing property for a link unit, any indirect branch not landing on a valid destination will cause a Branch Target Exception. PAC: The dynamic loader encodes with PACIA the address of the destination that the PLT entry will load from the .plt.got, placing the result in a subset of the top-bits that are not valid virtual addresses. The PLT entry may authenticate these top-bits using the AUTIA instruction before branching to the destination. Use of PAC in PLT sequences is a contract between the dynamic loader and the static linker, it is independent of whether the relocatable objects use PAC. BTI and PAC are independent features that can be combined. So we can have several combinations of PLT: - Standard with no BTI or PAC - BTI PLT with "BTI c" as first instruction. - PAC PLT with "AUTIA1716" before the indirect branch to X17. - BTIPAC PLT with "BTI c" as first instruction and "AUTIA1716" before the first indirect branch to X17. The use of BTI and PAC in relocatable object files are encoded by feature bits in the .note.gnu.property section in a similar way to Intel CET. There is one AArch64 specific program property GNU_PROPERTY_AARCH64_FEATURE_1_AND and two target feature bits defined: - GNU_PROPERTY_AARCH64_FEATURE_1_BTI -- All executable sections are compatible with BTI. - GNU_PROPERTY_AARCH64_FEATURE_1_PAC -- All executable sections have return address signing enabled. Due to the properties of FEATURE_1_AND the static linker can tell when all input relocatable objects have the BTI and PAC feature bits set. The static linker uses this to enable the appropriate PLT sequence. Neither -> standard PLT GNU_PROPERTY_AARCH64_FEATURE_1_BTI -> BTI PLT GNU_PROPERTY_AARCH64_FEATURE_1_PAC -> PAC PLT Both properties -> BTIPAC PLT In addition to the .note.gnu.properties there are two new command line options: --force-bti : Act as if all relocatable inputs had GNU_PROPERTY_AARCH64_FEATURE_1_BTI and warn for every relocatable object that does not. --pac-plt : Act as if all relocatable inputs had GNU_PROPERTY_AARCH64_FEATURE_1_PAC. As PAC is a contract between the loader and static linker no warning is given if it is not present in an input. Two processor specific dynamic tags are used to communicate that a non standard PLT sequence is being used. DTI_AARCH64_BTI_PLT and DTI_AARCH64_BTI_PAC. Differential Revision: https://reviews.llvm.org/D62609 llvm-svn: 362793
2019-06-07 21:00:17 +08:00
# REQUIRES: aarch64
# RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux-gnu %s -o %t.o
# RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux-gnu %p/Inputs/aarch64-addrifunc.s -o %lib.o
# RUN: ld.lld --shared %lib.o -o %lib.so
# RUN: ld.lld --pie %lib.so %t.o -o %t
# RUN: llvm-objdump -d -mattr=+bti -triple=aarch64-linux-gnu %t | FileCheck %s
# When the address of an ifunc is taken using a non-got reference which clang
# can do, LLD exports a canonical PLT entry that may have its address taken so
# we must use bti c.
# CHECK: Disassembly of section .plt:
# CHECK: 0000000000010020 .plt:
# CHECK-NEXT: 10020: 5f 24 03 d5 bti c
# CHECK-NEXT: 10024: f0 7b bf a9 stp x16, x30, [sp, #-16]!
# CHECK-NEXT: 10028: 10 01 00 90 adrp x16, #131072
# CHECK-NEXT: 1002c: 11 0a 40 f9 ldr x17, [x16, #16]
# CHECK-NEXT: 10030: 10 42 00 91 add x16, x16, #16
# CHECK-NEXT: 10034: 20 02 1f d6 br x17
# CHECK-NEXT: 10038: 1f 20 03 d5 nop
# CHECK-NEXT: 1003c: 1f 20 03 d5 nop
# CHECK: 0000000000010040 func1@plt:
# CHECK-NEXT: 10040: 5f 24 03 d5 bti c
# CHECK-NEXT: 10044: 10 01 00 90 adrp x16, #131072
# CHECK-NEXT: 10048: 11 0e 40 f9 ldr x17, [x16, #24]
# CHECK-NEXT: 1004c: 10 62 00 91 add x16, x16, #24
# CHECK-NEXT: 10050: 20 02 1f d6 br x17
# CHECK-NEXT: 10054: 1f 20 03 d5 nop
# CHECK-NEXT: ...
# CHECK: 0000000000010060 myfunc:
# CHECK-NEXT: 10060: 5f 24 03 d5 bti c
# CHECK-NEXT: 10064: 10 01 00 90 adrp x16, #131072
# CHECK-NEXT: 10068: 11 12 40 f9 ldr x17, [x16, #32]
# CHECK-NEXT: 1006c: 10 82 00 91 add x16, x16, #32
# CHECK-NEXT: 10070: 20 02 1f d6 br x17
# CHECK-NEXT: 10074: 1f 20 03 d5 nop
.section ".note.gnu.property", "a"
.long 4
.long 0x10
.long 0x5
.asciz "GNU"
.long 0xc0000000 // GNU_PROPERTY_AARCH64_FEATURE_1_AND
.long 4
.long 1 // GNU_PROPERTY_AARCH64_FEATURE_1_BTI
.long 0
.text
.globl myfunc
.type myfunc,@gnu_indirect_function
myfunc:
ret
.globl func1
.text
.globl _start
.type _start, %function
_start:
bl func1
adrp x8, myfunc
add x8, x8, :lo12:myfunc
ret