Skip to content

[PAuth] Emit Dwarf info for implicitly signed pointers #63

Closed
@kovdan01

Description

@kovdan01

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.

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions