[lld] r310602 - Compute isPreemtible only once.
Rafael Espindola via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 10 08:05:38 PDT 2017
Author: rafael
Date: Thu Aug 10 08:05:37 2017
New Revision: 310602
URL: http://llvm.org/viewvc/llvm-project?rev=310602&view=rev
Log:
Compute isPreemtible only once.
This is probably a small optimization, but the main motivation is
having a way of fixing pr34053 that doesn't require a hash lookup in
isPreempitible.
Modified:
lld/trunk/ELF/Relocations.cpp
lld/trunk/ELF/Symbols.cpp
lld/trunk/ELF/Symbols.h
lld/trunk/ELF/Writer.cpp
Modified: lld/trunk/ELF/Relocations.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Relocations.cpp?rev=310602&r1=310601&r2=310602&view=diff
==============================================================================
--- lld/trunk/ELF/Relocations.cpp (original)
+++ lld/trunk/ELF/Relocations.cpp Thu Aug 10 08:05:37 2017
@@ -149,7 +149,7 @@ static unsigned handleARMTlsRelocation(u
InputSectionBase &C, uint64_t Offset,
int64_t Addend, RelExpr Expr) {
// The Dynamic TLS Module Index Relocation for a symbol defined in an
- // executable is always 1. If the target Symbol is not preemtible then
+ // executable is always 1. If the target Symbol is not preemptible then
// we know the offset into the TLS block at static link time.
bool NeedDynId = Body.isPreemptible() || Config->Shared;
bool NeedDynOff = Body.isPreemptible();
@@ -527,6 +527,7 @@ template <class ELFT> static void addCop
// interpose any aliases.
for (SharedSymbol *Sym : getSymbolsAt<ELFT>(SS)) {
Sym->CopyRelSec = Sec;
+ Sym->IsPreemptible = false;
Sym->CopyRelSecOff = Off;
Sym->symbol()->IsUsedInRegularObj = true;
}
@@ -612,6 +613,7 @@ static RelExpr adjustExpr(SymbolBody &Bo
// plt. That is identified by special relocation types (R_X86_64_JUMP_SLOT,
// R_386_JMP_SLOT, etc).
Body.NeedsPltAddr = true;
+ Body.IsPreemptible = false;
return toPlt(Expr);
}
Modified: lld/trunk/ELF/Symbols.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.cpp?rev=310602&r1=310601&r2=310602&view=diff
==============================================================================
--- lld/trunk/ELF/Symbols.cpp (original)
+++ lld/trunk/ELF/Symbols.cpp Thu Aug 10 08:05:37 2017
@@ -127,7 +127,8 @@ SymbolBody::SymbolBody(Kind K, StringRef
uint8_t Type)
: SymbolKind(K), NeedsPltAddr(false), IsLocal(IsLocal),
IsInGlobalMipsGot(false), Is32BitMipsGot(false), IsInIplt(false),
- IsInIgot(false), Type(Type), StOther(StOther), Name(Name) {}
+ IsInIgot(false), IsPreemptible(false), Type(Type), StOther(StOther),
+ Name(Name) {}
InputFile *SymbolBody::getFile() const {
if (isLocal())
@@ -135,41 +136,6 @@ InputFile *SymbolBody::getFile() const {
return symbol()->File;
}
-// Returns true if a symbol can be replaced at load-time by a symbol
-// with the same name defined in other ELF executable or DSO.
-bool SymbolBody::isPreemptible() const {
- if (isLocal())
- return false;
-
- // Shared symbols resolve to the definition in the DSO. The exceptions are
- // symbols with copy relocations (which resolve to .bss) or preempt plt
- // entries (which resolve to that plt entry).
- if (auto *SS = dyn_cast<SharedSymbol>(this))
- return !SS->CopyRelSec && !NeedsPltAddr;
-
- // Only symbols that appear in dynsym can be preempted.
- if (!symbol()->includeInDynsym())
- return false;
-
- // Only default visibility symbols can be preempted.
- if (symbol()->Visibility != STV_DEFAULT)
- return false;
-
- // Undefined symbols in non-DSOs are usually just an error, so it
- // doesn't matter whether we return true or false here. However, if
- // -unresolved-symbols=ignore-all is specified, undefined symbols in
- // executables are automatically exported so that the runtime linker
- // can try to resolve them. In that case, they is preemptible. So, we
- // return true for an undefined symbol in case the option is specified.
- if (!Config->Shared)
- return isUndefined();
-
- // -Bsymbolic means that definitions are not preempted.
- if (Config->Bsymbolic || (Config->BsymbolicFunctions && isFunc()))
- return !isDefined();
- return true;
-}
-
// Overwrites all attributes with Other's so that this symbol becomes
// an alias to Other. This is useful for handling some options such as
// --wrap.
Modified: lld/trunk/ELF/Symbols.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.h?rev=310602&r1=310601&r2=310602&view=diff
==============================================================================
--- lld/trunk/ELF/Symbols.h (original)
+++ lld/trunk/ELF/Symbols.h Thu Aug 10 08:05:37 2017
@@ -70,7 +70,7 @@ public:
}
bool isLocal() const { return IsLocal; }
InputFile *getFile() const;
- bool isPreemptible() const;
+ bool isPreemptible() const { return IsPreemptible; }
StringRef getName() const { return Name; }
uint8_t getVisibility() const { return StOther & 0x3; }
void parseSymbolVersion();
@@ -121,6 +121,8 @@ public:
// True if this symbol is in the Igot sub-section of the .got.plt or .got.
unsigned IsInIgot : 1;
+ unsigned IsPreemptible : 1;
+
// The following fields have the same meaning as the ELF symbol attributes.
uint8_t Type; // symbol type
uint8_t StOther; // st_other field value
Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=310602&r1=310601&r2=310602&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Thu Aug 10 08:05:37 2017
@@ -1149,6 +1149,39 @@ static void removeUnusedSyntheticSection
}
}
+// Returns true if a symbol can be replaced at load-time by a symbol
+// with the same name defined in other ELF executable or DSO.
+static bool computeIsPreemptible(const SymbolBody &B) {
+ assert(!B.isLocal());
+ // Shared symbols resolve to the definition in the DSO. The exceptions are
+ // symbols with copy relocations (which resolve to .bss) or preempt plt
+ // entries (which resolve to that plt entry).
+ if (auto *SS = dyn_cast<SharedSymbol>(&B))
+ return !SS->CopyRelSec && !SS->NeedsPltAddr;
+
+ // Only symbols that appear in dynsym can be preempted.
+ if (!B.symbol()->includeInDynsym())
+ return false;
+
+ // Only default visibility symbols can be preempted.
+ if (B.symbol()->Visibility != STV_DEFAULT)
+ return false;
+
+ // Undefined symbols in non-DSOs are usually just an error, so it
+ // doesn't matter whether we return true or false here. However, if
+ // -unresolved-symbols=ignore-all is specified, undefined symbols in
+ // executables are automatically exported so that the runtime linker
+ // can try to resolve them. In that case, they is preemptible. So, we
+ // return true for an undefined symbol in case the option is specified.
+ if (!Config->Shared)
+ return B.isUndefined();
+
+ // -Bsymbolic means that definitions are not preempted.
+ if (Config->Bsymbolic || (Config->BsymbolicFunctions && B.isFunc()))
+ return !B.isDefined();
+ return true;
+}
+
// Create output section objects and add them to OutputSections.
template <class ELFT> void Writer<ELFT>::finalizeSections() {
Out::DebugInfo = findSection(".debug_info");
@@ -1182,6 +1215,9 @@ template <class ELFT> void Writer<ELFT>:
applySynthetic({In<ELFT>::EhFrame},
[](SyntheticSection *SS) { SS->finalizeContents(); });
+ for (Symbol *S : Symtab->getSymbols())
+ S->body()->IsPreemptible = computeIsPreemptible(*S->body());
+
// Scan relocations. This must be done after every symbol is declared so that
// we can correctly decide if a dynamic relocation is needed.
forEachRelSec(scanRelocations<ELFT>);
More information about the llvm-commits
mailing list