SectionSizes.cpp 4.3 KB

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