aboutsummaryrefslogtreecommitdiff
path: root/lld/ELF/ScriptParser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lld/ELF/ScriptParser.cpp')
-rw-r--r--lld/ELF/ScriptParser.cpp35
1 files changed, 19 insertions, 16 deletions
diff --git a/lld/ELF/ScriptParser.cpp b/lld/ELF/ScriptParser.cpp
index 3577e78c0d98..55b10f0c59b5 100644
--- a/lld/ELF/ScriptParser.cpp
+++ b/lld/ELF/ScriptParser.cpp
@@ -136,9 +136,6 @@ private:
// True if a script being read is in the --sysroot directory.
bool isUnderSysroot = false;
- bool seenDataAlign = false;
- bool seenRelroEnd = false;
-
// A set to detect an INCLUDE() cycle.
StringSet<> seen;
};
@@ -291,7 +288,7 @@ void ScriptParser::readDefsym(StringRef name) {
Expr e = readExpr();
if (!atEOF())
setError("EOF expected, but got " + next());
- SymbolAssignment *cmd = make<SymbolAssignment>(name, e, getCurrentLocation());
+ auto *cmd = make<SymbolAssignment>(name, e, 0, getCurrentLocation());
script->sectionCommands.push_back(cmd);
}
@@ -568,7 +565,7 @@ SmallVector<SectionCommand *, 0> ScriptParser::readOverlay() {
max = std::max(max, cast<OutputDesc>(cmd)->osec.size);
return addrExpr().getValue() + max;
};
- v.push_back(make<SymbolAssignment>(".", moveDot, getCurrentLocation()));
+ v.push_back(make<SymbolAssignment>(".", moveDot, 0, getCurrentLocation()));
return v;
}
@@ -600,7 +597,7 @@ void ScriptParser::readSections() {
// If DATA_SEGMENT_RELRO_END is absent, for sections after DATA_SEGMENT_ALIGN,
// the relro fields should be cleared.
- if (!seenRelroEnd)
+ if (!script->seenRelroEnd)
for (SectionCommand *cmd : v)
if (auto *osd = dyn_cast<OutputDesc>(cmd))
osd->osec.relro = false;
@@ -916,7 +913,7 @@ OutputDesc *ScriptParser::readOutputSectionDescription(StringRef outSec) {
script->createOutputSection(unquote(outSec), getCurrentLocation());
OutputSection *osec = &cmd->osec;
// Maybe relro. Will reset to false if DATA_SEGMENT_RELRO_END is absent.
- osec->relro = seenDataAlign && !seenRelroEnd;
+ osec->relro = script->seenDataAlign && !script->seenRelroEnd;
size_t symbolsReferenced = script->referencedSymbols.size();
@@ -1047,10 +1044,11 @@ SymbolAssignment *ScriptParser::readProvideHidden(bool provide, bool hidden) {
SymbolAssignment *ScriptParser::readAssignment(StringRef tok) {
// Assert expression returns Dot, so this is equal to ".=."
if (tok == "ASSERT")
- return make<SymbolAssignment>(".", readAssert(), getCurrentLocation());
+ return make<SymbolAssignment>(".", readAssert(), 0, getCurrentLocation());
size_t oldPos = pos;
SymbolAssignment *cmd = nullptr;
+ bool savedSeenRelroEnd = script->seenRelroEnd;
const StringRef op = peek();
if (op.starts_with("=")) {
// Support = followed by an expression without whitespace.
@@ -1071,6 +1069,7 @@ SymbolAssignment *ScriptParser::readAssignment(StringRef tok) {
}
if (cmd) {
+ cmd->dataSegmentRelroEnd = !savedSeenRelroEnd && script->seenRelroEnd;
cmd->commandString =
tok.str() + " " +
llvm::join(tokens.begin() + oldPos, tokens.begin() + pos, " ");
@@ -1084,7 +1083,7 @@ SymbolAssignment *ScriptParser::readSymbolAssignment(StringRef name) {
StringRef op = next();
assert(op == "=" || op == "*=" || op == "/=" || op == "+=" || op == "-=" ||
op == "&=" || op == "^=" || op == "|=" || op == "<<=" || op == ">>=");
- // Note: GNU ld does not support %= or ^=.
+ // Note: GNU ld does not support %=.
Expr e = readExpr();
if (op != "=") {
std::string loc = getCurrentLocation();
@@ -1117,7 +1116,8 @@ SymbolAssignment *ScriptParser::readSymbolAssignment(StringRef name) {
}
};
}
- return make<SymbolAssignment>(name, e, getCurrentLocation());
+ return make<SymbolAssignment>(name, e, ctx.scriptSymOrderCounter++,
+ getCurrentLocation());
}
// This is an operator-precedence parser to parse a linker
@@ -1438,7 +1438,7 @@ Expr ScriptParser::readPrimary() {
expect(",");
readExpr();
expect(")");
- seenDataAlign = true;
+ script->seenDataAlign = true;
return [=] {
uint64_t align = std::max(uint64_t(1), e().getValue());
return (script->getDot() + align - 1) & -align;
@@ -1459,15 +1459,18 @@ Expr ScriptParser::readPrimary() {
expect(",");
readExpr();
expect(")");
- seenRelroEnd = true;
- Expr e = getPageSize();
- return [=] { return alignToPowerOf2(script->getDot(), e().getValue()); };
+ script->seenRelroEnd = true;
+ return [=] { return alignToPowerOf2(script->getDot(), config->maxPageSize); };
}
if (tok == "DEFINED") {
StringRef name = unquote(readParenLiteral());
+ // Return 1 if s is defined. If the definition is only found in a linker
+ // script, it must happen before this DEFINED.
+ auto order = ctx.scriptSymOrderCounter++;
return [=] {
- Symbol *b = symtab.find(name);
- return (b && b->isDefined()) ? 1 : 0;
+ Symbol *s = symtab.find(name);
+ return s && s->isDefined() && ctx.scriptSymOrder.lookup(s) < order ? 1
+ : 0;
};
}
if (tok == "LENGTH") {