xref: /freebsd-src/contrib/llvm-project/llvm/tools/llvm-dwarfdump/SectionSizes.cpp (revision fe6060f10f634930ff71b7c50291ddc610da2475)
15ffd83dbSDimitry Andric //===-- SectionSizes.cpp - Debug section sizes ----------------------------===//
25ffd83dbSDimitry Andric //
35ffd83dbSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
45ffd83dbSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
55ffd83dbSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
65ffd83dbSDimitry Andric //
75ffd83dbSDimitry Andric //===----------------------------------------------------------------------===//
85ffd83dbSDimitry Andric 
95ffd83dbSDimitry Andric #include "llvm-dwarfdump.h"
105ffd83dbSDimitry Andric 
115ffd83dbSDimitry Andric #define DEBUG_TYPE "dwarfdump"
125ffd83dbSDimitry Andric 
135ffd83dbSDimitry Andric using namespace llvm;
145ffd83dbSDimitry Andric using namespace llvm::dwarfdump;
155ffd83dbSDimitry Andric using namespace llvm::object;
165ffd83dbSDimitry Andric 
getNameColumnWidth(const SectionSizes & Sizes,const StringRef SectionNameTitle)175ffd83dbSDimitry Andric static size_t getNameColumnWidth(const SectionSizes &Sizes,
185ffd83dbSDimitry Andric                                  const StringRef SectionNameTitle) {
195ffd83dbSDimitry Andric   // The minimum column width should be the size of "SECTION".
205ffd83dbSDimitry Andric   size_t Width = SectionNameTitle.size();
21*fe6060f1SDimitry Andric   for (const auto &It : Sizes.DebugSectionSizes)
22*fe6060f1SDimitry Andric     Width = std::max(Width, It.first.size());
235ffd83dbSDimitry Andric   return Width;
245ffd83dbSDimitry Andric }
255ffd83dbSDimitry Andric 
getSizeColumnWidth(const SectionSizes & Sizes,const StringRef SectionSizeTitle)265ffd83dbSDimitry Andric static size_t getSizeColumnWidth(const SectionSizes &Sizes,
275ffd83dbSDimitry Andric                                  const StringRef SectionSizeTitle) {
285ffd83dbSDimitry Andric   // The minimum column width should be the size of the column title.
295ffd83dbSDimitry Andric   size_t Width = SectionSizeTitle.size();
30*fe6060f1SDimitry Andric   for (const auto &It : Sizes.DebugSectionSizes) {
31*fe6060f1SDimitry Andric     size_t NumWidth = std::to_string(It.second).size();
325ffd83dbSDimitry Andric     Width = std::max(Width, NumWidth);
335ffd83dbSDimitry Andric   }
345ffd83dbSDimitry Andric   return Width;
355ffd83dbSDimitry Andric }
365ffd83dbSDimitry Andric 
prettyPrintSectionSizes(const ObjectFile & Obj,const SectionSizes & Sizes,raw_ostream & OS)375ffd83dbSDimitry Andric static void prettyPrintSectionSizes(const ObjectFile &Obj,
385ffd83dbSDimitry Andric                                     const SectionSizes &Sizes,
395ffd83dbSDimitry Andric                                     raw_ostream &OS) {
405ffd83dbSDimitry Andric   const StringRef SectionNameTitle = "SECTION";
415ffd83dbSDimitry Andric   const StringRef SectionSizeTitle = "SIZE (b)";
425ffd83dbSDimitry Andric 
435ffd83dbSDimitry Andric   size_t NameColWidth = getNameColumnWidth(Sizes, SectionNameTitle);
445ffd83dbSDimitry Andric   size_t SizeColWidth = getSizeColumnWidth(Sizes, SectionSizeTitle);
455ffd83dbSDimitry Andric 
465ffd83dbSDimitry Andric   OS << "----------------------------------------------------" << '\n';
475ffd83dbSDimitry Andric   OS << SectionNameTitle;
485ffd83dbSDimitry Andric   size_t SectionNameTitleWidth = SectionNameTitle.size();
495ffd83dbSDimitry Andric   for (unsigned i = 0; i < (NameColWidth - SectionNameTitleWidth) + 2; i++)
505ffd83dbSDimitry Andric     OS << " ";
515ffd83dbSDimitry Andric   OS << SectionSizeTitle << '\n';
525ffd83dbSDimitry Andric   for (unsigned i = 0; i < NameColWidth; i++)
535ffd83dbSDimitry Andric     OS << "-";
545ffd83dbSDimitry Andric   OS << "  ";
555ffd83dbSDimitry Andric 
565ffd83dbSDimitry Andric   for (unsigned i = 0; i < SizeColWidth; i++)
575ffd83dbSDimitry Andric     OS << "-";
585ffd83dbSDimitry Andric   OS << '\n';
595ffd83dbSDimitry Andric 
60*fe6060f1SDimitry Andric   for (const auto &It : Sizes.DebugSectionSizes) {
61*fe6060f1SDimitry Andric     OS << left_justify(It.first, NameColWidth) << "  ";
625ffd83dbSDimitry Andric 
63*fe6060f1SDimitry Andric     std::string NumBytes = std::to_string(It.second);
645ffd83dbSDimitry Andric     OS << right_justify(NumBytes, SizeColWidth) << " ("
65*fe6060f1SDimitry Andric        << format("%0.2f",
66*fe6060f1SDimitry Andric                  It.second / static_cast<double>(Sizes.TotalObjectSize) * 100)
675ffd83dbSDimitry Andric        << "%)\n";
685ffd83dbSDimitry Andric   }
695ffd83dbSDimitry Andric 
705ffd83dbSDimitry Andric   OS << '\n';
715ffd83dbSDimitry Andric   OS << " Total Size: " << Sizes.TotalDebugSectionsSize << "  ("
725ffd83dbSDimitry Andric      << format("%0.2f", Sizes.TotalDebugSectionsSize /
735ffd83dbSDimitry Andric                             static_cast<double>(Sizes.TotalObjectSize) * 100)
745ffd83dbSDimitry Andric      << "%)\n";
755ffd83dbSDimitry Andric   OS << " Total File Size: " << Sizes.TotalObjectSize << '\n';
765ffd83dbSDimitry Andric   OS << "----------------------------------------------------" << '\n';
775ffd83dbSDimitry Andric }
785ffd83dbSDimitry Andric 
calculateSectionSizes(const ObjectFile & Obj,SectionSizes & Sizes,const Twine & Filename)795ffd83dbSDimitry Andric void dwarfdump::calculateSectionSizes(const ObjectFile &Obj,
805ffd83dbSDimitry Andric                                       SectionSizes &Sizes,
815ffd83dbSDimitry Andric                                       const Twine &Filename) {
825ffd83dbSDimitry Andric   // Get total size.
835ffd83dbSDimitry Andric   Sizes.TotalObjectSize = Obj.getData().size();
845ffd83dbSDimitry Andric 
855ffd83dbSDimitry Andric   for (const SectionRef &Section : Obj.sections()) {
865ffd83dbSDimitry Andric     StringRef SectionName;
875ffd83dbSDimitry Andric     if (Expected<StringRef> NameOrErr = Section.getName())
885ffd83dbSDimitry Andric       SectionName = *NameOrErr;
895ffd83dbSDimitry Andric     else
905ffd83dbSDimitry Andric       WithColor::defaultWarningHandler(
915ffd83dbSDimitry Andric           createFileError(Filename, NameOrErr.takeError()));
925ffd83dbSDimitry Andric 
935ffd83dbSDimitry Andric     LLVM_DEBUG(dbgs() << SectionName.str() << ": " << Section.getSize()
945ffd83dbSDimitry Andric                       << '\n');
955ffd83dbSDimitry Andric 
96*fe6060f1SDimitry Andric     if (!Section.isDebugSection())
975ffd83dbSDimitry Andric       continue;
985ffd83dbSDimitry Andric 
995ffd83dbSDimitry Andric     Sizes.TotalDebugSectionsSize += Section.getSize();
100*fe6060f1SDimitry Andric     Sizes.DebugSectionSizes[std::string(SectionName)] += Section.getSize();
1015ffd83dbSDimitry Andric   }
1025ffd83dbSDimitry Andric }
1035ffd83dbSDimitry Andric 
collectObjectSectionSizes(ObjectFile & Obj,DWARFContext &,const Twine & Filename,raw_ostream & OS)1045ffd83dbSDimitry Andric bool dwarfdump::collectObjectSectionSizes(ObjectFile &Obj,
1055ffd83dbSDimitry Andric                                           DWARFContext & /*DICtx*/,
1065ffd83dbSDimitry Andric                                           const Twine &Filename,
1075ffd83dbSDimitry Andric                                           raw_ostream &OS) {
1085ffd83dbSDimitry Andric   SectionSizes Sizes;
1095ffd83dbSDimitry Andric 
1105ffd83dbSDimitry Andric   // Get the section sizes.
1115ffd83dbSDimitry Andric   calculateSectionSizes(Obj, Sizes, Filename);
1125ffd83dbSDimitry Andric 
1135ffd83dbSDimitry Andric   OS << "----------------------------------------------------\n";
1145ffd83dbSDimitry Andric   OS << "file: " << Filename.str() << '\n';
1155ffd83dbSDimitry Andric 
1165ffd83dbSDimitry Andric   prettyPrintSectionSizes(Obj, Sizes, OS);
1175ffd83dbSDimitry Andric 
1185ffd83dbSDimitry Andric   // TODO: If the input file is an archive, print the cumulative summary of all
1195ffd83dbSDimitry Andric   // files from the archive.
1205ffd83dbSDimitry Andric 
1215ffd83dbSDimitry Andric   return true;
1225ffd83dbSDimitry Andric }
123