diff --git a/lld/ELF/OutputSections.h b/lld/ELF/OutputSections.h --- a/lld/ELF/OutputSections.h +++ b/lld/ELF/OutputSections.h @@ -137,6 +137,12 @@ uint64_t getHeaderSize(); +/// Writes the sizes of the output sections to stream. +/// +/// If maxCount is nonzero, limits the output to the given number +/// of sections. +void logSectionSizes(raw_ostream &stream, size_t maxCount = 20); + extern std::vector outputSections; } // namespace elf } // namespace lld diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp --- a/lld/ELF/OutputSections.cpp +++ b/lld/ELF/OutputSections.cpp @@ -16,11 +16,13 @@ #include "lld/Common/Strings.h" #include "llvm/BinaryFormat/Dwarf.h" #include "llvm/Support/Compression.h" +#include "llvm/Support/Format.h" #include "llvm/Support/MD5.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/Parallel.h" #include "llvm/Support/SHA1.h" #include "llvm/Support/TimeProfiler.h" +#include #include #include @@ -539,6 +541,32 @@ return {0, 0, 0, 0}; } +void elf::logSectionSizes(raw_ostream &stream, size_t maxCount) { + // If maxCount is nonzero, limit output to maxCount items. + if (maxCount == 0 || maxCount > outputSections.size()) + maxCount = outputSections.size(); + std::vector sorted(maxCount); + auto largestFirst = [](const OutputSection *a, const OutputSection *b) { + return a->size > b->size; + }; + std::partial_sort_copy(outputSections.begin(), outputSections.end(), + sorted.begin(), sorted.end(), largestFirst); + + // We output the section sizes in a format similar to llvm-objdump -h. + // This uses a section name length of 13, or longer if required, + // followed by the size of the section in 8 hexadecimal digits. + unsigned nameWidth = 13; + for (OutputSection *s : sorted) { + if (s->name.size() > nameWidth) + nameWidth = s->name.size(); + } + + for (OutputSection *s : sorted) { + stream << llvm::format("%-*s %08x\n", nameWidth, s->name.str().c_str(), + s->size); + } +} + template void OutputSection::writeHeaderTo(ELF32LE::Shdr *Shdr); template void OutputSection::writeHeaderTo(ELF32BE::Shdr *Shdr); template void OutputSection::writeHeaderTo(ELF64LE::Shdr *Shdr); diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -2872,7 +2872,12 @@ template void Writer::openFile() { uint64_t maxSize = config->is64 ? INT64_MAX : UINT32_MAX; if (fileSize != size_t(fileSize) || maxSize < fileSize) { - error("output file too large: " + Twine(fileSize) + " bytes"); + std::string msg; + raw_string_ostream s(msg); + s << "output file too large: " << Twine(fileSize) << " bytes\n" + << "Largest sections:\n"; + logSectionSizes(s); + error(s.str()); return; }