aboutsummaryrefslogtreecommitdiff
path: root/lld/ELF/LinkerScript.cpp
diff options
context:
space:
mode:
authorAndreu Carminati <andreu.carminati@hightec-rt.com>2023-06-14 15:26:31 -0700
committerFangrui Song <i@maskray.me>2023-06-14 15:26:31 -0700
commite4118a7ac0fc2347e78d7c87a1663b70e8ab71ed (patch)
tree9448d2792ee5ae4699972469060a33cd5ae4c217 /lld/ELF/LinkerScript.cpp
parent58789ed62ad462d421e5c9272f0f80105f6025bf (diff)
downloadllvm-e4118a7ac0fc2347e78d7c87a1663b70e8ab71ed.zip
llvm-e4118a7ac0fc2347e78d7c87a1663b70e8ab71ed.tar.gz
llvm-e4118a7ac0fc2347e78d7c87a1663b70e8ab71ed.tar.bz2
[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
Diffstat (limited to 'lld/ELF/LinkerScript.cpp')
-rw-r--r--lld/ELF/LinkerScript.cpp26
1 files changed, 20 insertions, 6 deletions
diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp
index 295b078..777f1f2 100644
--- a/lld/ELF/LinkerScript.cpp
+++ b/lld/ELF/LinkerScript.cpp
@@ -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());
+ }
+}