Description
In f28e8db, DW_TAG_LLVM_ptrauth_type
and corresponding attributes were introduced. However, those are only emitted for explicitly signed pointers (those with explicit __ptrauth
specifier).
Consider the following code:
typedef void fptr();
fptr a;
fptr *__ptrauth(0, 0, 0) b = &a;
fptr x;
fptr *y = &x;
When building for a Linux target with -mbranch-protection=pauthabi
(or for an Apple's arm64e), we get the following Dwarf info (unrelated parts omitted):
0x0000001e: DW_TAG_variable [2] (0x0000000c)
DW_AT_name [DW_FORM_strx1] (indexed (00000003) string = "b")
DW_AT_type [DW_FORM_ref4] (cu + 0x0029 => {0x00000029} "fptr *__ptrauth(0, 1, 0x00)")
DW_AT_external [DW_FORM_flag_present] (true)
DW_AT_decl_file [DW_FORM_data1] ("/home/kovdan01/Work/armpac/dwarf/test.c")
DW_AT_decl_line [DW_FORM_data1] (52)
DW_AT_location [DW_FORM_exprloc] (DW_OP_addrx 0x0)
0x00000029: DW_TAG_LLVM_ptrauth_type [3] (0x0000000c)
DW_AT_type [DW_FORM_ref4] (cu + 0x0031 => {0x00000031} "fptr *")
DW_AT_LLVM_ptrauth_key [DW_FORM_data1] (0x00)
DW_AT_LLVM_ptrauth_address_discriminated [DW_FORM_flag_present] (true)
DW_AT_LLVM_ptrauth_extra_discriminator [DW_FORM_data2] (0x0000)
0x00000031: DW_TAG_pointer_type [4] (0x0000000c)
DW_AT_type [DW_FORM_ref4] (cu + 0x0036 => {0x00000036} "fptr")
0x00000041: DW_TAG_variable [2] (0x0000000c)
DW_AT_name [DW_FORM_strx1] (indexed (00000005) string = "y")
DW_AT_type [DW_FORM_ref4] (cu + 0x0031 => {0x00000031} "fptr *")
DW_AT_external [DW_FORM_flag_present] (true)
DW_AT_decl_file [DW_FORM_data1] ("/home/kovdan01/Work/armpac/dwarf/test.c")
DW_AT_decl_line [DW_FORM_data1] (56)
DW_AT_location [DW_FORM_exprloc] (DW_OP_addrx 0x1)
So, only pointer b
is listed in Dwarf info as signed, while y
is not. However, for both b
and y
signed R_AARCH64_AUTH_ABS64
relocations are emitted, so they are actually both signed (as expected when using -mbranch-protection=pauthabi
).
The same issue also applies to other implicitly signed pointers (by implicitly we here mean without explicit __ptrauth
specifier): pointers to member functions, vtable pointers, function pointers with are signed at runtime instead of a relocation.
The fix should include changes in functions declared in llvm/include/llvm/IR/DIBuilder.h
, such as DIBuilder::createClassType
. Now, we have DIBuilder::createPtrAuthQualifiedType
which is only applied to pointers with __ptrauth
specifier.