From 3d9f1c032addbff1c38e56c83b01c3b43c36af6e Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Wed, 13 Sep 2017 20:43:04 +0000 Subject: [PATCH] Add a helper for checking for weak undef. NFC. llvm-svn: 313188 --- lld/ELF/Arch/ARM.cpp | 3 +-- lld/ELF/InputSection.cpp | 4 ++-- lld/ELF/Relocations.cpp | 6 +++--- lld/ELF/Symbols.cpp | 12 ++++++++++-- lld/ELF/Symbols.h | 5 +++++ 5 files changed, 21 insertions(+), 9 deletions(-) diff --git a/lld/ELF/Arch/ARM.cpp b/lld/ELF/Arch/ARM.cpp index 37f4eae91cfa..8b4044d51998 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 9e50d970729e..7183df80c67a 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 a8d4a5403848..20b506d20d83 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(&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 906d32589cd2..e11d39b4c2ee 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(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 11364807874b..fe9457fa56cb 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; }