diff options
author | George Rimar <grimar@accesssoftek.com> | 2018-01-30 09:04:27 +0000 |
---|---|---|
committer | George Rimar <grimar@accesssoftek.com> | 2018-01-30 09:04:27 +0000 |
commit | c4ccfb5d932909e64511bcfdc995ab20a80b2a89 (patch) | |
tree | 576105251ee7ab529cc949afea944ecd632710fc /lld/ELF/LinkerScript.cpp | |
parent | f5ad62d9214b83638960feb7e25c4748c3ea8f12 (diff) | |
download | bcm5719-llvm-c4ccfb5d932909e64511bcfdc995ab20a80b2a89.tar.gz bcm5719-llvm-c4ccfb5d932909e64511bcfdc995ab20a80b2a89.zip |
[ELF] - Define linkerscript symbols early.
Currently symbols assigned or created by linkerscript are not processed early
enough. As a result it is not possible to version them or assign any other flags/properties.
Patch creates Defined symbols for -defsym and linkerscript symbols early,
so that issue from above can be addressed.
It is based on Rafael Espindola's version of D38239 patch.
Fixes PR34121.
Differential revision: https://reviews.llvm.org/D41987
llvm-svn: 323729
Diffstat (limited to 'lld/ELF/LinkerScript.cpp')
-rw-r--r-- | lld/ELF/LinkerScript.cpp | 50 |
1 files changed, 43 insertions, 7 deletions
diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp index 23c3a11a9d1..e6d0e455dd9 100644 --- a/lld/ELF/LinkerScript.cpp +++ b/lld/ELF/LinkerScript.cpp @@ -114,16 +114,28 @@ void LinkerScript::setDot(Expr E, const Twine &Loc, bool InSec) { Ctx->OutSec->Size = Dot - Ctx->OutSec->Addr; } -// This function is called from processSectionCommands, -// while we are fixing the output section layout. -void LinkerScript::addSymbol(SymbolAssignment *Cmd) { +// Used for handling linker symbol assignments, for both finalizing +// their values and doing early declarations. Returns true if symbol +// should be defined from linker script. +static bool shouldDefineSym(SymbolAssignment *Cmd) { if (Cmd->Name == ".") - return; + return false; - // If a symbol was in PROVIDE(), we need to define it only when - // it is a referenced undefined symbol. + if (!Cmd->Provide) + return true; + + // If a symbol was in PROVIDE(), we need to define it only + // when it is a referenced undefined symbol. Symbol *B = Symtab->find(Cmd->Name); - if (Cmd->Provide && (!B || B->isDefined())) + if (!B || B->isDefined()) + return false; + return true; +} + +// This function is called from processSectionCommands, +// while we are fixing the output section layout. +void LinkerScript::addSymbol(SymbolAssignment *Cmd) { + if (!shouldDefineSym(Cmd)) return; // Define a symbol. @@ -153,6 +165,30 @@ void LinkerScript::addSymbol(SymbolAssignment *Cmd) { Cmd->Sym = cast<Defined>(Sym); } +// Symbols defined in script should not be inlined by LTO. At the same time +// we don't know their final values until late stages of link. Here we scan +// over symbol assignment commands and create placeholder symbols if needed. +void LinkerScript::declareSymbols() { + assert(!Ctx); + for (BaseCommand *Base : SectionCommands) { + auto *Cmd = dyn_cast<SymbolAssignment>(Base); + if (!Cmd || !shouldDefineSym(Cmd)) + continue; + + // We can't calculate final value right now. + Symbol *Sym; + uint8_t Visibility = Cmd->Hidden ? STV_HIDDEN : STV_DEFAULT; + std::tie(Sym, std::ignore) = + Symtab->insert(Cmd->Name, /*Type*/ 0, Visibility, + /*CanOmitFromDynSym*/ false, + /*File*/ nullptr); + replaceSymbol<Defined>(Sym, nullptr, Cmd->Name, STB_GLOBAL, Visibility, + STT_NOTYPE, 0, 0, nullptr); + Cmd->Sym = cast<Defined>(Sym); + Cmd->Provide = false; + } +} + // This function is called from assignAddresses, while we are // fixing the output section addresses. This function is supposed // to set the final value for a given symbol assignment. |