Skip to content

[ELF] Postpone more linker script errors #96361

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 12 additions & 8 deletions lld/ELF/LinkerScript.cpp
Original file line number Diff line number Diff line change
@@ -177,11 +177,10 @@ void LinkerScript::setDot(Expr e, const Twine &loc, bool inSec) {
// report it if this is the last assignAddresses iteration. dot may be smaller
// if there is another assignAddresses iteration.
if (val < dot && inSec) {
backwardDotErr =
(loc + ": unable to move location counter (0x" + Twine::utohexstr(dot) +
") backward to 0x" + Twine::utohexstr(val) + " for section '" +
state->outSec->name + "'")
.str();
recordError(loc + ": unable to move location counter (0x" +
Twine::utohexstr(dot) + ") backward to 0x" +
Twine::utohexstr(val) + " for section '" + state->outSec->name +
"'");
}

// Update to location counter means update to section size.
@@ -1411,7 +1410,7 @@ LinkerScript::assignAddresses() {
state = &st;
errorOnMissingSection = true;
st.outSec = aether;
backwardDotErr.clear();
recordedErrors.clear();

SymbolAssignmentMap oldValues = getSymbolAssignmentValues(sectionCommands);
for (SectionCommand *cmd : sectionCommands) {
@@ -1661,6 +1660,11 @@ void LinkerScript::printMemoryUsage(raw_ostream& os) {
}
}

void LinkerScript::recordError(const Twine &msg) {
auto &str = recordedErrors.emplace_back();
msg.toVector(str);
}

static void checkMemoryRegion(const MemoryRegion *region,
const OutputSection *osec, uint64_t addr) {
uint64_t osecEnd = addr + osec->size;
@@ -1673,8 +1677,8 @@ static void checkMemoryRegion(const MemoryRegion *region,
}

void LinkerScript::checkFinalScriptConditions() const {
if (backwardDotErr.size())
errorOrWarn(backwardDotErr);
for (StringRef err : recordedErrors)
errorOrWarn(err);
for (const OutputSection *sec : outputSections) {
if (const MemoryRegion *memoryRegion = sec->memRegion)
checkMemoryRegion(memoryRegion, sec, sec->addr);
7 changes: 6 additions & 1 deletion lld/ELF/LinkerScript.h
Original file line number Diff line number Diff line change
@@ -350,6 +350,11 @@ class LinkerScript final {
// Describe memory region usage.
void printMemoryUsage(raw_ostream &os);

// Record a pending error during an assignAddresses invocation.
// assignAddresses is executed more than once. Therefore, lld::error should be
// avoided to not report duplicate errors.
void recordError(const Twine &msg);

// Check backward location counter assignment and memory region/LMA overflows.
void checkFinalScriptConditions() const;

@@ -375,7 +380,7 @@ class LinkerScript final {
bool seenDataAlign = false;
bool seenRelroEnd = false;
bool errorOnMissingSection = false;
std::string backwardDotErr;
SmallVector<SmallString<0>, 0> recordedErrors;

// List of section patterns specified with KEEP commands. They will
// be kept even if they are unused and --gc-sections is specified.
5 changes: 3 additions & 2 deletions lld/ELF/ScriptParser.cpp
Original file line number Diff line number Diff line change
@@ -158,7 +158,8 @@ static void moveAbsRight(ExprValue &a, ExprValue &b) {
if (a.sec == nullptr || (a.forceAbsolute && !b.isAbsolute()))
std::swap(a, b);
if (!b.isAbsolute())
error(a.loc + ": at least one side of the expression must be absolute");
script->recordError(
a.loc + ": at least one side of the expression must be absolute");
}

static ExprValue add(ExprValue a, ExprValue b) {
@@ -1384,7 +1385,7 @@ StringRef ScriptParser::readParenLiteral() {

static void checkIfExists(const OutputSection &osec, StringRef location) {
if (osec.location.empty() && script->errorOnMissingSection)
error(location + ": undefined section " + osec.name);
script->recordError(location + ": undefined section " + osec.name);
}

static bool isValidSymbolName(StringRef s) {
6 changes: 2 additions & 4 deletions lld/test/ELF/linkerscript/addr.test
Original file line number Diff line number Diff line change
@@ -13,13 +13,11 @@
# CHECK-NEXT: 0000000000001001 0 NOTYPE GLOBAL DEFAULT 1 x2
# CHECK-NEXT: 0000000000001000 0 NOTYPE GLOBAL DEFAULT 1 x3

## TODO Fix duplicate errors
# RUN: not ld.lld a.o -T absent.lds 2>&1 | FileCheck %s --check-prefix=ABSENT --implicit-check-not=error:
# ABSENT-COUNT-2: error: absent.lds:3: undefined section .aaa
# ABSENT: error: absent.lds:3: undefined section .aaa

## TODO Fix duplicate errors
# RUN: not ld.lld a.o -T absolute.lds 2>&1 | FileCheck %s --check-prefix=ABSOLUTE --implicit-check-not=error:
# ABSOLUTE-COUNT-4: error: absolute.lds:2: at least one side of the expression must be absolute
# ABSOLUTE: error: absolute.lds:2: at least one side of the expression must be absolute

#--- a.s
.globl _start
4 changes: 3 additions & 1 deletion lld/test/ELF/linkerscript/locationcountererr-arm-exidx.test
Original file line number Diff line number Diff line change
@@ -8,7 +8,9 @@
# RUN: not ld.lld -z norelro -z max-page-size=4096 -T a.t a.o -o /dev/null --no-merge-exidx-entries 2>&1 | \
# RUN: FileCheck %s --check-prefix=ERR --implicit-check-not=error:

# ERR: error: a.t:14: unable to move location counter (0x4104) backward to 0x4070 for section 'code.unused_space'
# ERR: error: a.t:9: unable to move location counter (0x1000) backward to 0xf6c for section 'dummy1'
# ERR-NEXT: error: a.t:10: unable to move location counter (0x2000) backward to 0x1f6c for section 'dummy2'
# ERR-NEXT: error: a.t:14: unable to move location counter (0x4104) backward to 0x4070 for section 'code.unused_space'
# ERR-NEXT: error: section '.ARM.exidx' will not fit in region 'CODE': overflowed by 148 bytes
# ERR-NEXT: error: section dummy1 at 0x1000 of size 0xFFFFFFFFFFFFFF6C exceeds available address space
# ERR-NEXT: error: section dummy2 at 0x2000 of size 0xFFFFFFFFFFFFFF6C exceeds available address space