Skip to content

Commit d6c32f8

Browse files
MaskRayAlexisPerry
authored andcommitted
[ELF] Postpone more linker script errors
Since `assignAddresses` is executed more than once, error reporting during `assignAddresses` would be duplicated. Generalize llvm#66854 to cover more errors. Note: address-related errors exposed in one invocation might not be errors in another invocation. Pull Request: llvm#96361
1 parent 5b5bdef commit d6c32f8

File tree

5 files changed

+26
-16
lines changed

5 files changed

+26
-16
lines changed

lld/ELF/LinkerScript.cpp

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -177,11 +177,10 @@ void LinkerScript::setDot(Expr e, const Twine &loc, bool inSec) {
177177
// report it if this is the last assignAddresses iteration. dot may be smaller
178178
// if there is another assignAddresses iteration.
179179
if (val < dot && inSec) {
180-
backwardDotErr =
181-
(loc + ": unable to move location counter (0x" + Twine::utohexstr(dot) +
182-
") backward to 0x" + Twine::utohexstr(val) + " for section '" +
183-
state->outSec->name + "'")
184-
.str();
180+
recordError(loc + ": unable to move location counter (0x" +
181+
Twine::utohexstr(dot) + ") backward to 0x" +
182+
Twine::utohexstr(val) + " for section '" + state->outSec->name +
183+
"'");
185184
}
186185

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

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

1663+
void LinkerScript::recordError(const Twine &msg) {
1664+
auto &str = recordedErrors.emplace_back();
1665+
msg.toVector(str);
1666+
}
1667+
16641668
static void checkMemoryRegion(const MemoryRegion *region,
16651669
const OutputSection *osec, uint64_t addr) {
16661670
uint64_t osecEnd = addr + osec->size;
@@ -1673,8 +1677,8 @@ static void checkMemoryRegion(const MemoryRegion *region,
16731677
}
16741678

16751679
void LinkerScript::checkFinalScriptConditions() const {
1676-
if (backwardDotErr.size())
1677-
errorOrWarn(backwardDotErr);
1680+
for (StringRef err : recordedErrors)
1681+
errorOrWarn(err);
16781682
for (const OutputSection *sec : outputSections) {
16791683
if (const MemoryRegion *memoryRegion = sec->memRegion)
16801684
checkMemoryRegion(memoryRegion, sec, sec->addr);

lld/ELF/LinkerScript.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,11 @@ class LinkerScript final {
350350
// Describe memory region usage.
351351
void printMemoryUsage(raw_ostream &os);
352352

353+
// Record a pending error during an assignAddresses invocation.
354+
// assignAddresses is executed more than once. Therefore, lld::error should be
355+
// avoided to not report duplicate errors.
356+
void recordError(const Twine &msg);
357+
353358
// Check backward location counter assignment and memory region/LMA overflows.
354359
void checkFinalScriptConditions() const;
355360

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

380385
// List of section patterns specified with KEEP commands. They will
381386
// be kept even if they are unused and --gc-sections is specified.

lld/ELF/ScriptParser.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,8 @@ static void moveAbsRight(ExprValue &a, ExprValue &b) {
158158
if (a.sec == nullptr || (a.forceAbsolute && !b.isAbsolute()))
159159
std::swap(a, b);
160160
if (!b.isAbsolute())
161-
error(a.loc + ": at least one side of the expression must be absolute");
161+
script->recordError(
162+
a.loc + ": at least one side of the expression must be absolute");
162163
}
163164

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

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

13901391
static bool isValidSymbolName(StringRef s) {

lld/test/ELF/linkerscript/addr.test

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,11 @@
1313
# CHECK-NEXT: 0000000000001001 0 NOTYPE GLOBAL DEFAULT 1 x2
1414
# CHECK-NEXT: 0000000000001000 0 NOTYPE GLOBAL DEFAULT 1 x3
1515

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

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

2422
#--- a.s
2523
.globl _start

lld/test/ELF/linkerscript/locationcountererr-arm-exidx.test

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@
88
# 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 | \
99
# RUN: FileCheck %s --check-prefix=ERR --implicit-check-not=error:
1010

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

0 commit comments

Comments
 (0)