[lld] r199973 - [ELF] Customize a relocation table output format (rel / rela).

Simon Atanasyan simon at atanasyan.com
Thu Jan 23 21:21:22 PST 2014


Author: atanasyan
Date: Thu Jan 23 23:21:21 2014
New Revision: 199973

URL: http://llvm.org/viewvc/llvm-project?rev=199973&view=rev
Log:
[ELF] Customize a relocation table output format (rel / rela).
Add new virtual virtual function `isRelaOutputFormat` to the
`ELFLinkingContext` class. Call this function everywhere we need to
select a relocation table format.

Patch reviewed by Shankar Easwaran and Rui Ueyama.

Added:
    lld/trunk/test/elf/Mips/exe-dynamic.test
Modified:
    lld/trunk/include/lld/ReaderWriter/ELFLinkingContext.h
    lld/trunk/lib/ReaderWriter/ELF/DefaultLayout.h
    lld/trunk/lib/ReaderWriter/ELF/ExecutableWriter.h
    lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.h
    lld/trunk/lib/ReaderWriter/ELF/SectionChunks.h
    lld/trunk/test/elf/Mips/exe-fileheader.test
    lld/trunk/test/elf/Mips/r26.test

Modified: lld/trunk/include/lld/ReaderWriter/ELFLinkingContext.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/ReaderWriter/ELFLinkingContext.h?rev=199973&r1=199972&r2=199973&view=diff
==============================================================================
--- lld/trunk/include/lld/ReaderWriter/ELFLinkingContext.h (original)
+++ lld/trunk/include/lld/ReaderWriter/ELFLinkingContext.h Thu Jan 23 23:21:21 2014
@@ -93,6 +93,9 @@ public:
 
   static std::unique_ptr<ELFLinkingContext> create(llvm::Triple);
 
+  /// \brief Use Elf_Rela format to output relocation tables.
+  virtual bool isRelaOutputFormat() const { return true; }
+
   /// \brief Does this relocation belong in the dynamic plt relocation table?
   ///
   /// This table holds all of the relocations used for delayed symbol binding.

Modified: lld/trunk/lib/ReaderWriter/ELF/DefaultLayout.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/DefaultLayout.h?rev=199973&r1=199972&r2=199973&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/DefaultLayout.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/DefaultLayout.h Thu Jan 23 23:21:21 2014
@@ -270,7 +270,8 @@ public:
   RelocationTable<ELFT> *getDynamicRelocationTable() {
     if (!_dynamicRelocationTable) {
       _dynamicRelocationTable.reset(new (_allocator) RelocationTable<ELFT>(
-          _context, ".rela.dyn", ORDER_DYNAMIC_RELOCS));
+          _context, _context.isRelaOutputFormat() ? ".rela.dyn" : ".rel.dyn",
+          ORDER_DYNAMIC_RELOCS));
       addSection(_dynamicRelocationTable.get());
     }
     return _dynamicRelocationTable.get();
@@ -280,7 +281,8 @@ public:
   RelocationTable<ELFT> *getPLTRelocationTable() {
     if (!_pltRelocationTable) {
       _pltRelocationTable.reset(new (_allocator) RelocationTable<ELFT>(
-          _context, ".rela.plt", ORDER_DYNAMIC_PLT_RELOCS));
+          _context, _context.isRelaOutputFormat() ? ".rela.plt" : ".rel.plt",
+          ORDER_DYNAMIC_PLT_RELOCS));
       addSection(_pltRelocationTable.get());
     }
     return _pltRelocationTable.get();

Modified: lld/trunk/lib/ReaderWriter/ELF/ExecutableWriter.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/ExecutableWriter.h?rev=199973&r1=199972&r2=199973&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/ExecutableWriter.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/ExecutableWriter.h Thu Jan 23 23:21:21 2014
@@ -55,8 +55,13 @@ void ExecutableWriter<ELFT>::addDefaultA
   _runtimeFile->addAbsoluteAtom("__preinit_array_end");
   _runtimeFile->addAbsoluteAtom("__init_array_start");
   _runtimeFile->addAbsoluteAtom("__init_array_end");
-  _runtimeFile->addAbsoluteAtom("__rela_iplt_start");
-  _runtimeFile->addAbsoluteAtom("__rela_iplt_end");
+  if (this->_context.isRelaOutputFormat()) {
+    _runtimeFile->addAbsoluteAtom("__rela_iplt_start");
+    _runtimeFile->addAbsoluteAtom("__rela_iplt_end");
+  } else {
+    _runtimeFile->addAbsoluteAtom("__rel_iplt_start");
+    _runtimeFile->addAbsoluteAtom("__rel_iplt_end");
+  }
   _runtimeFile->addAbsoluteAtom("__fini_array_start");
   _runtimeFile->addAbsoluteAtom("__fini_array_end");
 }
@@ -111,7 +116,10 @@ template <class ELFT> void ExecutableWri
 
   startEnd("preinit_array", ".preinit_array");
   startEnd("init_array", ".init_array");
-  startEnd("rela_iplt", ".rela.plt");
+  if (this->_context.isRelaOutputFormat())
+    startEnd("rela_iplt", ".rela.plt");
+  else
+    startEnd("rel_iplt", ".rel.plt");
   startEnd("fini_array", ".fini_array");
 
   assert(!(bssStartAtomIter == this->_layout->absoluteAtoms().end() ||

Modified: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.h?rev=199973&r1=199972&r2=199973&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.h Thu Jan 23 23:21:21 2014
@@ -45,6 +45,7 @@ public:
   virtual StringRef entrySymbolName() const;
   virtual StringRef getDefaultInterpreter() const;
   virtual void addPasses(PassManager &pm);
+  virtual bool isRelaOutputFormat() const { return false; }
   virtual bool isPLTRelocation(const DefinedAtom &, const Reference &r) const;
 };
 

Modified: lld/trunk/lib/ReaderWriter/ELF/SectionChunks.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/SectionChunks.h?rev=199973&r1=199972&r2=199973&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/SectionChunks.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/SectionChunks.h Thu Jan 23 23:21:21 2014
@@ -900,22 +900,29 @@ private:
 
 template <class ELFT> class RelocationTable : public Section<ELFT> {
 public:
+  typedef llvm::object::Elf_Rel_Impl<ELFT, false> Elf_Rel;
   typedef llvm::object::Elf_Rel_Impl<ELFT, true> Elf_Rela;
 
   RelocationTable(const ELFLinkingContext &context, StringRef str,
                   int32_t order)
       : Section<ELFT>(context, str), _symbolTable(nullptr) {
     this->setOrder(order);
-    this->_entSize = sizeof(Elf_Rela);
-    this->_align2 = llvm::alignOf<Elf_Rela>();
-    this->_type = SHT_RELA;
     this->_flags = SHF_ALLOC;
+    if (context.isRelaOutputFormat()) {
+      this->_entSize = sizeof(Elf_Rela);
+      this->_align2 = llvm::alignOf<Elf_Rela>();
+      this->_type = SHT_RELA;
+    } else {
+      this->_entSize = sizeof(Elf_Rel);
+      this->_align2 = llvm::alignOf<Elf_Rel>();
+      this->_type = SHT_REL;
+    }
   }
 
   /// \returns the index of the relocation added.
   uint32_t addRelocation(const DefinedAtom &da, const Reference &r) {
     _relocs.emplace_back(&da, &r);
-    this->_fsize = _relocs.size() * sizeof(Elf_Rela);
+    this->_fsize = _relocs.size() * this->_entSize;
     this->_msize = this->_fsize;
     return _relocs.size() - 1;
   }
@@ -945,34 +952,52 @@ public:
   }
 
   virtual void write(ELFWriter *writer, llvm::FileOutputBuffer &buffer) {
-    uint8_t *chunkBuffer = buffer.getBufferStart();
-    uint8_t *dest = chunkBuffer + this->fileOffset();
+    uint8_t *dest = buffer.getBufferStart() + this->fileOffset();
     for (const auto &rel : _relocs) {
-      Elf_Rela *r = reinterpret_cast<Elf_Rela *>(dest);
-      uint32_t index =
-          _symbolTable ? _symbolTable->getSymbolTableIndex(rel.second->target())
-                       : (uint32_t) STN_UNDEF;
-      r->setSymbolAndType(index, rel.second->kindValue());
-      r->r_offset =
-          writer->addressOfAtom(rel.first) + rel.second->offsetInAtom();
-      r->r_addend = 0;
-      // The addend is used only by relative relocations
-      if (this->_context.isRelativeReloc(*rel.second))
-        r->r_addend =
-            writer->addressOfAtom(rel.second->target()) + rel.second->addend();
-      dest += sizeof(Elf_Rela);
-      DEBUG_WITH_TYPE("ELFRelocationTable",
-                      llvm::dbgs() << rel.second->kindValue()
-                                   << " relocation at " << rel.first->name()
-                                   << "@" << r->r_offset << " to "
-                                   << rel.second->target()->name() << "@"
-                                   << r->r_addend << "\n";);
+      if (this->_context.isRelaOutputFormat())
+        writeRela(writer, *reinterpret_cast<Elf_Rela *>(dest), *rel.first,
+                  *rel.second);
+      else
+        writeRel(writer, *reinterpret_cast<Elf_Rel *>(dest), *rel.first,
+                 *rel.second);
+      dest += this->_entSize;
     }
   }
 
 private:
   std::vector<std::pair<const DefinedAtom *, const Reference *> > _relocs;
   const DynamicSymbolTable<ELFT> *_symbolTable;
+
+  void writeRela(ELFWriter *writer, Elf_Rela &r, const DefinedAtom &atom,
+                 const Reference &ref) {
+    uint32_t index =
+        _symbolTable ? _symbolTable->getSymbolTableIndex(ref.target())
+                     : (uint32_t)STN_UNDEF;
+    r.setSymbolAndType(index, ref.kindValue());
+    r.r_offset = writer->addressOfAtom(&atom) + ref.offsetInAtom();
+    r.r_addend = 0;
+    // The addend is used only by relative relocations
+    if (this->_context.isRelativeReloc(ref))
+      r.r_addend = writer->addressOfAtom(ref.target()) + ref.addend();
+    DEBUG_WITH_TYPE("ELFRelocationTable",
+                    llvm::dbgs() << ref.kindValue() << " relocation at "
+                                 << atom.name() << "@" << r.r_offset << " to "
+                                 << ref.target()->name() << "@" << r.r_addend
+                                 << "\n";);
+  }
+
+  void writeRel(ELFWriter *writer, Elf_Rel &r, const DefinedAtom &atom,
+                const Reference &ref) {
+    uint32_t index =
+        _symbolTable ? _symbolTable->getSymbolTableIndex(ref.target())
+                     : (uint32_t)STN_UNDEF;
+    r.setSymbolAndType(index, ref.kindValue());
+    r.r_offset = writer->addressOfAtom(&atom) + ref.offsetInAtom();
+    DEBUG_WITH_TYPE("ELFRelocationTable",
+                    llvm::dbgs() << ref.kindValue() << " relocation at "
+                                 << atom.name() << "@" << r.r_offset << " to "
+                                 << ref.target()->name() << "\n";);
+  }
 };
 
 template <class ELFT> class HashSection;
@@ -1017,6 +1042,8 @@ public:
   }
 
   virtual void createDefaultEntries() {
+    bool isRela = this->_context.isRelaOutputFormat();
+
     Elf_Dyn dyn;
     dyn.d_un.d_val = 0;
 
@@ -1035,11 +1062,11 @@ public:
     dyn.d_tag = DT_FINI_ARRAYSZ;
     _dt_fini_arraysz = addEntry(dyn);
     if (_layout->hasDynamicRelocationTable()) {
-      dyn.d_tag = DT_RELA;
+      dyn.d_tag = isRela ? DT_RELA : DT_REL;
       _dt_rela = addEntry(dyn);
-      dyn.d_tag = DT_RELASZ;
+      dyn.d_tag = isRela ? DT_RELASZ : DT_RELSZ;
       _dt_relasz = addEntry(dyn);
-      dyn.d_tag = DT_RELAENT;
+      dyn.d_tag = isRela ? DT_RELAENT : DT_RELENT;
       _dt_relaent = addEntry(dyn);
     }
     if (_layout->hasPLTRelocationTable()) {
@@ -1048,7 +1075,7 @@ public:
       dyn.d_tag = DT_PLTGOT;
       _dt_pltgot = addEntry(dyn);
       dyn.d_tag = DT_PLTREL;
-      dyn.d_un.d_val = DT_RELA;
+      dyn.d_un.d_val = isRela ? DT_RELA : DT_REL;
       _dt_pltrel = addEntry(dyn);
       dyn.d_un.d_val = 0;
       dyn.d_tag = DT_JMPREL;

Added: lld/trunk/test/elf/Mips/exe-dynamic.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Mips/exe-dynamic.test?rev=199973&view=auto
==============================================================================
--- lld/trunk/test/elf/Mips/exe-dynamic.test (added)
+++ lld/trunk/test/elf/Mips/exe-dynamic.test Thu Jan 23 23:21:21 2014
@@ -0,0 +1,48 @@
+# Check MIPS specific tags in the dynamic table in case executable linking.
+
+# Build shared library
+# RUN: llvm-mc -triple=mipsel -filetype=obj -relocation-model=pic \
+# RUN:         -o=%t-obj %p/Inputs/ext.s
+# RUN: lld -flavor gnu -target mipsel -shared -o %t-so %t-obj
+
+# Build executable
+# RUN: llvm-mc -triple=mipsel -filetype=obj -o=%t-obj %s
+# RUN: lld -flavor gnu -target mipsel -e glob -o %t-exe %t-obj %t-so
+# RUN: llvm-readobj -dynamic-table %t-exe | FileCheck %s
+
+# CHECK: Format: ELF32-mips
+# CHECK: Arch: mipsel
+# CHECK: AddressSize: 32bit
+# CHECK: LoadName:
+# CHECK: DynamicSection [ (20 entries)
+# CHECK:   Tag        Type                 Name/Value
+# CHECK:   0x00000004 HASH                 0x400110
+# CHECK:   0x00000005 STRTAB               0x400144
+# CHECK:   0x00000006 SYMTAB               0x400124
+# CHECK:   0x0000000A STRSZ                30 (bytes)
+# CHECK:   0x0000000B SYMENT               16 (bytes)
+# CHECK:   0x0000001A FINI_ARRAY           0x0
+# CHECK:   0x0000001C FINI_ARRAYSZ         0 (bytes)
+# CHECK:   0x00000002 PLTRELSZ             8 (bytes)
+# CHECK:   0x00000003 PLTGOT               0x402000
+# CHECK:   0x00000014 PLTREL               REL
+# CHECK:   0x00000017 JMPREL               0x400162
+# CHECK:   0x70000001 MIPS_RLD_VERSION     1
+# CHECK:   0x70000005 MIPS_FLAGS           0x2
+# CHECK:   0x70000006 MIPS_BASE_ADDRESS    0x400000
+# CHECK:   0x7000000A MIPS_LOCAL_GOTNO     2
+# CHECK:   0x70000011 MIPS_SYMTABNO        2
+# CHECK:   0x70000013 MIPS_GOTSYM          0x2
+# CHECK:   0x00000001 NEEDED               SharedLibrary (exe-dynamic.test.{{.*}})
+# CHECK:   0x00000000 NULL                 0x0
+# CHECK: ]
+
+    .abicalls
+    .global glob
+    .ent    glob
+loc:
+    jal     ext1
+glob:
+    jal     loc
+    jal     glob
+    .end    glob

Modified: lld/trunk/test/elf/Mips/exe-fileheader.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Mips/exe-fileheader.test?rev=199973&r1=199972&r2=199973&view=diff
==============================================================================
--- lld/trunk/test/elf/Mips/exe-fileheader.test (original)
+++ lld/trunk/test/elf/Mips/exe-fileheader.test Thu Jan 23 23:21:21 2014
@@ -27,7 +27,7 @@
 # CHECK:   Type: Executable (0x2)
 # CHECK:   Machine: EM_MIPS (0x8)
 # CHECK:   Version: 1
-# CHECK:   Entry: 0x4001B0
+# CHECK:   Entry: 0x4001A0
 # CHECK:   ProgramHeaderOffset: 0x34
 # CHECK:   SectionHeaderOffset: 0x2268
 # CHECK:   Flags [ (0x70001005)

Modified: lld/trunk/test/elf/Mips/r26.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Mips/r26.test?rev=199973&r1=199972&r2=199973&view=diff
==============================================================================
--- lld/trunk/test/elf/Mips/r26.test (original)
+++ lld/trunk/test/elf/Mips/r26.test Thu Jan 23 23:21:21 2014
@@ -24,7 +24,7 @@
 
 # Executable file has the only relocation for external symbol
 # EXE-REL: Relocations [
-# EXE-REL:   Section (5) .rela.plt {
+# EXE-REL:   Section (5) .rel.plt {
 # EXE-REL:     0x402008 R_MIPS_JUMP_SLOT ext1 0x0
 # EXE-REL:   }
 # EXE-REL: ]
@@ -32,32 +32,32 @@
 # EXE: Disassembly of section .plt:
 # EXE: .plt:
 # PLTA entry. Points to the .got.plt[1]
-# EXE:   400190:  40 00 0f 3c  lui     $15, 64
-# EXE:   400194:  08 20 f9 8d  lw      $25, 8200($15)
-# EXE:   400198:  08 00 20 03  jr      $25
-# EXE:   40019c:  08 20 f8 25  addiu   $24, $15, 8200
+# EXE:   400180:  40 00 0f 3c  lui     $15, 64
+# EXE:   400184:  08 20 f9 8d  lw      $25, 8200($15)
+# EXE:   400188:  08 00 20 03  jr      $25
+# EXE:   40018c:  08 20 f8 25  addiu   $24, $15, 8200
 
 # EXE: Disassembly of section .text:
 # EXE: glob:
-# EXE:   4001a0:  09 f8 20 03  jalr    $25
-# EXE:   4001a4:  00 00 00 00  nop
+# EXE:   400190:  09 f8 20 03  jalr    $25
+# EXE:   400194:  00 00 00 00  nop
 #
 # Jump to 'loc' label address
-# EXE:   4001a8:  6c 00 10 0c  jal     4194736
-# EXE:   4001ac:  00 00 00 00  nop
+# EXE:   400198:  6c 00 10 0c  jal     4194736
+# EXE:   40019c:  00 00 00 00  nop
 #
 # EXE: loc:
 # Jump to 'glob' label address
-# EXE:   4001b0:  68 00 10 0c  jal     4194720
-# EXE:   4001b4:  00 00 00 00  nop
+# EXE:   4001a0:  64 00 10 0c  jal     4194704
+# EXE:   4001a4:  00 00 00 00  nop
 #
 # Jump to the first PLT entry (.plt + 32) for ext1 entry
-# EXE:   4001b8:  64 00 10 0c  jal     4194704
-# EXE:   4001bc:  00 00 00 00  nop
+# EXE:   4001a8:  60 00 10 0c  jal     4194688
+# EXE:   4001ac:  00 00 00 00  nop
 
 # EXE: Sections:
 # EXE: Idx Name          Size      Address          Type
-# EXE:   6 .plt          00000030 0000000000400170 TEXT DATA
+# EXE:   6 .plt          00000030 0000000000400160 TEXT DATA
 # EXE:  10 .got.plt      0000000c 0000000000402000 DATA
 
     .abicalls





More information about the llvm-commits mailing list