Index: include/llvm/BinaryFormat/DynamicTags.def =================================================================== --- include/llvm/BinaryFormat/DynamicTags.def +++ include/llvm/BinaryFormat/DynamicTags.def @@ -6,6 +6,11 @@ // such as DT_HIOS, etc. to allow using this file to in other contexts. // For example we can use it to generate a stringification switch statement. +#ifndef AARCH64_DYNAMIC_TAG +#define AARCH64_DYNAMIC_TAG(name, value) DYNAMIC_TAG(name, value) +#define AARCH64_DYNAMIC_TAG_DEFINED +#endif + #ifndef HEXAGON_DYNAMIC_TAG #define HEXAGON_DYNAMIC_TAG(name, value) DYNAMIC_TAG(name, value) #define HEXAGON_DYNAMIC_TAG_DEFINED @@ -107,6 +112,10 @@ // table. DYNAMIC_TAG(VERNEEDNUM, 0X6FFFFFFF) // The number of entries in DT_VERNEED. +// AArch64 specific dynamic table entries +AARCH64_DYNAMIC_TAG(AARCH64_BTI_PLT, 0x70000001) +AARCH64_DYNAMIC_TAG(AARCH64_PAC_PLT, 0x70000003) + // Hexagon specific dynamic table entries HEXAGON_DYNAMIC_TAG(HEXAGON_SYMSZ, 0x70000000) HEXAGON_DYNAMIC_TAG(HEXAGON_VER, 0x70000001) @@ -204,6 +213,10 @@ #undef DYNAMIC_TAG_MARKER #undef DYNAMIC_TAG_MARKER_DEFINED #endif +#ifdef AARCH64_DYNAMIC_TAG_DEFINED +#undef AARCH64_DYNAMIC_TAG +#undef AARCH64_DYNAMIC_TAG_DEFINED +#endif #ifdef MIPS_DYNAMIC_TAG_DEFINED #undef MIPS_DYNAMIC_TAG #undef MIPS_DYNAMIC_TAG_DEFINED Index: lib/Object/ELF.cpp =================================================================== --- lib/Object/ELF.cpp +++ lib/Object/ELF.cpp @@ -434,6 +434,14 @@ #define DYNAMIC_TAG(n, v) switch (Arch) { + case ELF::EM_AARCH64: + switch (Type) { +#define AARCH64_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value) +#include "llvm/BinaryFormat/DynamicTags.def" +#undef AARCH64_DYNAMIC_TAG + } + break; + case ELF::EM_HEXAGON: switch (Type) { #define HEXAGON_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value) @@ -461,6 +469,7 @@ #undef DYNAMIC_TAG switch (Type) { // Now handle all dynamic tags except the architecture specific ones +#define AARCH64_DYNAMIC_TAG(name, value) #define MIPS_DYNAMIC_TAG(name, value) #define HEXAGON_DYNAMIC_TAG(name, value) #define PPC64_DYNAMIC_TAG(name, value) @@ -469,6 +478,7 @@ #define DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value) #include "llvm/BinaryFormat/DynamicTags.def" #undef DYNAMIC_TAG +#undef AARCH64_DYNAMIC_TAG #undef MIPS_DYNAMIC_TAG #undef HEXAGON_DYNAMIC_TAG #undef PPC64_DYNAMIC_TAG Index: lib/ObjectYAML/ELFYAML.cpp =================================================================== --- lib/ObjectYAML/ELFYAML.cpp +++ lib/ObjectYAML/ELFYAML.cpp @@ -680,6 +680,7 @@ assert(Object && "The IO context is not initialized"); // Disable architecture specific tags by default. We might enable them below. +#define AARCH64_DYNAMIC_TAG(name, value) #define MIPS_DYNAMIC_TAG(name, value) #define HEXAGON_DYNAMIC_TAG(name, value) #define PPC64_DYNAMIC_TAG(name, value) @@ -689,6 +690,13 @@ #define STRINGIFY(X) (#X) #define DYNAMIC_TAG(X, Y) IO.enumCase(Value, STRINGIFY(DT_##X), ELF::DT_##X); switch (Object->Header.Machine) { + case ELF::EM_AARCH64: +#undef AARCH64_DYNAMIC_TAG +#define AARCH64_DYNAMIC_TAG(name, value) DYNAMIC_TAG(name, value) +#include "llvm/BinaryFormat/DynamicTags.def" +#undef AARCH64_DYNAMIC_TAG +#define AARCH64_DYNAMIC_TAG(name, value) + break; case ELF::EM_MIPS: #undef MIPS_DYNAMIC_TAG #define MIPS_DYNAMIC_TAG(name, value) DYNAMIC_TAG(name, value) @@ -714,7 +722,7 @@ #include "llvm/BinaryFormat/DynamicTags.def" break; } - +#undef AARCH64_DYNAMIC_TAG #undef MIPS_DYNAMIC_TAG #undef HEXAGON_DYNAMIC_TAG #undef PPC64_DYNAMIC_TAG Index: test/tools/llvm-readobj/Inputs/elf-dynamic-tags-machine-specific.yaml =================================================================== --- test/tools/llvm-readobj/Inputs/elf-dynamic-tags-machine-specific.yaml +++ test/tools/llvm-readobj/Inputs/elf-dynamic-tags-machine-specific.yaml @@ -200,3 +200,41 @@ VAddr: 0x1010 Sections: - Section: .dynamic + +# Fourth document: AARCH64 +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_EXEC + Machine: EM_AARCH64 +Sections: + - Name: .dynstr + Type: SHT_STRTAB + Address: 0x1000 + Size: 0x10 + Content: "004400550066007700" + - Name: .dynamic + Type: SHT_DYNAMIC + Address: 0x1010 + Entries: + - Tag: DT_HASH + Value: 0x1000 + - Tag: DT_AARCH64_BTI_PLT + Value: 0 + - Tag: DT_AARCH64_PAC_PLT + Value: 0 + - Tag: 0x1234abcd + Value: 0x1 + - Tag: DT_NULL + Value: 0 +ProgramHeaders: + - Type: PT_LOAD + VAddr: 0x1000 + Sections: + - Section: .dynstr + - Section: .dynamic + - Type: PT_DYNAMIC + VAddr: 0x1010 + Sections: + - Section: .dynamic Index: test/tools/llvm-readobj/elf-dynamic-tags-machine-specific.test =================================================================== --- test/tools/llvm-readobj/elf-dynamic-tags-machine-specific.test +++ test/tools/llvm-readobj/elf-dynamic-tags-machine-specific.test @@ -151,3 +151,25 @@ # GNU-PPC-NEXT: 0x0000000070000000 (PPC64_GLINK) 0x1000 # GNU-PPC-NEXT: 0x000000001234abcd (unknown) 0x1 # GNU-PPC-NEXT: 0x0000000000000000 (NULL) 0x0 + +# Test that AARCH64 machine-specific tags can be dumped. +# RUN: yaml2obj --docnum=4 %S/Inputs/elf-dynamic-tags-machine-specific.yaml -o %t.aarch64 +# 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 [ (5 entries) +# LLVM-AARCH64-NEXT: Tag Type Name/Value +# LLVM-AARCH64-NEXT: 0x0000000000000004 HASH 0x1000 +# LLVM-AARCH64-NEXT: 0x0000000070000001 AARCH64_BTI_PLT 0 +# LLVM-AARCH64-NEXT: 0x0000000070000003 AARCH64_PAC_PLT 0 +# LLVM-AARCH64-NEXT: 0x000000001234ABCD unknown 0x1 +# LLVM-AARCH64-NEXT: 0x0000000000000000 NULL 0x0 +# LLVM-AARCH64-NEXT:] + +# GNU-AARCH64: Dynamic section at offset {{.*}} contains 5 entries: +# GNU-AARCH64-NEXT: Tag Type Name/Value +# GNU-AARCH64-NEXT: 0x0000000000000004 (HASH) 0x1000 +# GNU-AARCH64-NEXT: 0x0000000070000001 (AARCH64_BTI_PLT) 0 +# GNU-AARCH64-NEXT: 0x0000000070000003 (AARCH64_PAC_PLT) 0 +# GNU-AARCH64-NEXT: 0x000000001234abcd (unknown) 0x1 +# GNU-AARCH64-NEXT: 0x0000000000000000 (NULL) 0x0 Index: test/tools/obj2yaml/dynamic-section-arch-tags.test =================================================================== --- test/tools/obj2yaml/dynamic-section-arch-tags.test +++ test/tools/obj2yaml/dynamic-section-arch-tags.test @@ -249,12 +249,36 @@ - Tag: DT_PPC64_GLINK Value: 0x0000000000000001 +## Check we can handle AARCH64 specific tags. +# RUN: yaml2obj -docnum=4 %s -o %t2 +# RUN: obj2yaml %t2 | FileCheck %s --check-prefix=AARCH64 + +# AARCH64: - Tag: DT_AARCH64_BTI_PLT +# AARCH64-NEXT: Value: 0x0000000000000000 +# AARCH64-NEXT: - Tag: DT_AARCH64_PAC_PLT +# AARCH64-NEXT: Value: 0x0000000000000000 + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_AARCH64 +Sections: + - Name: .dynamic + Type: SHT_DYNAMIC + Entries: + - Tag: DT_AARCH64_BTI_PLT + Value: 0x0000000000000000 + - Tag: DT_AARCH64_PAC_PLT + Value: 0x0000000000000000 + ## Check we can't use a tag from a different architecture, ## even if it has the same numeric value as a valid tag. ## Here for EM_PPC64 we are trying to use DT_HEXAGON_SYMSZ ## instead of DT_PPC64_GLINK. They both have value of 0x70000000. -# RUN: not yaml2obj -docnum=4 %s 2>&1 | FileCheck %s --check-prefix=ERR +# RUN: not yaml2obj -docnum=5 %s 2>&1 | FileCheck %s --check-prefix=ERR # ERR: error: invalid hex64 number # ERR-NEXT: - Tag: DT_HEXAGON_SYMSZ Index: tools/llvm-readobj/ELFDumper.cpp =================================================================== --- tools/llvm-readobj/ELFDumper.cpp +++ tools/llvm-readobj/ELFDumper.cpp @@ -1463,6 +1463,17 @@ static const char *getTypeString(unsigned Arch, uint64_t Type) { #define DYNAMIC_TAG(n, v) switch (Arch) { + + case EM_AARCH64: + switch (Type) { +#define AARCH64_DYNAMIC_TAG(name, value) \ + case DT_##name: \ + return #name; +#include "llvm/BinaryFormat/DynamicTags.def" +#undef AARCH64_DYNAMIC_TAG + } + break; + case EM_HEXAGON: switch (Type) { #define HEXAGON_DYNAMIC_TAG(name, value) \ @@ -1496,6 +1507,7 @@ #undef DYNAMIC_TAG switch (Type) { // Now handle all dynamic tags except the architecture specific ones +#define AARCH64_DYNAMIC_TAG(name, value) #define MIPS_DYNAMIC_TAG(name, value) #define HEXAGON_DYNAMIC_TAG(name, value) #define PPC64_DYNAMIC_TAG(name, value) @@ -1506,6 +1518,7 @@ return #name; #include "llvm/BinaryFormat/DynamicTags.def" #undef DYNAMIC_TAG +#undef AARCH64_DYNAMIC_TAG #undef MIPS_DYNAMIC_TAG #undef HEXAGON_DYNAMIC_TAG #undef PPC64_DYNAMIC_TAG @@ -1783,6 +1796,51 @@ uint64_t Value) const { const char *ConvChar = (opts::Output == opts::GNU) ? "0x%" PRIx64 : "0x%" PRIX64; + + // Handle custom printing of architecture specific tags apart + // from the machine independent SUN extensions from DT_AUXILIARY + if (Type >= DT_LOPROC && Type < DT_AUXILIARY) { + switch (ObjF->getELFFile()->getHeader()->e_machine) { + case EM_AARCH64: + switch (Type) { + case DT_AARCH64_BTI_PLT: + case DT_AARCH64_PAC_PLT: + OS << Value; + return; + default: + OS << format(ConvChar, Value); + return; + } + case EM_HEXAGON: + switch (Type) { + case DT_HEXAGON_VER: + OS << Value; + return; + default: + OS << format(ConvChar, Value); + return; + } + case EM_MIPS: + switch (Type) { + case DT_MIPS_RLD_VERSION: + case DT_MIPS_LOCAL_GOTNO: + case DT_MIPS_SYMTABNO: + case DT_MIPS_UNREFEXTNO: + OS << Value; + return; + case DT_MIPS_FLAGS: + printFlags(Value, makeArrayRef(ElfDynamicDTMipsFlags), OS); + return; + default: + OS << format(ConvChar, Value); + return; + } + default: + OS << format(ConvChar, Value); + return; + } + } + switch (Type) { case DT_PLTREL: if (Value == DT_REL) { @@ -1811,22 +1869,12 @@ case DT_VERSYM: case DT_GNU_HASH: case DT_NULL: - case DT_MIPS_BASE_ADDRESS: - case DT_MIPS_GOTSYM: - case DT_MIPS_RLD_MAP: - case DT_MIPS_RLD_MAP_REL: - case DT_MIPS_PLTGOT: - case DT_MIPS_OPTIONS: OS << format(ConvChar, Value); break; case DT_RELACOUNT: case DT_RELCOUNT: case DT_VERDEFNUM: case DT_VERNEEDNUM: - case DT_MIPS_RLD_VERSION: - case DT_MIPS_LOCAL_GOTNO: - case DT_MIPS_SYMTABNO: - case DT_MIPS_UNREFEXTNO: OS << Value; break; case DT_PLTRELSZ: @@ -1862,9 +1910,6 @@ case DT_RUNPATH: OS << getDynamicString(Value); break; - case DT_MIPS_FLAGS: - printFlags(Value, makeArrayRef(ElfDynamicDTMipsFlags), OS); - break; case DT_FLAGS: printFlags(Value, makeArrayRef(ElfDynamicDTFlags), OS); break;