summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
authorJake Ehrlich <jakehehrlich@google.com>2017-09-26 18:02:25 +0000
committerJake Ehrlich <jakehehrlich@google.com>2017-09-26 18:02:25 +0000
commit9f1a390f72ea5ee64f3e7859133983e878835c0a (patch)
treef68df258ececeb26efed3e0db6227150b86f8df2 /llvm
parent448e8ad94326713b2ef3d19b7fdc397e81114750 (diff)
downloadbcm5719-llvm-9f1a390f72ea5ee64f3e7859133983e878835c0a.tar.gz
bcm5719-llvm-9f1a390f72ea5ee64f3e7859133983e878835c0a.zip
[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 llvm-svn: 314227
Diffstat (limited to 'llvm')
-rw-r--r--llvm/test/tools/llvm-objcopy/Inputs/dynrel.elfbin0 -> 13560 bytes
-rw-r--r--llvm/test/tools/llvm-objcopy/dynamic-relocations.test19
-rw-r--r--llvm/tools/llvm-objcopy/Object.cpp47
-rw-r--r--llvm/tools/llvm-objcopy/Object.h46
4 files changed, 72 insertions, 40 deletions
diff --git a/llvm/test/tools/llvm-objcopy/Inputs/dynrel.elf b/llvm/test/tools/llvm-objcopy/Inputs/dynrel.elf
new file mode 100644
index 00000000000..fe9d6835421
--- /dev/null
+++ b/llvm/test/tools/llvm-objcopy/Inputs/dynrel.elf
Binary files differ
diff --git a/llvm/test/tools/llvm-objcopy/dynamic-relocations.test b/llvm/test/tools/llvm-objcopy/dynamic-relocations.test
new file mode 100644
index 00000000000..e544e2dd8ef
--- /dev/null
+++ b/llvm/test/tools/llvm-objcopy/dynamic-relocations.test
@@ -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: )
diff --git a/llvm/tools/llvm-objcopy/Object.cpp b/llvm/tools/llvm-objcopy/Object.cpp
index a8cd321086b..cb7fddeee77 100644
--- a/llvm/tools/llvm-objcopy/Object.cpp
+++ b/llvm/tools/llvm-objcopy/Object.cpp
@@ -206,22 +206,24 @@ void SymbolTableSectionImpl<ELFT>::writeSection(
}
}
-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>::writeSection(llvm::FileOutputBuffer &Out) const {
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(uint16_t Index, Twine ErrMsg) {
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::object::ELFFile<ELFT> &ElfFile,
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>::readSectionHeaders(const ELFFile<ELFT> &ElfFile) {
}
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",
diff --git a/llvm/tools/llvm-objcopy/Object.h b/llvm/tools/llvm-objcopy/Object.h
index 6e849e47006..41c9d7b4a3b 100644
--- a/llvm/tools/llvm-objcopy/Object.h
+++ b/llvm/tools/llvm-objcopy/Object.h
@@ -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;
OpenPOWER on IntegriCloud