[llvm] r362493 - [AArch64][ELF][llvm-readobj] Add support for BTI and PAC dynamic tags

Peter Smith via llvm-commits llvm-commits at lists.llvm.org
Tue Jun 4 04:44:33 PDT 2019


Author: psmith
Date: Tue Jun  4 04:44:33 2019
New Revision: 362493

URL: http://llvm.org/viewvc/llvm-project?rev=362493&view=rev
Log:
[AArch64][ELF][llvm-readobj] Add support for BTI and PAC dynamic tags

ELF for the 64-bit Arm Architecture defines two processor-specific dynamic
tags:
DT_AARCH64_BTI_PLT 0x70000001, d_val
DT_AARCH64_PAC_PLT 0x70000003, d_val

These presence of these tags indicate that PLT sequences have been
protected using Branch Target Identification and Pointer Authentication
respectively. The presence of both indicates that the PLT sequences have
been protected with both Branch Target Identification and Pointer
Authentication.

This patch adds the tags and tests for llvm-readobj and yaml2obj.

As some of the processor specific dynamic tags overlap, this patch splits
them up, keeping their original default value if they were not previously
mentioned explicitly in a switch case.

Differential Revision: https://reviews.llvm.org/D62596

Modified:
    llvm/trunk/include/llvm/BinaryFormat/DynamicTags.def
    llvm/trunk/lib/Object/ELF.cpp
    llvm/trunk/lib/ObjectYAML/ELFYAML.cpp
    llvm/trunk/test/tools/llvm-readobj/Inputs/elf-dynamic-tags-machine-specific.yaml
    llvm/trunk/test/tools/llvm-readobj/elf-dynamic-tags-machine-specific.test
    llvm/trunk/test/tools/obj2yaml/dynamic-section-arch-tags.test
    llvm/trunk/tools/llvm-readobj/ELFDumper.cpp

Modified: llvm/trunk/include/llvm/BinaryFormat/DynamicTags.def
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/BinaryFormat/DynamicTags.def?rev=362493&r1=362492&r2=362493&view=diff
==============================================================================
--- llvm/trunk/include/llvm/BinaryFormat/DynamicTags.def (original)
+++ llvm/trunk/include/llvm/BinaryFormat/DynamicTags.def Tue Jun  4 04:44:33 2019
@@ -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 @@ DYNAMIC_TAG(VERNEED, 0X6FFFFFFE)    // T
                                     // 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 @@ DYNAMIC_TAG(FILTER, 0x7FFFFFFF)    // Sh
 #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

Modified: llvm/trunk/lib/Object/ELF.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Object/ELF.cpp?rev=362493&r1=362492&r2=362493&view=diff
==============================================================================
--- llvm/trunk/lib/Object/ELF.cpp (original)
+++ llvm/trunk/lib/Object/ELF.cpp Tue Jun  4 04:44:33 2019
@@ -434,6 +434,14 @@ std::string ELFFile<ELFT>::getDynamicTag
 
 #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 @@ std::string ELFFile<ELFT>::getDynamicTag
 #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 @@ std::string ELFFile<ELFT>::getDynamicTag
 #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

Modified: llvm/trunk/lib/ObjectYAML/ELFYAML.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ObjectYAML/ELFYAML.cpp?rev=362493&r1=362492&r2=362493&view=diff
==============================================================================
--- llvm/trunk/lib/ObjectYAML/ELFYAML.cpp (original)
+++ llvm/trunk/lib/ObjectYAML/ELFYAML.cpp Tue Jun  4 04:44:33 2019
@@ -680,6 +680,7 @@ void ScalarEnumerationTraits<ELFYAML::EL
   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 @@ void ScalarEnumerationTraits<ELFYAML::EL
 #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 @@ void ScalarEnumerationTraits<ELFYAML::EL
 #include "llvm/BinaryFormat/DynamicTags.def"
     break;
   }
-
+#undef AARCH64_DYNAMIC_TAG
 #undef MIPS_DYNAMIC_TAG
 #undef HEXAGON_DYNAMIC_TAG
 #undef PPC64_DYNAMIC_TAG

Modified: llvm/trunk/test/tools/llvm-readobj/Inputs/elf-dynamic-tags-machine-specific.yaml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-readobj/Inputs/elf-dynamic-tags-machine-specific.yaml?rev=362493&r1=362492&r2=362493&view=diff
==============================================================================
--- llvm/trunk/test/tools/llvm-readobj/Inputs/elf-dynamic-tags-machine-specific.yaml (original)
+++ llvm/trunk/test/tools/llvm-readobj/Inputs/elf-dynamic-tags-machine-specific.yaml Tue Jun  4 04:44:33 2019
@@ -200,3 +200,41 @@ ProgramHeaders:
     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

Modified: llvm/trunk/test/tools/llvm-readobj/elf-dynamic-tags-machine-specific.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-readobj/elf-dynamic-tags-machine-specific.test?rev=362493&r1=362492&r2=362493&view=diff
==============================================================================
--- llvm/trunk/test/tools/llvm-readobj/elf-dynamic-tags-machine-specific.test (original)
+++ llvm/trunk/test/tools/llvm-readobj/elf-dynamic-tags-machine-specific.test Tue Jun  4 04:44:33 2019
@@ -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

Modified: llvm/trunk/test/tools/obj2yaml/dynamic-section-arch-tags.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/obj2yaml/dynamic-section-arch-tags.test?rev=362493&r1=362492&r2=362493&view=diff
==============================================================================
--- llvm/trunk/test/tools/obj2yaml/dynamic-section-arch-tags.test (original)
+++ llvm/trunk/test/tools/obj2yaml/dynamic-section-arch-tags.test Tue Jun  4 04:44:33 2019
@@ -249,12 +249,36 @@ Sections:
       - 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
 

Modified: llvm/trunk/tools/llvm-readobj/ELFDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/ELFDumper.cpp?rev=362493&r1=362492&r2=362493&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-readobj/ELFDumper.cpp (original)
+++ llvm/trunk/tools/llvm-readobj/ELFDumper.cpp Tue Jun  4 04:44:33 2019
@@ -1463,6 +1463,17 @@ ELFDumper<ELFT>::ELFDumper(const object:
 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 @@ static const char *getTypeString(unsigne
 #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 @@ static const char *getTypeString(unsigne
     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,93 @@ void ELFDumper<ELFT>::printDynamicEntry(
                                         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) {
@@ -1811,22 +1911,12 @@ void ELFDumper<ELFT>::printDynamicEntry(
   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 +1952,6 @@ void ELFDumper<ELFT>::printDynamicEntry(
   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;




More information about the llvm-commits mailing list