summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lld/ELF/Arch/ARM.cpp3
-rw-r--r--lld/ELF/InputSection.cpp4
-rw-r--r--lld/ELF/Relocations.cpp6
-rw-r--r--lld/ELF/Symbols.cpp12
-rw-r--r--lld/ELF/Symbols.h5
5 files changed, 21 insertions, 9 deletions
diff --git a/lld/ELF/Arch/ARM.cpp b/lld/ELF/Arch/ARM.cpp
index 37f4eae91cf..8b4044d5199 100644
--- a/lld/ELF/Arch/ARM.cpp
+++ b/lld/ELF/Arch/ARM.cpp
@@ -194,8 +194,7 @@ bool ARM::needsThunk(RelExpr Expr, uint32_t RelocType, const InputFile *File,
// If S is an undefined weak symbol in an executable we don't need a Thunk.
// In a DSO calls to undefined symbols, including weak ones get PLT entries
// which may need a thunk.
- if (S.isUndefined() && !S.isLocal() && S.symbol()->isWeak() &&
- !Config->Shared)
+ if (S.isUndefWeak() && !Config->Shared)
return false;
// A state change from ARM to Thumb and vice versa must go through an
// interworking thunk if the relocation type is not R_ARM_CALL or
diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp
index 9e50d970729..7183df80c67 100644
--- a/lld/ELF/InputSection.cpp
+++ b/lld/ELF/InputSection.cpp
@@ -560,7 +560,7 @@ static uint64_t getRelocTargetVA(uint32_t Type, int64_t A, uint64_t P,
case R_PAGE_PC:
case R_PLT_PAGE_PC: {
uint64_t Dest;
- if (Body.isUndefined() && !Body.isLocal() && Body.symbol()->isWeak())
+ if (Body.isUndefWeak())
Dest = getAArch64Page(A);
else
Dest = getAArch64Page(Body.getVA(A));
@@ -568,7 +568,7 @@ static uint64_t getRelocTargetVA(uint32_t Type, int64_t A, uint64_t P,
}
case R_PC: {
uint64_t Dest;
- if (Body.isUndefined() && !Body.isLocal() && Body.symbol()->isWeak()) {
+ if (Body.isUndefWeak()) {
// On ARM and AArch64 a branch to an undefined weak resolves to the
// next instruction, otherwise the place.
if (Config->EMachine == EM_ARM)
diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp
index a8d4a540384..20b506d20d8 100644
--- a/lld/ELF/Relocations.cpp
+++ b/lld/ELF/Relocations.cpp
@@ -319,8 +319,8 @@ static uint32_t getMipsPairType(uint32_t Type, const SymbolBody &Sym) {
// True if non-preemptable symbol always has the same value regardless of where
// the DSO is loaded.
static bool isAbsolute(const SymbolBody &Body) {
- if (Body.isUndefined())
- return !Body.isLocal() && Body.symbol()->isWeak();
+ if (Body.isUndefWeak())
+ return true;
if (const auto *DR = dyn_cast<DefinedRegular>(&Body))
return DR->Section == nullptr; // Absolute symbol.
return false;
@@ -402,7 +402,7 @@ static bool isStaticLinkTimeConstant(RelExpr E, uint32_t Type,
// between start of a function and '_gp' value and defined as absolute just
// to simplify the code.
assert(AbsVal && RelE);
- if (Body.isUndefined() && !Body.isLocal() && Body.symbol()->isWeak())
+ if (Body.isUndefWeak())
return true;
error("relocation " + toString(Type) + " cannot refer to absolute symbol: " +
diff --git a/lld/ELF/Symbols.cpp b/lld/ELF/Symbols.cpp
index 906d32589cd..e11d39b4c2e 100644
--- a/lld/ELF/Symbols.cpp
+++ b/lld/ELF/Symbols.cpp
@@ -132,6 +132,12 @@ SymbolBody::SymbolBody(Kind K, StringRefZ Name, bool IsLocal, uint8_t StOther,
IsInIgot(false), IsPreemptible(false), Type(Type), StOther(StOther),
Name(Name) {}
+bool SymbolBody::isUndefWeak() const {
+ if (isLocal())
+ return false;
+ return symbol()->isWeak() && (isUndefined() || isLazy());
+}
+
InputFile *SymbolBody::getFile() const {
if (isLocal()) {
const SectionBase *Sec = cast<DefinedRegular>(this)->Section;
@@ -340,8 +346,10 @@ uint8_t Symbol::computeBinding() const {
bool Symbol::includeInDynsym() const {
if (computeBinding() == STB_LOCAL)
return false;
- if (body()->isUndefined() || body()->isLazy())
- return Config->Shared || !body()->symbol()->isWeak();
+ if (body()->isUndefWeak())
+ return Config->Shared;
+ if (!body()->isInCurrentDSO())
+ return true;
return ExportDynamic || body()->isShared();
}
diff --git a/lld/ELF/Symbols.h b/lld/ELF/Symbols.h
index 11364807874..fe9457fa56c 100644
--- a/lld/ELF/Symbols.h
+++ b/lld/ELF/Symbols.h
@@ -70,6 +70,11 @@ public:
return !isUndefined() && !isShared() && !isLazy();
}
bool isLocal() const { return IsLocal; }
+
+ // True is this is an undefined weak symbol. This only works once
+ // all input files have been added.
+ bool isUndefWeak() const;
+
InputFile *getFile() const;
bool isPreemptible() const { return IsPreemptible; }
StringRef getName() const { return Name; }
OpenPOWER on IntegriCloud