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;
 | |
| }
 |