[ELF] Fix early overflow check in finalizeAddressDependentContent

LLD terminates with errors when it detects overflows in the
finalizeAddressDependentContent calculation. Although, sometimes, those errors
are not really errors, but an intermediate result of an ongoing address
calculation.  If we continue the fixed-point algorithm we can converge to the
correct result.

This patch

* Removes the verification inside the fixed point algorithm.
* Calls checkMemoryRegions at the end.

Reviewed By: peter.smith, MaskRay

Differential Revision: https://reviews.llvm.org/D152170
This commit is contained in:
Andreu Carminati
2023-06-14 15:26:31 -07:00
committed by Fangrui Song
parent 58789ed62a
commit e4118a7ac0
5 changed files with 101 additions and 8 deletions

View File

@@ -157,12 +157,6 @@ OutputDesc *LinkerScript::getOrCreateOutputSection(StringRef name) {
static void expandMemoryRegion(MemoryRegion *memRegion, uint64_t size,
StringRef secName) {
memRegion->curPos += size;
uint64_t newSize = memRegion->curPos - memRegion->getOrigin();
uint64_t length = memRegion->getLength();
if (newSize > length)
error("section '" + secName + "' will not fit in region '" +
memRegion->name + "': overflowed by " + Twine(newSize - length) +
" bytes");
}
void LinkerScript::expandMemoryRegions(uint64_t size) {
@@ -1461,3 +1455,23 @@ void LinkerScript::printMemoryUsage(raw_ostream& os) {
os << '\n';
}
}
static void checkMemoryRegion(const MemoryRegion *region,
const OutputSection *osec, uint64_t addr) {
uint64_t osecEnd = addr + osec->size;
uint64_t regionEnd = region->getOrigin() + region->getLength();
if (osecEnd > regionEnd) {
error("section '" + osec->name + "' will not fit in region '" +
region->name + "': overflowed by " + Twine(osecEnd - regionEnd) +
" bytes");
}
}
void LinkerScript::checkMemoryRegions() const {
for (const OutputSection *sec : outputSections) {
if (const MemoryRegion *memoryRegion = sec->memRegion)
checkMemoryRegion(memoryRegion, sec, sec->addr);
if (const MemoryRegion *lmaRegion = sec->lmaRegion)
checkMemoryRegion(lmaRegion, sec, sec->getLMA());
}
}