SectionSizes.cpp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  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-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. #include "llvm-dwarfdump.h"
  9. #define DEBUG_TYPE "dwarfdump"
  10. using namespace llvm;
  11. using namespace llvm::dwarfdump;
  12. using namespace llvm::object;
  13. static size_t getNameColumnWidth(const SectionSizes &Sizes,
  14. const StringRef SectionNameTitle) {
  15. // The minimum column width should be the size of "SECTION".
  16. size_t Width = SectionNameTitle.size();
  17. for (const auto &It : Sizes.DebugSectionSizes)
  18. Width = std::max(Width, It.first.size());
  19. return Width;
  20. }
  21. static size_t getSizeColumnWidth(const SectionSizes &Sizes,
  22. const StringRef SectionSizeTitle) {
  23. // The minimum column width should be the size of the column title.
  24. size_t Width = SectionSizeTitle.size();
  25. for (const auto &It : Sizes.DebugSectionSizes) {
  26. size_t NumWidth = std::to_string(It.second).size();
  27. Width = std::max(Width, NumWidth);
  28. }
  29. return Width;
  30. }
  31. static void prettyPrintSectionSizes(const ObjectFile &Obj,
  32. const SectionSizes &Sizes,
  33. raw_ostream &OS) {
  34. const StringRef SectionNameTitle = "SECTION";
  35. const StringRef SectionSizeTitle = "SIZE (b)";
  36. size_t NameColWidth = getNameColumnWidth(Sizes, SectionNameTitle);
  37. size_t SizeColWidth = getSizeColumnWidth(Sizes, SectionSizeTitle);
  38. OS << "----------------------------------------------------" << '\n';
  39. OS << SectionNameTitle;
  40. size_t SectionNameTitleWidth = SectionNameTitle.size();
  41. for (unsigned i = 0; i < (NameColWidth - SectionNameTitleWidth) + 2; i++)
  42. OS << " ";
  43. OS << SectionSizeTitle << '\n';
  44. for (unsigned i = 0; i < NameColWidth; i++)
  45. OS << "-";
  46. OS << " ";
  47. for (unsigned i = 0; i < SizeColWidth; i++)
  48. OS << "-";
  49. OS << '\n';
  50. for (const auto &It : Sizes.DebugSectionSizes) {
  51. OS << left_justify(It.first, NameColWidth) << " ";
  52. std::string NumBytes = std::to_string(It.second);
  53. OS << right_justify(NumBytes, SizeColWidth) << " ("
  54. << format("%0.2f",
  55. It.second / static_cast<double>(Sizes.TotalObjectSize) * 100)
  56. << "%)\n";
  57. }
  58. OS << '\n';
  59. OS << " Total Size: " << Sizes.TotalDebugSectionsSize << " ("
  60. << format("%0.2f", Sizes.TotalDebugSectionsSize /
  61. static_cast<double>(Sizes.TotalObjectSize) * 100)
  62. << "%)\n";
  63. OS << " Total File Size: " << Sizes.TotalObjectSize << '\n';
  64. OS << "----------------------------------------------------" << '\n';
  65. }
  66. void dwarfdump::calculateSectionSizes(const ObjectFile &Obj,
  67. SectionSizes &Sizes,
  68. const Twine &Filename) {
  69. // Get total size.
  70. Sizes.TotalObjectSize = Obj.getData().size();
  71. for (const SectionRef &Section : Obj.sections()) {
  72. StringRef SectionName;
  73. if (Expected<StringRef> NameOrErr = Section.getName())
  74. SectionName = *NameOrErr;
  75. else
  76. WithColor::defaultWarningHandler(
  77. createFileError(Filename, NameOrErr.takeError()));
  78. LLVM_DEBUG(dbgs() << SectionName.str() << ": " << Section.getSize()
  79. << '\n');
  80. if (!Section.isDebugSection())
  81. continue;
  82. Sizes.TotalDebugSectionsSize += Section.getSize();
  83. Sizes.DebugSectionSizes[std::string(SectionName)] += Section.getSize();
  84. }
  85. }
  86. bool dwarfdump::collectObjectSectionSizes(ObjectFile &Obj,
  87. DWARFContext & /*DICtx*/,
  88. const Twine &Filename,
  89. raw_ostream &OS) {
  90. SectionSizes Sizes;
  91. // Get the section sizes.
  92. calculateSectionSizes(Obj, Sizes, Filename);
  93. OS << "----------------------------------------------------\n";
  94. OS << "file: " << Filename.str() << '\n';
  95. prettyPrintSectionSizes(Obj, Sizes, OS);
  96. // TODO: If the input file is an archive, print the cumulative summary of all
  97. // files from the archive.
  98. return true;
  99. }