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