125 lines
4.3 KiB
C++
125 lines
4.3 KiB
C++
|
//===-- SectionSizes.cpp - Debug section sizes ----------------------------===//
|
||
|
//
|
||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||
|
//
|
||
|
//===----------------------------------------------------------------------===//
|
||
|
|
||
|
#include "llvm-dwarfdump.h"
|
||
|
|
||
|
#define DEBUG_TYPE "dwarfdump"
|
||
|
|
||
|
using namespace llvm;
|
||
|
using namespace llvm::dwarfdump;
|
||
|
using namespace llvm::object;
|
||
|
|
||
|
static size_t getNameColumnWidth(const SectionSizes &Sizes,
|
||
|
const StringRef SectionNameTitle) {
|
||
|
// The minimum column width should be the size of "SECTION".
|
||
|
size_t Width = SectionNameTitle.size();
|
||
|
for (const auto &DebugSec : Sizes.DebugSectionSizes) {
|
||
|
StringRef SectionName = DebugSec.getKey();
|
||
|
Width = std::max(Width, SectionName.size());
|
||
|
}
|
||
|
return Width;
|
||
|
}
|
||
|
|
||
|
static size_t getSizeColumnWidth(const SectionSizes &Sizes,
|
||
|
const StringRef SectionSizeTitle) {
|
||
|
// The minimum column width should be the size of the column title.
|
||
|
size_t Width = SectionSizeTitle.size();
|
||
|
for (const auto &DebugSec : Sizes.DebugSectionSizes) {
|
||
|
size_t NumWidth = std::to_string(DebugSec.getValue()).size();
|
||
|
Width = std::max(Width, NumWidth);
|
||
|
}
|
||
|
return Width;
|
||
|
}
|
||
|
|
||
|
static void prettyPrintSectionSizes(const ObjectFile &Obj,
|
||
|
const SectionSizes &Sizes,
|
||
|
raw_ostream &OS) {
|
||
|
const StringRef SectionNameTitle = "SECTION";
|
||
|
const StringRef SectionSizeTitle = "SIZE (b)";
|
||
|
|
||
|
size_t NameColWidth = getNameColumnWidth(Sizes, SectionNameTitle);
|
||
|
size_t SizeColWidth = getSizeColumnWidth(Sizes, SectionSizeTitle);
|
||
|
|
||
|
OS << "----------------------------------------------------" << '\n';
|
||
|
OS << SectionNameTitle;
|
||
|
size_t SectionNameTitleWidth = SectionNameTitle.size();
|
||
|
for (unsigned i = 0; i < (NameColWidth - SectionNameTitleWidth) + 2; i++)
|
||
|
OS << " ";
|
||
|
OS << SectionSizeTitle << '\n';
|
||
|
for (unsigned i = 0; i < NameColWidth; i++)
|
||
|
OS << "-";
|
||
|
OS << " ";
|
||
|
|
||
|
for (unsigned i = 0; i < SizeColWidth; i++)
|
||
|
OS << "-";
|
||
|
OS << '\n';
|
||
|
|
||
|
for (const auto &DebugSec : Sizes.DebugSectionSizes) {
|
||
|
OS << left_justify(DebugSec.getKey(), NameColWidth) << " ";
|
||
|
|
||
|
auto NumBytes = std::to_string(DebugSec.getValue());
|
||
|
OS << right_justify(NumBytes, SizeColWidth) << " ("
|
||
|
<< format("%0.2f", DebugSec.getValue() /
|
||
|
static_cast<double>(Sizes.TotalObjectSize) * 100)
|
||
|
<< "%)\n";
|
||
|
}
|
||
|
|
||
|
OS << '\n';
|
||
|
OS << " Total Size: " << Sizes.TotalDebugSectionsSize << " ("
|
||
|
<< format("%0.2f", Sizes.TotalDebugSectionsSize /
|
||
|
static_cast<double>(Sizes.TotalObjectSize) * 100)
|
||
|
<< "%)\n";
|
||
|
OS << " Total File Size: " << Sizes.TotalObjectSize << '\n';
|
||
|
OS << "----------------------------------------------------" << '\n';
|
||
|
}
|
||
|
|
||
|
void dwarfdump::calculateSectionSizes(const ObjectFile &Obj,
|
||
|
SectionSizes &Sizes,
|
||
|
const Twine &Filename) {
|
||
|
// Get total size.
|
||
|
Sizes.TotalObjectSize = Obj.getData().size();
|
||
|
|
||
|
for (const SectionRef &Section : Obj.sections()) {
|
||
|
StringRef SectionName;
|
||
|
if (Expected<StringRef> NameOrErr = Section.getName())
|
||
|
SectionName = *NameOrErr;
|
||
|
else
|
||
|
WithColor::defaultWarningHandler(
|
||
|
createFileError(Filename, NameOrErr.takeError()));
|
||
|
|
||
|
LLVM_DEBUG(dbgs() << SectionName.str() << ": " << Section.getSize()
|
||
|
<< '\n');
|
||
|
|
||
|
if (!Section.isDebugSection(SectionName))
|
||
|
continue;
|
||
|
|
||
|
Sizes.TotalDebugSectionsSize += Section.getSize();
|
||
|
Sizes.DebugSectionSizes[SectionName] += Section.getSize();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
bool dwarfdump::collectObjectSectionSizes(ObjectFile &Obj,
|
||
|
DWARFContext & /*DICtx*/,
|
||
|
const Twine &Filename,
|
||
|
raw_ostream &OS) {
|
||
|
SectionSizes Sizes;
|
||
|
|
||
|
// Get the section sizes.
|
||
|
calculateSectionSizes(Obj, Sizes, Filename);
|
||
|
|
||
|
OS << "----------------------------------------------------\n";
|
||
|
OS << "file: " << Filename.str() << '\n';
|
||
|
|
||
|
prettyPrintSectionSizes(Obj, Sizes, OS);
|
||
|
|
||
|
// TODO: If the input file is an archive, print the cumulative summary of all
|
||
|
// files from the archive.
|
||
|
|
||
|
return true;
|
||
|
}
|