[llvm] r314227 - [llvm-objcopy] Add support for dynamic relocations

Jake Ehrlich via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 26 11:02:26 PDT 2017


Author: jakehehrlich
Date: Tue Sep 26 11:02:25 2017
New Revision: 314227

URL: http://llvm.org/viewvc/llvm-project?rev=314227&view=rev
Log:
[llvm-objcopy] Add support for dynamic relocations

This change adds support for dynamic relocations (allocated
SHT_REL/SHT_RELA sections with a dynamic symbol table as their link).

The binary I added for the test is here:
https://drive.google.com/file/d/0B3gtIAmiMwZXSjJUZE9pUjd4M0k/view?usp=sharing

Unless support for dynamic symbol tables in yaml2obj is added this is
needed.

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

Added:
    llvm/trunk/test/tools/llvm-objcopy/Inputs/dynrel.elf
    llvm/trunk/test/tools/llvm-objcopy/dynamic-relocations.test
Modified:
    llvm/trunk/tools/llvm-objcopy/Object.cpp
    llvm/trunk/tools/llvm-objcopy/Object.h

Added: llvm/trunk/test/tools/llvm-objcopy/Inputs/dynrel.elf
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objcopy/Inputs/dynrel.elf?rev=314227&view=auto
==============================================================================
Binary files llvm/trunk/test/tools/llvm-objcopy/Inputs/dynrel.elf (added) and llvm/trunk/test/tools/llvm-objcopy/Inputs/dynrel.elf Tue Sep 26 11:02:25 2017 differ

Added: llvm/trunk/test/tools/llvm-objcopy/dynamic-relocations.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objcopy/dynamic-relocations.test?rev=314227&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-objcopy/dynamic-relocations.test (added)
+++ llvm/trunk/test/tools/llvm-objcopy/dynamic-relocations.test Tue Sep 26 11:02:25 2017
@@ -0,0 +1,19 @@
+# RUN: llvm-objcopy %p/Inputs/dynrel.elf %t
+# RUN: llvm-readobj -sections -section-data %t | FileCheck %s
+
+#CHECK:         Name: .rela.plt
+#CHECK-NEXT:    Type: SHT_RELA
+#CHECK-NEXT:    Flags [
+#CHECK-NEXT:      SHF_ALLOC
+#CHECK-NEXT:    ]
+#CHECK-NEXT:    Address:
+#CHECK-NEXT:    Offset:
+#CHECK-NEXT:    Size: 24
+#CHECK-NEXT:    Link:
+#CHECK-NEXT:    Info:
+#CHECK-NEXT:    AddressAlignment: 8
+#CHECK-NEXT:    EntrySize: 24
+#CHECK-NEXT:    SectionData (
+#CHECK-NEXT:       0000: 18202000 00000000 07000000 01000000  |.  .............|
+#CHECK-NEXT:       0010: 00000000 00000000                    |........|
+#CHECK-NEXT:    )

Modified: llvm/trunk/tools/llvm-objcopy/Object.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objcopy/Object.cpp?rev=314227&r1=314226&r2=314227&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-objcopy/Object.cpp (original)
+++ llvm/trunk/tools/llvm-objcopy/Object.cpp Tue Sep 26 11:02:25 2017
@@ -206,22 +206,24 @@ void SymbolTableSectionImpl<ELFT>::write
   }
 }
 
-template <class ELFT>
-void RelocationSection<ELFT>::initialize(SectionTableRef SecTable) {
-  setSymTab(SecTable.getSectionOfType<SymbolTableSection>(
+template <class SymTabType>
+void RelocationSectionBase<SymTabType>::initialize(SectionTableRef SecTable) {
+  setSymTab(SecTable.getSectionOfType<SymTabType>(
       Link,
       "Link field value " + Twine(Link) + " in section " + Name + " is invalid",
       "Link field value " + Twine(Link) + " in section " + Name +
           " is not a symbol table"));
 
-  setSection(SecTable.getSection(Info,
-                                 "Info field value " + Twine(Info) +
-                                     " in section " + Name + " is invalid"));
+  if (Info != SHN_UNDEF)
+    setSection(SecTable.getSection(Info,
+                                   "Info field value " + Twine(Info) +
+                                       " in section " + Name + " is invalid"));
 }
 
-template <class ELFT> void RelocationSection<ELFT>::finalize() {
+template <class SymTabType> void RelocationSectionBase<SymTabType>::finalize() {
   this->Link = Symbols->Index;
-  this->Info = SecToApplyRel->Index;
+  if (SecToApplyRel != nullptr)
+    this->Info = SecToApplyRel->Index;
 }
 
 template <class ELFT>
@@ -252,6 +254,11 @@ void RelocationSection<ELFT>::writeSecti
     writeRel(reinterpret_cast<Elf_Rela *>(Buf));
 }
 
+void DynamicRelocationSection::writeSection(llvm::FileOutputBuffer &Out) const {
+  std::copy(std::begin(Contents), std::end(Contents),
+            Out.getBufferStart() + Offset);
+}
+
 bool SectionWithStrTab::classof(const SectionBase *S) {
   return isa<DynamicSymbolTableSection>(S) || isa<DynamicSection>(S);
 }
@@ -401,29 +408,13 @@ SectionBase *SectionTableRef::getSection
 
 template <class T>
 T *SectionTableRef::getSectionOfType(uint16_t Index, Twine IndexErrMsg,
-                                  Twine TypeErrMsg) {
+                                     Twine TypeErrMsg) {
   if (T *Sec = llvm::dyn_cast<T>(getSection(Index, IndexErrMsg)))
     return Sec;
   error(TypeErrMsg);
 }
 
 template <class ELFT>
-SectionBase *Object<ELFT>::getSection(uint16_t Index, Twine ErrMsg) {
-  if (Index == SHN_UNDEF || Index > Sections.size())
-    error(ErrMsg);
-  return Sections[Index - 1].get();
-}
-
-template <class ELFT>
-template <class T>
-T *Object<ELFT>::getSectionOfType(uint16_t Index, Twine IndexErrMsg,
-                                  Twine TypeErrMsg) {
-  if (T *TSec = llvm::dyn_cast<T>(getSection(Index, IndexErrMsg)))
-    return TSec;
-  error(TypeErrMsg);
-}
-
-template <class ELFT>
 std::unique_ptr<SectionBase>
 Object<ELFT>::makeSection(const llvm::object::ELFFile<ELFT> &ElfFile,
                           const Elf_Shdr &Shdr) {
@@ -431,6 +422,10 @@ Object<ELFT>::makeSection(const llvm::ob
   switch (Shdr.sh_type) {
   case SHT_REL:
   case SHT_RELA:
+    if (Shdr.sh_flags & SHF_ALLOC) {
+      Data = unwrapOrError(ElfFile.getSectionContents(&Shdr));
+      return llvm::make_unique<DynamicRelocationSection>(Data);
+    }
     return llvm::make_unique<RelocationSection<ELFT>>();
   case SHT_STRTAB:
     // If a string table is allocated we don't want to mess with it. That would
@@ -517,7 +512,7 @@ SectionTableRef Object<ELFT>::readSectio
     }
 
     if (auto Sec = dyn_cast<SectionWithStrTab>(Section.get())) {
-      Sec->setStrTab(getSectionOfType<StringTableSection>(
+      Sec->setStrTab(SecTable.getSectionOfType<StringTableSection>(
           Sec->Link,
           "Link field value " + Twine(Sec->Link) + " in section " + Sec->Name +
               " is invalid",

Modified: llvm/trunk/tools/llvm-objcopy/Object.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objcopy/Object.h?rev=314227&r1=314226&r2=314227&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-objcopy/Object.h (original)
+++ llvm/trunk/tools/llvm-objcopy/Object.h Tue Sep 26 11:02:25 2017
@@ -32,7 +32,6 @@ public:
   SectionBase *getSection(uint16_t Index, llvm::Twine ErrMsg);
 
   template <class T>
-
   T *getSectionOfType(uint16_t Index, llvm::Twine IndexErrMsg,
                       llvm::Twine TypeErrMsg);
 };
@@ -192,25 +191,35 @@ struct Relocation {
   uint32_t Type;
 };
 
-template <class ELFT> class RelocationSection : public SectionBase {
+template <class SymTabType> class RelocationSectionBase : public SectionBase {
+private:
+  SymTabType *Symbols;
+  SectionBase *SecToApplyRel;
+
+public:
+  void setSymTab(SymTabType *StrTab) { Symbols = StrTab; }
+  void setSection(SectionBase *Sec) { SecToApplyRel = Sec; }
+  void initialize(SectionTableRef SecTable) override;
+  void finalize() override;
+};
+
+template <class ELFT>
+class RelocationSection : public RelocationSectionBase<SymbolTableSection> {
 private:
   typedef typename ELFT::Rel Elf_Rel;
   typedef typename ELFT::Rela Elf_Rela;
 
   std::vector<Relocation> Relocations;
-  SymbolTableSection *Symbols;
-  SectionBase *SecToApplyRel;
 
   template <class T> void writeRel(T *Buf) const;
 
 public:
-  void setSymTab(SymbolTableSection *StrTab) { Symbols = StrTab; }
-  void setSection(SectionBase *Sec) { SecToApplyRel = Sec; }
   void addRelocation(Relocation Rel) { Relocations.push_back(Rel); }
-  void initialize(SectionTableRef SecTable) override;
-  void finalize() override;
   void writeSection(llvm::FileOutputBuffer &Out) const override;
+
   static bool classof(const SectionBase *S) {
+    if (S->Flags & llvm::ELF::SHF_ALLOC)
+      return false;
     return S->Type == llvm::ELF::SHT_REL || S->Type == llvm::ELF::SHT_RELA;
   }
 };
@@ -244,6 +253,21 @@ public:
   }
 };
 
+class DynamicRelocationSection
+    : public RelocationSectionBase<DynamicSymbolTableSection> {
+private:
+  llvm::ArrayRef<uint8_t> Contents;
+
+public:
+  DynamicRelocationSection(llvm::ArrayRef<uint8_t> Data) : Contents(Data) {}
+  void writeSection(llvm::FileOutputBuffer &Out) const override;
+  static bool classof(const SectionBase *S) {
+    if (!(S->Flags & llvm::ELF::SHF_ALLOC))
+      return false;
+    return S->Type == llvm::ELF::SHT_REL || S->Type == llvm::ELF::SHT_RELA;
+  }
+};
+
 template <class ELFT> class Object {
 private:
   typedef std::unique_ptr<SectionBase> SecPtr;
@@ -260,12 +284,6 @@ private:
   void readProgramHeaders(const llvm::object::ELFFile<ELFT> &ElfFile);
   SectionTableRef readSectionHeaders(const llvm::object::ELFFile<ELFT> &ElfFile);
 
-  SectionBase *getSection(uint16_t Index, llvm::Twine ErrMsg);
-
-  template <class T>
-  T *getSectionOfType(uint16_t Index, llvm::Twine IndexErrMsg,
-                      llvm::Twine TypeErrMsg);
-
 protected:
   StringTableSection *SectionNames;
   SymbolTableSection *SymbolTable;




More information about the llvm-commits mailing list