[llvm] r335922 - [llvm-readobj] Add experimental support for SHT_RELR sections

Jake Ehrlich via llvm-commits llvm-commits at lists.llvm.org
Thu Jun 28 14:07:34 PDT 2018


Author: jakehehrlich
Date: Thu Jun 28 14:07:34 2018
New Revision: 335922

URL: http://llvm.org/viewvc/llvm-project?rev=335922&view=rev
Log:
[llvm-readobj] Add experimental support for SHT_RELR sections

This change adds experimental support for SHT_RELR sections, proposed
here: https://groups.google.com/forum/#!topic/generic-abi/bX460iggiKg

Definitions for the new ELF section type and dynamic array tags, as well
as the encoding used in the new section are all under discussion and are
subject to change. Use with caution!

Author: rahulchaudhry

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

Added:
    llvm/trunk/test/tools/llvm-readobj/Inputs/elf-relr-relocs1.s
    llvm/trunk/test/tools/llvm-readobj/Inputs/elf-relr-relocs2.s
    llvm/trunk/test/tools/llvm-readobj/elf-relr-relocs.test
Modified:
    llvm/trunk/include/llvm/BinaryFormat/DynamicTags.def
    llvm/trunk/include/llvm/BinaryFormat/ELF.h
    llvm/trunk/include/llvm/Object/ELF.h
    llvm/trunk/include/llvm/Object/ELFTypes.h
    llvm/trunk/lib/Object/ELF.cpp
    llvm/trunk/lib/ObjectYAML/ELFYAML.cpp
    llvm/trunk/tools/llvm-readobj/ELFDumper.cpp
    llvm/trunk/tools/llvm-readobj/llvm-readobj.cpp
    llvm/trunk/tools/llvm-readobj/llvm-readobj.h
    llvm/trunk/tools/yaml2obj/yaml2elf.cpp

Modified: llvm/trunk/include/llvm/BinaryFormat/DynamicTags.def
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/BinaryFormat/DynamicTags.def?rev=335922&r1=335921&r2=335922&view=diff
==============================================================================
--- llvm/trunk/include/llvm/BinaryFormat/DynamicTags.def (original)
+++ llvm/trunk/include/llvm/BinaryFormat/DynamicTags.def Thu Jun 28 14:07:34 2018
@@ -65,6 +65,12 @@ DYNAMIC_TAG(PREINIT_ARRAYSZ, 33) // Size
 
 DYNAMIC_TAG(SYMTAB_SHNDX, 34) // Address of the SHT_SYMTAB_SHNDX section.
 
+// Experimental support for SHT_RELR sections. For details, see proposal
+// at https://groups.google.com/forum/#!topic/generic-abi/bX460iggiKg
+DYNAMIC_TAG(RELRSZ, 35)  // Size of Relr relocation table.
+DYNAMIC_TAG(RELR, 36)    // Address of relocation table (Relr entries).
+DYNAMIC_TAG(RELRENT, 37) // Size of a Relr relocation entry.
+
 DYNAMIC_TAG_MARKER(LOOS, 0x60000000)   // Start of environment specific tags.
 DYNAMIC_TAG_MARKER(HIOS, 0x6FFFFFFF)   // End of environment specific tags.
 DYNAMIC_TAG_MARKER(LOPROC, 0x70000000) // Start of processor specific tags.
@@ -77,6 +83,12 @@ DYNAMIC_TAG(ANDROID_RELSZ, 0x60000010)
 DYNAMIC_TAG(ANDROID_RELA, 0x60000011)
 DYNAMIC_TAG(ANDROID_RELASZ, 0x60000012)
 
+// Android's experimental support for SHT_RELR sections.
+// https://android.googlesource.com/platform/bionic/+/b7feec74547f84559a1467aca02708ff61346d2a/libc/include/elf.h#253
+DYNAMIC_TAG(ANDROID_RELR, 0x6FFFE000)      // Address of relocation table (Relr entries).
+DYNAMIC_TAG(ANDROID_RELRSZ, 0x6FFFE001)    // Size of Relr relocation table.
+DYNAMIC_TAG(ANDROID_RELRENT, 0x6FFFE003)   // Size of a Relr relocation entry.
+
 DYNAMIC_TAG(GNU_HASH, 0x6FFFFEF5)    // Reference to the GNU hash table.
 DYNAMIC_TAG(TLSDESC_PLT, 0x6FFFFEF6) // Location of PLT entry for TLS
                                      // descriptor resolver calls.

Modified: llvm/trunk/include/llvm/BinaryFormat/ELF.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/BinaryFormat/ELF.h?rev=335922&r1=335921&r2=335922&view=diff
==============================================================================
--- llvm/trunk/include/llvm/BinaryFormat/ELF.h (original)
+++ llvm/trunk/include/llvm/BinaryFormat/ELF.h Thu Jun 28 14:07:34 2018
@@ -796,6 +796,9 @@ enum : unsigned {
   SHT_PREINIT_ARRAY = 16,               // Pointers to pre-init functions.
   SHT_GROUP = 17,                       // Section group.
   SHT_SYMTAB_SHNDX = 18,                // Indices for SHN_XINDEX entries.
+  // Experimental support for SHT_RELR sections. For details, see proposal
+  // at https://groups.google.com/forum/#!topic/generic-abi/bX460iggiKg
+  SHT_RELR = 19,                        // Relocation entries; only offsets.
   SHT_LOOS = 0x60000000,                // Lowest operating system-specific type.
   // Android packed relocation section types.
   // https://android.googlesource.com/platform/bionic/+/6f12bfece5dcc01325e0abba56a46b1bcf991c69/tools/relocation_packer/src/elf_file.cc#37
@@ -804,6 +807,9 @@ enum : unsigned {
   SHT_LLVM_ODRTAB = 0x6fff4c00,         // LLVM ODR table.
   SHT_LLVM_LINKER_OPTIONS = 0x6fff4c01, // LLVM Linker Options.
   SHT_LLVM_CALL_GRAPH_PROFILE = 0x6fff4c02, // LLVM Call Graph Profile.
+  // Android's experimental support for SHT_RELR sections.
+  // https://android.googlesource.com/platform/bionic/+/b7feec74547f84559a1467aca02708ff61346d2a/libc/include/elf.h#512
+  SHT_ANDROID_RELR = 0x6fffff00,        // Relocation entries; only offsets.
   SHT_GNU_ATTRIBUTES = 0x6ffffff5,      // Object attributes.
   SHT_GNU_HASH = 0x6ffffff6,            // GNU-style hash table.
   SHT_GNU_verdef = 0x6ffffffd,          // GNU version definitions.
@@ -1067,6 +1073,9 @@ struct Elf32_Rela {
   }
 };
 
+// Relocation entry without explicit addend or info (relative relocations only).
+typedef Elf32_Word Elf32_Relr; // offset/bitmap for relative relocations
+
 // Relocation entry, without explicit addend.
 struct Elf64_Rel {
   Elf64_Addr r_offset; // Location (file byte offset, or program virtual addr).
@@ -1100,6 +1109,9 @@ struct Elf64_Rela {
   }
 };
 
+// Relocation entry without explicit addend or info (relative relocations only).
+typedef Elf64_Xword Elf64_Relr; // offset/bitmap for relative relocations
+
 // Program header for ELF32.
 struct Elf32_Phdr {
   Elf32_Word p_type;   // Type of segment

Modified: llvm/trunk/include/llvm/Object/ELF.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Object/ELF.h?rev=335922&r1=335921&r2=335922&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Object/ELF.h (original)
+++ llvm/trunk/include/llvm/Object/ELF.h Thu Jun 28 14:07:34 2018
@@ -32,6 +32,7 @@ namespace llvm {
 namespace object {
 
 StringRef getELFRelocationTypeName(uint32_t Machine, uint32_t Type);
+uint32_t getELFRelrRelocationType(uint32_t Machine);
 StringRef getELFSectionTypeName(uint32_t Machine, uint32_t Type);
 
 // Subclasses of ELFFile may need this for template instantiation
@@ -60,6 +61,7 @@ public:
   using Elf_Phdr = typename ELFT::Phdr;
   using Elf_Rel = typename ELFT::Rel;
   using Elf_Rela = typename ELFT::Rela;
+  using Elf_Relr = typename ELFT::Relr;
   using Elf_Verdef = typename ELFT::Verdef;
   using Elf_Verdaux = typename ELFT::Verdaux;
   using Elf_Verneed = typename ELFT::Verneed;
@@ -75,6 +77,7 @@ public:
   using Elf_Sym_Range = typename ELFT::SymRange;
   using Elf_Rel_Range = typename ELFT::RelRange;
   using Elf_Rela_Range = typename ELFT::RelaRange;
+  using Elf_Relr_Range = typename ELFT::RelrRange;
   using Elf_Phdr_Range = typename ELFT::PhdrRange;
 
   const uint8_t *base() const {
@@ -110,6 +113,7 @@ public:
   StringRef getRelocationTypeName(uint32_t Type) const;
   void getRelocationTypeName(uint32_t Type,
                              SmallVectorImpl<char> &Result) const;
+  uint32_t getRelrRelocationType() const;
 
   /// Get the symbol for a given relocation.
   Expected<const Elf_Sym *> getRelocationSymbol(const Elf_Rel *Rel,
@@ -143,6 +147,12 @@ public:
     return getSectionContentsAsArray<Elf_Rel>(Sec);
   }
 
+  Expected<Elf_Relr_Range> relrs(const Elf_Shdr *Sec) const {
+    return getSectionContentsAsArray<Elf_Relr>(Sec);
+  }
+
+  Expected<std::vector<Elf_Rela>> decode_relrs(Elf_Relr_Range relrs) const;
+
   Expected<std::vector<Elf_Rela>> android_relas(const Elf_Shdr *Sec) const;
 
   /// Iterate over program header table.
@@ -398,6 +408,11 @@ void ELFFile<ELFT>::getRelocationTypeNam
 }
 
 template <class ELFT>
+uint32_t ELFFile<ELFT>::getRelrRelocationType() const {
+  return getELFRelrRelocationType(getHeader()->e_machine);
+}
+
+template <class ELFT>
 Expected<const typename ELFT::Sym *>
 ELFFile<ELFT>::getRelocationSymbol(const Elf_Rel *Rel,
                                    const Elf_Shdr *SymTab) const {

Modified: llvm/trunk/include/llvm/Object/ELFTypes.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Object/ELFTypes.h?rev=335922&r1=335921&r2=335922&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Object/ELFTypes.h (original)
+++ llvm/trunk/include/llvm/Object/ELFTypes.h Thu Jun 28 14:07:34 2018
@@ -62,6 +62,7 @@ public:
   using Phdr = Elf_Phdr_Impl<ELFType<E, Is64>>;
   using Rel = Elf_Rel_Impl<ELFType<E, Is64>, false>;
   using Rela = Elf_Rel_Impl<ELFType<E, Is64>, true>;
+  using Relr = packed<uint>;
   using Verdef = Elf_Verdef_Impl<ELFType<E, Is64>>;
   using Verdaux = Elf_Verdaux_Impl<ELFType<E, Is64>>;
   using Verneed = Elf_Verneed_Impl<ELFType<E, Is64>>;
@@ -79,6 +80,7 @@ public:
   using SymRange = ArrayRef<Sym>;
   using RelRange = ArrayRef<Rel>;
   using RelaRange = ArrayRef<Rela>;
+  using RelrRange = ArrayRef<Relr>;
   using PhdrRange = ArrayRef<Phdr>;
 
   using Half = packed<uint16_t>;

Modified: llvm/trunk/lib/Object/ELF.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Object/ELF.cpp?rev=335922&r1=335921&r2=335922&view=diff
==============================================================================
--- llvm/trunk/lib/Object/ELF.cpp (original)
+++ llvm/trunk/lib/Object/ELF.cpp Thu Jun 28 14:07:34 2018
@@ -154,6 +154,52 @@ StringRef llvm::object::getELFRelocation
 
 #undef ELF_RELOC
 
+uint32_t llvm::object::getELFRelrRelocationType(uint32_t Machine) {
+  switch (Machine) {
+  case ELF::EM_X86_64:
+    return ELF::R_X86_64_RELATIVE;
+  case ELF::EM_386:
+  case ELF::EM_IAMCU:
+    return ELF::R_386_RELATIVE;
+  case ELF::EM_MIPS:
+    break;
+  case ELF::EM_AARCH64:
+    return ELF::R_AARCH64_RELATIVE;
+  case ELF::EM_ARM:
+    return ELF::R_ARM_RELATIVE;
+  case ELF::EM_ARC_COMPACT:
+  case ELF::EM_ARC_COMPACT2:
+    return ELF::R_ARC_RELATIVE;
+  case ELF::EM_AVR:
+    break;
+  case ELF::EM_HEXAGON:
+    return ELF::R_HEX_RELATIVE;
+  case ELF::EM_LANAI:
+    break;
+  case ELF::EM_PPC:
+    break;
+  case ELF::EM_PPC64:
+    return ELF::R_PPC64_RELATIVE;
+  case ELF::EM_RISCV:
+    return ELF::R_RISCV_RELATIVE;
+  case ELF::EM_S390:
+    return ELF::R_390_RELATIVE;
+  case ELF::EM_SPARC:
+  case ELF::EM_SPARC32PLUS:
+  case ELF::EM_SPARCV9:
+    return ELF::R_SPARC_RELATIVE;
+  case ELF::EM_WEBASSEMBLY:
+    break;
+  case ELF::EM_AMDGPU:
+    break;
+  case ELF::EM_BPF:
+    break;
+  default:
+    break;
+  }
+  return 0;
+}
+
 StringRef llvm::object::getELFSectionTypeName(uint32_t Machine, unsigned Type) {
   switch (Machine) {
   case ELF::EM_ARM:
@@ -202,8 +248,10 @@ StringRef llvm::object::getELFSectionTyp
     STRINGIFY_ENUM_CASE(ELF, SHT_PREINIT_ARRAY);
     STRINGIFY_ENUM_CASE(ELF, SHT_GROUP);
     STRINGIFY_ENUM_CASE(ELF, SHT_SYMTAB_SHNDX);
+    STRINGIFY_ENUM_CASE(ELF, SHT_RELR);
     STRINGIFY_ENUM_CASE(ELF, SHT_ANDROID_REL);
     STRINGIFY_ENUM_CASE(ELF, SHT_ANDROID_RELA);
+    STRINGIFY_ENUM_CASE(ELF, SHT_ANDROID_RELR);
     STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_ODRTAB);
     STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_LINKER_OPTIONS);
     STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_CALL_GRAPH_PROFILE);
@@ -218,6 +266,85 @@ StringRef llvm::object::getELFSectionTyp
 }
 
 template <class ELFT>
+Expected<std::vector<typename ELFT::Rela>>
+ELFFile<ELFT>::decode_relrs(Elf_Relr_Range relrs) const {
+  // This function decodes the contents of an SHT_RELR packed relocation
+  // section.
+  //
+  // Proposal for adding SHT_RELR sections to generic-abi is here:
+  //   https://groups.google.com/forum/#!topic/generic-abi/bX460iggiKg
+  //
+  // The encoded sequence of Elf64_Relr entries in a SHT_RELR section looks
+  // like [ AAAAAAAA BBBBBBB1 BBBBBBB1 ... AAAAAAAA BBBBBB1 ... ]
+  //
+  // i.e. start with an address, followed by any number of bitmaps. The address
+  // entry encodes 1 relocation. The subsequent bitmap entries encode up to 63
+  // relocations each, at subsequent offsets following the last address entry.
+  //
+  // The bitmap entries must have 1 in the least significant bit. The assumption
+  // here is that an address cannot have 1 in lsb. Odd addresses are not
+  // supported.
+  //
+  // Excluding the least significant bit in the bitmap, each non-zero bit in
+  // the bitmap represents a relocation to be applied to a corresponding machine
+  // word that follows the base address word. The second least significant bit
+  // represents the machine word immediately following the initial address, and
+  // each bit that follows represents the next word, in linear order. As such,
+  // a single bitmap can encode up to 31 relocations in a 32-bit object, and
+  // 63 relocations in a 64-bit object.
+  //
+  // This encoding has a couple of interesting properties:
+  // 1. Looking at any entry, it is clear whether it's an address or a bitmap:
+  //    even means address, odd means bitmap.
+  // 2. Just a simple list of addresses is a valid encoding.
+
+  Elf_Rela Rela;
+  Rela.r_info = 0;
+  Rela.r_addend = 0;
+  Rela.setType(getRelrRelocationType(), false);
+  std::vector<Elf_Rela> Relocs;
+
+  // Word type: uint32_t for Elf32, and uint64_t for Elf64.
+  typedef typename ELFT::uint Word;
+
+  // Word size in number of bytes.
+  const size_t WordSize = sizeof(Word);
+
+  // Number of bits used for the relocation offsets bitmap.
+  // These many relative relocations can be encoded in a single entry.
+  const size_t NBits = 8*WordSize - 1;
+
+  Word Base = 0;
+  for (const Elf_Relr &R : relrs) {
+    Word Entry = R;
+    if ((Entry&1) == 0) {
+      // Even entry: encodes the offset for next relocation.
+      Rela.r_offset = Entry;
+      Relocs.push_back(Rela);
+      // Set base offset for subsequent bitmap entries.
+      Base = Entry + WordSize;
+      continue;
+    }
+
+    // Odd entry: encodes bitmap for relocations starting at base.
+    Word Offset = Base;
+    while (Entry != 0) {
+      Entry >>= 1;
+      if ((Entry&1) != 0) {
+        Rela.r_offset = Offset;
+        Relocs.push_back(Rela);
+      }
+      Offset += WordSize;
+    }
+
+    // Advance base offset by NBits words.
+    Base += NBits * WordSize;
+  }
+
+  return Relocs;
+}
+
+template <class ELFT>
 Expected<std::vector<typename ELFT::Rela>>
 ELFFile<ELFT>::android_relas(const Elf_Shdr *Sec) const {
   // This function reads relocations in Android's packed relocation format,

Modified: llvm/trunk/lib/ObjectYAML/ELFYAML.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ObjectYAML/ELFYAML.cpp?rev=335922&r1=335921&r2=335922&view=diff
==============================================================================
--- llvm/trunk/lib/ObjectYAML/ELFYAML.cpp (original)
+++ llvm/trunk/lib/ObjectYAML/ELFYAML.cpp Thu Jun 28 14:07:34 2018
@@ -436,9 +436,11 @@ void ScalarEnumerationTraits<ELFYAML::EL
   ECase(SHT_PREINIT_ARRAY);
   ECase(SHT_GROUP);
   ECase(SHT_SYMTAB_SHNDX);
+  ECase(SHT_RELR);
   ECase(SHT_LOOS);
   ECase(SHT_ANDROID_REL);
   ECase(SHT_ANDROID_RELA);
+  ECase(SHT_ANDROID_RELR);
   ECase(SHT_LLVM_ODRTAB);
   ECase(SHT_LLVM_LINKER_OPTIONS);
   ECase(SHT_LLVM_CALL_GRAPH_PROFILE);

Added: llvm/trunk/test/tools/llvm-readobj/Inputs/elf-relr-relocs1.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-readobj/Inputs/elf-relr-relocs1.s?rev=335922&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-readobj/Inputs/elf-relr-relocs1.s (added)
+++ llvm/trunk/test/tools/llvm-readobj/Inputs/elf-relr-relocs1.s Thu Jun 28 14:07:34 2018
@@ -0,0 +1,5 @@
+.quad 0x0000000000010d60  // Initial offset
+.quad 0x0000000000000103  // Continuation bitmap
+.quad 0x0000000000020000  // New offset
+.quad 0x00000000000f0501  // Continuation bitmap
+.quad 0x000a700550400009  // Continuation bitmap

Added: llvm/trunk/test/tools/llvm-readobj/Inputs/elf-relr-relocs2.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-readobj/Inputs/elf-relr-relocs2.s?rev=335922&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-readobj/Inputs/elf-relr-relocs2.s (added)
+++ llvm/trunk/test/tools/llvm-readobj/Inputs/elf-relr-relocs2.s Thu Jun 28 14:07:34 2018
@@ -0,0 +1,5 @@
+.long 0x00010d60  // Initial offset
+.long 0x00000103  // Continuation bitmap
+.long 0x00020000  // New offset
+.long 0x000f0501  // Continuation bitmap
+.long 0x50400009  // Continuation bitmap

Added: llvm/trunk/test/tools/llvm-readobj/elf-relr-relocs.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-readobj/elf-relr-relocs.test?rev=335922&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-readobj/elf-relr-relocs.test (added)
+++ llvm/trunk/test/tools/llvm-readobj/elf-relr-relocs.test Thu Jun 28 14:07:34 2018
@@ -0,0 +1,172 @@
+# The binary blobs in this file were created like this:
+# llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu Inputs/elf-relr-relocs1.s -o - | obj2yaml | grep Content:
+
+# RUN: yaml2obj -docnum 1 %s \
+# RUN:   | llvm-readobj -elf-output-style=LLVM -relocations -raw-relr - \
+# RUN:   | FileCheck --check-prefix=RAW-LLVM1 %s
+# RAW-LLVM1:      Section (1) .relr.dyn {
+# RAW-LLVM1-NEXT:   0x10D60
+# RAW-LLVM1-NEXT:   0x103
+# RAW-LLVM1-NEXT:   0x20000
+# RAW-LLVM1-NEXT:   0xF0501
+# RAW-LLVM1-NEXT:   0xA700550400009
+# RAW-LLVM1-NEXT: }
+
+# RUN: yaml2obj -docnum 1 %s \
+# RUN:   | llvm-readobj -elf-output-style=LLVM -relocations - \
+# RUN:   | FileCheck --check-prefix=LLVM1 %s
+# LLVM1:      Section (1) .relr.dyn {
+# LLVM1-NEXT:   0x10D60 R_X86_64_RELATIVE - 0x0
+# LLVM1-NEXT:   0x10D68 R_X86_64_RELATIVE - 0x0
+# LLVM1-NEXT:   0x10DA0 R_X86_64_RELATIVE - 0x0
+# LLVM1-NEXT:   0x20000 R_X86_64_RELATIVE - 0x0
+# LLVM1-NEXT:   0x20040 R_X86_64_RELATIVE - 0x0
+# LLVM1-NEXT:   0x20050 R_X86_64_RELATIVE - 0x0
+# LLVM1-NEXT:   0x20080 R_X86_64_RELATIVE - 0x0
+# LLVM1-NEXT:   0x20088 R_X86_64_RELATIVE - 0x0
+# LLVM1-NEXT:   0x20090 R_X86_64_RELATIVE - 0x0
+# LLVM1-NEXT:   0x20098 R_X86_64_RELATIVE - 0x0
+# LLVM1-NEXT:   0x20210 R_X86_64_RELATIVE - 0x0
+# LLVM1-NEXT:   0x202A8 R_X86_64_RELATIVE - 0x0
+# LLVM1-NEXT:   0x202D8 R_X86_64_RELATIVE - 0x0
+# LLVM1-NEXT:   0x202E8 R_X86_64_RELATIVE - 0x0
+# LLVM1-NEXT:   0x202F8 R_X86_64_RELATIVE - 0x0
+# LLVM1-NEXT:   0x20308 R_X86_64_RELATIVE - 0x0
+# LLVM1-NEXT:   0x20358 R_X86_64_RELATIVE - 0x0
+# LLVM1-NEXT:   0x20360 R_X86_64_RELATIVE - 0x0
+# LLVM1-NEXT:   0x20368 R_X86_64_RELATIVE - 0x0
+# LLVM1-NEXT:   0x20380 R_X86_64_RELATIVE - 0x0
+# LLVM1-NEXT:   0x20390 R_X86_64_RELATIVE - 0x0
+# LLVM1-NEXT: }
+
+# RUN: yaml2obj -docnum 1 %s \
+# RUN:   | llvm-readobj -elf-output-style=GNU -relocations -raw-relr - \
+# RUN:   | FileCheck --check-prefix=RAW-GNU1 %s
+# RAW-GNU1:      Relocation section '.relr.dyn' at offset 0x180 contains 5 entries:
+# RAW-GNU1:      0000000000010d60
+# RAW-GNU1-NEXT: 0000000000000103
+# RAW-GNU1-NEXT: 0000000000020000
+# RAW-GNU1-NEXT: 00000000000f0501
+# RAW-GNU1-NEXT: 000a700550400009
+
+# RUN: yaml2obj -docnum 1 %s \
+# RUN:   | llvm-readobj -elf-output-style=GNU -relocations - \
+# RUN:   | FileCheck --check-prefix=GNU1 %s
+# GNU1:      Relocation section '.relr.dyn' at offset 0x180 contains 21 entries:
+# GNU1:      0000000000010d60  0000000000000008 R_X86_64_RELATIVE
+# GNU1-NEXT: 0000000000010d68  0000000000000008 R_X86_64_RELATIVE
+# GNU1-NEXT: 0000000000010da0  0000000000000008 R_X86_64_RELATIVE
+# GNU1-NEXT: 0000000000020000  0000000000000008 R_X86_64_RELATIVE
+# GNU1-NEXT: 0000000000020040  0000000000000008 R_X86_64_RELATIVE
+# GNU1-NEXT: 0000000000020050  0000000000000008 R_X86_64_RELATIVE
+# GNU1-NEXT: 0000000000020080  0000000000000008 R_X86_64_RELATIVE
+# GNU1-NEXT: 0000000000020088  0000000000000008 R_X86_64_RELATIVE
+# GNU1-NEXT: 0000000000020090  0000000000000008 R_X86_64_RELATIVE
+# GNU1-NEXT: 0000000000020098  0000000000000008 R_X86_64_RELATIVE
+# GNU1-NEXT: 0000000000020210  0000000000000008 R_X86_64_RELATIVE
+# GNU1-NEXT: 00000000000202a8  0000000000000008 R_X86_64_RELATIVE
+# GNU1-NEXT: 00000000000202d8  0000000000000008 R_X86_64_RELATIVE
+# GNU1-NEXT: 00000000000202e8  0000000000000008 R_X86_64_RELATIVE
+# GNU1-NEXT: 00000000000202f8  0000000000000008 R_X86_64_RELATIVE
+# GNU1-NEXT: 0000000000020308  0000000000000008 R_X86_64_RELATIVE
+# GNU1-NEXT: 0000000000020358  0000000000000008 R_X86_64_RELATIVE
+# GNU1-NEXT: 0000000000020360  0000000000000008 R_X86_64_RELATIVE
+# GNU1-NEXT: 0000000000020368  0000000000000008 R_X86_64_RELATIVE
+# GNU1-NEXT: 0000000000020380  0000000000000008 R_X86_64_RELATIVE
+# GNU1-NEXT: 0000000000020390  0000000000000008 R_X86_64_RELATIVE
+
+# elf-relr-relocs1.s
+--- !ELF
+FileHeader:
+  Class:           ELFCLASS64
+  Data:            ELFDATA2LSB
+  Type:            ET_DYN
+  Machine:         EM_X86_64
+  Entry:           0x0000000000001000
+Sections:
+  - Name:            .relr.dyn
+    Type:            SHT_RELR
+    Flags:           [ SHF_ALLOC ]
+    Address:         0x00000000000001C8
+    Link:            .symtab
+    AddressAlign:    0x0000000000000001
+    Content:         600D0100000000000301000000000000000002000000000001050F00000000000900405005700A00
+...
+
+# RUN: yaml2obj -docnum 2 %s \
+# RUN:   | llvm-readobj -elf-output-style=LLVM -relocations -raw-relr - \
+# RUN:   | FileCheck --check-prefix=RAW-LLVM2 %s
+# RAW-LLVM2:      Section (1) .relr.dyn {
+# RAW-LLVM2-NEXT:   0x10D60
+# RAW-LLVM2-NEXT:   0x103
+# RAW-LLVM2-NEXT:   0x20000
+# RAW-LLVM2-NEXT:   0xF0501
+# RAW-LLVM2-NEXT:   0x50400009
+# RAW-LLVM2-NEXT: }
+
+# RUN: yaml2obj -docnum 2 %s \
+# RUN:   | llvm-readobj -elf-output-style=LLVM -relocations - \
+# RUN:   | FileCheck --check-prefix=LLVM2 %s
+# LLVM2:      Section (1) .relr.dyn {
+# LLVM2-NEXT:   0x10D60 R_386_RELATIVE - 0x0
+# LLVM2-NEXT:   0x10D64 R_386_RELATIVE - 0x0
+# LLVM2-NEXT:   0x10D80 R_386_RELATIVE - 0x0
+# LLVM2-NEXT:   0x20000 R_386_RELATIVE - 0x0
+# LLVM2-NEXT:   0x20020 R_386_RELATIVE - 0x0
+# LLVM2-NEXT:   0x20028 R_386_RELATIVE - 0x0
+# LLVM2-NEXT:   0x20040 R_386_RELATIVE - 0x0
+# LLVM2-NEXT:   0x20044 R_386_RELATIVE - 0x0
+# LLVM2-NEXT:   0x20048 R_386_RELATIVE - 0x0
+# LLVM2-NEXT:   0x2004C R_386_RELATIVE - 0x0
+# LLVM2-NEXT:   0x20088 R_386_RELATIVE - 0x0
+# LLVM2-NEXT:   0x200D4 R_386_RELATIVE - 0x0
+# LLVM2-NEXT:   0x200EC R_386_RELATIVE - 0x0
+# LLVM2-NEXT:   0x200F4 R_386_RELATIVE - 0x0
+# LLVM2-NEXT: }
+
+# RUN: yaml2obj -docnum 2 %s \
+# RUN:   | llvm-readobj -elf-output-style=GNU -relocations -raw-relr - \
+# RUN:   | FileCheck --check-prefix=RAW-GNU2 %s
+# RAW-GNU2:      Relocation section '.relr.dyn' at offset 0xfc contains 5 entries:
+# RAW-GNU2:      00010d60
+# RAW-GNU2-NEXT: 00000103
+# RAW-GNU2-NEXT: 00020000
+# RAW-GNU2-NEXT: 000f0501
+# RAW-GNU2-NEXT: 50400009
+
+# RUN: yaml2obj -docnum 2 %s \
+# RUN:   | llvm-readobj -elf-output-style=GNU -relocations - \
+# RUN:   | FileCheck --check-prefix=GNU2 %s
+# GNU2:      Relocation section '.relr.dyn' at offset 0xfc contains 14 entries:
+# GNU2:      00010d60  00000008 R_386_RELATIVE
+# GNU2-NEXT: 00010d64  00000008 R_386_RELATIVE
+# GNU2-NEXT: 00010d80  00000008 R_386_RELATIVE
+# GNU2-NEXT: 00020000  00000008 R_386_RELATIVE
+# GNU2-NEXT: 00020020  00000008 R_386_RELATIVE
+# GNU2-NEXT: 00020028  00000008 R_386_RELATIVE
+# GNU2-NEXT: 00020040  00000008 R_386_RELATIVE
+# GNU2-NEXT: 00020044  00000008 R_386_RELATIVE
+# GNU2-NEXT: 00020048  00000008 R_386_RELATIVE
+# GNU2-NEXT: 0002004c  00000008 R_386_RELATIVE
+# GNU2-NEXT: 00020088  00000008 R_386_RELATIVE
+# GNU2-NEXT: 000200d4  00000008 R_386_RELATIVE
+# GNU2-NEXT: 000200ec  00000008 R_386_RELATIVE
+# GNU2-NEXT: 000200f4  00000008 R_386_RELATIVE
+
+# elf-relr-relocs2.s
+--- !ELF
+FileHeader:
+  Class:           ELFCLASS32
+  Data:            ELFDATA2LSB
+  Type:            ET_DYN
+  Machine:         EM_386
+  Entry:           0x00001000
+Sections:
+  - Name:            .relr.dyn
+    Type:            SHT_RELR
+    Flags:           [ SHF_ALLOC ]
+    Address:         0x000001C8
+    Link:            .symtab
+    AddressAlign:    0x00000001
+    Content:         600D0100030100000000020001050F0009004050
+...

Modified: llvm/trunk/tools/llvm-readobj/ELFDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/ELFDumper.cpp?rev=335922&r1=335921&r2=335922&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-readobj/ELFDumper.cpp (original)
+++ llvm/trunk/tools/llvm-readobj/ELFDumper.cpp Thu Jun 28 14:07:34 2018
@@ -85,8 +85,10 @@ using namespace ELF;
   using Elf_Dyn_Range = typename ELFT::DynRange;                               \
   using Elf_Rel = typename ELFT::Rel;                                          \
   using Elf_Rela = typename ELFT::Rela;                                        \
+  using Elf_Relr = typename ELFT::Relr;                                        \
   using Elf_Rel_Range = typename ELFT::RelRange;                               \
   using Elf_Rela_Range = typename ELFT::RelaRange;                             \
+  using Elf_Relr_Range = typename ELFT::RelrRange;                             \
   using Elf_Phdr = typename ELFT::Phdr;                                        \
   using Elf_Half = typename ELFT::Half;                                        \
   using Elf_Ehdr = typename ELFT::Ehdr;                                        \
@@ -206,6 +208,7 @@ private:
   const ELFO *Obj;
   DynRegionInfo DynRelRegion;
   DynRegionInfo DynRelaRegion;
+  DynRegionInfo DynRelrRegion;
   DynRegionInfo DynPLTRelRegion;
   DynRegionInfo DynSymRegion;
   DynRegionInfo DynamicTable;
@@ -257,6 +260,7 @@ public:
 
   Elf_Rel_Range dyn_rels() const;
   Elf_Rela_Range dyn_relas() const;
+  Elf_Relr_Range dyn_relrs() const;
   std::string getFullSymbolName(const Elf_Sym *Symbol, StringRef StrTable,
                                 bool IsDynamic) const;
   void getSectionNameIndex(const Elf_Sym *Symbol, const Elf_Sym *FirstSym,
@@ -271,6 +275,7 @@ public:
   StringRef getDynamicStringTable() const { return DynamicStringTable; }
   const DynRegionInfo &getDynRelRegion() const { return DynRelRegion; }
   const DynRegionInfo &getDynRelaRegion() const { return DynRelaRegion; }
+  const DynRegionInfo &getDynRelrRegion() const { return DynRelrRegion; }
   const DynRegionInfo &getDynPLTRelRegion() const { return DynPLTRelRegion; }
   const Elf_Hash *getHashTable() const { return HashTable; }
   const Elf_GnuHash *getGnuHashTable() const { return GnuHashTable; }
@@ -392,6 +397,7 @@ private:
   }
   void printHashedSymbol(const ELFO *Obj, const Elf_Sym *FirstSym, uint32_t Sym,
                          StringRef StrTable, uint32_t Bucket);
+  void printRelocHeader(unsigned SType);
   void printRelocation(const ELFO *Obj, const Elf_Shdr *SymTab,
                        const Elf_Rela &R, bool IsRela);
   void printSymbol(const ELFO *Obj, const Elf_Sym *Symbol, const Elf_Sym *First,
@@ -1492,6 +1498,18 @@ void ELFDumper<ELFT>::parseDynamicTable(
     case ELF::DT_RELENT:
       DynRelRegion.EntSize = Dyn.getVal();
       break;
+    case ELF::DT_RELR:
+    case ELF::DT_ANDROID_RELR:
+      DynRelrRegion.Addr = toMappedAddr(Dyn.getPtr());
+      break;
+    case ELF::DT_RELRSZ:
+    case ELF::DT_ANDROID_RELRSZ:
+      DynRelrRegion.Size = Dyn.getVal();
+      break;
+    case ELF::DT_RELRENT:
+    case ELF::DT_ANDROID_RELRENT:
+      DynRelrRegion.EntSize = Dyn.getVal();
+      break;
     case ELF::DT_PLTREL:
       if (Dyn.getVal() == DT_REL)
         DynPLTRelRegion.EntSize = sizeof(Elf_Rel);
@@ -1525,6 +1543,11 @@ typename ELFDumper<ELFT>::Elf_Rela_Range
   return DynRelaRegion.getAsArrayRef<Elf_Rela>();
 }
 
+template <typename ELFT>
+typename ELFDumper<ELFT>::Elf_Relr_Range ELFDumper<ELFT>::dyn_relrs() const {
+  return DynRelrRegion.getAsArrayRef<Elf_Relr>();
+}
+
 template<class ELFT>
 void ELFDumper<ELFT>::printFileHeaders() {
   ELFDumperStyle->printFileHeaders(Obj);
@@ -2582,7 +2605,6 @@ void GNUStyle<ELFT>::printRelocation(con
                                      const Elf_Rela &R, bool IsRela) {
   std::string Offset, Info, Addend, Value;
   SmallString<32> RelocName;
-  StringRef StrTable = unwrapOrError(Obj->getStringTableForSymtab(*SymTab));
   StringRef TargetName;
   const Elf_Sym *Sym = nullptr;
   unsigned Width = ELFT::Is64Bits ? 16 : 8;
@@ -2598,6 +2620,7 @@ void GNUStyle<ELFT>::printRelocation(con
         Obj->getSection(Sym, SymTab, this->dumper()->getShndxTable()));
     TargetName = unwrapOrError(Obj->getSectionName(Sec));
   } else if (Sym) {
+    StringRef StrTable = unwrapOrError(Obj->getStringTableForSymtab(*SymTab));
     TargetName = unwrapOrError(Sym->getName(StrTable));
   }
 
@@ -2629,24 +2652,36 @@ void GNUStyle<ELFT>::printRelocation(con
   OS << "\n";
 }
 
-static inline void printRelocHeader(raw_ostream &OS, bool Is64, bool IsRela) {
-  if (Is64)
-    OS << "    Offset             Info             Type"
+template <class ELFT> void GNUStyle<ELFT>::printRelocHeader(unsigned SType) {
+  bool IsRela = SType == ELF::SHT_RELA || SType == ELF::SHT_ANDROID_RELA;
+  bool IsRelr = SType == ELF::SHT_RELR || SType == ELF::SHT_ANDROID_RELR;
+  if (ELFT::Is64Bits)
+    OS << "    ";
+  else
+    OS << " ";
+  if (IsRelr && opts::RawRelr)
+    OS << "Data  ";
+  else
+    OS << "Offset";
+  if (ELFT::Is64Bits)
+    OS << "             Info             Type"
        << "               Symbol's Value  Symbol's Name";
   else
-    OS << " Offset     Info    Type                Sym. Value  "
-       << "Symbol's Name";
+    OS << "     Info    Type                Sym. Value  Symbol's Name";
   if (IsRela)
-    OS << (IsRela ? " + Addend" : "");
+    OS << " + Addend";
   OS << "\n";
 }
 
 template <class ELFT> void GNUStyle<ELFT>::printRelocations(const ELFO *Obj) {
   bool HasRelocSections = false;
   for (const Elf_Shdr &Sec : unwrapOrError(Obj->sections())) {
-    if (Sec.sh_type != ELF::SHT_REL && Sec.sh_type != ELF::SHT_RELA &&
+    if (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_RELA &&
+        Sec.sh_type != ELF::SHT_ANDROID_RELR)
       continue;
     HasRelocSections = true;
     StringRef Name = unwrapOrError(Obj->getSectionName(&Sec));
@@ -2659,13 +2694,20 @@ template <class ELFT> void GNUStyle<ELFT
       AndroidRelas = unwrapOrError(Obj->android_relas(&Sec));
       Entries = AndroidRelas.size();
     }
+    std::vector<Elf_Rela> RelrRelas;
+    if (!opts::RawRelr && (Sec.sh_type == ELF::SHT_RELR ||
+                           Sec.sh_type == ELF::SHT_ANDROID_RELR)) {
+      // .relr.dyn relative relocation section needs to be unpacked first
+      // to get the actual number of entries.
+      Elf_Relr_Range Relrs = unwrapOrError(Obj->relrs(&Sec));
+      RelrRelas = unwrapOrError(Obj->decode_relrs(Relrs));
+      Entries = RelrRelas.size();
+    }
     uintX_t Offset = Sec.sh_offset;
     OS << "\nRelocation section '" << Name << "' at offset 0x"
        << to_hexString(Offset, false) << " contains " << Entries
        << " entries:\n";
-    printRelocHeader(OS, ELFT::Is64Bits,
-                     Sec.sh_type == ELF::SHT_RELA ||
-                         Sec.sh_type == ELF::SHT_ANDROID_RELA);
+    printRelocHeader(Sec.sh_type);
     const Elf_Shdr *SymTab = unwrapOrError(Obj->getSection(Sec.sh_link));
     switch (Sec.sh_type) {
     case ELF::SHT_REL:
@@ -2681,6 +2723,16 @@ template <class ELFT> void GNUStyle<ELFT
       for (const auto &R : unwrapOrError(Obj->relas(&Sec)))
         printRelocation(Obj, SymTab, R, true);
       break;
+    case ELF::SHT_RELR:
+    case ELF::SHT_ANDROID_RELR:
+      if (opts::RawRelr)
+        for (const auto &R : unwrapOrError(Obj->relrs(&Sec)))
+          OS << to_string(format_hex_no_prefix(R, ELFT::Is64Bits ? 16 : 8))
+             << "\n";
+      else
+        for (const auto &R : RelrRelas)
+          printRelocation(Obj, SymTab, R, false);
+      break;
     case ELF::SHT_ANDROID_REL:
     case ELF::SHT_ANDROID_RELA:
       for (const auto &R : AndroidRelas)
@@ -2762,6 +2814,9 @@ std::string getSectionTypeString(unsigne
     return "GROUP";
   case SHT_SYMTAB_SHNDX:
     return "SYMTAB SECTION INDICES";
+  case SHT_RELR:
+  case SHT_ANDROID_RELR:
+    return "RELR";
   case SHT_LLVM_ODRTAB:
     return "LLVM_ODRTAB";
   case SHT_LLVM_LINKER_OPTIONS:
@@ -3300,13 +3355,14 @@ template <class ELFT>
 void GNUStyle<ELFT>::printDynamicRelocations(const ELFO *Obj) {
   const DynRegionInfo &DynRelRegion = this->dumper()->getDynRelRegion();
   const DynRegionInfo &DynRelaRegion = this->dumper()->getDynRelaRegion();
+  const DynRegionInfo &DynRelrRegion = this->dumper()->getDynRelrRegion();
   const DynRegionInfo &DynPLTRelRegion = this->dumper()->getDynPLTRelRegion();
   if (DynRelaRegion.Size > 0) {
     OS << "\n'RELA' relocation section at offset "
        << format_hex(reinterpret_cast<const uint8_t *>(DynRelaRegion.Addr) -
                          Obj->base(),
                      1) << " contains " << DynRelaRegion.Size << " bytes:\n";
-    printRelocHeader(OS, ELFT::Is64Bits, true);
+    printRelocHeader(ELF::SHT_RELA);
     for (const Elf_Rela &Rela : this->dumper()->dyn_relas())
       printDynamicRelocation(Obj, Rela, true);
   }
@@ -3315,7 +3371,7 @@ void GNUStyle<ELFT>::printDynamicRelocat
        << format_hex(reinterpret_cast<const uint8_t *>(DynRelRegion.Addr) -
                          Obj->base(),
                      1) << " contains " << DynRelRegion.Size << " bytes:\n";
-    printRelocHeader(OS, ELFT::Is64Bits, false);
+    printRelocHeader(ELF::SHT_REL);
     for (const Elf_Rel &Rel : this->dumper()->dyn_rels()) {
       Elf_Rela Rela;
       Rela.r_offset = Rel.r_offset;
@@ -3324,6 +3380,18 @@ void GNUStyle<ELFT>::printDynamicRelocat
       printDynamicRelocation(Obj, Rela, false);
     }
   }
+  if (DynRelrRegion.Size > 0) {
+    OS << "\n'RELR' relocation section at offset "
+       << format_hex(reinterpret_cast<const uint8_t *>(DynRelrRegion.Addr) -
+                         Obj->base(),
+                     1) << " contains " << DynRelrRegion.Size << " bytes:\n";
+    printRelocHeader(ELF::SHT_REL);
+    Elf_Relr_Range Relrs = this->dumper()->dyn_relrs();
+    std::vector<Elf_Rela> RelrRelas = unwrapOrError(Obj->decode_relrs(Relrs));
+    for (const Elf_Rela &Rela : RelrRelas) {
+      printDynamicRelocation(Obj, Rela, false);
+    }
+  }
   if (DynPLTRelRegion.Size) {
     OS << "\n'PLT' relocation section at offset "
        << format_hex(reinterpret_cast<const uint8_t *>(DynPLTRelRegion.Addr) -
@@ -3331,11 +3399,11 @@ void GNUStyle<ELFT>::printDynamicRelocat
                      1) << " contains " << DynPLTRelRegion.Size << " bytes:\n";
   }
   if (DynPLTRelRegion.EntSize == sizeof(Elf_Rela)) {
-    printRelocHeader(OS, ELFT::Is64Bits, true);
+    printRelocHeader(ELF::SHT_RELA);
     for (const Elf_Rela &Rela : DynPLTRelRegion.getAsArrayRef<Elf_Rela>())
       printDynamicRelocation(Obj, Rela, true);
   } else {
-    printRelocHeader(OS, ELFT::Is64Bits, false);
+    printRelocHeader(ELF::SHT_REL);
     for (const Elf_Rel &Rel : DynPLTRelRegion.getAsArrayRef<Elf_Rel>()) {
       Elf_Rela Rela;
       Rela.r_offset = Rel.r_offset;
@@ -3956,9 +4024,12 @@ template <class ELFT> void LLVMStyle<ELF
   for (const Elf_Shdr &Sec : unwrapOrError(Obj->sections())) {
     ++SectionNumber;
 
-    if (Sec.sh_type != ELF::SHT_REL && Sec.sh_type != ELF::SHT_RELA &&
+    if (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_RELA &&
+        Sec.sh_type != ELF::SHT_ANDROID_RELR)
       continue;
 
     StringRef Name = unwrapOrError(Obj->getSectionName(&Sec));
@@ -3991,6 +4062,19 @@ void LLVMStyle<ELFT>::printRelocations(c
     for (const Elf_Rela &R : unwrapOrError(Obj->relas(Sec)))
       printRelocation(Obj, R, SymTab);
     break;
+  case ELF::SHT_RELR:
+  case ELF::SHT_ANDROID_RELR: {
+    Elf_Relr_Range Relrs = unwrapOrError(Obj->relrs(Sec));
+    if (opts::RawRelr) {
+      for (const Elf_Relr &R : Relrs)
+        W.startLine() << W.hex(R) << "\n";
+    } else {
+      std::vector<Elf_Rela> RelrRelas = unwrapOrError(Obj->decode_relrs(Relrs));
+      for (const Elf_Rela &R : RelrRelas)
+        printRelocation(Obj, R, SymTab);
+    }
+    break;
+  }
   case ELF::SHT_ANDROID_REL:
   case ELF::SHT_ANDROID_RELA:
     for (const Elf_Rela &R : unwrapOrError(Obj->android_relas(Sec)))
@@ -4171,6 +4255,7 @@ template <class ELFT>
 void LLVMStyle<ELFT>::printDynamicRelocations(const ELFO *Obj) {
   const DynRegionInfo &DynRelRegion = this->dumper()->getDynRelRegion();
   const DynRegionInfo &DynRelaRegion = this->dumper()->getDynRelaRegion();
+  const DynRegionInfo &DynRelrRegion = this->dumper()->getDynRelrRegion();
   const DynRegionInfo &DynPLTRelRegion = this->dumper()->getDynPLTRelRegion();
   if (DynRelRegion.Size && DynRelaRegion.Size)
     report_fatal_error("There are both REL and RELA dynamic relocations");
@@ -4187,6 +4272,12 @@ void LLVMStyle<ELFT>::printDynamicReloca
       Rela.r_addend = 0;
       printDynamicRelocation(Obj, Rela);
     }
+  if (DynRelrRegion.Size > 0) {
+    Elf_Relr_Range Relrs = this->dumper()->dyn_relrs();
+    std::vector<Elf_Rela> RelrRelas = unwrapOrError(Obj->decode_relrs(Relrs));
+    for (const Elf_Rela &Rela : RelrRelas)
+      printDynamicRelocation(Obj, Rela);
+  }
   if (DynPLTRelRegion.EntSize == sizeof(Elf_Rela))
     for (const Elf_Rela &Rela : DynPLTRelRegion.getAsArrayRef<Elf_Rela>())
       printDynamicRelocation(Obj, Rela);

Modified: llvm/trunk/tools/llvm-readobj/llvm-readobj.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/llvm-readobj.cpp?rev=335922&r1=335921&r2=335922&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-readobj/llvm-readobj.cpp (original)
+++ llvm/trunk/tools/llvm-readobj/llvm-readobj.cpp Thu Jun 28 14:07:34 2018
@@ -164,6 +164,10 @@ namespace opts {
   cl::opt<bool> ExpandRelocs("expand-relocs",
     cl::desc("Expand each shown relocation to multiple lines"));
 
+  // -raw-relr
+  cl::opt<bool> RawRelr("raw-relr",
+    cl::desc("Do not decode relocations in SHT_RELR section, display raw contents"));
+
   // -codeview
   cl::opt<bool> CodeView("codeview",
                          cl::desc("Display CodeView debug information"));

Modified: llvm/trunk/tools/llvm-readobj/llvm-readobj.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/llvm-readobj.h?rev=335922&r1=335921&r2=335922&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-readobj/llvm-readobj.h (original)
+++ llvm/trunk/tools/llvm-readobj/llvm-readobj.h Thu Jun 28 14:07:34 2018
@@ -60,6 +60,7 @@ namespace opts {
   extern llvm::cl::opt<bool> DynamicSymbols;
   extern llvm::cl::opt<bool> UnwindInfo;
   extern llvm::cl::opt<bool> ExpandRelocs;
+  extern llvm::cl::opt<bool> RawRelr;
   extern llvm::cl::opt<bool> CodeView;
   extern llvm::cl::opt<bool> CodeViewSubsectionBytes;
   extern llvm::cl::opt<bool> ARMAttributes;

Modified: llvm/trunk/tools/yaml2obj/yaml2elf.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/yaml2obj/yaml2elf.cpp?rev=335922&r1=335921&r2=335922&view=diff
==============================================================================
--- llvm/trunk/tools/yaml2obj/yaml2elf.cpp (original)
+++ llvm/trunk/tools/yaml2obj/yaml2elf.cpp Thu Jun 28 14:07:34 2018
@@ -114,6 +114,7 @@ class ELFState {
   typedef typename ELFT::Sym Elf_Sym;
   typedef typename ELFT::Rel Elf_Rel;
   typedef typename ELFT::Rela Elf_Rela;
+  typedef typename ELFT::Relr Elf_Relr;
 
   enum class SymtabType { Static, Dynamic };
 
@@ -459,7 +460,10 @@ ELFState<ELFT>::writeSectionContent(Elf_
   Section.Content.writeAsBinary(OS);
   for (auto i = Section.Content.binary_size(); i < Section.Size; ++i)
     OS.write(0);
-  SHeader.sh_entsize = 0;
+  if (Section.Type == llvm::ELF::SHT_RELR)
+    SHeader.sh_entsize = sizeof(Elf_Relr);
+  else
+    SHeader.sh_entsize = 0;
   SHeader.sh_size = Section.Size;
 }
 




More information about the llvm-commits mailing list