aboutsummaryrefslogtreecommitdiff
path: root/lld/ELF/LinkerScript.cpp
diff options
context:
space:
mode:
authorPetr Hosek <phosek@google.com>2023-05-16 07:18:26 +0000
committerPetr Hosek <phosek@google.com>2023-05-25 07:14:18 +0000
commit811cbfc26233587f01f1b7b8cdeb8200747c366a (patch)
treef7467505899f2f396f4c311598f272edaa1d4fc5 /lld/ELF/LinkerScript.cpp
parent3d90c8126f8990490cd25a8a4b67a16b99898970 (diff)
downloadllvm-811cbfc26233587f01f1b7b8cdeb8200747c366a.zip
llvm-811cbfc26233587f01f1b7b8cdeb8200747c366a.tar.gz
llvm-811cbfc26233587f01f1b7b8cdeb8200747c366a.tar.bz2
[lld][ELF] Implement –print-memory-usage
This option was introduced in GNU ld in https://sourceware.org/legacy-ml/binutils/2015-06/msg00086.html and is often used in embedded development. This change implements this option in LLD matching the GNU ld output verbatim. Differential Revision: https://reviews.llvm.org/D150644
Diffstat (limited to 'lld/ELF/LinkerScript.cpp')
-rw-r--r--lld/ELF/LinkerScript.cpp31
1 files changed, 29 insertions, 2 deletions
diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp
index 9207751..2f183eb 100644
--- a/lld/ELF/LinkerScript.cpp
+++ b/lld/ELF/LinkerScript.cpp
@@ -157,8 +157,8 @@ OutputDesc *LinkerScript::getOrCreateOutputSection(StringRef name) {
static void expandMemoryRegion(MemoryRegion *memRegion, uint64_t size,
StringRef secName) {
memRegion->curPos += size;
- uint64_t newSize = memRegion->curPos - (memRegion->origin)().getValue();
- uint64_t length = (memRegion->length)().getValue();
+ 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) +
@@ -1429,3 +1429,30 @@ SmallVector<size_t, 0> LinkerScript::getPhdrIndices(OutputSection *cmd) {
}
return ret;
}
+
+void LinkerScript::printMemoryUsage(raw_ostream& os) {
+ auto printSize = [&](uint64_t size) {
+ if ((size & 0x3fffffff) == 0)
+ os << format_decimal(size >> 30, 10) << " GB";
+ else if ((size & 0xfffff) == 0)
+ os << format_decimal(size >> 20, 10) << " MB";
+ else if ((size & 0x3ff) == 0)
+ os << format_decimal(size >> 10, 10) << " KB";
+ else
+ os << " " << format_decimal(size, 10) << " B";
+ };
+ os << "Memory region Used Size Region Size %age Used\n";
+ for (auto &pair : memoryRegions) {
+ MemoryRegion *m = pair.second;
+ uint64_t usedLength = m->curPos - m->getOrigin();
+ os << right_justify(m->name, 16) << ": ";
+ printSize(usedLength);
+ uint64_t length = m->getLength();
+ if (length != 0) {
+ printSize(length);
+ double percent = usedLength * 100.0 / length;
+ os << " " << format("%6.2f%%", percent);
+ }
+ os << '\n';
+ }
+}