Index: llvm/tools/llvm-dwarfdump/CMakeLists.txt
===================================================================
--- llvm/tools/llvm-dwarfdump/CMakeLists.txt
+++ llvm/tools/llvm-dwarfdump/CMakeLists.txt
@@ -9,6 +9,7 @@
 
 add_llvm_tool(llvm-dwarfdump
   Statistics.cpp
+  SectionsSizes.cpp
   llvm-dwarfdump.cpp
   )
 
Index: llvm/tools/llvm-dwarfdump/SectionsSizes.cpp
===================================================================
--- /dev/null
+++ llvm/tools/llvm-dwarfdump/SectionsSizes.cpp
@@ -0,0 +1,167 @@
+//===- SectionsSizes.cpp ---------------------------------------- *- C++ *-===//
+//
+// 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/DebugInfo/DIContext.h"
+#include "llvm/DebugInfo/DWARF/DWARFContext.h"
+#include "llvm/Object/ObjectFile.h"
+#include "llvm/Support/WithColor.h"
+
+#define DEBUG_TYPE "dwarfdump"
+using namespace llvm;
+using namespace object;
+
+/// Holds cumulative section sizes for an object file.
+struct SectionsSizes {
+  /// Total number of bytes of the object file.
+  /// This includes .text,.data, .bss and all .debug_* sections.
+  uint64_t TotalObjectSize = 0;
+  /// Total number of bytes of all .debug_* sections.
+  uint64_t TotalDebugSectionsSize = 0;
+  /// Total number of bytes of the .debug_info section.
+  uint64_t TotalDebugInfo = 0;
+  /// Total number of bytes of the .debug_str section.
+  uint64_t TotalDebugStr = 0;
+  /// Total number of bytes of the .debug_abbrev section.
+  uint64_t TotalDebugAbbrev = 0;
+  /// Total number of bytes of the .debug_line section.
+  uint64_t TotalDebugLine = 0;
+  /// Total number of bytes of the .debug_ranges section.
+  uint64_t TotalDebugRanges = 0;
+  /// Total number of bytes of the .debug_loc section.
+  uint64_t TotalDebugLoc = 0;
+};
+
+static void prettyPrintTheSecsSizes(const ObjectFile &Obj,
+                                    const SectionsSizes &Sizes,
+                                    raw_ostream &OS) {
+  OS << "----------------------------------------------------"
+     << "\n";
+  OS << "  SECTION \t\t"
+     << "    SIZE"
+     << "\n";
+  OS << "------------ \t\t  ------------\n";
+
+  OS << " .debug_info \t\t  " << Sizes.TotalDebugInfo << "\n";
+  OS << " .debug_str \t\t  " << Sizes.TotalDebugStr << "\n";
+  OS << " .debug_abbrev \t\t  " << Sizes.TotalDebugAbbrev << "\n";
+  OS << " .debug_line \t\t  " << Sizes.TotalDebugLine << "\n";
+  OS << " .debug_ranges \t\t  " << Sizes.TotalDebugRanges << "\n";
+  OS << " .debug_loc \t\t  " << Sizes.TotalDebugLoc << "\n\n";
+  OS << " .debug_*: \t\t  " << Sizes.TotalDebugSectionsSize << "\n";
+  OS << "----------------------------------------------------"
+     << "\n";
+  OS << " TOTAL: " << Sizes.TotalObjectSize << "\n";
+  OS << "----------------------------------------------------"
+     << "\n";
+}
+
+static bool isDebugInfo(StringRef SectionName) {
+  if (SectionName == ".debug_info")
+    return true;
+  return false;
+}
+
+static bool isDebugStr(StringRef SectionName) {
+  if (SectionName == ".debug_str")
+    return true;
+  return false;
+}
+
+static bool isDebugAbbrev(StringRef SectionName) {
+  if (SectionName == ".debug_abbrev")
+    return true;
+  return false;
+}
+
+static bool isDebugLine(StringRef SectionName) {
+  if (SectionName == ".debug_line")
+    return true;
+  return false;
+}
+
+static bool isDebugRanges(StringRef SectionName) {
+  if (SectionName == ".debug_ranges")
+    return true;
+  return false;
+}
+
+static bool isDebugLoc(StringRef SectionName) {
+  if (SectionName == ".debug_loc")
+    return true;
+  return false;
+}
+
+static bool isDebugSection(StringRef SectionName) {
+  if (isDebugInfo(SectionName) || isDebugStr(SectionName) ||
+      isDebugAbbrev(SectionName) || isDebugLine(SectionName) ||
+      isDebugRanges(SectionName) || isDebugLoc(SectionName))
+    return true;
+  return false;
+}
+
+static bool calculateSizes(const ObjectFile &Obj, SectionsSizes &Sizes) {
+  for (const SectionRef &Section : Obj.sections()) {
+    StringRef SectionName;
+    if (Expected<StringRef> NameOrErr = Section.getName()) {
+      SectionName = *NameOrErr;
+    } else {
+      consumeError(NameOrErr.takeError());
+      return false;
+    }
+
+    LLVM_DEBUG(dbgs() << SectionName.str() << ": " << Section.getSize());
+
+    if (Section.isBerkeleyText() || Section.isBerkeleyData() ||
+        Section.isBSS() || isDebugSection(SectionName))
+      Sizes.TotalObjectSize += Section.getSize();
+
+    if (isDebugSection(SectionName))
+      Sizes.TotalDebugSectionsSize += Section.getSize();
+
+    if (SectionName == ".debug_info") {
+      Sizes.TotalDebugInfo += Section.getSize();
+    } else if (SectionName == ".debug_str") {
+      Sizes.TotalDebugStr += Section.getSize();
+    } else if (SectionName == ".debug_abbrev") {
+      Sizes.TotalDebugAbbrev += Section.getSize();
+    } else if (SectionName == ".debug_line") {
+      Sizes.TotalDebugLine += Section.getSize();
+    } else if (SectionName == ".debug_ranges") {
+      Sizes.TotalDebugRanges += Section.getSize();
+    } else if (SectionName == ".debug_loc") {
+      Sizes.TotalDebugLoc += Section.getSize();
+    }
+  }
+
+  return true;
+}
+
+bool collectSecsSizesForObjectFile(ObjectFile &Obj, DWARFContext &DICtx,
+                                   Twine Filename, raw_ostream &OS) {
+  SectionsSizes Sizes;
+  if (!calculateSizes(Obj, Sizes)) {
+    WithColor::error() << " \n";
+    exit(1);
+  }
+
+  OS << "----------------------------------------------------"
+     << "\n";
+  OS << Filename.str() << ": file format " << Obj.getFileFormatName() << "\n";
+
+  uint64_t TotalCUs = 0;
+  for (const auto &CU : static_cast<DWARFContext *>(&DICtx)->compile_units()) {
+    (void)CU;
+    ++TotalCUs;
+  }
+
+  LLVM_DEBUG(dbgs() << "Total num of compile units: " << TotalCUs << "\n");
+
+  prettyPrintTheSecsSizes(Obj, Sizes, OS);
+
+  return true;
+}
Index: llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
===================================================================
--- llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
+++ llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
@@ -208,6 +208,10 @@
     Statistics("statistics",
                cl::desc("Emit JSON-formatted debug info quality metrics."),
                cat(DwarfDumpCategory));
+static cl::opt<bool>
+    ShowSecSizes("show-sections-sizes",
+                 cl::desc("Show the sizes of the .debug_* sections."),
+                 cat(DwarfDumpCategory));
 static opt<bool> Verify("verify", desc("Verify the DWARF debug info."),
                         cat(DwarfDumpCategory));
 static opt<bool> Quiet("quiet", desc("Use with -verify to not emit to STDOUT."),
@@ -413,6 +417,9 @@
 bool collectStatsForObjectFile(ObjectFile &Obj, DWARFContext &DICtx,
                                Twine Filename, raw_ostream &OS);
 
+bool collectSecsSizesForObjectFile(ObjectFile &Obj, DWARFContext &DICtx,
+                                   Twine Filename, raw_ostream &OS);
+
 static bool dumpObjectFile(ObjectFile &Obj, DWARFContext &DICtx, Twine Filename,
                            raw_ostream &OS) {
   logAllUnhandledErrors(DICtx.loadRegisterInfo(Obj), errs(),
@@ -635,12 +642,16 @@
           return handleFile(Object, verifyObjectFile, OutputFile.os());
         }))
       return 1;
-  } else if (Statistics)
+  } else if (Statistics) {
     for (auto Object : Objects)
       handleFile(Object, collectStatsForObjectFile, OutputFile.os());
-  else
+  } else if (ShowSecSizes) {
+    for (auto Object : Objects)
+      handleFile(Object, collectSecsSizesForObjectFile, OutputFile.os());
+  } else {
     for (auto Object : Objects)
       handleFile(Object, dumpObjectFile, OutputFile.os());
+  }
 
   return EXIT_SUCCESS;
 }