[llvm] 5e508b9 - [llvm-dwarfdump] Add the --show-sections-sizes option

Djordje Todorovic via llvm-commits llvm-commits at lists.llvm.org
Thu Apr 2 04:14:51 PDT 2020


Author: Djordje Todorovic
Date: 2020-04-02T13:14:30+02:00
New Revision: 5e508b9bac05cef8c1f77a154f943183f97cd131

URL: https://github.com/llvm/llvm-project/commit/5e508b9bac05cef8c1f77a154f943183f97cd131
DIFF: https://github.com/llvm/llvm-project/commit/5e508b9bac05cef8c1f77a154f943183f97cd131.diff

LOG: [llvm-dwarfdump] Add the --show-sections-sizes option

Add an option to llvm-dwarfdump to calculate the bytes within
the debug sections. Dump this numbers when using --statistics
option as well.

This is an initial patch (e.g. we should support other units,
since we only support 'bytes' now).

Differential Revision: https://reviews.llvm.org/D74205

Added: 
    llvm/test/tools/llvm-dwarfdump/X86/Inputs/i386_macho_with_debug.yaml
    llvm/test/tools/llvm-dwarfdump/X86/Inputs/x86_64_macho_with_debug.yaml
    llvm/test/tools/llvm-dwarfdump/X86/section_sizes_archive.test
    llvm/test/tools/llvm-dwarfdump/X86/section_sizes_coff.test
    llvm/test/tools/llvm-dwarfdump/X86/section_sizes_elf.test
    llvm/test/tools/llvm-dwarfdump/X86/section_sizes_fat_binary.test
    llvm/test/tools/llvm-dwarfdump/X86/section_sizes_macho.test
    llvm/test/tools/llvm-dwarfdump/X86/section_sizes_no_debug_sections.test
    llvm/tools/llvm-dwarfdump/SectionSizes.cpp
    llvm/tools/llvm-dwarfdump/SectionSizes.h

Modified: 
    llvm/docs/CommandGuide/llvm-dwarfdump.rst
    llvm/test/tools/llvm-dwarfdump/X86/statistics.ll
    llvm/tools/llvm-dwarfdump/CMakeLists.txt
    llvm/tools/llvm-dwarfdump/Statistics.cpp
    llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/docs/CommandGuide/llvm-dwarfdump.rst b/llvm/docs/CommandGuide/llvm-dwarfdump.rst
index b8de0847aaae..840c93345d29 100644
--- a/llvm/docs/CommandGuide/llvm-dwarfdump.rst
+++ b/llvm/docs/CommandGuide/llvm-dwarfdump.rst
@@ -105,6 +105,10 @@ OPTIONS
             When displaying debug info entries, only show children to a maximum
             depth of <N>.
 
+.. option:: --show-section-sizes
+
+            Show the sizes of all debug sections, expressed in bytes.
+
 .. option:: --statistics
 
             Collect debug info quality metrics and print the results

diff  --git a/llvm/test/tools/llvm-dwarfdump/X86/Inputs/i386_macho_with_debug.yaml b/llvm/test/tools/llvm-dwarfdump/X86/Inputs/i386_macho_with_debug.yaml
new file mode 100644
index 000000000000..ad03961b060e
--- /dev/null
+++ b/llvm/test/tools/llvm-dwarfdump/X86/Inputs/i386_macho_with_debug.yaml
@@ -0,0 +1,88 @@
+--- !mach-o
+FileHeader:
+  magic:           0xFEEDFACE
+  cputype:         0x00000007
+  cpusubtype:      0x00000003
+  filetype:        0x00000001
+  ncmds:           4
+  sizeofcmds:      312
+  flags:           0x00002000
+LoadCommands:
+  - cmd:             LC_SEGMENT
+    cmdsize:         192
+    segname:         ''
+    vmaddr:          0
+    vmsize:          72
+    fileoff:         340
+    filesize:        72
+    maxprot:         7
+    initprot:        7
+    nsects:          2
+    flags:           0
+    Sections:
+      - sectname:        __text
+        segname:         __TEXT
+        addr:            0x0000000000000000
+        size:            18
+        offset:          0x00000154
+        align:           4
+        reloff:          0x00000000
+        nreloc:          0
+        flags:           0x80000400
+        reserved1:       0x00000000
+        reserved2:       0x00000000
+        reserved3:       0x00000000
+      - sectname:        __debug_info
+        segname:         __DWARF
+        addr:            0x0000000000000014
+        size:            52
+        offset:          0x00000168
+        align:           2
+        reloff:          0x00000000
+        nreloc:          0
+        flags:           0x6800000B
+        reserved1:       0x00000000
+        reserved2:       0x00000000
+        reserved3:       0x00000000
+  - cmd:             LC_VERSION_MIN_MACOSX
+    cmdsize:         16
+    version:         656384
+    sdk:             0
+  - cmd:             LC_SYMTAB
+    cmdsize:         24
+    symoff:          412
+    nsyms:           1
+    stroff:          424
+    strsize:         8
+  - cmd:             LC_DYSYMTAB
+    cmdsize:         80
+    ilocalsym:       0
+    nlocalsym:       0
+    iextdefsym:      0
+    nextdefsym:      1
+    iundefsym:       1
+    nundefsym:       0
+    tocoff:          0
+    ntoc:            0
+    modtaboff:       0
+    nmodtab:         0
+    extrefsymoff:    0
+    nextrefsyms:     0
+    indirectsymoff:  0
+    nindirectsyms:   0
+    extreloff:       0
+    nextrel:         0
+    locreloff:       0
+    nlocrel:         0
+LinkEditData:
+  NameList:
+    - n_strx:          1
+      n_type:          0x0F
+      n_sect:          1
+      n_desc:          0
+      n_value:         0
+  StringTable:
+    - ''
+    - _main
+    - ''
+...

diff  --git a/llvm/test/tools/llvm-dwarfdump/X86/Inputs/x86_64_macho_with_debug.yaml b/llvm/test/tools/llvm-dwarfdump/X86/Inputs/x86_64_macho_with_debug.yaml
new file mode 100644
index 000000000000..9333794939be
--- /dev/null
+++ b/llvm/test/tools/llvm-dwarfdump/X86/Inputs/x86_64_macho_with_debug.yaml
@@ -0,0 +1,89 @@
+--- !mach-o
+FileHeader:
+  magic:           0xFEEDFACF
+  cputype:         0x01000007
+  cpusubtype:      0x00000003
+  filetype:        0x00000001
+  ncmds:           4
+  sizeofcmds:      352
+  flags:           0x00002000
+  reserved:        0x00000000
+LoadCommands:
+  - cmd:             LC_SEGMENT_64
+    cmdsize:         232
+    segname:         ''
+    vmaddr:          0
+    vmsize:          80
+    fileoff:         384
+    filesize:        80
+    maxprot:         7
+    initprot:        7
+    nsects:          2
+    flags:           0
+    Sections:
+      - sectname:        __text
+        segname:         __TEXT
+        addr:            0x0000000000000000
+        size:            15
+        offset:          0x00000180
+        align:           4
+        reloff:          0x00000000
+        nreloc:          0
+        flags:           0x80000400
+        reserved1:       0x00000000
+        reserved2:       0x00000000
+        reserved3:       0x00000000
+      - sectname:        __debug_info
+        segname:         __DWARF
+        addr:            0x0000000000000010
+        size:            64
+        offset:          0x00000190
+        align:           3
+        reloff:          0x00000000
+        nreloc:          0
+        flags:           0x6800000B
+        reserved1:       0x00000000
+        reserved2:       0x00000000
+        reserved3:       0x00000000
+  - cmd:             LC_VERSION_MIN_MACOSX
+    cmdsize:         16
+    version:         656384
+    sdk:             0
+  - cmd:             LC_SYMTAB
+    cmdsize:         24
+    symoff:          464
+    nsyms:           1
+    stroff:          480
+    strsize:         8
+  - cmd:             LC_DYSYMTAB
+    cmdsize:         80
+    ilocalsym:       0
+    nlocalsym:       0
+    iextdefsym:      0
+    nextdefsym:      1
+    iundefsym:       1
+    nundefsym:       0
+    tocoff:          0
+    ntoc:            0
+    modtaboff:       0
+    nmodtab:         0
+    extrefsymoff:    0
+    nextrefsyms:     0
+    indirectsymoff:  0
+    nindirectsyms:   0
+    extreloff:       0
+    nextrel:         0
+    locreloff:       0
+    nlocrel:         0
+LinkEditData:
+  NameList:
+    - n_strx:          1
+      n_type:          0x0F
+      n_sect:          1
+      n_desc:          0
+      n_value:         0
+  StringTable:
+    - ''
+    - _main
+    - ''
+...

diff  --git a/llvm/test/tools/llvm-dwarfdump/X86/section_sizes_archive.test b/llvm/test/tools/llvm-dwarfdump/X86/section_sizes_archive.test
new file mode 100644
index 000000000000..7280046043a2
--- /dev/null
+++ b/llvm/test/tools/llvm-dwarfdump/X86/section_sizes_archive.test
@@ -0,0 +1,66 @@
+## Check how llvm-dwarfdump calculates section sizes
+## with --show-section-sizes on an archive.
+
+# RUN: rm -rf %t && mkdir -p %t
+# RUN: yaml2obj --docnum=1 %s -o %t/1.o
+# RUN: yaml2obj --docnum=2 %s -o %t/2.o
+
+# RUN: rm -f %t.a
+# RUN: llvm-ar rc %t.a %t/1.o %t/2.o
+
+# RUN: llvm-dwarfdump --show-section-sizes %t.a \
+# RUN:    | FileCheck %s -DARCHIVE=%t.a --match-full-lines --strict-whitespace
+
+#      CHECK:----------------------------------------------------
+# CHECK-NEXT:file: [[ARCHIVE]](1.o)
+# CHECK-NEXT:----------------------------------------------------
+# CHECK-NEXT:SECTION      SIZE (b)
+# CHECK-NEXT:-----------  --------
+# CHECK-NEXT:.debug_info        17 (3.17%)
+# CHECK-NEXT:.debug_line        19 (3.54%)
+# CHECK-EMPTY:
+# CHECK-NEXT: Total Size: 36  (6.72%)
+# CHECK-NEXT: Total File Size: 536
+# CHECK-NEXT:----------------------------------------------------
+# CHECK-NEXT:----------------------------------------------------
+# CHECK-NEXT:file: [[ARCHIVE]](2.o)
+# CHECK-NEXT:----------------------------------------------------
+# CHECK-NEXT:SECTION      SIZE (b)
+# CHECK-NEXT:-----------  --------
+# CHECK-NEXT:.debug_loc          1 (0.20%)
+# CHECK-NEXT:.debug_line        13 (2.54%)
+# CHECK-EMPTY:
+# CHECK-NEXT: Total Size: 14  (2.73%)
+# CHECK-NEXT: Total File Size: 512
+# CHECK-NEXT:----------------------------------------------------
+
+--- !ELF
+FileHeader:
+  Class:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_X86_64
+Sections:
+- Name:    .text1
+  Type:    SHT_PROGBITS
+- Name: .debug_info
+  Type: SHT_PROGBITS
+  Size: 17
+- Name: .debug_line
+  Type: SHT_PROGBITS
+  Size: 19
+--- !ELF
+FileHeader:
+  Class:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_X86_64
+Sections:
+- Name:    .text2
+  Type:    SHT_PROGBITS
+- Name: .debug_loc
+  Type: SHT_PROGBITS
+  Size: 1
+- Name: .debug_line
+  Type: SHT_PROGBITS
+  Size: 13

diff  --git a/llvm/test/tools/llvm-dwarfdump/X86/section_sizes_coff.test b/llvm/test/tools/llvm-dwarfdump/X86/section_sizes_coff.test
new file mode 100644
index 000000000000..7d72e02b946d
--- /dev/null
+++ b/llvm/test/tools/llvm-dwarfdump/X86/section_sizes_coff.test
@@ -0,0 +1,43 @@
+## Check how llvm-dwarfdump calculates section sizes
+## with --show-section-sizes for COFF objects.
+
+# RUN: yaml2obj %s | llvm-dwarfdump - --show-section-sizes \
+# RUN:   | FileCheck %s --match-full-lines --strict-whitespace
+
+#      CHECK:----------------------------------------------------
+# CHECK-NEXT:file: {{.*}}
+# CHECK-NEXT:----------------------------------------------------
+# CHECK-NEXT:SECTION        SIZE (b)
+# CHECK-NEXT:-------------  --------
+# CHECK-NEXT:.debug_info           2 (0.70%)
+# CHECK-NEXT:.debug_abbrev         1 (0.35%)
+# CHECK-NEXT:.debug_str            1 (0.35%)
+# CHECK-EMPTY:
+# CHECK-NEXT: Total Size: 4  (1.40%)
+# CHECK-NEXT: Total File Size: 286
+# CHECK-NEXT:----------------------------------------------------
+
+--- !COFF
+header:
+  Machine:         IMAGE_FILE_MACHINE_AMD64
+sections:
+  - Name:            .bss
+    Characteristics: []
+    SectionData:     ''
+  - Name:            .debug_str
+    Characteristics: []
+    SectionData:     00
+  - Name:            .debug_abbrev
+    Characteristics: []
+    Alignment:       1
+    SectionData:     00
+  - Name:            .debug_info
+    Characteristics: []
+    SectionData:     1111
+## This is a debug section following the Mach-O naming style, and is used
+## to show that such sections are not included in the report.
+  - Name:            __debug_foo
+    Characteristics: []
+    SectionData:     00
+symbols:
+...

diff  --git a/llvm/test/tools/llvm-dwarfdump/X86/section_sizes_elf.test b/llvm/test/tools/llvm-dwarfdump/X86/section_sizes_elf.test
new file mode 100644
index 000000000000..ad1763faaa32
--- /dev/null
+++ b/llvm/test/tools/llvm-dwarfdump/X86/section_sizes_elf.test
@@ -0,0 +1,55 @@
+## Check how llvm-dwarfdump calculates section sizes
+## with --show-section-sizes for ELF objects.
+
+# RUN: yaml2obj %s | llvm-dwarfdump - --show-section-sizes \
+# RUN:   | FileCheck %s --match-full-lines --strict-whitespace
+
+#      CHECK:----------------------------------------------------
+# CHECK-NEXT:file: {{.*}}
+# CHECK-NEXT:----------------------------------------------------
+# CHECK-NEXT:SECTION          SIZE (b)
+# CHECK-NEXT:---------------  --------
+# CHECK-NEXT:.debug_info            17 (1.62%)
+# CHECK-NEXT:.debug_loc              1 (0.10%)
+# CHECK-NEXT:.debug_type            26 (2.48%)
+# CHECK-NEXT:.debug_foo            100 (9.54%)
+# CHECK-NEXT:.debug_info.dwo         9 (0.86%)
+# CHECK-NEXT:.debug_line            19 (1.81%)
+# CHECK-EMPTY:
+# CHECK-NEXT: Total Size: 172  (16.41%)
+# CHECK-NEXT: Total File Size: 1048
+# CHECK-NEXT:----------------------------------------------------
+
+--- !ELF
+FileHeader:
+  Class:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_X86_64
+Sections:
+  - Name: .debug_info
+    Type: SHT_PROGBITS
+    Size: 17
+  - Name: .debug_line
+    Type: SHT_PROGBITS
+    Size: 19
+  - Name: .debug_loc
+    Type: SHT_PROGBITS
+    Size: 1
+  - Name: .debug_type
+    Type: SHT_PROGBITS
+    Size: 13
+  - Name: .debug_type [1]
+    Type: SHT_PROGBITS
+    Size: 13
+  - Name: .debug_foo
+    Type: SHT_PROGBITS
+    Size: 100
+  - Name: .debug_info.dwo
+    Type: SHT_PROGBITS
+    Size: 9
+## This is a debug section following the Mach-O naming style, and is used
+## to show that such sections are not included in the report.
+  - Name: __debug_bar
+    Type: SHT_PROGBITS
+    Size: 1

diff  --git a/llvm/test/tools/llvm-dwarfdump/X86/section_sizes_fat_binary.test b/llvm/test/tools/llvm-dwarfdump/X86/section_sizes_fat_binary.test
new file mode 100644
index 000000000000..d0b8c43a0f4c
--- /dev/null
+++ b/llvm/test/tools/llvm-dwarfdump/X86/section_sizes_fat_binary.test
@@ -0,0 +1,31 @@
+## Check how llvm-dwarfdump calculates section sizes
+## with --show-section-sizes on a fat binary.
+
+# RUN: yaml2obj %p/Inputs/i386_macho_with_debug.yaml -o %t-i386.o
+# RUN: yaml2obj %p/Inputs/x86_64_macho_with_debug.yaml -o %t-x86_64.o
+
+# RUN: llvm-lipo %t-i386.o %t-x86_64.o -create -output %t.o
+
+# RUN: llvm-dwarfdump --show-section-sizes %t.o \
+# RUN:    | FileCheck %s -DFILE=%t.o --match-full-lines --strict-whitespace
+
+#      CHECK:----------------------------------------------------
+# CHECK-NEXT:file: [[FILE]](i386)
+# CHECK-NEXT:----------------------------------------------------
+# CHECK-NEXT:SECTION       SIZE (b)
+# CHECK-NEXT:------------  --------
+# CHECK-NEXT:__debug_info        52 (12.04%)
+# CHECK-EMPTY:
+# CHECK-NEXT: Total Size: 52  (12.04%)
+# CHECK-NEXT: Total File Size: 432
+# CHECK-NEXT:----------------------------------------------------
+# CHECK-NEXT:----------------------------------------------------
+# CHECK-NEXT:file: [[FILE]](x86_64)
+# CHECK-NEXT:----------------------------------------------------
+# CHECK-NEXT:SECTION       SIZE (b)
+# CHECK-NEXT:------------  --------
+# CHECK-NEXT:__debug_info        64 (13.11%)
+# CHECK-EMPTY:
+# CHECK-NEXT: Total Size: 64  (13.11%)
+# CHECK-NEXT: Total File Size: 488
+# CHECK-NEXT:----------------------------------------------------

diff  --git a/llvm/test/tools/llvm-dwarfdump/X86/section_sizes_macho.test b/llvm/test/tools/llvm-dwarfdump/X86/section_sizes_macho.test
new file mode 100644
index 000000000000..517416e4ca64
--- /dev/null
+++ b/llvm/test/tools/llvm-dwarfdump/X86/section_sizes_macho.test
@@ -0,0 +1,106 @@
+## Check how llvm-dwarfdump calculates section sizes
+## with --show-section-sizes for Mach-O objects.
+
+# RUN: yaml2obj %s | llvm-dwarfdump - --show-section-sizes \
+# RUN:   | FileCheck %s --match-full-lines --strict-whitespace
+
+#      CHECK:----------------------------------------------------
+# CHECK-NEXT:file: {{.*}}
+# CHECK-NEXT:----------------------------------------------------
+# CHECK-NEXT:SECTION       SIZE (b)
+# CHECK-NEXT:------------  --------
+# CHECK-NEXT:__debug_info         4 (0.93%)
+# CHECK-EMPTY:
+# CHECK-NEXT: Total Size: 4  (0.93%)
+# CHECK-NEXT: Total File Size: 432
+# CHECK-NEXT:----------------------------------------------------
+
+--- !mach-o
+FileHeader:
+  magic:           0xFEEDFACF
+  cputype:         0x01000007
+  cpusubtype:      0x00000003
+  filetype:        0x00000001
+  ncmds:           4
+  sizeofcmds:      360
+  flags:           0x00002000
+  reserved:        0x00000000
+LoadCommands:
+  - cmd:             LC_SEGMENT_64
+    cmdsize:         232
+    segname:         ''
+    vmaddr:          0
+    vmsize:          4
+    fileoff:         392
+    filesize:        0
+    maxprot:         7
+    initprot:        7
+    nsects:          2
+    flags:           0
+    Sections:
+## This is a debug section following the ELF naming style, and is used
+## to show that such sections are not included in the report.
+      - sectname:        .debug_line
+        segname:         __DWARF
+        addr:            0x0000000000000000
+        size:            0
+        offset:          0x00000188
+        align:           0
+        reloff:          0x00000000
+        nreloc:          0
+        flags:           0x80000000
+        reserved1:       0x00000000
+        reserved2:       0x00000000
+        reserved3:       0x00000000
+        content:         ''
+      - sectname:        __debug_info
+        segname:         __DWARF
+        addr:            0x0000000000000000
+        size:            4
+        offset:          0x00000000
+        align:           2
+        reloff:          0x00000000
+        nreloc:          0
+        flags:           0x00000001
+        reserved1:       0x00000000
+        reserved2:       0x00000000
+        reserved3:       0x00000000
+  - cmd:             LC_BUILD_VERSION
+    cmdsize:         24
+    platform:        1
+    minos:           658944
+    sdk:             658944
+    ntools:          0
+  - cmd:             LC_SYMTAB
+    cmdsize:         24
+    symoff:          392
+    nsyms:           2
+    stroff:          424
+    strsize:         8
+  - cmd:             LC_DYSYMTAB
+    cmdsize:         80
+    ilocalsym:       0
+    nlocalsym:       1
+    iextdefsym:      1
+    nextdefsym:      0
+    iundefsym:       1
+    nundefsym:       1
+    tocoff:          0
+    ntoc:            0
+    modtaboff:       0
+    nmodtab:         0
+    extrefsymoff:    0
+    nextrefsyms:     0
+    indirectsymoff:  0
+    nindirectsyms:   0
+    extreloff:       0
+    nextrel:         0
+    locreloff:       0
+    nlocrel:         0
+LinkEditData:
+  StringTable:
+    - ''
+    - _b
+    - _a
+    - ''
+...

diff  --git a/llvm/test/tools/llvm-dwarfdump/X86/section_sizes_no_debug_sections.test b/llvm/test/tools/llvm-dwarfdump/X86/section_sizes_no_debug_sections.test
new file mode 100644
index 000000000000..e272b1f64bde
--- /dev/null
+++ b/llvm/test/tools/llvm-dwarfdump/X86/section_sizes_no_debug_sections.test
@@ -0,0 +1,29 @@
+## Check how llvm-dwarfdump calculates section sizes with
+## --show-section-sizes in the case there isn't any debug section.
+
+# RUN: yaml2obj %s | llvm-dwarfdump - --show-section-sizes \
+# RUN:   | FileCheck %s --match-full-lines --strict-whitespace
+
+#      CHECK:----------------------------------------------------
+# CHECK-NEXT:file: {{.*}}
+# CHECK-NEXT:----------------------------------------------------
+# CHECK-NEXT:SECTION  SIZE (b)
+# CHECK-NEXT:-------  --------
+# CHECK-EMPTY:
+# CHECK-NEXT: Total Size: 0  (0.00%)
+# CHECK-NEXT: Total File Size: 456
+# CHECK-NEXT:----------------------------------------------------
+
+--- !ELF
+FileHeader:
+  Class:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_X86_64
+Sections:
+  - Name: .foo
+    Type: SHT_PROGBITS
+    Size: 17
+  - Name: .bar
+    Type: SHT_PROGBITS
+    Size: 19

diff  --git a/llvm/test/tools/llvm-dwarfdump/X86/statistics.ll b/llvm/test/tools/llvm-dwarfdump/X86/statistics.ll
index 1830e27837dd..aa4bcaf121a6 100644
--- a/llvm/test/tools/llvm-dwarfdump/X86/statistics.ll
+++ b/llvm/test/tools/llvm-dwarfdump/X86/statistics.ll
@@ -48,7 +48,11 @@
 ; CHECK: "scope bytes covered":
 ; CHECK: "total function size":[[FUNCSIZE:[0-9]+]]
 ; CHECK: "total inlined function size":[[INLINESIZE:[0-9]+]]
-
+; CHECK: "size of __debug_info":380
+; CHECK: "size of __debug_loc":35
+; CHECK: "size of __debug_abbrev":303
+; CHECK: "size of __debug_line":117
+; CHECK: "size of __debug_str":204
 
 ; ModuleID = '/tmp/quality.cpp'
 source_filename = "/tmp/quality.cpp"

diff  --git a/llvm/tools/llvm-dwarfdump/CMakeLists.txt b/llvm/tools/llvm-dwarfdump/CMakeLists.txt
index 77620e0faaf8..58d8114cbe79 100644
--- a/llvm/tools/llvm-dwarfdump/CMakeLists.txt
+++ b/llvm/tools/llvm-dwarfdump/CMakeLists.txt
@@ -8,6 +8,7 @@ set(LLVM_LINK_COMPONENTS
   )
 
 add_llvm_tool(llvm-dwarfdump
+  SectionSizes.cpp
   Statistics.cpp
   llvm-dwarfdump.cpp
   )

diff  --git a/llvm/tools/llvm-dwarfdump/SectionSizes.cpp b/llvm/tools/llvm-dwarfdump/SectionSizes.cpp
new file mode 100644
index 000000000000..21bbee57e19d
--- /dev/null
+++ b/llvm/tools/llvm-dwarfdump/SectionSizes.cpp
@@ -0,0 +1,120 @@
+//===-- 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 "SectionSizes.h"
+
+#define DEBUG_TYPE "dwarfdump"
+
+using namespace llvm;
+using namespace 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 &DebugSec : Sizes.DebugSectionSizes) {
+    StringRef SectionName = DebugSec.getKey();
+    Width = std::max(Width, SectionName.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 &DebugSec : Sizes.DebugSectionSizes) {
+    size_t NumWidth = std::to_string(DebugSec.getValue()).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 &DebugSec : Sizes.DebugSectionSizes) {
+    OS << left_justify(DebugSec.getKey(), NameColWidth) << "  ";
+
+    auto NumBytes = std::to_string(DebugSec.getValue());
+    OS << right_justify(NumBytes, SizeColWidth) << " ("
+       << format("%0.2f", DebugSec.getValue() /
+                              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 llvm::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(SectionName))
+      continue;
+
+    Sizes.TotalDebugSectionsSize += Section.getSize();
+    Sizes.DebugSectionSizes[SectionName] += Section.getSize();
+  }
+}
+
+bool 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;
+}

diff  --git a/llvm/tools/llvm-dwarfdump/SectionSizes.h b/llvm/tools/llvm-dwarfdump/SectionSizes.h
new file mode 100644
index 000000000000..1664b1a236d6
--- /dev/null
+++ b/llvm/tools/llvm-dwarfdump/SectionSizes.h
@@ -0,0 +1,38 @@
+//===- SectionSizes.h - Debug section sizes ---------------------*- 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
+//
+//===-----------------------------------------------------------------------===/
+
+#ifndef LLVM_TOOLS_SECTION_SIZES_H
+#define LLVM_TOOLS_SECTION_SIZES_H
+
+#include "llvm/DebugInfo/DIContext.h"
+#include "llvm/DebugInfo/DWARF/DWARFContext.h"
+#include "llvm/Object/ObjectFile.h"
+#include "llvm/Support/WithColor.h"
+
+namespace llvm {
+
+using SectionSizeMap = StringMap<uint64_t>;
+
+/// Holds cumulative section sizes for an object file.
+struct SectionSizes {
+  /// Map of .debug section names and their sizes across all such-named
+  /// sections.
+  SectionSizeMap DebugSectionSizes;
+  /// Total number of bytes of all sections.
+  uint64_t TotalObjectSize = 0;
+  /// Total number of bytes of all debug sections.
+  uint64_t TotalDebugSectionsSize = 0;
+};
+
+/// Calculate the section sizes.
+void calculateSectionSizes(const object::ObjectFile &Obj, SectionSizes &Sizes,
+                           const Twine &Filename);
+
+} // end namespace llvm
+
+#endif // LLVM_TOOLS_SECTION_SIZES_H

diff  --git a/llvm/tools/llvm-dwarfdump/Statistics.cpp b/llvm/tools/llvm-dwarfdump/Statistics.cpp
index 6ba6a7037136..ca94426519fd 100644
--- a/llvm/tools/llvm-dwarfdump/Statistics.cpp
+++ b/llvm/tools/llvm-dwarfdump/Statistics.cpp
@@ -15,6 +15,8 @@
 #include "llvm/Object/ObjectFile.h"
 #include "llvm/Support/JSON.h"
 
+#include "SectionSizes.h"
+
 #define DEBUG_TYPE "dwarfdump"
 using namespace llvm;
 using namespace object;
@@ -468,6 +470,7 @@ static void printDatum(raw_ostream &OS, const char *Key, json::Value Value) {
   OS << ",\"" << Key << "\":" << Value;
   LLVM_DEBUG(llvm::dbgs() << Key << ": " << Value << '\n');
 }
+
 static void printLocationStats(raw_ostream &OS,
                                const char *Key,
                                std::vector<unsigned> &LocationStats) {
@@ -491,6 +494,12 @@ static void printLocationStats(raw_ostream &OS,
   LLVM_DEBUG(llvm::dbgs() << Key << " with 100% of its scope covered: "
                           << LocationStats[NumOfCoverageCategories - 1]);
 }
+
+static void printSectionSizes(raw_ostream &OS, const SectionSizes &Sizes) {
+  for (const auto &DebugSec : Sizes.DebugSectionSizes)
+    OS << ",\"size of " << DebugSec.getKey() << "\":" << DebugSec.getValue();
+}
+
 /// \}
 
 /// Collect debug info quality metrics for an entire DIContext.
@@ -512,6 +521,10 @@ bool collectStatsForObjectFile(ObjectFile &Obj, DWARFContext &DICtx,
       collectStatsRecursive(CUDie, "/", "g", 0, 0, Statistics, GlobalStats,
                             LocStats);
 
+  /// Collect the sizes of debug sections.
+  SectionSizes Sizes;
+  calculateSectionSizes(Obj, Sizes, Filename);
+
   /// The version number should be increased every time the algorithm is changed
   /// (including bug fixes). New metrics may be added without increasing the
   /// version.
@@ -602,6 +615,7 @@ bool collectStatsForObjectFile(ObjectFile &Obj, DWARFContext &DICtx,
   printDatum(OS, "vars with binary location", VarWithLoc);
   printDatum(OS, "total variables procesed by location statistics",
              LocStats.NumVarParam);
+  printSectionSizes(OS, Sizes);
   printLocationStats(OS, "variables", LocStats.VarParamLocStats);
   printLocationStats(OS, "variables (excluding the debug entry values)",
                      LocStats.VarParamNonEntryValLocStats);

diff  --git a/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp b/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
index 28ede2ef5029..e559de1059cf 100644
--- a/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
+++ b/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
@@ -208,6 +208,11 @@ static cl::opt<bool>
     Statistics("statistics",
                cl::desc("Emit JSON-formatted debug info quality metrics."),
                cat(DwarfDumpCategory));
+static cl::opt<bool>
+    ShowSectionSizes("show-section-sizes",
+                     cl::desc("Show the sizes of all debug sections, "
+                              "expressed in bytes."),
+                     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 +418,9 @@ static bool lookup(ObjectFile &Obj, DWARFContext &DICtx, uint64_t Address,
 bool collectStatsForObjectFile(ObjectFile &Obj, DWARFContext &DICtx,
                                const Twine &Filename, raw_ostream &OS);
 
+bool collectObjectSectionSizes(ObjectFile &Obj, DWARFContext & /*DICtx*/,
+                               const Twine &Filename, raw_ostream &OS);
+
 static bool dumpObjectFile(ObjectFile &Obj, DWARFContext &DICtx,
                            const Twine &Filename, raw_ostream &OS) {
   logAllUnhandledErrors(DICtx.loadRegisterInfo(Obj), errs(),
@@ -635,12 +643,16 @@ int main(int argc, char **argv) {
           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 (ShowSectionSizes) {
+    for (auto Object : Objects)
+      handleFile(Object, collectObjectSectionSizes, OutputFile.os());
+  } else {
     for (auto Object : Objects)
       handleFile(Object, dumpObjectFile, OutputFile.os());
+  }
 
   return EXIT_SUCCESS;
 }


        


More information about the llvm-commits mailing list