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