summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lld/ELF/Writer.cpp19
1 files changed, 13 insertions, 6 deletions
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index 4a839e11688..c99d1ed207b 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -293,16 +293,23 @@ void Writer<ELFT>::scanRelocs(
continue;
}
+ // If a symbol in a DSO is referenced directly instead of through GOT,
+ // we need to create a copy relocation for the symbol.
+ if (auto *B = dyn_cast_or_null<SharedSymbol<ELFT>>(Body)) {
+ if (B->NeedsCopy)
+ continue;
+ if (Target->needsCopyRel(Type, *B)) {
+ B->NeedsCopy = true;
+ B->setUsedInDynamicReloc();
+ Out<ELFT>::RelaDyn->addReloc({&C, &RI});
+ continue;
+ }
+ }
+
bool NeedsGot = false;
bool NeedsPlt = false;
if (Body) {
- if (auto *E = dyn_cast<SharedSymbol<ELFT>>(Body)) {
- if (E->NeedsCopy)
- continue;
- if (Target->needsCopyRel(Type, *Body))
- E->NeedsCopy = true;
- }
NeedsPlt = Target->needsPlt(Type, *Body);
if (NeedsPlt) {
if (Body->isInPlt())
OpenPOWER on IntegriCloud