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.cpp44
1 files changed, 22 insertions, 22 deletions
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index 1d8fdcff04c..dfb4380a268 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -96,7 +96,7 @@ private:
void ensureBss();
void addCommonSymbols(std::vector<DefinedCommon *> &Syms);
- void addCopyRelSymbols(std::vector<SharedSymbol<ELFT> *> &Syms);
+ void addCopyRelSymbol(SharedSymbol<ELFT> *Sym);
std::unique_ptr<llvm::FileOutputBuffer> Buffer;
@@ -385,9 +385,7 @@ void Writer<ELFT>::scanRelocs(InputSectionBase<ELFT> &C,
if (B->needsCopy())
continue;
if (Target->needsCopyRel<ELFT>(Type, *B)) {
- B->NeedsCopyOrPltAddr = true;
- Out<ELFT>::RelaDyn->addReloc(
- {Target->CopyRel, DynamicReloc<ELFT>::Off_Bss, B});
+ addCopyRelSymbol(B);
continue;
}
}
@@ -741,23 +739,30 @@ template <class ELFT> static uint32_t getAlignment(SharedSymbol<ELFT> *SS) {
return 1 << TrailingZeros;
}
-// Reserve space in .bss for copy relocations.
+// Reserve space in .bss for copy relocation.
template <class ELFT>
-void Writer<ELFT>::addCopyRelSymbols(std::vector<SharedSymbol<ELFT> *> &Syms) {
- if (Syms.empty())
- return;
+void Writer<ELFT>::addCopyRelSymbol(SharedSymbol<ELFT> *SS) {
ensureBss();
uintX_t Off = Out<ELFT>::Bss->getSize();
- uintX_t MaxAlign = Out<ELFT>::Bss->getAlign();
- for (SharedSymbol<ELFT> *SS : Syms) {
- uintX_t Align = getAlignment(SS);
- Off = alignTo(Off, Align);
- SS->OffsetInBss = Off;
- Off += SS->template getSize<ELFT>();
- MaxAlign = std::max(MaxAlign, Align);
+ uintX_t Align = getAlignment(SS);
+ Off = alignTo(Off, Align);
+ Out<ELFT>::Bss->setSize(Off + SS->template getSize<ELFT>());
+ Out<ELFT>::Bss->updateAlign(Align);
+ Out<ELFT>::RelaDyn->addReloc(
+ {Target->CopyRel, DynamicReloc<ELFT>::Off_Bss, SS});
+ uintX_t Shndx = SS->Sym.st_shndx;
+ uintX_t Value = SS->Sym.st_value;
+ // Look through the DSO's dynamic symbol for aliases and create a dynamic
+ // symbol for each one. This causes the copy relocation to correctly interpose
+ // any aliases.
+ for (SharedSymbol<ELFT> &S : SS->File->getSharedSymbols()) {
+ if (S.Sym.st_shndx != Shndx || S.Sym.st_value != Value)
+ continue;
+ S.OffsetInBss = Off;
+ S.NeedsCopyOrPltAddr = true;
+ S.setUsedInRegularObj();
+ S.MustBeInDynSym = true;
}
- Out<ELFT>::Bss->setSize(Off);
- Out<ELFT>::Bss->updateAlign(MaxAlign);
}
template <class ELFT>
@@ -1080,7 +1085,6 @@ template <class ELFT> void Writer<ELFT>::createSections() {
// Now that we have defined all possible symbols including linker-
// synthesized ones. Visit all symbols to give the finishing touches.
std::vector<DefinedCommon *> CommonSymbols;
- std::vector<SharedSymbol<ELFT> *> CopyRelSymbols;
for (auto &P : Symtab.getSymbols()) {
SymbolBody *Body = P.second->Body;
if (auto *U = dyn_cast<Undefined>(Body))
@@ -1089,9 +1093,6 @@ template <class ELFT> void Writer<ELFT>::createSections() {
if (auto *C = dyn_cast<DefinedCommon>(Body))
CommonSymbols.push_back(C);
- if (auto *SC = dyn_cast<SharedSymbol<ELFT>>(Body))
- if (SC->needsCopy())
- CopyRelSymbols.push_back(SC);
if (!includeInSymtab<ELFT>(*Body))
continue;
@@ -1107,7 +1108,6 @@ template <class ELFT> void Writer<ELFT>::createSections() {
return;
addCommonSymbols(CommonSymbols);
- addCopyRelSymbols(CopyRelSymbols);
// So far we have added sections from input object files.
// This function adds linker-created Out<ELFT>::* sections.
OpenPOWER on IntegriCloud