Skip to content

Commit

Permalink
[llvm-readobj][AArch64][ELF][PAC] Support ELF AUTH constants
Browse files Browse the repository at this point in the history
This patch adds llvm-readobj support for:

- Dynamic R_AARCH64_AUTH_* relocations (including RELR compressed AUTH
  relocations) as described here:
  https://github.com/ARM-software/abi-aa/blob/main/pauthabielf64/pauthabielf64.rst#auth-variant-dynamic-relocations

- .note.AARCH64-PAUTH-ABI-tag section as defined here
  https://github.com/ARM-software/abi-aa/blob/main/pauthabielf64/pauthabielf64.rst#elf-marking
  • Loading branch information
kovdan01 committed Dec 4, 2023
1 parent e9c6f3f commit 647aa46
Show file tree
Hide file tree
Showing 11 changed files with 302 additions and 26 deletions.
6 changes: 6 additions & 0 deletions llvm/include/llvm/BinaryFormat/DynamicTags.def
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,12 @@ AARCH64_DYNAMIC_TAG(AARCH64_MEMTAG_STACK, 0x7000000c)
AARCH64_DYNAMIC_TAG(AARCH64_MEMTAG_GLOBALS, 0x7000000d)
AARCH64_DYNAMIC_TAG(AARCH64_MEMTAG_GLOBALSSZ, 0x7000000f)

// AArch64 specific dynamic table entries for RELR auth relocations as described here:
// https://github.com/ARM-software/abi-aa/blob/main/pauthabielf64/pauthabielf64.rst#dynamic-section
AARCH64_DYNAMIC_TAG(AARCH64_AUTH_RELRSZ, 0x70000011)
AARCH64_DYNAMIC_TAG(AARCH64_AUTH_RELR, 0x70000012)
AARCH64_DYNAMIC_TAG(AARCH64_AUTH_RELRENT, 0x70000013)

// Hexagon specific dynamic table entries
HEXAGON_DYNAMIC_TAG(HEXAGON_SYMSZ, 0x70000000)
HEXAGON_DYNAMIC_TAG(HEXAGON_VER, 0x70000001)
Expand Down
8 changes: 8 additions & 0 deletions llvm/include/llvm/BinaryFormat/ELF.h
Original file line number Diff line number Diff line change
Expand Up @@ -1060,6 +1060,9 @@ enum : unsigned {
SHT_ARM_ATTRIBUTES = 0x70000003U,
SHT_ARM_DEBUGOVERLAY = 0x70000004U,
SHT_ARM_OVERLAYSECTION = 0x70000005U,
// Special aarch64-specific section for MTE support, as described in:
// https://github.com/ARM-software/abi-aa/blob/main/pauthabielf64/pauthabielf64.rst#section-types
SHT_AARCH64_AUTH_RELR = 0x70000004U,
// Special aarch64-specific sections for MTE support, as described in:
// https://github.com/ARM-software/abi-aa/blob/main/memtagabielf64/memtagabielf64.rst#7section-types
SHT_AARCH64_MEMTAG_GLOBALS_STATIC = 0x70000007U,
Expand Down Expand Up @@ -1647,6 +1650,11 @@ enum {
NT_ANDROID_TYPE_MEMTAG = 4,
};

// ARM note types.
enum {
NT_ARM_TYPE_PAUTH_ABI_TAG = 1,
};

// Memory tagging values used in NT_ANDROID_TYPE_MEMTAG notes.
enum {
// Enumeration to determine the tagging mode. In Android-land, 'SYNC' means
Expand Down
1 change: 1 addition & 0 deletions llvm/include/llvm/BinaryFormat/ELFRelocs/AArch64.def
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ ELF_RELOC(R_AARCH64_TLS_TPREL64, 0x406)
ELF_RELOC(R_AARCH64_TLSDESC, 0x407)
ELF_RELOC(R_AARCH64_IRELATIVE, 0x408)
ELF_RELOC(R_AARCH64_AUTH_ABS64, 0xe100)
ELF_RELOC(R_AARCH64_AUTH_RELATIVE, 0xe200)

// ELF_RELOC(R_AARCH64_P32_NONE, 0)
ELF_RELOC(R_AARCH64_P32_ABS32, 0x001)
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Object/ELF.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,7 @@ StringRef llvm::object::getELFSectionTypeName(uint32_t Machine, unsigned Type) {
STRINGIFY_ENUM_CASE(ELF, SHT_GROUP);
STRINGIFY_ENUM_CASE(ELF, SHT_SYMTAB_SHNDX);
STRINGIFY_ENUM_CASE(ELF, SHT_RELR);
STRINGIFY_ENUM_CASE(ELF, SHT_AARCH64_AUTH_RELR);
STRINGIFY_ENUM_CASE(ELF, SHT_ANDROID_REL);
STRINGIFY_ENUM_CASE(ELF, SHT_ANDROID_RELA);
STRINGIFY_ENUM_CASE(ELF, SHT_ANDROID_RELR);
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/ObjectYAML/ELFYAML.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -672,6 +672,7 @@ void ScalarEnumerationTraits<ELFYAML::ELF_SHT>::enumeration(
ECase(SHT_GROUP);
ECase(SHT_SYMTAB_SHNDX);
ECase(SHT_RELR);
ECase(SHT_AARCH64_AUTH_RELR);
ECase(SHT_ANDROID_REL);
ECase(SHT_ANDROID_RELA);
ECase(SHT_ANDROID_RELR);
Expand Down
98 changes: 98 additions & 0 deletions llvm/test/tools/llvm-readobj/ELF/AArch64/aarch64-feature-pauth.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
# RUN: rm -rf %t && split-file %s %t && cd %t

# RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu abi-tag.s -o tag.o
# RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu abi-tag-short.s -o tag-short.o
# RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu abi-tag-long.s -o tag-long.o

# RUN: llvm-readelf --notes tag.o | FileCheck --check-prefix NORMAL %s
# RUN: llvm-readelf --notes tag-short.o | FileCheck --check-prefix SHORT %s
# RUN: llvm-readelf --notes tag-long.o | FileCheck --check-prefix LONG %s

# NORMAL: AArch64 PAuth ABI tag: platform 0x2a, version 0x1
# SHORT: AArch64 PAuth ABI tag: <corrupted size: expected at least 16, got 12>
# LONG: AArch64 PAuth ABI tag: platform 0x2a, version 0x1, additional info 0xEFCDAB8967452301

# RUN: llvm-readobj --notes tag.o | FileCheck --check-prefix LLVM-NORMAL %s
# RUN: llvm-readobj --notes tag-short.o | FileCheck --check-prefix LLVM-SHORT %s
# RUN: llvm-readobj --notes tag-long.o | FileCheck --check-prefix LLVM-LONG %s

// LLVM-SHORT: Notes [
// LLVM-SHORT-NEXT: NoteSection {
// LLVM-SHORT-NEXT: Name: .note.AARCH64-PAUTH-ABI-tag
// LLVM-SHORT-NEXT: Offset: 0x40
// LLVM-SHORT-NEXT: Size: 0x1C
// LLVM-SHORT-NEXT: Note {
// LLVM-SHORT-NEXT: Owner: ARM
// LLVM-SHORT-NEXT: Data size: 0xC
// LLVM-SHORT-NEXT: Type: NT_ARM_TYPE_PAUTH_ABI_TAG
// LLVM-SHORT-NEXT: Description data (
// LLVM-SHORT-NEXT: 0000: 2A000000 00000000 01000000
// LLVM-SHORT-NEXT: )
// LLVM-SHORT-NEXT: }
// LLVM-SHORT-NEXT: }
// LLVM-SHORT-NEXT: ]

// LLVM-NORMAL: Notes [
// LLVM-NORMAL-NEXT: NoteSection {
// LLVM-NORMAL-NEXT: Name: .note.AARCH64-PAUTH-ABI-tag
// LLVM-NORMAL-NEXT: Offset: 0x40
// LLVM-NORMAL-NEXT: Size: 0x20
// LLVM-NORMAL-NEXT: Note {
// LLVM-NORMAL-NEXT: Owner: ARM
// LLVM-NORMAL-NEXT: Data size: 0x10
// LLVM-NORMAL-NEXT: Type: NT_ARM_TYPE_PAUTH_ABI_TAG
// LLVM-NORMAL-NEXT: Platform: 42
// LLVM-NORMAL-NEXT: Version: 1
// LLVM-NORMAL-NEXT: }
// LLVM-NORMAL-NEXT: }
// LLVM-NORMAL-NEXT: ]

// LLVM-LONG: Notes [
// LLVM-LONG-NEXT: NoteSection {
// LLVM-LONG-NEXT: Name: .note.AARCH64-PAUTH-ABI-tag
// LLVM-LONG-NEXT: Offset: 0x40
// LLVM-LONG-NEXT: Size: 0x28
// LLVM-LONG-NEXT: Note {
// LLVM-LONG-NEXT: Owner: ARM
// LLVM-LONG-NEXT: Data size: 0x18
// LLVM-LONG-NEXT: Type: NT_ARM_TYPE_PAUTH_ABI_TAG
// LLVM-LONG-NEXT: Platform: 42
// LLVM-LONG-NEXT: Version: 1
// LLVM-LONG-NEXT: Additional info: EFCDAB8967452301
// LLVM-LONG-NEXT: }
// LLVM-LONG-NEXT: }
// LLVM-LONG-NEXT: ]

#--- abi-tag.s

.section ".note.AARCH64-PAUTH-ABI-tag", "a"
.long 4
.long 16
.long 1
.asciz "ARM"

.quad 42 // platform
.quad 1 // version

#--- abi-tag-short.s

.section ".note.AARCH64-PAUTH-ABI-tag", "a"
.long 4
.long 12
.long 1
.asciz "ARM"

.quad 42
.word 1

#--- abi-tag-long.s

.section ".note.AARCH64-PAUTH-ABI-tag", "a"
.long 4
.long 24
.long 1
.asciz "ARM"

.quad 42 // platform
.quad 1 // version
.quad 0x0123456789ABCDEF // extra data
40 changes: 40 additions & 0 deletions llvm/test/tools/llvm-readobj/ELF/broken-dynamic-reloc.test
Original file line number Diff line number Diff line change
Expand Up @@ -459,3 +459,43 @@ ProgramHeaders:
- Type: PT_DYNAMIC
FirstSec: .dynamic
LastSec: .dynamic

## Show we print a warning for an invalid relocation table size stored in a DT_AARCH64_AUTH_RELRSZ entry.
# RUN: yaml2obj --docnum=8 -DRELTYPE=RELR -DTAG1=DT_AARCH64_AUTH_RELRSZ -DTAG1VAL=0xFF -DTAG2=DT_AARCH64_AUTH_RELRENT %s -o %t14
# RUN: llvm-readobj --dyn-relocations %t14 2>&1 | FileCheck %s -DFILE=%t14 --check-prefix=INVALID-DT-AARCH64-AUTH-RELRSZ
# RUN: llvm-readelf --dyn-relocations %t14 2>&1 | FileCheck %s -DFILE=%t14 --check-prefix=INVALID-DT-AARCH64-AUTH-RELRSZ

# INVALID-DT-AARCH64-AUTH-RELRSZ: warning: '[[FILE]]': invalid DT_AARCH64_AUTH_RELRSZ value (0xff) or DT_AARCH64_AUTH_RELRENT value (0x18)

## Show we print a warning for an invalid relocation table entry size stored in a DT_AARCH64_AUTH_RELRENT entry.
# RUN: yaml2obj --docnum=8 -DRELTYPE=RELR -DTAG1=DT_AARCH64_AUTH_RELRSZ -DTAG2=DT_AARCH64_AUTH_RELRENT -DTAG2VAL=0xFF %s -o %t15
# RUN: llvm-readobj --dyn-relocations %t15 2>&1 | FileCheck %s -DFILE=%t15 --check-prefix=INVALID-DT-AARCH64-AUTH-RELRENT
# RUN: llvm-readelf --dyn-relocations %t15 2>&1 | FileCheck %s -DFILE=%t15 --check-prefix=INVALID-DT-AARCH64-AUTH-RELRENT

# INVALID-DT-AARCH64-AUTH-RELRENT: invalid DT_AARCH64_AUTH_RELRSZ value (0x18) or DT_AARCH64_AUTH_RELRENT value (0xff)

--- !ELF
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_DYN
Machine: EM_AARCH64
Sections:
- Name: .relx.dyn
Type: SHT_[[RELTYPE]]
- Name: .dynamic
Type: SHT_DYNAMIC
Entries:
- Tag: DT_[[RELTYPE]]
Value: 0x0
- Tag: [[TAG1]]
Value: [[TAG1VAL=0x18]]
- Tag: [[TAG2]]
Value: [[TAG2VAL=0x18]]
- Tag: DT_NULL
Value: 0x0
DynamicSymbols: []
ProgramHeaders:
- Type: PT_LOAD
FirstSec: .relx.dyn
LastSec: .dynamic
32 changes: 22 additions & 10 deletions llvm/test/tools/llvm-readobj/ELF/dynamic-tags-machine-specific.test
Original file line number Diff line number Diff line change
Expand Up @@ -355,20 +355,26 @@ ProgramHeaders:
# RUN: llvm-readobj --dynamic-table %t.aarch64 | FileCheck %s --check-prefix=LLVM-AARCH64
# RUN: llvm-readelf --dynamic-table %t.aarch64 | FileCheck %s --check-prefix=GNU-AARCH64

# LLVM-AARCH64: DynamicSection [ (4 entries)
# LLVM-AARCH64: DynamicSection [ (7 entries)
# LLVM-AARCH64-NEXT: Tag Type Name/Value
# LLVM-AARCH64-NEXT: 0x0000000070000001 AARCH64_BTI_PLT 1
# LLVM-AARCH64-NEXT: 0x0000000070000003 AARCH64_PAC_PLT 2
# LLVM-AARCH64-NEXT: 0x0000000070000005 AARCH64_VARIANT_PCS 3
# LLVM-AARCH64-NEXT: 0x0000000000000000 NULL 0x0
# LLVM-AARCH64-NEXT: 0x0000000070000001 AARCH64_BTI_PLT 1
# LLVM-AARCH64-NEXT: 0x0000000070000003 AARCH64_PAC_PLT 2
# LLVM-AARCH64-NEXT: 0x0000000070000005 AARCH64_VARIANT_PCS 3
# LLVM-AARCH64-NEXT: 0x0000000070000012 AARCH64_AUTH_RELR 0x4
# LLVM-AARCH64-NEXT: 0x0000000070000011 AARCH64_AUTH_RELRSZ 5
# LLVM-AARCH64-NEXT: 0x0000000070000013 AARCH64_AUTH_RELRENT 6
# LLVM-AARCH64-NEXT: 0x0000000000000000 NULL 0x0
# LLVM-AARCH64-NEXT:]

# GNU-AARCH64: Dynamic section at offset {{.*}} contains 4 entries:
# GNU-AARCH64: Dynamic section at offset {{.*}} contains 7 entries:
# GNU-AARCH64-NEXT: Tag Type Name/Value
# GNU-AARCH64-NEXT: 0x0000000070000001 (AARCH64_BTI_PLT) 1
# GNU-AARCH64-NEXT: 0x0000000070000003 (AARCH64_PAC_PLT) 2
# GNU-AARCH64-NEXT: 0x0000000070000005 (AARCH64_VARIANT_PCS) 3
# GNU-AARCH64-NEXT: 0x0000000000000000 (NULL) 0x0
# GNU-AARCH64-NEXT: 0x0000000070000001 (AARCH64_BTI_PLT) 1
# GNU-AARCH64-NEXT: 0x0000000070000003 (AARCH64_PAC_PLT) 2
# GNU-AARCH64-NEXT: 0x0000000070000005 (AARCH64_VARIANT_PCS) 3
# GNU-AARCH64-NEXT: 0x0000000070000012 (AARCH64_AUTH_RELR) 0x4
# GNU-AARCH64-NEXT: 0x0000000070000011 (AARCH64_AUTH_RELRSZ) 5
# GNU-AARCH64-NEXT: 0x0000000070000013 (AARCH64_AUTH_RELRENT) 6
# GNU-AARCH64-NEXT: 0x0000000000000000 (NULL) 0x0

--- !ELF
FileHeader:
Expand All @@ -386,6 +392,12 @@ Sections:
Value: 2
- Tag: DT_AARCH64_VARIANT_PCS
Value: 3
- Tag: DT_AARCH64_AUTH_RELR
Value: 4
- Tag: DT_AARCH64_AUTH_RELRSZ
Value: 5
- Tag: DT_AARCH64_AUTH_RELRENT
Value: 6
- Tag: DT_NULL
Value: 0
ProgramHeaders:
Expand Down
22 changes: 20 additions & 2 deletions llvm/test/tools/llvm-readobj/ELF/relr-relocs.test
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ Sections:
Link: [[LINK=<none>]]

## Check we report a warning when we are unable to dump relocations
## for a SHT_RELR/SHT_ANDROID_RELR section.
## for a SHT_RELR/SHT_ANDROID_RELR/SHT_AARCH64_AUTH_RELR section.

## Case A: check the case when relocations can't be read from an SHT_RELR section.
# RUN: yaml2obj --docnum=2 -DENTSIZE=1 %s -o %t2.broken
Expand Down Expand Up @@ -186,7 +186,25 @@ Sections:
# RUN: llvm-readelf --relocations %t2.broken.android 2>&1 | \
# RUN: FileCheck -DFILE=%t2.broken.android --check-prefix=BROKEN-GNU %s -DSECNAME=SHT_ANDROID_RELR

## Check the behavior when the sh_link field of the SHT_RELR/SHT_ANDROID_RELR section
## Case C: check the case when relocations can't be read from an SHT_AARCH64_AUTH_RELR section.
## SHT_AARCH64_AUTH_RELR = 0x70000004.
# RUN: yaml2obj --docnum=2 -DENTSIZE=1 -DSHTYPE=0x70000004 %s -o %t2.broken.aarch64auth
# RUN: llvm-readobj --relocations %t2.broken.aarch64auth 2>&1 | \
# RUN: FileCheck -DFILE=%t2.broken.aarch64auth --check-prefix=BROKEN-LLVM-AARCH64-AUTH %s -DSECNAME=SHT_AARCH64_AUTH_RELR
# RUN: llvm-readelf --relocations %t2.broken.aarch64auth 2>&1 | \
# RUN: FileCheck -DFILE=%t2.broken.aarch64auth --check-prefix=BROKEN-GNU-AARCH64-AUTH %s -DSECNAME=SHT_AARCH64_AUTH_RELR

# BROKEN-LLVM-AARCH64-AUTH: Relocations [
# BROKEN-LLVM-AARCH64-AUTH-NEXT: Section (1) .relr.dyn {
# BROKEN-LLVM-AARCH64-AUTH-NEXT: warning: '[[FILE]]': SHT_AARCH64_AUTH_RELR section in non-AArch64 ELF found, skipping
# BROKEN-LLVM-AARCH64-AUTH-NEXT: }
# BROKEN-LLVM-AARCH64-AUTH-NEXT: ]

# BROKEN-GNU-AARCH64-AUTH: Relocation section '.relr.dyn' at offset 0x34 contains <?> entries:
# BROKEN-GNU-AARCH64-AUTH-NEXT: Offset Info Type Sym. Value Symbol's Name
# BROKEN-GNU-AARCH64-AUTH-NEXT: warning: '[[FILE]]': SHT_AARCH64_AUTH_RELR section in non-AArch64 ELF found, skipping

## Check the behavior when the sh_link field of the SHT_RELR/SHT_ANDROID_RELR/SHT_AARCH64_AUTH_RELR section
## is set to an arbitrary value. Normally, it is set to 0, because such sections contains
## only relative relocations and do not have an associated symbol table, like other
## relocation sections.
Expand Down
5 changes: 5 additions & 0 deletions llvm/test/tools/llvm-readobj/ELF/section-types.test
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@
# LLVM: Type: SHT_ANDROID_RELA
# LLVM: Name: android_relr
# LLVM: Type: SHT_ANDROID_RELR
# LLVM: Name: aarch64_auth_relr
# LLVM: Type: SHT_AARCH64_AUTH_RELR
# LLVM: Name: llvm_odrtab
# LLVM: Type: SHT_LLVM_ODRTAB
# LLVM: Name: linker_options
Expand Down Expand Up @@ -113,6 +115,7 @@
# GNU-NEXT: android_rel ANDROID_REL
# GNU-NEXT: android_rela ANDROID_RELA
# GNU-NEXT: android_relr ANDROID_RELR
# GNU-NEXT: aarch64_auth_relr AARCH64_AUTH_RELR
# GNU-NEXT: llvm_odrtab LLVM_ODRTAB
# GNU-NEXT: linker_options LLVM_LINKER_OPTIONS
# GNU-NEXT: llvm_call_graph_profile LLVM_CALL_GRAPH_PROFILE
Expand Down Expand Up @@ -191,6 +194,8 @@ Sections:
Type: SHT_ANDROID_RELA
- Name: android_relr
Type: SHT_ANDROID_RELR
- Name: aarch64_auth_relr
Type: SHT_AARCH64_AUTH_RELR
- Name: llvm_odrtab
Type: SHT_LLVM_ODRTAB
- Name: linker_options
Expand Down
Loading

0 comments on commit 647aa46

Please sign in to comment.