summaryrefslogtreecommitdiffstats
path: root/lld/ELF/Writer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lld/ELF/Writer.cpp')
-rw-r--r--lld/ELF/Writer.cpp35
1 files changed, 33 insertions, 2 deletions
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index 76cde102675..854722cbf2d 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -85,6 +85,9 @@ private:
bool isOutputDynamic() const {
return !Symtab.getSharedFiles().empty() || Config->Pic;
}
+ template <class RelTy>
+ void scanRelocsForThunks(const elf::ObjectFile<ELFT> &File,
+ iterator_range<const RelTy *> Rels);
void ensureBss();
void addCommonSymbols(std::vector<DefinedCommon *> &Syms);
@@ -298,6 +301,25 @@ static unsigned handleTlsRelocation(uint32_t Type, SymbolBody &Body,
return 0;
}
+// Some targets might require creation of thunks for relocations. Now we
+// support only MIPS which requires LA25 thunk to call PIC code from non-PIC
+// one. Scan relocations to find each one requires thunk.
+template <class ELFT>
+template <class RelTy>
+void Writer<ELFT>::scanRelocsForThunks(const elf::ObjectFile<ELFT> &File,
+ iterator_range<const RelTy *> Rels) {
+ for (const RelTy &RI : Rels) {
+ uint32_t Type = RI.getType(Config->Mips64EL);
+ uint32_t SymIndex = RI.getSymbol(Config->Mips64EL);
+ SymbolBody &Body = File.getSymbolBody(SymIndex).repl();
+ if (Body.hasThunk() || !Target->needsThunk(Type, File, Body))
+ continue;
+ auto *D = cast<DefinedRegular<ELFT>>(&Body);
+ auto *S = cast<InputSection<ELFT>>(D->Section);
+ S->addThunk(Body);
+ }
+}
+
// The reason we have to do this early scan is as follows
// * To mmap the output file, we need to know the size
// * For that, we need to know how many dynamic relocs we will have.
@@ -479,6 +501,10 @@ void Writer<ELFT>::scanRelocs(InputSectionBase<ELFT> &C,
Out<ELFT>::RelaDyn->addReloc(
{Target->RelativeRel, &C, RI.r_offset, true, &Body, Addend});
}
+
+ // Scan relocations for necessary thunks.
+ if (Config->EMachine == EM_MIPS)
+ scanRelocsForThunks(File, Rels);
}
template <class ELFT> void Writer<ELFT>::scanRelocs(InputSection<ELFT> &C) {
@@ -1042,6 +1068,9 @@ template <class ELFT> bool Writer<ELFT>::createSections() {
}
}
+ for (OutputSectionBase<ELFT> *Sec : getSections())
+ Sec->assignOffsets();
+
// Now that we have defined all possible symbols including linker-
// synthesized ones. Visit all symbols to give the finishing touches.
std::vector<DefinedCommon *> CommonSymbols;
@@ -1167,7 +1196,8 @@ template <class ELFT> void Writer<ELFT>::addStartEndSymbols() {
OutputSectionBase<ELFT> *OS) {
if (OS) {
Symtab.addSynthetic(Start, *OS, 0, STV_DEFAULT);
- Symtab.addSynthetic(End, *OS, OS->getSize(), STV_DEFAULT);
+ Symtab.addSynthetic(End, *OS, DefinedSynthetic<ELFT>::SectionEnd,
+ STV_DEFAULT);
} else {
Symtab.addIgnored(Start);
Symtab.addIgnored(End);
@@ -1200,7 +1230,8 @@ void Writer<ELFT>::addStartStopSymbols(OutputSectionBase<ELFT> *Sec) {
Symtab.addSynthetic(Start, *Sec, 0, STV_DEFAULT);
if (SymbolBody *B = Symtab.find(Stop))
if (B->isUndefined())
- Symtab.addSynthetic(Stop, *Sec, Sec->getSize(), STV_DEFAULT);
+ Symtab.addSynthetic(Stop, *Sec, DefinedSynthetic<ELFT>::SectionEnd,
+ STV_DEFAULT);
}
template <class ELFT> static bool needsPtLoad(OutputSectionBase<ELFT> *Sec) {
OpenPOWER on IntegriCloud