123 lines · cpp
1//===-- SectionSizes.cpp - Debug section sizes ----------------------------===//2//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-exception6//7//===----------------------------------------------------------------------===//8 9#include "llvm-dwarfdump.h"10 11#define DEBUG_TYPE "dwarfdump"12 13using namespace llvm;14using namespace llvm::dwarfdump;15using namespace llvm::object;16 17static 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());23 return Width;24}25 26static 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);33 }34 return Width;35}36 37static void prettyPrintSectionSizes(const ObjectFile &Obj,38 const SectionSizes &Sizes,39 raw_ostream &OS) {40 const StringRef SectionNameTitle = "SECTION";41 const StringRef SectionSizeTitle = "SIZE (b)";42 43 size_t NameColWidth = getNameColumnWidth(Sizes, SectionNameTitle);44 size_t SizeColWidth = getSizeColumnWidth(Sizes, SectionSizeTitle);45 46 OS << "----------------------------------------------------" << '\n';47 OS << SectionNameTitle;48 size_t SectionNameTitleWidth = SectionNameTitle.size();49 for (unsigned i = 0; i < (NameColWidth - SectionNameTitleWidth) + 2; i++)50 OS << " ";51 OS << SectionSizeTitle << '\n';52 for (unsigned i = 0; i < NameColWidth; i++)53 OS << "-";54 OS << " ";55 56 for (unsigned i = 0; i < SizeColWidth; i++)57 OS << "-";58 OS << '\n';59 60 for (const auto &It : Sizes.DebugSectionSizes) {61 OS << left_justify(It.first, NameColWidth) << " ";62 63 std::string NumBytes = std::to_string(It.second);64 OS << right_justify(NumBytes, SizeColWidth) << " ("65 << format("%0.2f",66 It.second / static_cast<double>(Sizes.TotalObjectSize) * 100)67 << "%)\n";68 }69 70 OS << '\n';71 OS << " Total Size: " << Sizes.TotalDebugSectionsSize << " ("72 << format("%0.2f", Sizes.TotalDebugSectionsSize /73 static_cast<double>(Sizes.TotalObjectSize) * 100)74 << "%)\n";75 OS << " Total File Size: " << Sizes.TotalObjectSize << '\n';76 OS << "----------------------------------------------------" << '\n';77}78 79void dwarfdump::calculateSectionSizes(const ObjectFile &Obj,80 SectionSizes &Sizes,81 const Twine &Filename) {82 // Get total size.83 Sizes.TotalObjectSize = Obj.getData().size();84 85 for (const SectionRef &Section : Obj.sections()) {86 StringRef SectionName;87 if (Expected<StringRef> NameOrErr = Section.getName())88 SectionName = *NameOrErr;89 else90 WithColor::defaultWarningHandler(91 createFileError(Filename, NameOrErr.takeError()));92 93 LLVM_DEBUG(dbgs() << SectionName.str() << ": " << Section.getSize()94 << '\n');95 96 if (!Section.isDebugSection())97 continue;98 99 Sizes.TotalDebugSectionsSize += Section.getSize();100 Sizes.DebugSectionSizes[std::string(SectionName)] += Section.getSize();101 }102}103 104bool dwarfdump::collectObjectSectionSizes(ObjectFile &Obj,105 DWARFContext & /*DICtx*/,106 const Twine &Filename,107 raw_ostream &OS) {108 SectionSizes Sizes;109 110 // Get the section sizes.111 calculateSectionSizes(Obj, Sizes, Filename);112 113 OS << "----------------------------------------------------\n";114 OS << "file: " << Filename.str() << '\n';115 116 prettyPrintSectionSizes(Obj, Sizes, OS);117 118 // TODO: If the input file is an archive, print the cumulative summary of all119 // files from the archive.120 121 return true;122}123