// 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
// 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)
#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
#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)
#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)
#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
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)
#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)
#include "llvm/BinaryFormat/DynamicTags.def"
break;
}
-
+#undef AARCH64_DYNAMIC_TAG
#undef MIPS_DYNAMIC_TAG
#undef HEXAGON_DYNAMIC_TAG
#undef PPC64_DYNAMIC_TAG
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
# 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
- 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
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) \
#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)
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
uint64_t Value) const {
const char *ConvChar =
(opts::Output == opts::GNU) ? "0x%" PRIx64 : "0x%" PRIX64;
+
+ // Handle custom printing of architecture specific tags
+ 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:
+ break;
+ }
+ break;
+ case EM_HEXAGON:
+ switch (Type) {
+ case DT_HEXAGON_VER:
+ OS << Value;
+ return;
+ case DT_HEXAGON_SYMSZ:
+ case DT_HEXAGON_PLT:
+ OS << format(ConvChar, Value);
+ return;
+ default:
+ break;
+ }
+ break;
+ 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_TIME_STAMP:
+ case DT_MIPS_ICHECKSUM:
+ case DT_MIPS_IVERSION:
+ case DT_MIPS_BASE_ADDRESS:
+ case DT_MIPS_MSYM:
+ case DT_MIPS_CONFLICT:
+ case DT_MIPS_LIBLIST:
+ case DT_MIPS_CONFLICTNO:
+ case DT_MIPS_LIBLISTNO:
+ case DT_MIPS_GOTSYM:
+ case DT_MIPS_HIPAGENO:
+ case DT_MIPS_RLD_MAP:
+ case DT_MIPS_DELTA_CLASS:
+ case DT_MIPS_DELTA_CLASS_NO:
+ case DT_MIPS_DELTA_INSTANCE:
+ case DT_MIPS_DELTA_RELOC:
+ case DT_MIPS_DELTA_RELOC_NO:
+ case DT_MIPS_DELTA_SYM:
+ case DT_MIPS_DELTA_SYM_NO:
+ case DT_MIPS_DELTA_CLASSSYM:
+ case DT_MIPS_DELTA_CLASSSYM_NO:
+ case DT_MIPS_CXX_FLAGS:
+ case DT_MIPS_PIXIE_INIT:
+ case DT_MIPS_SYMBOL_LIB:
+ case DT_MIPS_LOCALPAGE_GOTIDX:
+ case DT_MIPS_LOCAL_GOTIDX:
+ case DT_MIPS_HIDDEN_GOTIDX:
+ case DT_MIPS_PROTECTED_GOTIDX:
+ case DT_MIPS_OPTIONS:
+ case DT_MIPS_INTERFACE:
+ case DT_MIPS_DYNSTR_ALIGN:
+ case DT_MIPS_INTERFACE_SIZE:
+ case DT_MIPS_RLD_TEXT_RESOLVE_ADDR:
+ case DT_MIPS_PERF_SUFFIX:
+ case DT_MIPS_COMPACT_SIZE:
+ case DT_MIPS_GP_VALUE:
+ case DT_MIPS_AUX_DYNAMIC:
+ case DT_MIPS_PLTGOT:
+ case DT_MIPS_RWPLT:
+ case DT_MIPS_RLD_MAP_REL:
+ OS << format(ConvChar, Value);
+ return;
+ case DT_MIPS_FLAGS:
+ printFlags(Value, makeArrayRef(ElfDynamicDTMipsFlags), OS);
+ return;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+
switch (Type) {
case DT_PLTREL:
if (Value == DT_REL) {
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:
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;