1//===-- SectionSizes.cpp - Debug section sizes ----------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "llvm-dwarfdump.h"
10
11#define DEBUG_TYPE "dwarfdump"
12
13using namespace llvm;
14using namespace llvm::dwarfdump;
15using namespace llvm::object;
16
17static size_t getNameColumnWidth(const SectionSizes &Sizes,
18 const StringRef SectionNameTitle) {
19 // The minimum column width should be the size of "SECTION".
20 size_t Width = SectionNameTitle.size();
21 for (const auto &It : Sizes.DebugSectionSizes)
22 Width = std::max(a: Width, b: It.first.size());
23 return Width;
24}
25
26static size_t getSizeColumnWidth(const SectionSizes &Sizes,
27 const StringRef SectionSizeTitle) {
28 // The minimum column width should be the size of the column title.
29 size_t Width = SectionSizeTitle.size();
30 for (const auto &It : Sizes.DebugSectionSizes) {
31 size_t NumWidth = std::to_string(val: It.second).size();
32 Width = std::max(a: Width, b: NumWidth);
33 }
34 return Width;
35}
36
37static void prettyPrintSectionSizes(const ObjectFile &Obj,
38 const SectionSizes &Sizes,
39 raw_ostream &OS) {
40 const StringRef SectionNameTitle = "SECTION";
41 const StringRef SectionSizeTitle = "SIZE (b)";
42
43 size_t NameColWidth = getNameColumnWidth(Sizes, SectionNameTitle);
44 size_t SizeColWidth = getSizeColumnWidth(Sizes, SectionSizeTitle);
45
46 OS << "----------------------------------------------------" << '\n';
47 OS << SectionNameTitle;
48 size_t SectionNameTitleWidth = SectionNameTitle.size();
49 for (unsigned i = 0; i < (NameColWidth - SectionNameTitleWidth) + 2; i++)
50 OS << " ";
51 OS << SectionSizeTitle << '\n';
52 for (unsigned i = 0; i < NameColWidth; i++)
53 OS << "-";
54 OS << " ";
55
56 for (unsigned i = 0; i < SizeColWidth; i++)
57 OS << "-";
58 OS << '\n';
59
60 for (const auto &It : Sizes.DebugSectionSizes) {
61 OS << left_justify(Str: It.first, Width: NameColWidth) << " ";
62
63 std::string NumBytes = std::to_string(val: It.second);
64 OS << right_justify(Str: NumBytes, Width: SizeColWidth) << " ("
65 << format(Fmt: "%0.2f",
66 Vals: It.second / static_cast<double>(Sizes.TotalObjectSize) * 100)
67 << "%)\n";
68 }
69
70 OS << '\n';
71 OS << " Total Size: " << Sizes.TotalDebugSectionsSize << " ("
72 << format(Fmt: "%0.2f", Vals: Sizes.TotalDebugSectionsSize /
73 static_cast<double>(Sizes.TotalObjectSize) * 100)
74 << "%)\n";
75 OS << " Total File Size: " << Sizes.TotalObjectSize << '\n';
76 OS << "----------------------------------------------------" << '\n';
77}
78
79void dwarfdump::calculateSectionSizes(const ObjectFile &Obj,
80 SectionSizes &Sizes,
81 const Twine &Filename) {
82 // Get total size.
83 Sizes.TotalObjectSize = Obj.getData().size();
84
85 for (const SectionRef &Section : Obj.sections()) {
86 StringRef SectionName;
87 if (Expected<StringRef> NameOrErr = Section.getName())
88 SectionName = *NameOrErr;
89 else
90 WithColor::defaultWarningHandler(
91 Warning: createFileError(F: Filename, E: NameOrErr.takeError()));
92
93 LLVM_DEBUG(dbgs() << SectionName.str() << ": " << Section.getSize()
94 << '\n');
95
96 if (!Section.isDebugSection())
97 continue;
98
99 Sizes.TotalDebugSectionsSize += Section.getSize();
100 Sizes.DebugSectionSizes[std::string(SectionName)] += Section.getSize();
101 }
102}
103
104bool dwarfdump::collectObjectSectionSizes(ObjectFile &Obj,
105 DWARFContext & /*DICtx*/,
106 const Twine &Filename,
107 raw_ostream &OS) {
108 SectionSizes Sizes;
109
110 // Get the section sizes.
111 calculateSectionSizes(Obj, Sizes, Filename);
112
113 OS << "----------------------------------------------------\n";
114 OS << "file: " << Filename.str() << '\n';
115
116 prettyPrintSectionSizes(Obj, Sizes, OS);
117
118 // TODO: If the input file is an archive, print the cumulative summary of all
119 // files from the archive.
120
121 return true;
122}
123