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
Show file tree
Hide file tree
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
Expand Up @@ -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.
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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;
Expand All @@ -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);
Expand Down
7 changes: 6 additions & 1 deletion lld/ELF/LinkerScript.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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.
Expand Down
5 changes: 3 additions & 2 deletions lld/ELF/ScriptParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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) {
Expand Down
6 changes: 2 additions & 4 deletions lld/test/ELF/linkerscript/addr.test
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 3 additions & 1 deletion lld/test/ELF/linkerscript/locationcountererr-arm-exidx.test
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading