[llvm-readobj] Display multiple function names for stack size entries

The current implementation of displaying .stack_size information
presumes that each entry represents a single function but this is not
always the case. For example with the use of ICF multiple functions can
be represented with the same code, meaning that the address found in a
.stack_size entry corresponds to multiple function symbols.
This change allows multiple function names to be displayed when
appropriate.

Differential Revision: https://reviews.llvm.org/D105884
This commit is contained in:
gbreynoo 2021-07-26 14:49:53 +01:00
parent 453349344b
commit 40ac5ec4fa
3 changed files with 139 additions and 83 deletions

View File

@ -11,7 +11,7 @@
# CHECK-NEXT: ]
# CHECK: StackSizes [
# CHECK-NEXT: Entry {
# CHECK-NEXT: Function: test
# CHECK-NEXT: Functions: [test]
# CHECK-NEXT: Size: 0x0
# CHECK-NEXT: }
# CHECK-NEXT: ]

View File

@ -6,7 +6,7 @@
# RUN: | FileCheck %s --check-prefix=RELOC-GNU --strict-whitespace --match-full-lines
# RUN: llvm-readobj --stack-sizes %t01 | FileCheck %s --check-prefix=RELOC-LLVM
# RELOC-GNU: Size Function
# RELOC-GNU: Size Functions
# RELOC-GNU-NEXT: 16 referenced_by_symbol_foo
# RELOC-GNU-NEXT: 32 referenced_via_section_bar
# RELOC-GNU-NEXT: 8 separate_text_section_baz
@ -14,15 +14,15 @@
# RELOC-LLVM: StackSizes [
# RELOC-LLVM-NEXT: Entry {
# RELOC-LLVM-NEXT: Function: referenced_by_symbol_foo
# RELOC-LLVM-NEXT: Functions: [referenced_by_symbol_foo]
# RELOC-LLVM-NEXT: Size: 0x10
# RELOC-LLVM-NEXT: }
# RELOC-LLVM-NEXT: Entry {
# RELOC-LLVM-NEXT: Function: referenced_via_section_bar
# RELOC-LLVM-NEXT: Functions: [referenced_via_section_bar]
# RELOC-LLVM-NEXT: Size: 0x20
# RELOC-LLVM-NEXT: }
# RELOC-LLVM-NEXT: Entry {
# RELOC-LLVM-NEXT: Function: separate_text_section_baz
# RELOC-LLVM-NEXT: Functions: [separate_text_section_baz]
# RELOC-LLVM-NEXT: Size: 0x8
# RELOC-LLVM-NEXT: }
# RELOC-LLVM-NEXT: ]
@ -105,7 +105,7 @@ Symbols:
# RUN: FileCheck %s -DFILE=%t01.broken.symtab --check-prefix=SYMTAB-LLVM --implicit-check-not=warning:
# SYMTAB-GNU: Stack Sizes:
# SYMTAB-GNU-NEXT: Size Function
# SYMTAB-GNU-NEXT: Size Functions
# SYMTAB-GNU-NEXT: warning: '[[FILE]]': unable to get the target of relocation with index 0 in SHT_RELA section with index 5: unable to read an entry with index 3 from SHT_SYMTAB section with index 7: section [index 7] has a sh_offset (0xffffeeee) + sh_size (0x78) that is greater than the file size (0x450)
# SYMTAB-GNU-NEXT: warning: '[[FILE]]': unable to read the symbol table: section [index 7] has a sh_offset (0xffffeeee) + sh_size (0x78) that is greater than the file size (0x450)
# SYMTAB-GNU-NEXT: warning: '[[FILE]]': could not identify function symbol for stack size entry in SHT_PROGBITS section with index 3
@ -121,18 +121,18 @@ Symbols:
# SYMTAB-LLVM-NEXT: warning: '[[FILE]]': unable to read the symbol table: section [index 7] has a sh_offset (0xffffeeee) + sh_size (0x78) that is greater than the file size (0x450)
# SYMTAB-LLVM-NEXT: warning: '[[FILE]]': could not identify function symbol for stack size entry in SHT_PROGBITS section with index 3
# SYMTAB-LLVM-NEXT: Entry {
# SYMTAB-LLVM-NEXT: Function: ?
# SYMTAB-LLVM-NEXT: Functions: [?]
# SYMTAB-LLVM-NEXT: Size: 0x10
# SYMTAB-LLVM-NEXT: }
# SYMTAB-LLVM-NEXT: warning: '[[FILE]]': unable to get the target of relocation with index 1 in SHT_RELA section with index 5: unable to read an entry with index 2 from SHT_SYMTAB section with index 7: section [index 7] has a sh_offset (0xffffeeee) + sh_size (0x78) that is greater than the file size (0x450)
# SYMTAB-LLVM-NEXT: Entry {
# SYMTAB-LLVM-NEXT: Function: ?
# SYMTAB-LLVM-NEXT: Functions: [?]
# SYMTAB-LLVM-NEXT: Size: 0x20
# SYMTAB-LLVM-NEXT: }
# SYMTAB-LLVM-NEXT: warning: '[[FILE]]': unable to get the target of relocation with index 0 in SHT_RELA section with index 6: unable to read an entry with index 1 from SHT_SYMTAB section with index 7: section [index 7] has a sh_offset (0xffffeeee) + sh_size (0x78) that is greater than the file size (0x450)
# SYMTAB-LLVM-NEXT: warning: '[[FILE]]': could not identify function symbol for stack size entry in SHT_PROGBITS section with index 4
# SYMTAB-LLVM-NEXT: Entry {
# SYMTAB-LLVM-NEXT: Function: ?
# SYMTAB-LLVM-NEXT: Functions: [?]
# SYMTAB-LLVM-NEXT: Size: 0x8
# SYMTAB-LLVM-NEXT: }
# SYMTAB-LLVM-NEXT: ]
@ -147,7 +147,7 @@ Symbols:
# RUN: FileCheck %s -DFILE=%t01.broken.sym --check-prefix=SYM-LLVM --implicit-check-not=warning:
# SYM-GNU: Stack Sizes:
# SYM-GNU-NEXT: Size Function
# SYM-GNU-NEXT: Size Functions
# SYM-GNU-NEXT: warning: '[[FILE]]': unable to get address of symbol 'separate_text_section_baz': invalid section index: 255
# SYM-GNU-NEXT: warning: '[[FILE]]': could not identify function symbol for stack size entry in SHT_PROGBITS section with index 3
# SYM-GNU-NEXT: 16 ?
@ -160,17 +160,17 @@ Symbols:
# SYM-LLVM-NEXT: warning: '[[FILE]]': unable to get address of symbol 'separate_text_section_baz': invalid section index: 255
# SYM-LLVM-NEXT: warning: '[[FILE]]': could not identify function symbol for stack size entry in SHT_PROGBITS section with index 3
# SYM-LLVM-NEXT: Entry {
# SYM-LLVM-NEXT: Function: ?
# SYM-LLVM-NEXT: Functions: [?]
# SYM-LLVM-NEXT: Size: 0x10
# SYM-LLVM-NEXT: }
# SYM-LLVM-NEXT: Entry {
# SYM-LLVM-NEXT: Function: ?
# SYM-LLVM-NEXT: Functions: [?]
# SYM-LLVM-NEXT: Size: 0x20
# SYM-LLVM-NEXT: }
# SYM-LLVM-NEXT: warning: '[[FILE]]': cannot identify the section for relocation symbol 'separate_text_section_baz': invalid section index: 255
# SYM-LLVM-NEXT: warning: '[[FILE]]': could not identify function symbol for stack size entry in SHT_PROGBITS section with index 4
# SYM-LLVM-NEXT: Entry {
# SYM-LLVM-NEXT: Function: ?
# SYM-LLVM-NEXT: Functions: [?]
# SYM-LLVM-NEXT: Size: 0x8
# SYM-LLVM-NEXT: }
# SYM-LLVM-NEXT: ]
@ -186,7 +186,7 @@ Symbols:
# RUN: llvm-readobj --stack-sizes %t02 2>&1 \
# RUN: | FileCheck %s --check-prefix=EXEC-LLVM --implicit-check-not=warning:
# EXEC-GNU: Size Function
# EXEC-GNU: Size Functions
# EXEC-GNU-NEXT: 16 other
# EXEC-GNU-NEXT: 32 other_end
# EXEC-GNU-NEXT: 48 bar
@ -194,15 +194,15 @@ Symbols:
# EXEC-LLVM: StackSizes [
# EXEC-LLVM-NEXT: Entry {
# EXEC-LLVM-NEXT: Function: other
# EXEC-LLVM-NEXT: Functions: [other]
# EXEC-LLVM-NEXT: Size: 0x10
# EXEC-LLVM-NEXT: }
# EXEC-LLVM-NEXT: Entry {
# EXEC-LLVM-NEXT: Function: other_end
# EXEC-LLVM-NEXT: Functions: [other_end]
# EXEC-LLVM-NEXT: Size: 0x20
# EXEC-LLVM-NEXT: }
# EXEC-LLVM-NEXT: Entry {
# EXEC-LLVM-NEXT: Function: bar
# EXEC-LLVM-NEXT: Functions: [bar]
# EXEC-LLVM-NEXT: Size: 0x30
# EXEC-LLVM-NEXT: }
# EXEC-LLVM-NEXT: ]
@ -242,18 +242,11 @@ Symbols:
Value: 0
Type: STT_FUNC
Binding: STB_GLOBAL
## If two symbols have the same value, the first is picked, regardless of
## the sh_link value of the .stack_sizes section.
- Name: other_end
Section: .text
Value: 0x10
Type: STT_FUNC
Binding: STB_GLOBAL
- Name: foo
Section: .text2
Value: 0x10
Type: STT_FUNC
Binding: STB_GLOBAL
- Name: bar
Section: .text2
Value: 0x20
@ -268,19 +261,19 @@ Symbols:
# RUN: llvm-readobj --stack-sizes %t03 2>&1 | FileCheck %s --check-prefix=SHORT-LLVM -DFILE=%t03
# SHORT-GNU: Stack Sizes:
# SHORT-GNU-NEXT: Size Function
# SHORT-GNU-NEXT: Size Functions
# SHORT-GNU-NEXT: 8 foo
# SHORT-GNU-NEXT: warning: '[[FILE]]': found invalid relocation offset (0x1) into SHT_PROGBITS section with index 2 while trying to extract a stack size entry
# SHORT-GNU-NEXT: 8 foo
# SHORT-LLVM: StackSizes [
# SHORT-LLVM-NEXT: Entry {
# SHORT-LLVM-NEXT: Function: foo
# SHORT-LLVM-NEXT: Functions: [foo]
# SHORT-LLVM-NEXT: Size: 0x8
# SHORT-LLVM-NEXT: }
# SHORT-LLVM-NEXT: warning: '[[FILE]]': found invalid relocation offset (0x1) into SHT_PROGBITS section with index 2 while trying to extract a stack size entry
# SHORT-LLVM-NEXT: Entry {
# SHORT-LLVM-NEXT: Function: foo
# SHORT-LLVM-NEXT: Functions: [foo]
# SHORT-LLVM-NEXT: Size: 0x8
# SHORT-LLVM-NEXT: }
# SHORT-LLVM-NEXT: ]
@ -336,12 +329,12 @@ Symbols:
# RUN: llvm-readelf --stack-sizes --demangle %t04 2>&1 | FileCheck %s --check-prefix=WRONGSECTION-DEMANGLE-ERR -DFILE=%t04
# RUN: llvm-readobj --stack-sizes --demangle %t04 2>&1 | FileCheck %s --check-prefix=WRONGSECTION-DEMANGLE-ERR -DFILE=%t04
# WRONGSECTION-GNU: Size Function
# WRONGSECTION-GNU: Size Functions
# WRONGSECTION-GNU-NEXT: 8 _Z3foof
# WRONGSECTION-LLVM: StackSizes [
# WRONGSECTION-LLVM-NEXT: Entry {
# WRONGSECTION-LLVM-NEXT: Function: _Z3foof
# WRONGSECTION-LLVM-NEXT: Functions: [_Z3foof]
# WRONGSECTION-LLVM-NEXT: Size: 0x8
# WRONGSECTION-LLVM-NEXT: }
# WRONGSECTION-LLVM-NEXT: ]
@ -390,7 +383,7 @@ Symbols:
# RUN: FileCheck %s --check-prefix=SUDDENEND-LLVM -DFILE=%t05
# SUDDENEND-GNU: Stack Sizes:
# SUDDENEND-GNU-NEXT: Size Function
# SUDDENEND-GNU-NEXT: Size Functions
# SUDDENEND-GNU-NEXT: 8 foo
# SUDDENEND-GNU-NEXT: warning: '[[FILE]]': SHT_PROGBITS section with index 2 ended while trying to extract a stack size entry
# SUDDENEND-GNU-NEXT: 8 foo
@ -398,12 +391,12 @@ Symbols:
# SUDDENEND-LLVM: StackSizes [
# SUDDENEND-LLVM-NEXT: Entry {
# SUDDENEND-LLVM-NEXT: Function: foo
# SUDDENEND-LLVM-NEXT: Functions: [foo]
# SUDDENEND-LLVM-NEXT: Size: 0x8
# SUDDENEND-LLVM-NEXT: }
# SUDDENEND-LLVM-NEXT: warning: '[[FILE]]': SHT_PROGBITS section with index 2 ended while trying to extract a stack size entry
# SUDDENEND-LLVM-NEXT: Entry {
# SUDDENEND-LLVM-NEXT: Function: foo
# SUDDENEND-LLVM-NEXT: Functions: [foo]
# SUDDENEND-LLVM-NEXT: Size: 0x8
# SUDDENEND-LLVM-NEXT: }
# SUDDENEND-LLVM-NEXT: warning: '[[FILE]]': SHT_PROGBITS section with index 3 ended while trying to extract a stack size entry
@ -486,7 +479,7 @@ Symbols:
# RUN: FileCheck %s -DFILE=%t07 --check-prefix=BADSECTION-OUT-LLVM --implicit-check-not=warning:
# BADSECTION-OUT-GNU: Stack Sizes:
# BADSECTION-OUT-GNU-NEXT: Size Function
# BADSECTION-OUT-GNU-NEXT: Size Functions
# BADSECTION-OUT-GNU-NEXT: warning: '[[FILE]]': cannot identify the section for relocation symbol '_Z3foof': invalid section index: 10
# BADSECTION-OUT-GNU-NEXT: warning: '[[FILE]]': unable to get address of symbol '_Z3foof': invalid section index: 10
# BADSECTION-OUT-GNU-NEXT: warning: '[[FILE]]': could not identify function symbol for stack size entry in SHT_PROGBITS section with index 2
@ -501,17 +494,17 @@ Symbols:
# BADSECTION-OUT-LLVM-NEXT: warning: '[[FILE]]': unable to get address of symbol '_Z3foof': invalid section index: 10
# BADSECTION-OUT-LLVM-NEXT: warning: '[[FILE]]': could not identify function symbol for stack size entry in SHT_PROGBITS section with index 2
# BADSECTION-OUT-LLVM-NEXT: Entry {
# BADSECTION-OUT-LLVM-NEXT: Function: ?
# BADSECTION-OUT-LLVM-NEXT: Functions: [?]
# BADSECTION-OUT-LLVM-NEXT: Size: 0x8
# BADSECTION-OUT-LLVM-NEXT: }
# BADSECTION-OUT-LLVM-NEXT: warning: '[[FILE]]': unable to get the target of relocation with index 1 in SHT_RELA section with index 3: unable to read an entry with index 255 from SHT_SYMTAB section with index 4: can't read an entry at 0x17e8: it goes past the end of the section (0x30)
# BADSECTION-OUT-LLVM-NEXT: Entry {
# BADSECTION-OUT-LLVM-NEXT: Function: ?
# BADSECTION-OUT-LLVM-NEXT: Functions: [?]
# BADSECTION-OUT-LLVM-NEXT: Size: 0x16
# BADSECTION-OUT-LLVM-NEXT: }
# BADSECTION-OUT-LLVM-NEXT: warning: '[[FILE]]': unable to get the target of relocation with index 2 in SHT_RELA section with index 3: unable to read an entry with index 255 from SHT_SYMTAB section with index 4: can't read an entry at 0x17e8: it goes past the end of the section (0x30)
# BADSECTION-OUT-LLVM-NEXT: Entry {
# BADSECTION-OUT-LLVM-NEXT: Function: ?
# BADSECTION-OUT-LLVM-NEXT: Functions: [?]
# BADSECTION-OUT-LLVM-NEXT: Size: 0x24
# BADSECTION-OUT-LLVM-NEXT: }
# BADSECTION-OUT-LLVM-NEXT: ]
@ -569,7 +562,7 @@ Symbols:
# RUN: llvm-readobj --stack-sizes %t08 2> %t08-llvm.err | FileCheck %s --check-prefix=NORELOCSECTION-OUT-LLVM
# RUN: FileCheck %s < %t08-llvm.err --check-prefix=NORELOCSECTION-ERR -DFILE=%t08
# NORELOCSECTION-OUT-GNU: Size Function
# NORELOCSECTION-OUT-GNU: Size Functions
# NORELOCSECTION-OUT-GNU-NOT: {{.}}
# NORELOCSECTION-OUT-LLVM: StackSizes [
@ -611,7 +604,7 @@ Sections:
# ARCHIVE:File: [[FILE]]({{.*01}})
# MULTIPLE-GNU:Stack Sizes:
# MULTIPLE-GNU-NEXT: Size Function
# MULTIPLE-GNU-NEXT: Size Functions
# MULTIPLE-GNU-NEXT: 16 referenced_by_symbol_foo
# MULTIPLE-GNU-NEXT: 32 referenced_via_section_bar
# MULTIPLE-GNU-NEXT: 8 separate_text_section_baz
@ -619,15 +612,15 @@ Sections:
# MULTIPLE-LLVM: StackSizes [
# MULTIPLE-LLVM-NEXT: Entry {
# MULTIPLE-LLVM-NEXT: Function: referenced_by_symbol_foo
# MULTIPLE-LLVM-NEXT: Functions: [referenced_by_symbol_foo]
# MULTIPLE-LLVM-NEXT: Size: 0x10
# MULTIPLE-LLVM-NEXT: }
# MULTIPLE-LLVM-NEXT: Entry {
# MULTIPLE-LLVM-NEXT: Function: referenced_via_section_bar
# MULTIPLE-LLVM-NEXT: Functions: [referenced_via_section_bar]
# MULTIPLE-LLVM-NEXT: Size: 0x20
# MULTIPLE-LLVM-NEXT: }
# MULTIPLE-LLVM-NEXT: Entry {
# MULTIPLE-LLVM-NEXT: Function: separate_text_section_baz
# MULTIPLE-LLVM-NEXT: Functions: [separate_text_section_baz]
# MULTIPLE-LLVM-NEXT: Size: 0x8
# MULTIPLE-LLVM-NEXT: }
# MULTIPLE-LLVM-NEXT: ]
@ -637,22 +630,22 @@ Sections:
# MULTIPLE-GNU-EMPTY:
# MULTIPLE-GNU-NEXT:Stack Sizes:
# MULTIPLE-GNU-NEXT: Size Function
# MULTIPLE-GNU-NEXT: Size Functions
# MULTIPLE-GNU-NEXT: 16 other
# MULTIPLE-GNU-NEXT: 32 other_end
# MULTIPLE-GNU-NEXT: 48 bar
# MULTIPLE-LLVM: StackSizes [
# MULTIPLE-LLVM-NEXT: Entry {
# MULTIPLE-LLVM-NEXT: Function: other
# MULTIPLE-LLVM-NEXT: Functions: [other]
# MULTIPLE-LLVM-NEXT: Size: 0x10
# MULTIPLE-LLVM-NEXT: }
# MULTIPLE-LLVM-NEXT: Entry {
# MULTIPLE-LLVM-NEXT: Function: other_end
# MULTIPLE-LLVM-NEXT: Functions: [other_end]
# MULTIPLE-LLVM-NEXT: Size: 0x20
# MULTIPLE-LLVM-NEXT: }
# MULTIPLE-LLVM-NEXT: Entry {
# MULTIPLE-LLVM-NEXT: Function: bar
# MULTIPLE-LLVM-NEXT: Functions: [bar]
# MULTIPLE-LLVM-NEXT: Size: 0x30
# MULTIPLE-LLVM-NEXT: }
# MULTIPLE-LLVM-NEXT: ]
@ -671,7 +664,7 @@ Sections:
# NONFUNCTIONSYM-LLVM: StackSizes [
# NONFUNCTIONSYM-LLVM-NEXT: Entry {
# NONFUNCTIONSYM-LLVM-NEXT: Function: ?
# NONFUNCTIONSYM-LLVM-NEXT: Functions: [?]
# NONFUNCTIONSYM-LLVM-NEXT: Size: 0x0
# NONFUNCTIONSYM-LLVM-NEXT: }
# NONFUNCTIONSYM-LLVM-NEXT: ]
@ -714,7 +707,7 @@ Symbols:
# RUN: llvm-readobj --stack-sizes %t15 2>&1 | FileCheck %s --check-prefix=UNSUPPRELOC-LLVM -DFILE=%t15
# UNSUPPRELOC-GNU: Stack Sizes:
# UNSUPPRELOC-GNU-NEXT: Size Function
# UNSUPPRELOC-GNU-NEXT: Size Functions
# UNSUPPRELOC-GNU-NEXT: warning: '[[FILE]]': SHT_RELA section with index 3 contains an unsupported relocation with index 0: R_X86_64_RELATIVE
# UNSUPPRELOC-GNU-NEXT: 0 foo
# UNSUPPRELOC-GNU-NEXT: warning: '[[FILE]]': SHT_RELA section with index 3 contains an unsupported relocation with index 2: R_X86_64_RELATIVE
@ -722,7 +715,7 @@ Symbols:
# UNSUPPRELOC-LLVM: StackSizes [
# UNSUPPRELOC-LLVM-NEXT: warning: '[[FILE]]': SHT_RELA section with index 3 contains an unsupported relocation with index 0: R_X86_64_RELATIVE
# UNSUPPRELOC-LLVM-NEXT: Entry {
# UNSUPPRELOC-LLVM-NEXT: Function: foo
# UNSUPPRELOC-LLVM-NEXT: Functions: [foo]
# UNSUPPRELOC-LLVM-NEXT: Size: 0x0
# UNSUPPRELOC-LLVM-NEXT: }
# UNSUPPRELOC-LLVM-NEXT: warning: '[[FILE]]': SHT_RELA section with index 3 contains an unsupported relocation with index 2: R_X86_64_RELATIVE
@ -773,12 +766,12 @@ Symbols:
# ARCHIVEWARN-GNU:File: [[FILE]]({{.*04}})
# ARCHIVEWARN-GNU:Stack Sizes:
# ARCHIVEWARN-GNU-NEXT: Size Function
# ARCHIVEWARN-GNU-NEXT: Size Functions
# ARCHIVEWARN-GNU:{{.*}}: warning: '{{.*04}}': relocation symbol '_Z3foof' is not in the expected section
# ARCHIVEWARN-GNU: 8 _Z3foof
# ARCHIVEWARN-GNU:File: [[FILE]]({{.*01}})
# ARCHIVEWARN-GNU:Stack Sizes:
# ARCHIVEWARN-GNU-NEXT: Size Function
# ARCHIVEWARN-GNU-NEXT: Size Functions
# ARCHIVEWARN-GNU-NEXT: 16 referenced_by_symbol_foo
# ARCHIVEWARN-GNU-NEXT: 32 referenced_via_section_bar
# ARCHIVEWARN-GNU-NEXT: 8 separate_text_section_baz
@ -789,22 +782,22 @@ Symbols:
# ARCHIVEWARN-LLVM: StackSizes [
# ARCHIVEWARN-LLVM: warning: '{{.*04}}': relocation symbol '_Z3foof' is not in the expected section
# ARCHIVEWARN-LLVM-NEXT: Entry {
# ARCHIVEWARN-LLVM-NEXT: Function: _Z3foof
# ARCHIVEWARN-LLVM-NEXT: Functions: [_Z3foof]
# ARCHIVEWARN-LLVM-NEXT: Size: 0x8
# ARCHIVEWARN-LLVM-NEXT: }
# ARCHIVEWARN-LLVM-NEXT: ]
# ARCHIVEWARN-LLVM: File: [[FILE]]({{.*01}})
# ARCHIVEWARN-LLVM: StackSizes [
# ARCHIVEWARN-LLVM-NEXT: Entry {
# ARCHIVEWARN-LLVM-NEXT: Function: referenced_by_symbol_foo
# ARCHIVEWARN-LLVM-NEXT: Functions: [referenced_by_symbol_foo]
# ARCHIVEWARN-LLVM-NEXT: Size: 0x10
# ARCHIVEWARN-LLVM-NEXT: }
# ARCHIVEWARN-LLVM-NEXT: Entry {
# ARCHIVEWARN-LLVM-NEXT: Function: referenced_via_section_bar
# ARCHIVEWARN-LLVM-NEXT: Functions: [referenced_via_section_bar]
# ARCHIVEWARN-LLVM-NEXT: Size: 0x20
# ARCHIVEWARN-LLVM-NEXT: }
# ARCHIVEWARN-LLVM-NEXT: Entry {
# ARCHIVEWARN-LLVM-NEXT: Function: separate_text_section_baz
# ARCHIVEWARN-LLVM-NEXT: Functions: [separate_text_section_baz]
# ARCHIVEWARN-LLVM-NEXT: Size: 0x8
# ARCHIVEWARN-LLVM-NEXT: }
# ARCHIVEWARN-LLVM-NEXT: ]
@ -816,7 +809,7 @@ Symbols:
# RUN: llvm-readobj --stack-sizes --demangle %t16 | FileCheck %s --check-prefix=DEMANGLE-LLVM
# DEMANGLE-GNU: 16 foo(float)
# DEMANGLE-LLVM: Function: foo(float)
# DEMANGLE-LLVM: Functions: [foo(float)]
--- !ELF
FileHeader:
@ -896,3 +889,53 @@ Sections:
Link: 0
Info: 0xFF
Relocations: []
## Check that that we see multiple symbols output in cases when multiple symbols
## share the same stack size entry, for example when use of ICF means two functions
## are represented by the same code.
# RUN: yaml2obj --docnum=14 %s -o %t19
# RUN: llvm-readelf --stack-sizes %t19 2>&1 \
# RUN: | FileCheck %s --check-prefix=MULTIPLE-SYMBOLS-GNU
# RUN: llvm-readobj --stack-sizes %t19 2>&1 \
# RUN: | FileCheck %s --check-prefix=MULTIPLE-SYMBOLS-LLVM
# MULTIPLE-SYMBOLS-GNU: Size Functions
# MULTIPLE-SYMBOLS-GNU: 16 foo, bar
# MULTIPLE-SYMBOLS-GNU-NOT:{{.}}
# MULTIPLE-SYMBOLS-LLVM: StackSizes [
# MULTIPLE-SYMBOLS-LLVM-NEXT: Entry {
# MULTIPLE-SYMBOLS-LLVM-NEXT: Functions: [foo, bar]
# MULTIPLE-SYMBOLS-LLVM-NEXT: Size: 0x10
# MULTIPLE-SYMBOLS-LLVM-NEXT: }
# MULTIPLE-SYMBOLS-LLVM-NEXT: ]
# MULTIPLE-SYMBOLS-LLVM-NOT:{{.}}
--- !ELF
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_EXEC
Sections:
- Name: .text
Type: SHT_PROGBITS
Flags: [SHF_ALLOC]
Size: 16
- Name: .stack_sizes
Type: SHT_PROGBITS
Entries:
- Address: 0x0
Size: 0x10
Link: .text
Symbols:
- Name: foo
Section: .text
Value: 0x0
Type: STT_FUNC
Binding: STB_GLOBAL
- Name: bar
Section: .text
Value: 0x0
Type: STT_FUNC
Binding: STB_GLOBAL

View File

@ -302,9 +302,9 @@ protected:
// symbol's section with FunctionSec when specified.
// Returns None if no function symbol can be found for the address or in case
// it is not defined in the specified section.
Optional<uint32_t>
getSymbolIndexForFunctionAddress(uint64_t SymValue,
Optional<const Elf_Shdr *> FunctionSec);
SmallVector<uint32_t>
getSymbolIndexesForFunctionAddress(uint64_t SymValue,
Optional<const Elf_Shdr *> FunctionSec);
bool printFunctionStackSize(uint64_t SymValue,
Optional<const Elf_Shdr *> FunctionSec,
const Elf_Shdr &StackSizeSec, DataExtractor Data,
@ -313,7 +313,8 @@ protected:
unsigned Ndx, const Elf_Shdr *SymTab,
const Elf_Shdr *FunctionSec, const Elf_Shdr &StackSizeSec,
const RelocationResolver &Resolver, DataExtractor Data);
virtual void printStackSizeEntry(uint64_t Size, StringRef FuncName) = 0;
virtual void printStackSizeEntry(uint64_t Size,
ArrayRef<std::string> FuncNames) = 0;
void printRelocatableStackSizes(std::function<void()> PrintHeader);
void printNonRelocatableStackSizes(std::function<void()> PrintHeader);
@ -645,7 +646,8 @@ private:
void printGNUVersionSectionProlog(const typename ELFT::Shdr &Sec,
const Twine &Label, unsigned EntriesNum);
void printStackSizeEntry(uint64_t Size, StringRef FuncName) override;
void printStackSizeEntry(uint64_t Size,
ArrayRef<std::string> FuncNames) override;
void printMipsGOT(const MipsGOTParser<ELFT> &Parser) override;
void printMipsPLT(const MipsGOTParser<ELFT> &Parser) override;
@ -693,7 +695,8 @@ private:
bool /*NonVisibilityBitsUsed*/) const override;
void printProgramHeaders() override;
void printSectionMapping() override {}
void printStackSizeEntry(uint64_t Size, StringRef FuncName) override;
void printStackSizeEntry(uint64_t Size,
ArrayRef<std::string> FuncNames) override;
void printMipsGOT(const MipsGOTParser<ELFT> &Parser) override;
void printMipsPLT(const MipsGOTParser<ELFT> &Parser) override;
@ -5716,8 +5719,9 @@ template <class ELFT> void GNUELFDumper<ELFT>::printDependentLibs() {
}
template <class ELFT>
Optional<uint32_t> ELFDumper<ELFT>::getSymbolIndexForFunctionAddress(
SmallVector<uint32_t> ELFDumper<ELFT>::getSymbolIndexesForFunctionAddress(
uint64_t SymValue, Optional<const Elf_Shdr *> FunctionSec) {
SmallVector<uint32_t> SymbolIndexes;
if (!this->AddressToIndexMap.hasValue()) {
// Populate the address to index map upon the first invocation of this
// function.
@ -5738,7 +5742,7 @@ Optional<uint32_t> ELFDumper<ELFT>::getSymbolIndexForFunctionAddress(
std::string Name = this->getStaticSymbolName(Index);
reportUniqueWarning("unable to get address of symbol '" + Name +
"': " + toString(SymAddrOrErr.takeError()));
return None;
return SymbolIndexes;
}
(*this->AddressToIndexMap)[*SymAddrOrErr].push_back(Index);
@ -5752,7 +5756,7 @@ Optional<uint32_t> ELFDumper<ELFT>::getSymbolIndexForFunctionAddress(
auto Symbols = this->AddressToIndexMap->find(SymValue);
if (Symbols == this->AddressToIndexMap->end())
return None;
return SymbolIndexes;
for (uint32_t Index : Symbols->second) {
// Check if the symbol is in the right section. FunctionSec == None
@ -5770,28 +5774,26 @@ Optional<uint32_t> ELFDumper<ELFT>::getSymbolIndexForFunctionAddress(
// untested.
reportUniqueWarning("unable to get section of symbol '" + Name +
"': " + toString(SecOrErr.takeError()));
return None;
return SymbolIndexes;
}
}
return Index;
SymbolIndexes.push_back(Index);
}
return None;
return SymbolIndexes;
}
template <class ELFT>
bool ELFDumper<ELFT>::printFunctionStackSize(
uint64_t SymValue, Optional<const Elf_Shdr *> FunctionSec,
const Elf_Shdr &StackSizeSec, DataExtractor Data, uint64_t *Offset) {
Optional<uint32_t> FuncSymIndex =
this->getSymbolIndexForFunctionAddress(SymValue, FunctionSec);
std::string FuncName = "?";
if (!FuncSymIndex)
SmallVector<uint32_t> FuncSymIndexes =
this->getSymbolIndexesForFunctionAddress(SymValue, FunctionSec);
if (FuncSymIndexes.empty())
reportUniqueWarning(
"could not identify function symbol for stack size entry in " +
describe(StackSizeSec));
else
FuncName = this->getStaticSymbolName(*FuncSymIndex);
// Extract the size. The expectation is that Offset is pointing to the right
// place, i.e. past the function address.
@ -5803,17 +5805,27 @@ bool ELFDumper<ELFT>::printFunctionStackSize(
toString(std::move(Err)));
return false;
}
printStackSizeEntry(StackSize, FuncName);
if (FuncSymIndexes.empty()) {
printStackSizeEntry(StackSize, {"?"});
} else {
SmallVector<std::string> FuncSymNames;
for (uint32_t Index : FuncSymIndexes)
FuncSymNames.push_back(this->getStaticSymbolName(Index));
printStackSizeEntry(StackSize, FuncSymNames);
}
return true;
}
template <class ELFT>
void GNUELFDumper<ELFT>::printStackSizeEntry(uint64_t Size,
StringRef FuncName) {
ArrayRef<std::string> FuncNames) {
OS.PadToColumn(2);
OS << format_decimal(Size, 11);
OS.PadToColumn(18);
OS << FuncName << "\n";
OS << join(FuncNames.begin(), FuncNames.end(), ", ") << "\n";
}
template <class ELFT>
@ -6002,7 +6014,7 @@ void GNUELFDumper<ELFT>::printStackSizes() {
OS.PadToColumn(9);
OS << "Size";
OS.PadToColumn(18);
OS << "Function\n";
OS << "Functions\n";
HeaderHasBeenPrinted = true;
};
@ -6816,15 +6828,15 @@ template <class ELFT> void LLVMELFDumper<ELFT>::printBBAddrMaps() {
for (const Elf_BBAddrMap &AM : *BBAddrMapOrErr) {
DictScope D(W, "Function");
W.printHex("At", AM.Addr);
Optional<uint32_t> FuncSymIndex =
this->getSymbolIndexForFunctionAddress(AM.Addr, FunctionSec);
SmallVector<uint32_t> FuncSymIndex =
this->getSymbolIndexesForFunctionAddress(AM.Addr, FunctionSec);
std::string FuncName = "<?>";
if (FuncSymIndex == None)
if (FuncSymIndex.empty())
this->reportUniqueWarning(
"could not identify function symbol for address (0x" +
Twine::utohexstr(AM.Addr) + ") in " + this->describe(Sec));
else
FuncName = this->getStaticSymbolName(*FuncSymIndex);
FuncName = this->getStaticSymbolName(FuncSymIndex.front());
W.printString("Name", FuncName);
ListScope L(W, "BB entries");
@ -7040,9 +7052,10 @@ template <class ELFT> void LLVMELFDumper<ELFT>::printStackSizes() {
}
template <class ELFT>
void LLVMELFDumper<ELFT>::printStackSizeEntry(uint64_t Size, StringRef FuncName) {
void LLVMELFDumper<ELFT>::printStackSizeEntry(uint64_t Size,
ArrayRef<std::string> FuncNames) {
DictScope D(W, "Entry");
W.printString("Function", FuncName);
W.printList("Functions", FuncNames);
W.printHex("Size", Size);
}