summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2016-03-11 12:14:02 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2016-03-11 12:14:02 +0000
commitccb8b4d4fe4385ec6750d38ca4d860ce4892a64f (patch)
tree72b4464d9c587ed905dc0980eaae4703c84a2a14
parentec5872bc4276fbf779af0bde6aeb7d6489850c8f (diff)
downloadbcm5719-llvm-ccb8b4d4fe4385ec6750d38ca4d860ce4892a64f.tar.gz
bcm5719-llvm-ccb8b4d4fe4385ec6750d38ca4d860ce4892a64f.zip
Remember the input section of locals.
This is already a simplification, but will allow much more. llvm-svn: 263224
-rw-r--r--lld/ELF/InputFiles.cpp2
-rw-r--r--lld/ELF/OutputSections.cpp20
-rw-r--r--lld/ELF/OutputSections.h9
-rw-r--r--lld/ELF/Symbols.h7
-rw-r--r--lld/ELF/Writer.cpp14
5 files changed, 21 insertions, 31 deletions
diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp
index 6060de65bc9..30e2c701b13 100644
--- a/lld/ELF/InputFiles.cpp
+++ b/lld/ELF/InputFiles.cpp
@@ -292,7 +292,7 @@ template <class ELFT>
SymbolBody *elf::ObjectFile<ELFT>::createSymbolBody(const Elf_Sym *Sym) {
unsigned char Binding = Sym->getBinding();
if (Binding == STB_LOCAL)
- return new (Alloc) LocalSymbol<ELFT>(*Sym);
+ return new (Alloc) LocalSymbol<ELFT>(*Sym, getSection(*Sym));
StringRef Name = check(Sym->getName(this->StringTable));
diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp
index 19e910313ab..05f1b9cede0 100644
--- a/lld/ELF/OutputSections.cpp
+++ b/lld/ELF/OutputSections.cpp
@@ -267,12 +267,20 @@ template <class ELFT> void RelocationSection<ELFT>::writeTo(uint8_t *Buf) {
if (IsRela) {
uintX_t VA = 0;
- if (Rel.UseSymVA)
- VA = Sym->getVA<ELFT>();
- else if (Rel.TargetSec)
- VA = Rel.TargetSec->getOffset(Rel.OffsetInTargetSec) +
- Rel.TargetSec->OutSec->getVA();
- reinterpret_cast<Elf_Rela *>(P)->r_addend = Rel.Addend + VA;
+ uintX_t Addend = Rel.Addend;
+ if (Rel.UseSymVA) {
+ if (auto *L = dyn_cast<LocalSymbol<ELFT>>(Sym)) {
+ uintX_t Pos = L->Sym.st_value;
+ if (L->Sym.getType() == STT_SECTION) {
+ Pos += Addend;
+ Addend = 0;
+ }
+ VA = L->Section->OutSec->getVA() + L->Section->getOffset(Pos);
+ } else {
+ VA = Sym->getVA<ELFT>();
+ }
+ }
+ reinterpret_cast<Elf_Rela *>(P)->r_addend = Addend + VA;
}
P->r_offset = Rel.getOffset();
diff --git a/lld/ELF/OutputSections.h b/lld/ELF/OutputSections.h
index f9e4a536e29..b4db5b813b1 100644
--- a/lld/ELF/OutputSections.h
+++ b/lld/ELF/OutputSections.h
@@ -186,8 +186,6 @@ template <class ELFT> struct DynamicReloc {
InputSectionBase<ELFT> *OffsetSec = nullptr;
uintX_t OffsetInSec = 0;
bool UseSymVA = false;
- InputSectionBase<ELFT> *TargetSec = nullptr;
- uintX_t OffsetInTargetSec = 0;
uintX_t Addend = 0;
DynamicReloc(uint32_t Type, OffsetKind OKind, SymbolBody *Sym)
@@ -202,13 +200,6 @@ template <class ELFT> struct DynamicReloc {
: Type(Type), OKind(Off_Sec), Sym(Sym), OffsetSec(OffsetSec),
OffsetInSec(OffsetInSec), UseSymVA(UseSymVA), Addend(Addend) {}
- DynamicReloc(uint32_t Type, InputSectionBase<ELFT> *OffsetSec,
- uintX_t OffsetInSec, InputSectionBase<ELFT> *TargetSec,
- uintX_t OffsetInTargetSec, uintX_t Addend)
- : Type(Type), OKind(Off_Sec), OffsetSec(OffsetSec),
- OffsetInSec(OffsetInSec), TargetSec(TargetSec),
- OffsetInTargetSec(OffsetInTargetSec), Addend(Addend) {}
-
uintX_t getOffset() const;
};
diff --git a/lld/ELF/Symbols.h b/lld/ELF/Symbols.h
index d76be4f8a1b..bb6b9fa3988 100644
--- a/lld/ELF/Symbols.h
+++ b/lld/ELF/Symbols.h
@@ -310,12 +310,15 @@ template <class ELFT> class LocalSymbol : public DefinedElf<ELFT> {
typedef typename llvm::object::ELFFile<ELFT>::Elf_Sym Elf_Sym;
public:
- LocalSymbol(const Elf_Sym &Sym)
- : DefinedElf<ELFT>(SymbolBody::DefinedLocalKind, "", Sym) {}
+ LocalSymbol(const Elf_Sym &Sym, InputSectionBase<ELFT> *Section)
+ : DefinedElf<ELFT>(SymbolBody::DefinedLocalKind, "", Sym),
+ Section(Section) {}
static bool classof(const SymbolBody *S) {
return S->kind() == SymbolBody::DefinedLocalKind;
}
+
+ InputSectionBase<ELFT> *Section;
};
// This class represents a symbol defined in an archive file. It is
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index cb51fd5c1c8..7c5c33633e6 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -474,20 +474,8 @@ void Writer<ELFT>::scanRelocs(
(uintX_t)getPPC64TocBase() + Addend});
continue;
}
- if (!Body.isLocal()) {
- Out<ELFT>::RelaDyn->addReloc(
- {Target->RelativeRel, &C, RI.r_offset, true, &Body, Addend});
- continue;
- }
- const Elf_Sym &Sym = cast<LocalSymbol<ELFT>>(Body).Sym;
- InputSectionBase<ELFT> *Section = File.getSection(Sym);
- uintX_t Offset = Sym.st_value;
- if (Sym.getType() == STT_SECTION) {
- Offset += Addend;
- Addend = 0;
- }
Out<ELFT>::RelaDyn->addReloc(
- {Target->RelativeRel, &C, RI.r_offset, Section, Offset, Addend});
+ {Target->RelativeRel, &C, RI.r_offset, true, &Body, Addend});
}
}
OpenPOWER on IntegriCloud