[PATCH] D94560: [ELF] report section sizes when output file too large

Bob Haarman via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Jan 12 15:34:46 PST 2021


inglorion created this revision.
inglorion added reviewers: MaskRay, grimar.
Herald added subscribers: arichardson, emaste.
Herald added a reviewer: espindola.
inglorion requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

Fixes PR48523. When the linker errors with "output file too large",
one question that comes to mind is how the section sizes differ from
what they were previously. Unfortunately, this information is lost
when the linker exits without writing the output file. This change
makes it so that the error message includes the sizes of the largest
sections.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D94560

Files:
  lld/ELF/OutputSections.cpp
  lld/ELF/OutputSections.h
  lld/ELF/Writer.cpp


Index: lld/ELF/Writer.cpp
===================================================================
--- lld/ELF/Writer.cpp
+++ lld/ELF/Writer.cpp
@@ -2872,7 +2872,12 @@
 template <class ELFT> void Writer<ELFT>::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;
   }
 
Index: lld/ELF/OutputSections.h
===================================================================
--- lld/ELF/OutputSections.h
+++ 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<OutputSection *> outputSections;
 } // namespace elf
 } // namespace lld
Index: lld/ELF/OutputSections.cpp
===================================================================
--- lld/ELF/OutputSections.cpp
+++ 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 <algorithm>
 #include <regex>
 #include <unordered_set>
 
@@ -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<OutputSection *> 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>(ELF32LE::Shdr *Shdr);
 template void OutputSection::writeHeaderTo<ELF32BE>(ELF32BE::Shdr *Shdr);
 template void OutputSection::writeHeaderTo<ELF64LE>(ELF64LE::Shdr *Shdr);


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D94560.316259.patch
Type: text/x-patch
Size: 3044 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210112/47597d33/attachment.bin>


More information about the llvm-commits mailing list