summaryrefslogtreecommitdiffstats
path: root/lld/ELF/Symbols.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lld/ELF/Symbols.cpp')
-rw-r--r--lld/ELF/Symbols.cpp20
1 files changed, 14 insertions, 6 deletions
diff --git a/lld/ELF/Symbols.cpp b/lld/ELF/Symbols.cpp
index d8c459795b3..9eb222362bb 100644
--- a/lld/ELF/Symbols.cpp
+++ b/lld/ELF/Symbols.cpp
@@ -112,10 +112,14 @@ static typename ELFT::uint getSymVA(const SymbolBody &Body, int64_t &Addend) {
return 0;
return In<ELFT>::Common->OutSec->Addr + In<ELFT>::Common->OutSecOff +
cast<DefinedCommon>(Body).Offset;
- case SymbolBody::SharedKind:
- if (cast<SharedSymbol>(Body).NeedsPltAddr)
+ case SymbolBody::SharedKind: {
+ auto &SS = cast<SharedSymbol>(Body);
+ if (SS.NeedsCopy)
+ return SS.Section->OutSec->Addr + SS.Section->OutSecOff;
+ if (SS.NeedsPltAddr)
return Body.getPltVA<ELFT>();
return 0;
+ }
case SymbolBody::UndefinedKind:
return 0;
case SymbolBody::LazyArchiveKind:
@@ -128,7 +132,7 @@ static typename ELFT::uint getSymVA(const SymbolBody &Body, int64_t &Addend) {
SymbolBody::SymbolBody(Kind K, StringRefZ Name, bool IsLocal, uint8_t StOther,
uint8_t Type)
- : SymbolKind(K), NeedsPltAddr(false), IsLocal(IsLocal),
+ : SymbolKind(K), NeedsCopy(false), NeedsPltAddr(false), IsLocal(IsLocal),
IsInGlobalMipsGot(false), Is32BitMipsGot(false), IsInIplt(false),
IsInIgot(false), Type(Type), StOther(StOther), Name(Name) {}
@@ -139,9 +143,10 @@ bool SymbolBody::isPreemptible() const {
return false;
// Shared symbols resolve to the definition in the DSO. The exceptions are
- // symbols that needs plt entries (which resolve to that plt entry).
+ // symbols with copy relocations (which resolve to .bss) or preempt plt
+ // entries (which resolve to that plt entry).
if (isShared())
- return !NeedsPltAddr;
+ return !NeedsCopy && !NeedsPltAddr;
// That's all that can be preempted in a non-DSO.
if (!Config->Shared)
@@ -210,8 +215,11 @@ const OutputSection *SymbolBody::getOutputSection() const {
return nullptr;
}
- if (isa<SharedSymbol>(this))
+ if (auto *S = dyn_cast<SharedSymbol>(this)) {
+ if (S->NeedsCopy)
+ return S->Section->OutSec;
return nullptr;
+ }
if (isa<DefinedCommon>(this)) {
if (Config->DefineCommon)
OpenPOWER on IntegriCloud