[lld] r247888 - Add support of Elf_Rel dynamic relocations.
Rafael Espindola via llvm-commits
llvm-commits at lists.llvm.org
Thu Sep 17 07:02:10 PDT 2015
Author: rafael
Date: Thu Sep 17 09:02:10 2015
New Revision: 247888
URL: http://llvm.org/viewvc/llvm-project?rev=247888&view=rev
Log:
Add support of Elf_Rel dynamic relocations.
Modified:
lld/trunk/ELF/SymbolTable.cpp
lld/trunk/ELF/SymbolTable.h
lld/trunk/ELF/Writer.cpp
lld/trunk/test/elf2/shared.s
Modified: lld/trunk/ELF/SymbolTable.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.cpp?rev=247888&r1=247887&r2=247888&view=diff
==============================================================================
--- lld/trunk/ELF/SymbolTable.cpp (original)
+++ lld/trunk/ELF/SymbolTable.cpp Thu Sep 17 09:02:10 2015
@@ -20,6 +20,11 @@ using namespace lld::elf2;
SymbolTable::SymbolTable() {}
+bool SymbolTable::shouldUseRela() const {
+ ELFKind K = getFirstELF()->getELFKind();
+ return K == ELF64LEKind || K == ELF64BEKind;
+}
+
void SymbolTable::addFile(std::unique_ptr<InputFile> File) {
File->parse();
InputFile *FileP = File.release();
Modified: lld/trunk/ELF/SymbolTable.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.h?rev=247888&r1=247887&r2=247888&view=diff
==============================================================================
--- lld/trunk/ELF/SymbolTable.h (original)
+++ lld/trunk/ELF/SymbolTable.h Thu Sep 17 09:02:10 2015
@@ -42,6 +42,8 @@ public:
return nullptr;
}
+ bool shouldUseRela() const;
+
const llvm::DenseMap<StringRef, Symbol *> &getSymbols() const {
return Symtab;
}
Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=247888&r1=247887&r2=247888&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Thu Sep 17 09:02:10 2015
@@ -93,34 +93,37 @@ protected:
template <class ELFT> class SymbolTableSection;
template <class ELFT> struct DynamicReloc {
- typedef typename ELFFile<ELFT>::Elf_Rela Elf_Rela;
+ typedef typename ELFFile<ELFT>::Elf_Rel Elf_Rel;
const SectionChunk<ELFT> &C;
- const Elf_Rela &RI;
+ const Elf_Rel &RI;
};
template <class ELFT>
class RelocationSection final : public OutputSectionBase<ELFT::Is64Bits> {
+ typedef typename ELFFile<ELFT>::Elf_Rel Elf_Rel;
typedef typename ELFFile<ELFT>::Elf_Rela Elf_Rela;
public:
- RelocationSection(SymbolTableSection<ELFT> &DynSymSec)
- : OutputSectionBase<ELFT::Is64Bits>(".rela.dyn", SHT_RELA, SHF_ALLOC),
- DynSymSec(DynSymSec) {
- this->Header.sh_entsize = sizeof(Elf_Rela);
+ RelocationSection(SymbolTableSection<ELFT> &DynSymSec, bool IsRela)
+ : OutputSectionBase<ELFT::Is64Bits>(IsRela ? ".rela.dyn" : ".rel.dyn",
+ IsRela ? SHT_RELA : SHT_REL,
+ SHF_ALLOC),
+ DynSymSec(DynSymSec), IsRela(IsRela) {
+ this->Header.sh_entsize = IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel);
this->Header.sh_addralign = ELFT::Is64Bits ? 8 : 4;
}
void addReloc(const DynamicReloc<ELFT> &Reloc) { Relocs.push_back(Reloc); }
void finalize() override {
this->Header.sh_link = DynSymSec.getSectionIndex();
- this->Header.sh_size = Relocs.size() * sizeof(Elf_Rela);
+ this->Header.sh_size = Relocs.size() * this->Header.sh_entsize;
}
void writeTo(uint8_t *Buf) override {
auto *P = reinterpret_cast<Elf_Rela *>(Buf);
bool IsMips64EL = Relocs[0].C.getFile()->getObj()->isMips64EL();
for (const DynamicReloc<ELFT> &Rel : Relocs) {
const SectionChunk<ELFT> &C = Rel.C;
- const Elf_Rela &RI = Rel.RI;
+ const Elf_Rel &RI = Rel.RI;
OutputSection<ELFT> *Out = C.getOutputSection();
uint32_t SymIndex = RI.getSymbol(IsMips64EL);
const SymbolBody *Body = C.getFile()->getSymbolBody(SymIndex);
@@ -128,16 +131,19 @@ public:
P->r_offset = RI.r_offset + C.getOutputSectionOff() + Out->getVA();
P->setSymbolAndType(Body->getDynamicSymbolTableIndex(),
RI.getType(IsMips64EL), IsMips64EL);
- P->r_addend = RI.r_addend;
+ if (IsRela)
+ P->r_addend = static_cast<const Elf_Rela &>(RI).r_addend;
++P;
}
}
bool hasRelocs() const { return !Relocs.empty(); }
+ bool isRela() const { return IsRela; }
private:
std::vector<DynamicReloc<ELFT>> Relocs;
SymbolTableSection<ELFT> &DynSymSec;
+ const bool IsRela;
};
}
@@ -357,8 +363,8 @@ public:
unsigned NumEntries = 0;
if (RelaDynSec.hasRelocs()) {
- ++NumEntries; // DT_RELA
- ++NumEntries; // DT_RELASZ
+ ++NumEntries; // DT_RELA / DT_REL
+ ++NumEntries; // DT_RELASZ / DTRELSZ
}
++NumEntries; // DT_SYMTAB
++NumEntries; // DT_STRTAB
@@ -386,11 +392,12 @@ public:
auto *P = reinterpret_cast<Elf_Dyn *>(Buf);
if (RelaDynSec.hasRelocs()) {
- P->d_tag = DT_RELA;
+ bool IsRela = RelaDynSec.isRela();
+ P->d_tag = IsRela ? DT_RELA : DT_REL;
P->d_un.d_ptr = RelaDynSec.getVA();
++P;
- P->d_tag = DT_RELASZ;
+ P->d_tag = IsRela ? DT_RELASZ : DT_RELSZ;
P->d_un.d_val = RelaDynSec.getSize();
++P;
}
@@ -451,7 +458,7 @@ public:
typedef typename ELFFile<ELFT>::Elf_Rela Elf_Rela;
Writer(SymbolTable *T)
: SymTabSec(*this, *T, StrTabSec), DynSymSec(*this, *T, DynStrSec),
- RelaDynSec(DynSymSec), HashSec(DynSymSec),
+ RelaDynSec(DynSymSec, T->shouldUseRela()), HashSec(DynSymSec),
DynamicSec(*T, HashSec, RelaDynSec) {}
void run();
@@ -462,6 +469,9 @@ public:
private:
void createSections();
+ template <bool isRela>
+ void scanRelocs(const SectionChunk<ELFT> &C,
+ iterator_range<const Elf_Rel_Impl<ELFT, isRela> *> Rels);
void scanRelocs(const SectionChunk<ELFT> &C);
void assignAddresses();
void openFile(StringRef OutputPath);
@@ -821,6 +831,26 @@ static bool compSec(OutputSectionBase<Is
// * Write the dynamic relocations.
// * Write the rest of the file.
template <class ELFT>
+template <bool isRela>
+void Writer<ELFT>::scanRelocs(
+ const SectionChunk<ELFT> &C,
+ iterator_range<const Elf_Rel_Impl<ELFT, isRela> *> Rels) {
+ typedef Elf_Rel_Impl<ELFT, isRela> RelType;
+ const ObjectFile<ELFT> &File = *C.getFile();
+ bool IsMips64EL = File.getObj()->isMips64EL();
+ for (const RelType &RI : Rels) {
+ uint32_t SymIndex = RI.getSymbol(IsMips64EL);
+ const SymbolBody *Body = File.getSymbolBody(SymIndex);
+ if (!Body)
+ continue;
+ auto *S = dyn_cast<SharedSymbol<ELFT>>(Body);
+ if (!S)
+ continue;
+ RelaDynSec.addReloc({C, RI});
+ }
+}
+
+template <class ELFT>
void Writer<ELFT>::scanRelocs(const SectionChunk<ELFT> &C) {
const ObjectFile<ELFT> *File = C.getFile();
ELFFile<ELFT> *EObj = File->getObj();
@@ -829,18 +859,10 @@ void Writer<ELFT>::scanRelocs(const Sect
return;
for (const Elf_Shdr *RelSec : C.RelocSections) {
- if (RelSec->sh_type != SHT_RELA)
- continue;
- for (const Elf_Rela &RI : EObj->relas(RelSec)) {
- uint32_t SymIndex = RI.getSymbol(EObj->isMips64EL());
- const SymbolBody *Body = File->getSymbolBody(SymIndex);
- if (!Body)
- continue;
- auto *S = dyn_cast<SharedSymbol<ELFT>>(Body);
- if (!S)
- continue;
- RelaDynSec.addReloc({C, RI});
- }
+ if (RelSec->sh_type == SHT_RELA)
+ scanRelocs(C, EObj->relas(RelSec));
+ else
+ scanRelocs(C, EObj->rels(RelSec));
}
}
Modified: lld/trunk/test/elf2/shared.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf2/shared.s?rev=247888&r1=247887&r2=247888&view=diff
==============================================================================
--- lld/trunk/test/elf2/shared.s (original)
+++ lld/trunk/test/elf2/shared.s Thu Sep 17 09:02:10 2015
@@ -106,6 +106,15 @@
// CHECK: )
// CHECK-NEXT: }
+// CHECK: Name: .rel.dyn
+// CHECK-NEXT: Type: SHT_REL
+// CHECK-NEXT: Flags [
+// CHECK-NEXT: SHF_ALLOC
+// CHECK-NEXT: ]
+// CHECK-NEXT: Address: [[RELADDR:.*]]
+// CHECK-NEXT: Offset:
+// CHECK-NEXT: Size: [[RELSIZE:.*]]
+
// CHECK: Symbols [
// CHECK-NEXT: Symbol {
@@ -169,6 +178,8 @@
// CHECK: DynamicSection [
// CHECK-NEXT: Tag Type Name/Value
+// CHECK-NEXT: 0x00000011 REL [[RELADDR]]
+// CHECK-NEXT: 0x00000012 RELSZ [[RELSIZE]] (bytes)
// CHECK-NEXT: 0x00000006 SYMTAB [[DYNSYMADDR]]
// CHECK-NEXT: 0x00000005 STRTAB [[DYNSTRADDR]]
// CHECK-NEXT: 0x0000000A STRSZ
More information about the llvm-commits
mailing list