1 //===-- SectionSizes.cpp - Debug section sizes ----------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "llvm-dwarfdump.h"
11 #define DEBUG_TYPE "dwarfdump"
14 using namespace llvm::dwarfdump
;
15 using namespace llvm::object
;
17 static 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(Width
, It
.first
.size());
26 static 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(It
.second
).size();
32 Width
= std::max(Width
, NumWidth
);
37 static void prettyPrintSectionSizes(const ObjectFile
&Obj
,
38 const SectionSizes
&Sizes
,
40 const StringRef SectionNameTitle
= "SECTION";
41 const StringRef SectionSizeTitle
= "SIZE (b)";
43 size_t NameColWidth
= getNameColumnWidth(Sizes
, SectionNameTitle
);
44 size_t SizeColWidth
= getSizeColumnWidth(Sizes
, SectionSizeTitle
);
46 OS
<< "----------------------------------------------------" << '\n';
47 OS
<< SectionNameTitle
;
48 size_t SectionNameTitleWidth
= SectionNameTitle
.size();
49 for (unsigned i
= 0; i
< (NameColWidth
- SectionNameTitleWidth
) + 2; i
++)
51 OS
<< SectionSizeTitle
<< '\n';
52 for (unsigned i
= 0; i
< NameColWidth
; i
++)
56 for (unsigned i
= 0; i
< SizeColWidth
; i
++)
60 for (const auto &It
: Sizes
.DebugSectionSizes
) {
61 OS
<< left_justify(It
.first
, NameColWidth
) << " ";
63 std::string NumBytes
= std::to_string(It
.second
);
64 OS
<< right_justify(NumBytes
, SizeColWidth
) << " ("
66 It
.second
/ static_cast<double>(Sizes
.TotalObjectSize
) * 100)
71 OS
<< " Total Size: " << Sizes
.TotalDebugSectionsSize
<< " ("
72 << format("%0.2f", Sizes
.TotalDebugSectionsSize
/
73 static_cast<double>(Sizes
.TotalObjectSize
) * 100)
75 OS
<< " Total File Size: " << Sizes
.TotalObjectSize
<< '\n';
76 OS
<< "----------------------------------------------------" << '\n';
79 void dwarfdump::calculateSectionSizes(const ObjectFile
&Obj
,
81 const Twine
&Filename
) {
83 Sizes
.TotalObjectSize
= Obj
.getData().size();
85 for (const SectionRef
&Section
: Obj
.sections()) {
86 StringRef SectionName
;
87 if (Expected
<StringRef
> NameOrErr
= Section
.getName())
88 SectionName
= *NameOrErr
;
90 WithColor::defaultWarningHandler(
91 createFileError(Filename
, NameOrErr
.takeError()));
93 LLVM_DEBUG(dbgs() << SectionName
.str() << ": " << Section
.getSize()
96 if (!Section
.isDebugSection())
99 Sizes
.TotalDebugSectionsSize
+= Section
.getSize();
100 Sizes
.DebugSectionSizes
[std::string(SectionName
)] += Section
.getSize();
104 bool dwarfdump::collectObjectSectionSizes(ObjectFile
&Obj
,
105 DWARFContext
& /*DICtx*/,
106 const Twine
&Filename
,
110 // Get the section sizes.
111 calculateSectionSizes(Obj
, Sizes
, Filename
);
113 OS
<< "----------------------------------------------------\n";
114 OS
<< "file: " << Filename
.str() << '\n';
116 prettyPrintSectionSizes(Obj
, Sizes
, OS
);
118 // TODO: If the input file is an archive, print the cumulative summary of all
119 // files from the archive.