diff --git a/llvm/include/llvm/BinaryFormat/DynamicTags.def b/llvm/include/llvm/BinaryFormat/DynamicTags.def --- a/llvm/include/llvm/BinaryFormat/DynamicTags.def +++ b/llvm/include/llvm/BinaryFormat/DynamicTags.def @@ -132,6 +132,14 @@ 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 +// FIXME: use AARCH64_DYNAMIC_TAG instead of DYNAMIC_TAG. +// Currently, using AARCH64_DYNAMIC_TAG breaks yaml2obj for some reason. +DYNAMIC_TAG(AARCH64_AUTH_RELRSZ, 0x70000011) +DYNAMIC_TAG(AARCH64_AUTH_RELR, 0x70000012) +DYNAMIC_TAG(AARCH64_AUTH_RELRENT, 0x70000013) + // Hexagon specific dynamic table entries HEXAGON_DYNAMIC_TAG(HEXAGON_SYMSZ, 0x70000000) HEXAGON_DYNAMIC_TAG(HEXAGON_VER, 0x70000001) diff --git a/llvm/include/llvm/BinaryFormat/ELF.h b/llvm/include/llvm/BinaryFormat/ELF.h --- a/llvm/include/llvm/BinaryFormat/ELF.h +++ b/llvm/include/llvm/BinaryFormat/ELF.h @@ -1056,6 +1056,9 @@ 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, @@ -1642,6 +1645,11 @@ 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 diff --git a/llvm/include/llvm/BinaryFormat/ELFRelocs/AArch64.def b/llvm/include/llvm/BinaryFormat/ELFRelocs/AArch64.def --- a/llvm/include/llvm/BinaryFormat/ELFRelocs/AArch64.def +++ b/llvm/include/llvm/BinaryFormat/ELFRelocs/AArch64.def @@ -135,6 +135,7 @@ 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) diff --git a/llvm/lib/Object/ELF.cpp b/llvm/lib/Object/ELF.cpp --- a/llvm/lib/Object/ELF.cpp +++ b/llvm/lib/Object/ELF.cpp @@ -299,6 +299,7 @@ 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); diff --git a/llvm/lib/ObjectYAML/ELFYAML.cpp b/llvm/lib/ObjectYAML/ELFYAML.cpp --- a/llvm/lib/ObjectYAML/ELFYAML.cpp +++ b/llvm/lib/ObjectYAML/ELFYAML.cpp @@ -669,6 +669,7 @@ 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); diff --git a/llvm/test/tools/llvm-objdump/ELF/dynamic-section.test b/llvm/test/tools/llvm-objdump/ELF/dynamic-section.test --- a/llvm/test/tools/llvm-objdump/ELF/dynamic-section.test +++ b/llvm/test/tools/llvm-objdump/ELF/dynamic-section.test @@ -45,6 +45,9 @@ # ELF64-NEXT: ANDROID_RELR 0x0000000000001000 # ELF64-NEXT: ANDROID_RELRSZ 0x0000000000000010 # ELF64-NEXT: ANDROID_RELRENT 0x0000000000001234 +# ELF64-NEXT: AARCH64_AUTH_RELR 0x0000000000001000 +# ELF64-NEXT: AARCH64_AUTH_RELRSZ 0x0000000000000010 +# ELF64-NEXT: AARCH64_AUTH_RELRENT 0x0000000000005678 # ELF64-NEXT: GNU_HASH 0x0000000000001000 # ELF64-NEXT: TLSDESC_PLT 0x0000000000001000 # ELF64-NEXT: TLSDESC_GOT 0x0000000000001000 @@ -166,6 +169,12 @@ Value: 0x10 - Tag: DT_ANDROID_RELRENT Value: 0x1234 + - Tag: DT_AARCH64_AUTH_RELR + Value: 0x1000 + - Tag: DT_AARCH64_AUTH_RELRSZ + Value: 0x10 + - Tag: DT_AARCH64_AUTH_RELRENT + Value: 0x5678 - Tag: DT_GNU_HASH Value: 0x1000 - Tag: DT_TLSDESC_PLT @@ -261,6 +270,9 @@ # ELF32-NEXT: ANDROID_RELR 0x00001000 # ELF32-NEXT: ANDROID_RELRSZ 0x00000010 # ELF32-NEXT: ANDROID_RELRENT 0x00001234 +# ELF32-NEXT: AARCH64_AUTH_RELR 0x00001000 +# ELF32-NEXT: AARCH64_AUTH_RELRSZ 0x00000010 +# ELF32-NEXT: AARCH64_AUTH_RELRENT 0x00005678 # ELF32-NEXT: GNU_HASH 0x00001000 # ELF32-NEXT: TLSDESC_PLT 0x00001000 # ELF32-NEXT: TLSDESC_GOT 0x00001000 @@ -381,6 +393,12 @@ Value: 0x10 - Tag: DT_ANDROID_RELRENT Value: 0x1234 + - Tag: DT_AARCH64_AUTH_RELR + Value: 0x1000 + - Tag: DT_AARCH64_AUTH_RELRSZ + Value: 0x10 + - Tag: DT_AARCH64_AUTH_RELRENT + Value: 0x5678 - Tag: DT_GNU_HASH Value: 0x1000 - Tag: DT_TLSDESC_PLT diff --git a/llvm/test/tools/llvm-readobj/ELF/AArch64/aarch64-feature-pauth.s b/llvm/test/tools/llvm-readobj/ELF/AArch64/aarch64-feature-pauth.s new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-readobj/ELF/AArch64/aarch64-feature-pauth.s @@ -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: +# 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 diff --git a/llvm/test/tools/llvm-readobj/ELF/broken-dynamic-reloc.test b/llvm/test/tools/llvm-readobj/ELF/broken-dynamic-reloc.test --- a/llvm/test/tools/llvm-readobj/ELF/broken-dynamic-reloc.test +++ b/llvm/test/tools/llvm-readobj/ELF/broken-dynamic-reloc.test @@ -129,7 +129,7 @@ ## INVALID-DT-RELENT: warning: '[[FILE]]': invalid DT_RELSZ value (0x18) or DT_RELENT value (0xff) -## Show we print a warning for an invalid relocation table size stored in a DT_RELRSZ/DT_ANDROID_RELRSZ entry. +## Show we print a warning for an invalid relocation table size stored in a DT_RELRSZ/DT_ANDROID_RELRSZ/DT_AARCH64_AUTH_RELRSZ entry. # RUN: yaml2obj --docnum=2 -DRELTYPE=RELR -DTAG1=DT_RELRSZ -DTAG1VAL=0xFF -DTAG2=DT_RELRENT %s -o %t6 # RUN: llvm-readobj --dyn-relocations %t6 2>&1 | FileCheck %s -DFILE=%t6 --check-prefix=INVALID-DT-RELRSZ # RUN: llvm-readelf --dyn-relocations %t6 2>&1 | FileCheck %s -DFILE=%t6 --check-prefix=INVALID-DT-RELRSZ @@ -138,19 +138,28 @@ # RUN: llvm-readobj --dyn-relocations %t7 2>&1 | FileCheck %s -DFILE=%t7 --check-prefix=INVALID-DT-ANDROID-RELRSZ # RUN: llvm-readelf --dyn-relocations %t7 2>&1 | FileCheck %s -DFILE=%t7 --check-prefix=INVALID-DT-ANDROID-RELRSZ -## INVALID-DT-RELRSZ: warning: '[[FILE]]': invalid DT_RELRSZ value (0xff) or DT_RELRENT value (0x18) -## INVALID-DT-ANDROID-RELRSZ: warning: '[[FILE]]': invalid DT_ANDROID_RELRSZ value (0xff) or DT_ANDROID_RELRENT value (0x18) - -## Show we print a warning for an invalid relocation table entry size stored in a DT_RELRENT/DT_ANDROID_RELRENT entry. -# RUN: yaml2obj --docnum=2 -DRELTYPE=RELR -DTAG1=DT_RELRSZ -DTAG2=DT_RELRENT -DTAG2VAL=0xFF %s -o %t8 -# RUN: llvm-readobj --dyn-relocations %t8 2>&1 | FileCheck %s -DFILE=%t8 --check-prefix=INVALID-DT-RELRENT -# RUN: llvm-readelf --dyn-relocations %t8 2>&1 | FileCheck %s -DFILE=%t8 --check-prefix=INVALID-DT-RELRENT -# RUN: yaml2obj --docnum=2 -DRELTYPE=RELR -DTAG1=DT_ANDROID_RELRSZ -DTAG2=DT_ANDROID_RELRENT -DTAG2VAL=0xFF %s -o %t9 -# RUN: llvm-readobj --dyn-relocations %t9 2>&1 | FileCheck %s -DFILE=%t9 --check-prefix=INVALID-DT-ANDROID-RELRENT -# RUN: llvm-readelf --dyn-relocations %t9 2>&1 | FileCheck %s -DFILE=%t9 --check-prefix=INVALID-DT-ANDROID-RELRENT - -## INVALID-DT-RELRENT: invalid DT_RELRSZ value (0x18) or DT_RELRENT value (0xff) -## INVALID-DT-ANDROID-RELRENT: invalid DT_ANDROID_RELRSZ value (0x18) or DT_ANDROID_RELRENT value (0xff) +# RUN: yaml2obj --docnum=2 -DRELTYPE=RELR -DTAG1=DT_AARCH64_AUTH_RELRSZ -DTAG1VAL=0xFF -DTAG2=DT_AARCH64_AUTH_RELRENT %s -o %t8 +# RUN: llvm-readobj --dyn-relocations %t8 2>&1 | FileCheck %s -DFILE=%t8 --check-prefix=INVALID-DT-AARCH64-AUTH-RELRSZ +# RUN: llvm-readelf --dyn-relocations %t8 2>&1 | FileCheck %s -DFILE=%t8 --check-prefix=INVALID-DT-AARCH64-AUTH-RELRSZ + +## INVALID-DT-RELRSZ: warning: '[[FILE]]': invalid DT_RELRSZ value (0xff) or DT_RELRENT value (0x18) +## INVALID-DT-ANDROID-RELRSZ: warning: '[[FILE]]': invalid DT_ANDROID_RELRSZ value (0xff) or DT_ANDROID_RELRENT value (0x18) +## 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_RELRENT/DT_ANDROID_RELRENT/DT_AARCH64_AUTH_RELRENT entry. +# RUN: yaml2obj --docnum=2 -DRELTYPE=RELR -DTAG1=DT_RELRSZ -DTAG2=DT_RELRENT -DTAG2VAL=0xFF %s -o %t9 +# RUN: llvm-readobj --dyn-relocations %t9 2>&1 | FileCheck %s -DFILE=%t9 --check-prefix=INVALID-DT-RELRENT +# RUN: llvm-readelf --dyn-relocations %t9 2>&1 | FileCheck %s -DFILE=%t9 --check-prefix=INVALID-DT-RELRENT +# RUN: yaml2obj --docnum=2 -DRELTYPE=RELR -DTAG1=DT_ANDROID_RELRSZ -DTAG2=DT_ANDROID_RELRENT -DTAG2VAL=0xFF %s -o %t10 +# RUN: llvm-readobj --dyn-relocations %t10 2>&1 | FileCheck %s -DFILE=%t10 --check-prefix=INVALID-DT-ANDROID-RELRENT +# RUN: llvm-readelf --dyn-relocations %t10 2>&1 | FileCheck %s -DFILE=%t10 --check-prefix=INVALID-DT-ANDROID-RELRENT +# RUN: yaml2obj --docnum=2 -DRELTYPE=RELR -DTAG1=DT_AARCH64_AUTH_RELRSZ -DTAG2=DT_AARCH64_AUTH_RELRENT -DTAG2VAL=0xFF %s -o %t11 +# RUN: llvm-readobj --dyn-relocations %t11 2>&1 | FileCheck %s -DFILE=%t11 --check-prefix=INVALID-DT-AARCH64-AUTH-RELRENT +# RUN: llvm-readelf --dyn-relocations %t11 2>&1 | FileCheck %s -DFILE=%t11 --check-prefix=INVALID-DT-AARCH64-AUTH-RELRENT + +## INVALID-DT-RELRENT: invalid DT_RELRSZ value (0x18) or DT_RELRENT value (0xff) +## INVALID-DT-ANDROID-RELRENT: invalid DT_ANDROID_RELRSZ value (0x18) or DT_ANDROID_RELRENT value (0xff) +## INVALID-DT-AARCH64-AUTH-RELRENT: invalid DT_AARCH64_AUTH_RELRSZ value (0x18) or DT_AARCH64_AUTH_RELRENT value (0xff) ## Show we print a warning for an invalid value of DT_PLTRELSZ, which describes the total size ## of the relocation entries associated with the procedure linkage table. diff --git a/llvm/test/tools/llvm-readobj/ELF/dynamic-tags.test b/llvm/test/tools/llvm-readobj/ELF/dynamic-tags.test --- a/llvm/test/tools/llvm-readobj/ELF/dynamic-tags.test +++ b/llvm/test/tools/llvm-readobj/ELF/dynamic-tags.test @@ -9,7 +9,7 @@ # RUN: | FileCheck %s --strict-whitespace --match-full-lines --check-prefix=GNU64 # RUN: llvm-readelf -d %t1 | FileCheck %s --check-prefix=GNU64 -# LLVM64:DynamicSection [ (61 entries) +# LLVM64:DynamicSection [ (64 entries) # LLVM64-NEXT: Tag Type Name/Value # LLVM64-NEXT: 0x0000000000000001 NEEDED Shared library: [D] # LLVM64-NEXT: 0x0000000000000002 PLTRELSZ 16 (bytes) @@ -54,6 +54,9 @@ # LLVM64-NEXT: 0x000000006FFFE000 ANDROID_RELR 0x1000 # LLVM64-NEXT: 0x000000006FFFE001 ANDROID_RELRSZ 0x10 # LLVM64-NEXT: 0x000000006FFFE003 ANDROID_RELRENT 0x1234 +# LLVM64-NEXT: 0x0000000070000012 AARCH64_AUTH_RELR 0x1000 +# LLVM64-NEXT: 0x0000000070000011 AARCH64_AUTH_RELRSZ 16 (bytes) +# LLVM64-NEXT: 0x0000000070000013 AARCH64_AUTH_RELRENT 22136 (bytes) # LLVM64-NEXT: 0x000000006FFFFEF5 GNU_HASH 0x1000 # LLVM64-NEXT: 0x000000006FFFFEF6 TLSDESC_PLT 0x1000 # LLVM64-NEXT: 0x000000006FFFFEF7 TLSDESC_GOT 0x1000 @@ -74,7 +77,7 @@ # LLVM64-NEXT: 0x0000000000000000 NULL 0x0 # LLVM64-NEXT:] -# GNU64:Dynamic section at offset {{.*}} contains 61 entries: +# GNU64:Dynamic section at offset {{.*}} contains 64 entries: # GNU64-NEXT: Tag Type Name/Value # GNU64-NEXT: 0x0000000000000001 (NEEDED) Shared library: [D] # GNU64-NEXT: 0x0000000000000002 (PLTRELSZ) 16 (bytes) @@ -119,6 +122,9 @@ # GNU64-NEXT: 0x000000006fffe000 (ANDROID_RELR) 0x1000 # GNU64-NEXT: 0x000000006fffe001 (ANDROID_RELRSZ) 0x10 # GNU64-NEXT: 0x000000006fffe003 (ANDROID_RELRENT) 0x1234 +# GNU64-NEXT: 0x0000000070000012 (AARCH64_AUTH_RELR) 0x1000 +# GNU64-NEXT: 0x0000000070000011 (AARCH64_AUTH_RELRSZ) 16 (bytes) +# GNU64-NEXT: 0x0000000070000013 (AARCH64_AUTH_RELRENT) 22136 (bytes) # GNU64-NEXT: 0x000000006ffffef5 (GNU_HASH) 0x1000 # GNU64-NEXT: 0x000000006ffffef6 (TLSDESC_PLT) 0x1000 # GNU64-NEXT: 0x000000006ffffef7 (TLSDESC_GOT) 0x1000 @@ -240,6 +246,12 @@ Value: 0x10 - Tag: DT_ANDROID_RELRENT Value: 0x1234 + - Tag: DT_AARCH64_AUTH_RELR + Value: 0x1000 + - Tag: DT_AARCH64_AUTH_RELRSZ + Value: 0x10 + - Tag: DT_AARCH64_AUTH_RELRENT + Value: 0x5678 - Tag: DT_GNU_HASH Value: 0x1000 - Tag: DT_TLSDESC_PLT @@ -300,7 +312,7 @@ # RUN: | FileCheck %s --check-prefix=GNU32 --strict-whitespace --match-full-lines # RUN: llvm-readelf -d %t2 | FileCheck %s --check-prefix=GNU32 --strict-whitespace --match-full-lines -# LLVM32:DynamicSection [ (61 entries) +# LLVM32:DynamicSection [ (64 entries) # LLVM32-NEXT: Tag Type Name/Value # LLVM32-NEXT: 0x00000001 NEEDED Shared library: [D] # LLVM32-NEXT: 0x00000002 PLTRELSZ 16 (bytes) @@ -345,6 +357,9 @@ # LLVM32-NEXT: 0x6FFFE000 ANDROID_RELR 0x1000 # LLVM32-NEXT: 0x6FFFE001 ANDROID_RELRSZ 0x10 # LLVM32-NEXT: 0x6FFFE003 ANDROID_RELRENT 0x1234 +# LLVM32-NEXT: 0x70000012 AARCH64_AUTH_RELR 0x1000 +# LLVM32-NEXT: 0x70000011 AARCH64_AUTH_RELRSZ 16 (bytes) +# LLVM32-NEXT: 0x70000013 AARCH64_AUTH_RELRENT 22136 (bytes) # LLVM32-NEXT: 0x6FFFFEF5 GNU_HASH 0x1000 # LLVM32-NEXT: 0x6FFFFEF6 TLSDESC_PLT 0x1000 # LLVM32-NEXT: 0x6FFFFEF7 TLSDESC_GOT 0x1000 @@ -365,7 +380,7 @@ # LLVM32-NEXT: 0x00000000 NULL 0x0 # LLVM32-NEXT:] -# GNU32:Dynamic section at offset 0x84 contains 61 entries: +# GNU32:Dynamic section at offset 0x84 contains 64 entries: # GNU32-NEXT: Tag Type Name/Value # GNU32-NEXT: 0x00000001 (NEEDED) Shared library: [D] # GNU32-NEXT: 0x00000002 (PLTRELSZ) 16 (bytes) @@ -410,6 +425,9 @@ # GNU32-NEXT: 0x6fffe000 (ANDROID_RELR) 0x1000 # GNU32-NEXT: 0x6fffe001 (ANDROID_RELRSZ) 0x10 # GNU32-NEXT: 0x6fffe003 (ANDROID_RELRENT) 0x1234 +# GNU32-NEXT: 0x70000012 (AARCH64_AUTH_RELR) 0x1000 +# GNU32-NEXT: 0x70000011 (AARCH64_AUTH_RELRSZ) 16 (bytes) +# GNU32-NEXT: 0x70000013 (AARCH64_AUTH_RELRENT) 22136 (bytes) # GNU32-NEXT: 0x6ffffef5 (GNU_HASH) 0x1000 # GNU32-NEXT: 0x6ffffef6 (TLSDESC_PLT) 0x1000 # GNU32-NEXT: 0x6ffffef7 (TLSDESC_GOT) 0x1000 @@ -490,12 +508,13 @@ # PHENTSIZE-WARN-NEXT: warning: '[[FILE]]': unable to parse DT_SYMTAB_SHNDX: invalid e_phentsize: 1 # PHENTSIZE-WARN-NEXT: warning: '[[FILE]]': unable to parse DT_RELR: invalid e_phentsize: 1 # PHENTSIZE-WARN-NEXT: warning: '[[FILE]]': unable to parse DT_ANDROID_RELR: invalid e_phentsize: 1 +# PHENTSIZE-WARN-NEXT: warning: '[[FILE]]': unable to parse DT_AARCH64_AUTH_RELR: invalid e_phentsize: 1 # PHENTSIZE-WARN-NEXT: warning: '[[FILE]]': unable to parse DT_GNU_HASH: invalid e_phentsize: 1 # PHENTSIZE-LLVM: warning: '[[FILE]]': string table was not found # PHENTSIZE-LLVM-NEXT: LoadName: -# PHENTSIZE-LLVM: DynamicSection [ (61 entries) +# PHENTSIZE-LLVM: DynamicSection [ (64 entries) # PHENTSIZE-LLVM-NEXT: Tag Type Name/Value # PHENTSIZE-LLVM-NEXT: 0x0000000000000001 NEEDED Shared library: [] # PHENTSIZE-LLVM-NEXT: 0x0000000000000002 PLTRELSZ 16 (bytes) @@ -540,6 +559,9 @@ # PHENTSIZE-LLVM-NEXT: 0x000000006FFFE000 ANDROID_RELR 0x1000 # PHENTSIZE-LLVM-NEXT: 0x000000006FFFE001 ANDROID_RELRSZ 0x10 # PHENTSIZE-LLVM-NEXT: 0x000000006FFFE003 ANDROID_RELRENT 0x1234 +# PHENTSIZE-LLVM-NEXT: 0x0000000070000012 AARCH64_AUTH_RELR 0x1000 +# PHENTSIZE-LLVM-NEXT: 0x0000000070000011 AARCH64_AUTH_RELRSZ 16 (bytes) +# PHENTSIZE-LLVM-NEXT: 0x0000000070000013 AARCH64_AUTH_RELRENT 22136 (bytes) # PHENTSIZE-LLVM-NEXT: 0x000000006FFFFEF5 GNU_HASH 0x1000 # PHENTSIZE-LLVM-NEXT: 0x000000006FFFFEF6 TLSDESC_PLT 0x1000 # PHENTSIZE-LLVM-NEXT: 0x000000006FFFFEF7 TLSDESC_GOT 0x1000 @@ -560,7 +582,7 @@ # PHENTSIZE-LLVM-NEXT: 0x0000000000000000 NULL 0x0 # PHENTSIZE-LLVM-NEXT: ] -# PHENTSIZE-GNU: Dynamic section at offset 0xc0 contains 61 entries: +# PHENTSIZE-GNU: Dynamic section at offset 0xc0 contains 64 entries: # PHENTSIZE-GNU-NEXT: Tag Type Name/Value # PHENTSIZE-GNU-NEXT: warning: '[[FILE]]': string table was not found # PHENTSIZE-GNU-NEXT: 0x0000000000000001 (NEEDED) Shared library: [] @@ -606,6 +628,9 @@ # PHENTSIZE-GNU-NEXT: 0x000000006fffe000 (ANDROID_RELR) 0x1000 # PHENTSIZE-GNU-NEXT: 0x000000006fffe001 (ANDROID_RELRSZ) 0x10 # PHENTSIZE-GNU-NEXT: 0x000000006fffe003 (ANDROID_RELRENT) 0x1234 +# PHENTSIZE-GNU-NEXT: 0x0000000070000012 (AARCH64_AUTH_RELR) 0x1000 +# PHENTSIZE-GNU-NEXT: 0x0000000070000011 (AARCH64_AUTH_RELRSZ) 16 (bytes) +# PHENTSIZE-GNU-NEXT: 0x0000000070000013 (AARCH64_AUTH_RELRENT) 22136 (bytes) # PHENTSIZE-GNU-NEXT: 0x000000006ffffef5 (GNU_HASH) 0x1000 # PHENTSIZE-GNU-NEXT: 0x000000006ffffef6 (TLSDESC_PLT) 0x1000 # PHENTSIZE-GNU-NEXT: 0x000000006ffffef7 (TLSDESC_GOT) 0x1000 diff --git a/llvm/test/tools/llvm-readobj/ELF/relr-relocs.test b/llvm/test/tools/llvm-readobj/ELF/relr-relocs.test --- a/llvm/test/tools/llvm-readobj/ELF/relr-relocs.test +++ b/llvm/test/tools/llvm-readobj/ELF/relr-relocs.test @@ -158,7 +158,7 @@ Link: [[LINK=]] ## 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 @@ -186,7 +186,25 @@ # 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. diff --git a/llvm/test/tools/llvm-readobj/ELF/section-types.test b/llvm/test/tools/llvm-readobj/ELF/section-types.test --- a/llvm/test/tools/llvm-readobj/ELF/section-types.test +++ b/llvm/test/tools/llvm-readobj/ELF/section-types.test @@ -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 @@ -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 @@ -191,6 +194,8 @@ 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 diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp --- a/llvm/tools/llvm-readobj/ELFDumper.cpp +++ b/llvm/tools/llvm-readobj/ELFDumper.cpp @@ -2087,21 +2087,34 @@ break; case ELF::DT_RELR: case ELF::DT_ANDROID_RELR: + case ELF::DT_AARCH64_AUTH_RELR: DynRelrRegion.Addr = toMappedAddr(Dyn.getTag(), Dyn.getPtr()); break; case ELF::DT_RELRSZ: case ELF::DT_ANDROID_RELRSZ: + case ELF::DT_AARCH64_AUTH_RELRSZ: DynRelrRegion.Size = Dyn.getVal(); - DynRelrRegion.SizePrintName = Dyn.d_tag == ELF::DT_RELRSZ - ? "DT_RELRSZ value" - : "DT_ANDROID_RELRSZ value"; + if (Dyn.d_tag == ELF::DT_RELRSZ) + DynRelrRegion.SizePrintName = "DT_RELRSZ value"; + else if (Dyn.d_tag == ELF::DT_ANDROID_RELRSZ) + DynRelrRegion.SizePrintName = "DT_ANDROID_RELRSZ value"; + else if (Dyn.d_tag == ELF::DT_AARCH64_AUTH_RELRSZ) + DynRelrRegion.SizePrintName = "DT_AARCH64_AUTH_RELRSZ value"; + else + llvm_unreachable("unexpected Dyn.d_tag value"); break; case ELF::DT_RELRENT: case ELF::DT_ANDROID_RELRENT: + case ELF::DT_AARCH64_AUTH_RELRENT: DynRelrRegion.EntSize = Dyn.getVal(); - DynRelrRegion.EntSizePrintName = Dyn.d_tag == ELF::DT_RELRENT - ? "DT_RELRENT value" - : "DT_ANDROID_RELRENT value"; + if (Dyn.d_tag == ELF::DT_RELRENT) + DynRelrRegion.EntSizePrintName = "DT_RELRENT value"; + else if (Dyn.d_tag == ELF::DT_ANDROID_RELRENT) + DynRelrRegion.EntSizePrintName = "DT_ANDROID_RELRENT value"; + else if (Dyn.d_tag == ELF::DT_AARCH64_AUTH_RELRENT) + DynRelrRegion.EntSizePrintName = "DT_AARCH64_AUTH_RELRENT value"; + else + llvm_unreachable("unexpected Dyn.d_tag value"); break; case ELF::DT_PLTREL: if (Dyn.getVal() == DT_REL) @@ -2464,6 +2477,8 @@ case DT_PREINIT_ARRAYSZ: case DT_RELRSZ: case DT_RELRENT: + case DT_AARCH64_AUTH_RELRSZ: + case DT_AARCH64_AUTH_RELRENT: case DT_ANDROID_RELSZ: case DT_ANDROID_RELASZ: return std::to_string(Value) + " (bytes)"; @@ -3798,7 +3813,8 @@ template static void printRelocHeaderFields(formatted_raw_ostream &OS, unsigned SType) { bool IsRela = SType == ELF::SHT_RELA || SType == ELF::SHT_ANDROID_RELA; - bool IsRelr = SType == ELF::SHT_RELR || SType == ELF::SHT_ANDROID_RELR; + bool IsRelr = SType == ELF::SHT_RELR || SType == ELF::SHT_ANDROID_RELR || + SType == ELF::SHT_AARCH64_AUTH_RELR; if (ELFT::Is64Bits) OS << " "; else @@ -3831,7 +3847,8 @@ return Sec.sh_type == ELF::SHT_REL || Sec.sh_type == ELF::SHT_RELA || Sec.sh_type == ELF::SHT_RELR || Sec.sh_type == ELF::SHT_ANDROID_REL || Sec.sh_type == ELF::SHT_ANDROID_RELA || - Sec.sh_type == ELF::SHT_ANDROID_RELR; + Sec.sh_type == ELF::SHT_ANDROID_RELR || + Sec.sh_type == ELF::SHT_AARCH64_AUTH_RELR; } template void GNUELFDumper::printRelocations() { @@ -3847,8 +3864,9 @@ return RelasOrErr->size(); } - if (!opts::RawRelr && (Sec.sh_type == ELF::SHT_RELR || - Sec.sh_type == ELF::SHT_ANDROID_RELR)) { + if (!opts::RawRelr && + (Sec.sh_type == ELF::SHT_RELR || Sec.sh_type == ELF::SHT_ANDROID_RELR || + Sec.sh_type == ELF::SHT_AARCH64_AUTH_RELR)) { Expected RelrsOrErr = this->Obj.relrs(Sec); if (!RelrsOrErr) return RelrsOrErr.takeError(); @@ -5345,6 +5363,31 @@ return true; } +template +static bool printAArch64Note(raw_ostream &OS, uint32_t NoteType, + ArrayRef Desc) { + if (NoteType != NT_ARM_TYPE_PAUTH_ABI_TAG) + return false; + + OS << " AArch64 PAuth ABI tag: "; + if (Desc.size() < 16) { + OS << format("", Desc.size()); + return false; + } + + uint64_t platform = + support::endian::read64(Desc.data() + 0); + uint64_t version = + support::endian::read64(Desc.data() + 8); + OS << format("platform 0x%x, version 0x%x", platform, version); + + if (Desc.size() > 16) + OS << ", additional info 0x" + << toHex(ArrayRef(Desc.data() + 16, Desc.size() - 16)); + + return true; +} + template void GNUELFDumper::printMemtag( const ArrayRef> DynamicEntries, @@ -5744,6 +5787,10 @@ "NT_ANDROID_TYPE_MEMTAG (Android memory tagging information)"}, }; +const NoteType ARMNoteTypes[] = { + {ELF::NT_ARM_TYPE_PAUTH_ABI_TAG, "NT_ARM_TYPE_PAUTH_ABI_TAG"}, +}; + const NoteType CoreNoteTypes[] = { {ELF::NT_PRSTATUS, "NT_PRSTATUS (prstatus structure)"}, {ELF::NT_FPREGSET, "NT_FPREGSET (floating point registers)"}, @@ -5860,6 +5907,8 @@ return FindNote(LLVMOMPOFFLOADNoteTypes); if (Name == "Android") return FindNote(AndroidNoteTypes); + if (Name == "ARM") + return FindNote(ARMNoteTypes); if (ELFType == ELF::ET_CORE) return FindNote(CoreNoteTypes); @@ -6015,6 +6064,9 @@ } else if (Name == "Android") { if (printAndroidNote(OS, Type, Descriptor)) return Error::success(); + } else if (Name == "ARM") { + if (printAArch64Note(OS, Type, Descriptor)) + return Error::success(); } if (!Descriptor.empty()) { OS << " description data:"; @@ -6207,11 +6259,12 @@ toString(std::move(E))); }; - // SHT_RELR/SHT_ANDROID_RELR sections do not have an associated symbol table. - // For them we should not treat the value of the sh_link field as an index of - // a symbol table. + // SHT_RELR/SHT_ANDROID_RELR/SHT_AARCH64_AUTH_RELR sections do not have an + // associated symbol table. For them we should not treat the value of the + // sh_link field as an index of a symbol table. const Elf_Shdr *SymTab; - if (Sec.sh_type != ELF::SHT_RELR && Sec.sh_type != ELF::SHT_ANDROID_RELR) { + if (Sec.sh_type != ELF::SHT_RELR && Sec.sh_type != ELF::SHT_ANDROID_RELR && + Sec.sh_type != ELF::SHT_AARCH64_AUTH_RELR) { Expected SymTabOrErr = Obj.getSection(Sec.sh_link); if (!SymTabOrErr) { Warn(SymTabOrErr.takeError(), "unable to locate a symbol table for"); @@ -6239,6 +6292,12 @@ Warn(RangeOrErr.takeError()); } break; + case ELF::SHT_AARCH64_AUTH_RELR: + if (Obj.getHeader().e_machine != EM_AARCH64) { + this->reportUniqueWarning("SHT_AARCH64_AUTH_RELR section in non-AArch64 ELF found, skipping"); + break; + } + [[fallthrough]]; case ELF::SHT_RELR: case ELF::SHT_ANDROID_RELR: { Expected RangeOrErr = Obj.relrs(Sec); @@ -7576,6 +7635,29 @@ return true; } +template +static bool printAarch64NoteLLVMStyle(uint32_t NoteType, ArrayRef Desc, + ScopedPrinter &W) { + if (NoteType != NT_ARM_TYPE_PAUTH_ABI_TAG) + return false; + + if (Desc.size() < 16) + return false; + + uint64_t platform = + support::endian::read64(Desc.data() + 0); + uint64_t version = + support::endian::read64(Desc.data() + 8); + W.printNumber("Platform", platform); + W.printNumber("Version", version); + + if (Desc.size() > 16) + W.printString("Additional info", + toHex(ArrayRef(Desc.data() + 16, Desc.size() - 16))); + + return true; +} + template void LLVMELFDumper::printMemtag( const ArrayRef> DynamicEntries, @@ -7712,6 +7794,9 @@ } else if (Name == "Android") { if (printAndroidNoteLLVMStyle(Type, Descriptor, W)) return Error::success(); + } else if (Name == "ARM") { + if (printAarch64NoteLLVMStyle(Type, Descriptor, W)) + return Error::success(); } if (!Descriptor.empty()) { W.printBinaryBlock("Description data", Descriptor);