123 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			123 lines
		
	
	
		
			4.2 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 &It : Sizes.DebugSectionSizes)
 | 
						|
    Width = std::max(Width, It.first.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 &It : Sizes.DebugSectionSizes) {
 | 
						|
    size_t NumWidth = std::to_string(It.second).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 &It : Sizes.DebugSectionSizes) {
 | 
						|
    OS << left_justify(It.first, NameColWidth) << "  ";
 | 
						|
 | 
						|
    std::string NumBytes = std::to_string(It.second);
 | 
						|
    OS << right_justify(NumBytes, SizeColWidth) << " ("
 | 
						|
       << format("%0.2f",
 | 
						|
                 It.second / 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())
 | 
						|
      continue;
 | 
						|
 | 
						|
    Sizes.TotalDebugSectionsSize += Section.getSize();
 | 
						|
    Sizes.DebugSectionSizes[std::string(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;
 | 
						|
}
 |