mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 12:41:49 +01:00
[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
This commit is contained in:
parent
f3f5e6c3a7
commit
b4201a6dd9
@ -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
|
||||
|
@ -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
|
||||
- ''
|
||||
...
|
@ -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
|
||||
- ''
|
||||
...
|
66
test/tools/llvm-dwarfdump/X86/section_sizes_archive.test
Normal file
66
test/tools/llvm-dwarfdump/X86/section_sizes_archive.test
Normal file
@ -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
|
43
test/tools/llvm-dwarfdump/X86/section_sizes_coff.test
Normal file
43
test/tools/llvm-dwarfdump/X86/section_sizes_coff.test
Normal file
@ -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:
|
||||
...
|
55
test/tools/llvm-dwarfdump/X86/section_sizes_elf.test
Normal file
55
test/tools/llvm-dwarfdump/X86/section_sizes_elf.test
Normal file
@ -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
|
31
test/tools/llvm-dwarfdump/X86/section_sizes_fat_binary.test
Normal file
31
test/tools/llvm-dwarfdump/X86/section_sizes_fat_binary.test
Normal file
@ -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:----------------------------------------------------
|
106
test/tools/llvm-dwarfdump/X86/section_sizes_macho.test
Normal file
106
test/tools/llvm-dwarfdump/X86/section_sizes_macho.test
Normal file
@ -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
|
||||
- ''
|
||||
...
|
@ -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
|
@ -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"
|
||||
|
@ -8,6 +8,7 @@ set(LLVM_LINK_COMPONENTS
|
||||
)
|
||||
|
||||
add_llvm_tool(llvm-dwarfdump
|
||||
SectionSizes.cpp
|
||||
Statistics.cpp
|
||||
llvm-dwarfdump.cpp
|
||||
)
|
||||
|
120
tools/llvm-dwarfdump/SectionSizes.cpp
Normal file
120
tools/llvm-dwarfdump/SectionSizes.cpp
Normal file
@ -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;
|
||||
}
|
38
tools/llvm-dwarfdump/SectionSizes.h
Normal file
38
tools/llvm-dwarfdump/SectionSizes.h
Normal file
@ -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
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user