xref: /openbsd-src/gnu/llvm/llvm/tools/llvm-dwarfdump/SectionSizes.cpp (revision 73471bf04ceb096474c7f0fa83b1b65c70a787a1)
1097a140dSpatrick //===-- SectionSizes.cpp - Debug section sizes ----------------------------===//
2097a140dSpatrick //
3097a140dSpatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4097a140dSpatrick // See https://llvm.org/LICENSE.txt for license information.
5097a140dSpatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6097a140dSpatrick //
7097a140dSpatrick //===----------------------------------------------------------------------===//
8097a140dSpatrick 
9097a140dSpatrick #include "llvm-dwarfdump.h"
10097a140dSpatrick 
11097a140dSpatrick #define DEBUG_TYPE "dwarfdump"
12097a140dSpatrick 
13097a140dSpatrick using namespace llvm;
14097a140dSpatrick using namespace llvm::dwarfdump;
15097a140dSpatrick using namespace llvm::object;
16097a140dSpatrick 
getNameColumnWidth(const SectionSizes & Sizes,const StringRef SectionNameTitle)17097a140dSpatrick static size_t getNameColumnWidth(const SectionSizes &Sizes,
18097a140dSpatrick                                  const StringRef SectionNameTitle) {
19097a140dSpatrick   // The minimum column width should be the size of "SECTION".
20097a140dSpatrick   size_t Width = SectionNameTitle.size();
21*73471bf0Spatrick   for (const auto &It : Sizes.DebugSectionSizes)
22*73471bf0Spatrick     Width = std::max(Width, It.first.size());
23097a140dSpatrick   return Width;
24097a140dSpatrick }
25097a140dSpatrick 
getSizeColumnWidth(const SectionSizes & Sizes,const StringRef SectionSizeTitle)26097a140dSpatrick static size_t getSizeColumnWidth(const SectionSizes &Sizes,
27097a140dSpatrick                                  const StringRef SectionSizeTitle) {
28097a140dSpatrick   // The minimum column width should be the size of the column title.
29097a140dSpatrick   size_t Width = SectionSizeTitle.size();
30*73471bf0Spatrick   for (const auto &It : Sizes.DebugSectionSizes) {
31*73471bf0Spatrick     size_t NumWidth = std::to_string(It.second).size();
32097a140dSpatrick     Width = std::max(Width, NumWidth);
33097a140dSpatrick   }
34097a140dSpatrick   return Width;
35097a140dSpatrick }
36097a140dSpatrick 
prettyPrintSectionSizes(const ObjectFile & Obj,const SectionSizes & Sizes,raw_ostream & OS)37097a140dSpatrick static void prettyPrintSectionSizes(const ObjectFile &Obj,
38097a140dSpatrick                                     const SectionSizes &Sizes,
39097a140dSpatrick                                     raw_ostream &OS) {
40097a140dSpatrick   const StringRef SectionNameTitle = "SECTION";
41097a140dSpatrick   const StringRef SectionSizeTitle = "SIZE (b)";
42097a140dSpatrick 
43097a140dSpatrick   size_t NameColWidth = getNameColumnWidth(Sizes, SectionNameTitle);
44097a140dSpatrick   size_t SizeColWidth = getSizeColumnWidth(Sizes, SectionSizeTitle);
45097a140dSpatrick 
46097a140dSpatrick   OS << "----------------------------------------------------" << '\n';
47097a140dSpatrick   OS << SectionNameTitle;
48097a140dSpatrick   size_t SectionNameTitleWidth = SectionNameTitle.size();
49097a140dSpatrick   for (unsigned i = 0; i < (NameColWidth - SectionNameTitleWidth) + 2; i++)
50097a140dSpatrick     OS << " ";
51097a140dSpatrick   OS << SectionSizeTitle << '\n';
52097a140dSpatrick   for (unsigned i = 0; i < NameColWidth; i++)
53097a140dSpatrick     OS << "-";
54097a140dSpatrick   OS << "  ";
55097a140dSpatrick 
56097a140dSpatrick   for (unsigned i = 0; i < SizeColWidth; i++)
57097a140dSpatrick     OS << "-";
58097a140dSpatrick   OS << '\n';
59097a140dSpatrick 
60*73471bf0Spatrick   for (const auto &It : Sizes.DebugSectionSizes) {
61*73471bf0Spatrick     OS << left_justify(It.first, NameColWidth) << "  ";
62097a140dSpatrick 
63*73471bf0Spatrick     std::string NumBytes = std::to_string(It.second);
64097a140dSpatrick     OS << right_justify(NumBytes, SizeColWidth) << " ("
65*73471bf0Spatrick        << format("%0.2f",
66*73471bf0Spatrick                  It.second / static_cast<double>(Sizes.TotalObjectSize) * 100)
67097a140dSpatrick        << "%)\n";
68097a140dSpatrick   }
69097a140dSpatrick 
70097a140dSpatrick   OS << '\n';
71097a140dSpatrick   OS << " Total Size: " << Sizes.TotalDebugSectionsSize << "  ("
72097a140dSpatrick      << format("%0.2f", Sizes.TotalDebugSectionsSize /
73097a140dSpatrick                             static_cast<double>(Sizes.TotalObjectSize) * 100)
74097a140dSpatrick      << "%)\n";
75097a140dSpatrick   OS << " Total File Size: " << Sizes.TotalObjectSize << '\n';
76097a140dSpatrick   OS << "----------------------------------------------------" << '\n';
77097a140dSpatrick }
78097a140dSpatrick 
calculateSectionSizes(const ObjectFile & Obj,SectionSizes & Sizes,const Twine & Filename)79097a140dSpatrick void dwarfdump::calculateSectionSizes(const ObjectFile &Obj,
80097a140dSpatrick                                       SectionSizes &Sizes,
81097a140dSpatrick                                       const Twine &Filename) {
82097a140dSpatrick   // Get total size.
83097a140dSpatrick   Sizes.TotalObjectSize = Obj.getData().size();
84097a140dSpatrick 
85097a140dSpatrick   for (const SectionRef &Section : Obj.sections()) {
86097a140dSpatrick     StringRef SectionName;
87097a140dSpatrick     if (Expected<StringRef> NameOrErr = Section.getName())
88097a140dSpatrick       SectionName = *NameOrErr;
89097a140dSpatrick     else
90097a140dSpatrick       WithColor::defaultWarningHandler(
91097a140dSpatrick           createFileError(Filename, NameOrErr.takeError()));
92097a140dSpatrick 
93097a140dSpatrick     LLVM_DEBUG(dbgs() << SectionName.str() << ": " << Section.getSize()
94097a140dSpatrick                       << '\n');
95097a140dSpatrick 
96*73471bf0Spatrick     if (!Section.isDebugSection())
97097a140dSpatrick       continue;
98097a140dSpatrick 
99097a140dSpatrick     Sizes.TotalDebugSectionsSize += Section.getSize();
100*73471bf0Spatrick     Sizes.DebugSectionSizes[std::string(SectionName)] += Section.getSize();
101097a140dSpatrick   }
102097a140dSpatrick }
103097a140dSpatrick 
collectObjectSectionSizes(ObjectFile & Obj,DWARFContext &,const Twine & Filename,raw_ostream & OS)104097a140dSpatrick bool dwarfdump::collectObjectSectionSizes(ObjectFile &Obj,
105097a140dSpatrick                                           DWARFContext & /*DICtx*/,
106097a140dSpatrick                                           const Twine &Filename,
107097a140dSpatrick                                           raw_ostream &OS) {
108097a140dSpatrick   SectionSizes Sizes;
109097a140dSpatrick 
110097a140dSpatrick   // Get the section sizes.
111097a140dSpatrick   calculateSectionSizes(Obj, Sizes, Filename);
112097a140dSpatrick 
113097a140dSpatrick   OS << "----------------------------------------------------\n";
114097a140dSpatrick   OS << "file: " << Filename.str() << '\n';
115097a140dSpatrick 
116097a140dSpatrick   prettyPrintSectionSizes(Obj, Sizes, OS);
117097a140dSpatrick 
118097a140dSpatrick   // TODO: If the input file is an archive, print the cumulative summary of all
119097a140dSpatrick   // files from the archive.
120097a140dSpatrick 
121097a140dSpatrick   return true;
122097a140dSpatrick }
123