summaryrefslogtreecommitdiffstats
path: root/lld/ELF/LinkerScript.cpp
diff options
context:
space:
mode:
authorGeorge Rimar <grimar@accesssoftek.com>2018-01-30 09:04:27 +0000
committerGeorge Rimar <grimar@accesssoftek.com>2018-01-30 09:04:27 +0000
commitc4ccfb5d932909e64511bcfdc995ab20a80b2a89 (patch)
tree576105251ee7ab529cc949afea944ecd632710fc /lld/ELF/LinkerScript.cpp
parentf5ad62d9214b83638960feb7e25c4748c3ea8f12 (diff)
downloadbcm5719-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.cpp50
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.
OpenPOWER on IntegriCloud