summaryrefslogtreecommitdiff
path: root/llvm/tools/llvm-dwarfdump/SectionSizes.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/tools/llvm-dwarfdump/SectionSizes.cpp')
-rw-r--r--llvm/tools/llvm-dwarfdump/SectionSizes.cpp124
1 files changed, 124 insertions, 0 deletions
diff --git a/llvm/tools/llvm-dwarfdump/SectionSizes.cpp b/llvm/tools/llvm-dwarfdump/SectionSizes.cpp
new file mode 100644
index 0000000000000..8c456d50baa7c
--- /dev/null
+++ b/llvm/tools/llvm-dwarfdump/SectionSizes.cpp
@@ -0,0 +1,124 @@
+//===-- SectionSizes.cpp - Debug section sizes ----------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm-dwarfdump.h"
+
+#define DEBUG_TYPE "dwarfdump"
+
+using namespace llvm;
+using namespace llvm::dwarfdump;
+using namespace llvm::object;
+
+static size_t getNameColumnWidth(const SectionSizes &Sizes,
+ const StringRef SectionNameTitle) {
+ // The minimum column width should be the size of "SECTION".
+ size_t Width = SectionNameTitle.size();
+ for (const auto &DebugSec : Sizes.DebugSectionSizes) {
+ StringRef SectionName = DebugSec.getKey();
+ Width = std::max(Width, SectionName.size());
+ }
+ return Width;
+}
+
+static size_t getSizeColumnWidth(const SectionSizes &Sizes,
+ const StringRef SectionSizeTitle) {
+ // The minimum column width should be the size of the column title.
+ size_t Width = SectionSizeTitle.size();
+ for (const auto &DebugSec : Sizes.DebugSectionSizes) {
+ size_t NumWidth = std::to_string(DebugSec.getValue()).size();
+ Width = std::max(Width, NumWidth);
+ }
+ return Width;
+}
+
+static void prettyPrintSectionSizes(const ObjectFile &Obj,
+ const SectionSizes &Sizes,
+ raw_ostream &OS) {
+ const StringRef SectionNameTitle = "SECTION";
+ const StringRef SectionSizeTitle = "SIZE (b)";
+
+ size_t NameColWidth = getNameColumnWidth(Sizes, SectionNameTitle);
+ size_t SizeColWidth = getSizeColumnWidth(Sizes, SectionSizeTitle);
+
+ OS << "----------------------------------------------------" << '\n';
+ OS << SectionNameTitle;
+ size_t SectionNameTitleWidth = SectionNameTitle.size();
+ for (unsigned i = 0; i < (NameColWidth - SectionNameTitleWidth) + 2; i++)
+ OS << " ";
+ OS << SectionSizeTitle << '\n';
+ for (unsigned i = 0; i < NameColWidth; i++)
+ OS << "-";
+ OS << " ";
+
+ for (unsigned i = 0; i < SizeColWidth; i++)
+ OS << "-";
+ OS << '\n';
+
+ for (const auto &DebugSec : Sizes.DebugSectionSizes) {
+ OS << left_justify(DebugSec.getKey(), NameColWidth) << " ";
+
+ auto NumBytes = std::to_string(DebugSec.getValue());
+ OS << right_justify(NumBytes, SizeColWidth) << " ("
+ << format("%0.2f", DebugSec.getValue() /
+ static_cast<double>(Sizes.TotalObjectSize) * 100)
+ << "%)\n";
+ }
+
+ OS << '\n';
+ OS << " Total Size: " << Sizes.TotalDebugSectionsSize << " ("
+ << format("%0.2f", Sizes.TotalDebugSectionsSize /
+ static_cast<double>(Sizes.TotalObjectSize) * 100)
+ << "%)\n";
+ OS << " Total File Size: " << Sizes.TotalObjectSize << '\n';
+ OS << "----------------------------------------------------" << '\n';
+}
+
+void dwarfdump::calculateSectionSizes(const ObjectFile &Obj,
+ SectionSizes &Sizes,
+ const Twine &Filename) {
+ // Get total size.
+ Sizes.TotalObjectSize = Obj.getData().size();
+
+ for (const SectionRef &Section : Obj.sections()) {
+ StringRef SectionName;
+ if (Expected<StringRef> NameOrErr = Section.getName())
+ SectionName = *NameOrErr;
+ else
+ WithColor::defaultWarningHandler(
+ createFileError(Filename, NameOrErr.takeError()));
+
+ LLVM_DEBUG(dbgs() << SectionName.str() << ": " << Section.getSize()
+ << '\n');
+
+ if (!Section.isDebugSection(SectionName))
+ continue;
+
+ Sizes.TotalDebugSectionsSize += Section.getSize();
+ Sizes.DebugSectionSizes[SectionName] += Section.getSize();
+ }
+}
+
+bool dwarfdump::collectObjectSectionSizes(ObjectFile &Obj,
+ DWARFContext & /*DICtx*/,
+ const Twine &Filename,
+ raw_ostream &OS) {
+ SectionSizes Sizes;
+
+ // Get the section sizes.
+ calculateSectionSizes(Obj, Sizes, Filename);
+
+ OS << "----------------------------------------------------\n";
+ OS << "file: " << Filename.str() << '\n';
+
+ prettyPrintSectionSizes(Obj, Sizes, OS);
+
+ // TODO: If the input file is an archive, print the cumulative summary of all
+ // files from the archive.
+
+ return true;
+}