[llvm-branch-commits] [llvm] [llvm-readobj][ELF] Print the relocation of each --stack-sizes entry (PR #232332)
Prabhu Rajasekaran via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Thu Oct 15 06:59:08 PDT 2026
https://github.com/Prabhuk updated https://github.com/llvm/llvm-project/pull/232332
>From 865b06eacda0db0a6264aa1f5a80a20891464b91 Mon Sep 17 00:00:00 2001
From: prabhukr <prabhukr at google.com>
Date: Thu, 15 Oct 2026 06:57:12 -0700
Subject: [PATCH] [llvm-readobj][ELF] Print the relocation of each
--stack-sizes entry
In a relocatable file, print the relocation that applies to each
.stack_sizes entry as a Relocation object in the LLVM and JSON output,
with the same fields as in --call-graph-info. The code that prints the
object is shared with --call-graph-info, so the addend of a SHT_REL
relocation is again the value stored in the address field.
Assisted-by: Gemini
---
.../tools/llvm-readobj/ELF/stack-sizes.test | 138 +++++++++++++++++-
llvm/tools/llvm-readobj/ELFDumper.cpp | 105 ++++++++-----
2 files changed, 207 insertions(+), 36 deletions(-)
diff --git a/llvm/test/tools/llvm-readobj/ELF/stack-sizes.test b/llvm/test/tools/llvm-readobj/ELF/stack-sizes.test
index c9c5fd52142ea..15225bf8c445b 100644
--- a/llvm/test/tools/llvm-readobj/ELF/stack-sizes.test
+++ b/llvm/test/tools/llvm-readobj/ELF/stack-sizes.test
@@ -1,10 +1,13 @@
## Check that we correctly display the contents of the .stack_sizes section
-## in a relocatable object file.
+## in a relocatable object file, with the relocation for each function in the
+## LLVM and JSON output.
# RUN: yaml2obj --docnum=1 %s -o %t01
# RUN: llvm-readelf --stack-sizes %t01 \
# RUN: | FileCheck %s --check-prefix=RELOC-GNU --strict-whitespace --match-full-lines
# RUN: llvm-readobj --stack-sizes %t01 | FileCheck %s --check-prefix=RELOC-LLVM
+# RUN: llvm-readobj --elf-output-style=JSON --pretty-print --stack-sizes %t01 \
+# RUN: | FileCheck %s --check-prefix=RELOC-JSON
# RELOC-GNU: Size Functions
# RELOC-GNU-NEXT: 16 referenced_by_symbol_foo
@@ -15,18 +18,45 @@
# RELOC-LLVM: StackSizes [
# RELOC-LLVM-NEXT: Entry {
# RELOC-LLVM-NEXT: Functions: [referenced_by_symbol_foo]
+# RELOC-LLVM-NEXT: Relocation {
+# RELOC-LLVM-NEXT: SymbolIndex: 3{{$}}
+# RELOC-LLVM-NEXT: SymbolName: referenced_by_symbol_foo
+# RELOC-LLVM-NEXT: }
# RELOC-LLVM-NEXT: Size: 0x10
# RELOC-LLVM-NEXT: }
# RELOC-LLVM-NEXT: Entry {
# RELOC-LLVM-NEXT: Functions: [referenced_via_section_bar]
+# RELOC-LLVM-NEXT: Relocation {
+# RELOC-LLVM-NEXT: SymbolIndex: 2{{$}}
+# RELOC-LLVM-NEXT: SymbolName: .text
+# RELOC-LLVM-NEXT: Addend: 16{{$}}
+# RELOC-LLVM-NEXT: }
# RELOC-LLVM-NEXT: Size: 0x20
# RELOC-LLVM-NEXT: }
# RELOC-LLVM-NEXT: Entry {
# RELOC-LLVM-NEXT: Functions: [separate_text_section_baz]
+# RELOC-LLVM-NEXT: Relocation {
+# RELOC-LLVM-NEXT: SymbolIndex: 1{{$}}
+# RELOC-LLVM-NEXT: SymbolName: separate_text_section_baz
+# RELOC-LLVM-NEXT: }
# RELOC-LLVM-NEXT: Size: 0x8
# RELOC-LLVM-NEXT: }
# RELOC-LLVM-NEXT: ]
+# RELOC-JSON: "StackSizes": [
+# RELOC-JSON-NEXT: {
+# RELOC-JSON-NEXT: "Entry": {
+# RELOC-JSON-NEXT: "Functions": [
+# RELOC-JSON-NEXT: "referenced_by_symbol_foo"
+# RELOC-JSON-NEXT: ],
+# RELOC-JSON-NEXT: "Relocation": {
+# RELOC-JSON-NEXT: "SymbolIndex": 3,
+# RELOC-JSON-NEXT: "SymbolName": "referenced_by_symbol_foo"
+# RELOC-JSON-NEXT: },
+# RELOC-JSON-NEXT: "Size": 16
+# RELOC-JSON-NEXT: }
+# RELOC-JSON-NEXT: },
+
--- !ELF
FileHeader:
Class: ELFCLASS64
@@ -122,17 +152,27 @@ Symbols:
# 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: Functions: [?]
+# SYMTAB-LLVM-NEXT: Relocation {
+# SYMTAB-LLVM-NEXT: SymbolIndex: 3{{$}}
+# SYMTAB-LLVM-NEXT: }
# 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: Functions: [?]
+# SYMTAB-LLVM-NEXT: Relocation {
+# SYMTAB-LLVM-NEXT: SymbolIndex: 2{{$}}
+# SYMTAB-LLVM-NEXT: Addend: 16{{$}}
+# SYMTAB-LLVM-NEXT: }
# 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: Functions: [?]
+# SYMTAB-LLVM-NEXT: Relocation {
+# SYMTAB-LLVM-NEXT: SymbolIndex: 1{{$}}
+# SYMTAB-LLVM-NEXT: }
# SYMTAB-LLVM-NEXT: Size: 0x8
# SYMTAB-LLVM-NEXT: }
# SYMTAB-LLVM-NEXT: ]
@@ -161,16 +201,29 @@ Symbols:
# 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: Functions: [?]
+# SYM-LLVM-NEXT: Relocation {
+# SYM-LLVM-NEXT: SymbolIndex: 3{{$}}
+# SYM-LLVM-NEXT: SymbolName: referenced_by_symbol_foo
+# SYM-LLVM-NEXT: }
# SYM-LLVM-NEXT: Size: 0x10
# SYM-LLVM-NEXT: }
# SYM-LLVM-NEXT: Entry {
# SYM-LLVM-NEXT: Functions: [?]
+# SYM-LLVM-NEXT: Relocation {
+# SYM-LLVM-NEXT: SymbolIndex: 2{{$}}
+# SYM-LLVM-NEXT: SymbolName: .text
+# SYM-LLVM-NEXT: Addend: 16{{$}}
+# SYM-LLVM-NEXT: }
# 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: Functions: [?]
+# SYM-LLVM-NEXT: Relocation {
+# SYM-LLVM-NEXT: SymbolIndex: 1{{$}}
+# SYM-LLVM-NEXT: SymbolName: separate_text_section_baz
+# SYM-LLVM-NEXT: }
# SYM-LLVM-NEXT: Size: 0x8
# SYM-LLVM-NEXT: }
# SYM-LLVM-NEXT: ]
@@ -285,11 +338,19 @@ Symbols:
# SHORT-LLVM: StackSizes [
# SHORT-LLVM-NEXT: Entry {
# SHORT-LLVM-NEXT: Functions: [foo]
+# SHORT-LLVM-NEXT: Relocation {
+# SHORT-LLVM-NEXT: SymbolIndex: 1{{$}}
+# SHORT-LLVM-NEXT: SymbolName: foo
+# SHORT-LLVM-NEXT: }
# 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: Functions: [foo]
+# SHORT-LLVM-NEXT: Relocation {
+# SHORT-LLVM-NEXT: SymbolIndex: 1{{$}}
+# SHORT-LLVM-NEXT: SymbolName: foo
+# SHORT-LLVM-NEXT: }
# SHORT-LLVM-NEXT: Size: 0x8
# SHORT-LLVM-NEXT: }
# SHORT-LLVM-NEXT: ]
@@ -343,7 +404,8 @@ Symbols:
# RUN: FileCheck %s < %t04-llvm.err --check-prefix=WRONGSECTION-ERR -DFILE=%t04
# 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
+# RUN: llvm-readobj --stack-sizes --demangle %t04 2>&1 | \
+# RUN: FileCheck %s --check-prefixes=WRONGSECTION-DEMANGLE-ERR,WRONGSECTION-DEMANGLE-LLVM -DFILE=%t04
# WRONGSECTION-GNU: Size Functions
# WRONGSECTION-GNU-NEXT: 8 _Z3foof
@@ -351,6 +413,10 @@ Symbols:
# WRONGSECTION-LLVM: StackSizes [
# WRONGSECTION-LLVM-NEXT: Entry {
# WRONGSECTION-LLVM-NEXT: Functions: [_Z3foof]
+# WRONGSECTION-LLVM-NEXT: Relocation {
+# WRONGSECTION-LLVM-NEXT: SymbolIndex: 1{{$}}
+# WRONGSECTION-LLVM-NEXT: SymbolName: _Z3foof
+# WRONGSECTION-LLVM-NEXT: }
# WRONGSECTION-LLVM-NEXT: Size: 0x8
# WRONGSECTION-LLVM-NEXT: }
# WRONGSECTION-LLVM-NEXT: ]
@@ -358,6 +424,15 @@ Symbols:
# WRONGSECTION-ERR: warning: '[[FILE]]': relocation symbol '_Z3foof' is not in the expected section
# WRONGSECTION-DEMANGLE-ERR: warning: '[[FILE]]': relocation symbol 'foo(float)' is not in the expected section
+## With --demangle, the relocation's symbol name is still printed as it is in the
+## symbol table, followed by its demangled form.
+# WRONGSECTION-DEMANGLE-LLVM: Functions: [foo(float)]
+# WRONGSECTION-DEMANGLE-LLVM-NEXT: Relocation {
+# WRONGSECTION-DEMANGLE-LLVM-NEXT: SymbolIndex: 1{{$}}
+# WRONGSECTION-DEMANGLE-LLVM-NEXT: SymbolName: _Z3foof
+# WRONGSECTION-DEMANGLE-LLVM-NEXT: DemangledName: foo(float)
+# WRONGSECTION-DEMANGLE-LLVM-NEXT: }
+
--- !ELF
FileHeader:
Class: ELFCLASS64
@@ -513,16 +588,26 @@ Symbols:
# 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: Functions: [?]
+# BADSECTION-OUT-LLVM-NEXT: Relocation {
+# BADSECTION-OUT-LLVM-NEXT: SymbolIndex: 1{{$}}
+# BADSECTION-OUT-LLVM-NEXT: SymbolName: _Z3foof
+# BADSECTION-OUT-LLVM-NEXT: }
# 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: Functions: [?]
+# BADSECTION-OUT-LLVM-NEXT: Relocation {
+# BADSECTION-OUT-LLVM-NEXT: SymbolIndex: 255{{$}}
+# BADSECTION-OUT-LLVM-NEXT: }
# 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: Functions: [?]
+# BADSECTION-OUT-LLVM-NEXT: Relocation {
+# BADSECTION-OUT-LLVM-NEXT: SymbolIndex: 255{{$}}
+# BADSECTION-OUT-LLVM-NEXT: }
# BADSECTION-OUT-LLVM-NEXT: Size: 0x24
# BADSECTION-OUT-LLVM-NEXT: }
# BADSECTION-OUT-LLVM-NEXT: ]
@@ -631,14 +716,27 @@ Sections:
# MULTIPLE-LLVM: StackSizes [
# MULTIPLE-LLVM-NEXT: Entry {
# MULTIPLE-LLVM-NEXT: Functions: [referenced_by_symbol_foo]
+# MULTIPLE-LLVM-NEXT: Relocation {
+# MULTIPLE-LLVM-NEXT: SymbolIndex: 3{{$}}
+# MULTIPLE-LLVM-NEXT: SymbolName: referenced_by_symbol_foo
+# MULTIPLE-LLVM-NEXT: }
# MULTIPLE-LLVM-NEXT: Size: 0x10
# MULTIPLE-LLVM-NEXT: }
# MULTIPLE-LLVM-NEXT: Entry {
# MULTIPLE-LLVM-NEXT: Functions: [referenced_via_section_bar]
+# MULTIPLE-LLVM-NEXT: Relocation {
+# MULTIPLE-LLVM-NEXT: SymbolIndex: 2{{$}}
+# MULTIPLE-LLVM-NEXT: SymbolName: .text
+# MULTIPLE-LLVM-NEXT: Addend: 16{{$}}
+# MULTIPLE-LLVM-NEXT: }
# MULTIPLE-LLVM-NEXT: Size: 0x20
# MULTIPLE-LLVM-NEXT: }
# MULTIPLE-LLVM-NEXT: Entry {
# MULTIPLE-LLVM-NEXT: Functions: [separate_text_section_baz]
+# MULTIPLE-LLVM-NEXT: Relocation {
+# MULTIPLE-LLVM-NEXT: SymbolIndex: 1{{$}}
+# MULTIPLE-LLVM-NEXT: SymbolName: separate_text_section_baz
+# MULTIPLE-LLVM-NEXT: }
# MULTIPLE-LLVM-NEXT: Size: 0x8
# MULTIPLE-LLVM-NEXT: }
# MULTIPLE-LLVM-NEXT: ]
@@ -686,6 +784,10 @@ Sections:
# NONFUNCTIONSYM-LLVM: StackSizes [
# NONFUNCTIONSYM-LLVM-NEXT: Entry {
# NONFUNCTIONSYM-LLVM-NEXT: Functions: [?]
+# NONFUNCTIONSYM-LLVM-NEXT: Relocation {
+# NONFUNCTIONSYM-LLVM-NEXT: SymbolIndex: 1{{$}}
+# NONFUNCTIONSYM-LLVM-NEXT: SymbolName: foo
+# NONFUNCTIONSYM-LLVM-NEXT: }
# NONFUNCTIONSYM-LLVM-NEXT: Size: 0x0
# NONFUNCTIONSYM-LLVM-NEXT: }
# NONFUNCTIONSYM-LLVM-NEXT: ]
@@ -737,6 +839,10 @@ Symbols:
# 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: Functions: [foo]
+# UNSUPPRELOC-LLVM-NEXT: Relocation {
+# UNSUPPRELOC-LLVM-NEXT: SymbolIndex: 1{{$}}
+# UNSUPPRELOC-LLVM-NEXT: SymbolName: foo
+# UNSUPPRELOC-LLVM-NEXT: }
# 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
@@ -804,6 +910,10 @@ Symbols:
# ARCHIVEWARN-LLVM: warning: '{{.*04}}': relocation symbol '_Z3foof' is not in the expected section
# ARCHIVEWARN-LLVM-NEXT: Entry {
# ARCHIVEWARN-LLVM-NEXT: Functions: [_Z3foof]
+# ARCHIVEWARN-LLVM-NEXT: Relocation {
+# ARCHIVEWARN-LLVM-NEXT: SymbolIndex: 1{{$}}
+# ARCHIVEWARN-LLVM-NEXT: SymbolName: _Z3foof
+# ARCHIVEWARN-LLVM-NEXT: }
# ARCHIVEWARN-LLVM-NEXT: Size: 0x8
# ARCHIVEWARN-LLVM-NEXT: }
# ARCHIVEWARN-LLVM-NEXT: ]
@@ -811,14 +921,27 @@ Symbols:
# ARCHIVEWARN-LLVM: StackSizes [
# ARCHIVEWARN-LLVM-NEXT: Entry {
# ARCHIVEWARN-LLVM-NEXT: Functions: [referenced_by_symbol_foo]
+# ARCHIVEWARN-LLVM-NEXT: Relocation {
+# ARCHIVEWARN-LLVM-NEXT: SymbolIndex: 3{{$}}
+# ARCHIVEWARN-LLVM-NEXT: SymbolName: referenced_by_symbol_foo
+# ARCHIVEWARN-LLVM-NEXT: }
# ARCHIVEWARN-LLVM-NEXT: Size: 0x10
# ARCHIVEWARN-LLVM-NEXT: }
# ARCHIVEWARN-LLVM-NEXT: Entry {
# ARCHIVEWARN-LLVM-NEXT: Functions: [referenced_via_section_bar]
+# ARCHIVEWARN-LLVM-NEXT: Relocation {
+# ARCHIVEWARN-LLVM-NEXT: SymbolIndex: 2{{$}}
+# ARCHIVEWARN-LLVM-NEXT: SymbolName: .text
+# ARCHIVEWARN-LLVM-NEXT: Addend: 16{{$}}
+# ARCHIVEWARN-LLVM-NEXT: }
# ARCHIVEWARN-LLVM-NEXT: Size: 0x20
# ARCHIVEWARN-LLVM-NEXT: }
# ARCHIVEWARN-LLVM-NEXT: Entry {
# ARCHIVEWARN-LLVM-NEXT: Functions: [separate_text_section_baz]
+# ARCHIVEWARN-LLVM-NEXT: Relocation {
+# ARCHIVEWARN-LLVM-NEXT: SymbolIndex: 1{{$}}
+# ARCHIVEWARN-LLVM-NEXT: SymbolName: separate_text_section_baz
+# ARCHIVEWARN-LLVM-NEXT: }
# ARCHIVEWARN-LLVM-NEXT: Size: 0x8
# ARCHIVEWARN-LLVM-NEXT: }
# ARCHIVEWARN-LLVM-NEXT: ]
@@ -1010,7 +1133,8 @@ Symbols:
## Check that on ARM the Thumb bit is also cleared from the address that a
## relocation resolves to, so that Thumb functions are found in relocatable
-## object files too.
+## object files too. The addend of a SHT_REL relocation is the value stored in
+## the address field, as in --call-graph-info.
# RUN: yaml2obj --docnum=16 %s -o %t21
# RUN: llvm-readelf --stack-sizes %t21 2>&1 | \
@@ -1025,10 +1149,18 @@ Symbols:
# THUMB-REL-LLVM: StackSizes [
# THUMB-REL-LLVM-NEXT: Entry {
# THUMB-REL-LLVM-NEXT: Functions: [foo]
+# THUMB-REL-LLVM-NEXT: Relocation {
+# THUMB-REL-LLVM-NEXT: SymbolIndex: 2{{$}}
+# THUMB-REL-LLVM-NEXT: SymbolName: foo
+# THUMB-REL-LLVM-NEXT: }
# THUMB-REL-LLVM-NEXT: Size: 0x10
# THUMB-REL-LLVM-NEXT: }
# THUMB-REL-LLVM-NEXT: Entry {
# THUMB-REL-LLVM-NEXT: Functions: [bar]
+# THUMB-REL-LLVM-NEXT: Relocation {
+# THUMB-REL-LLVM-NEXT: SymbolIndex: 1{{$}}
+# THUMB-REL-LLVM-NEXT: Addend: 17{{$}}
+# THUMB-REL-LLVM-NEXT: }
# THUMB-REL-LLVM-NEXT: Size: 0x20
# THUMB-REL-LLVM-NEXT: }
# THUMB-REL-LLVM-NEXT: ]
diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp
index 77f2eaa28b3fa..3b7ac5916ef11 100644
--- a/llvm/tools/llvm-readobj/ELFDumper.cpp
+++ b/llvm/tools/llvm-readobj/ELFDumper.cpp
@@ -229,6 +229,17 @@ template <class ELFT> struct FunctionCallGraphInfo {
bool IsIndirectTarget;
};
+// The relocation that applies to the address field of a .stack_sizes entry in
+// a relocatable file.
+template <class ELFT> struct StackSizeRelocation {
+ const Relocation<ELFT> &R;
+ // The symbol of the relocation, if it could be read, and its symbol table.
+ const typename ELFT::Sym *Sym;
+ const typename ELFT::Shdr &SymTab;
+ // The value stored in the address field.
+ uint64_t FieldValue;
+};
+
template <class ELFT> class MipsGOTParser;
template <typename ELFT> class ELFDumper : public ObjDumper {
@@ -363,17 +374,19 @@ template <typename ELFT> class ELFDumper : public ObjDumper {
bool printFunctionStackSize(uint64_t SymValue,
std::optional<const Elf_Shdr *> FunctionSec,
const Elf_Shdr &StackSizeSec, DataExtractor Data,
- uint64_t *Offset);
+ uint64_t *Offset,
+ const StackSizeRelocation<ELFT> *Reloc);
void printStackSize(const Relocation<ELFT> &R, const Elf_Shdr &RelocSec,
unsigned Ndx, const Elf_Shdr *SymTab,
const Elf_Shdr *FunctionSec, const Elf_Shdr &StackSizeSec,
const RelocationResolver &Resolver, DataExtractor Data);
// Prints a stack size entry. Address is the function's address: the value
// stored in the entry in a linked file, or the value that its relocation
- // resolves to in a relocatable file.
+ // resolves to in a relocatable file. Reloc is that relocation, if any.
virtual void printStackSizeEntry(uint64_t Size,
ArrayRef<std::string> FuncNames,
- uint64_t Address) = 0;
+ uint64_t Address,
+ const StackSizeRelocation<ELFT> *Reloc) = 0;
void printRelocatableStackSizes(std::function<void()> PrintHeader);
void printNonRelocatableStackSizes(std::function<void()> PrintHeader);
@@ -754,7 +767,8 @@ template <typename ELFT> class GNUELFDumper : public ELFDumper<ELFT> {
const Twine &Label, unsigned EntriesNum);
void printStackSizeEntry(uint64_t Size, ArrayRef<std::string> FuncNames,
- uint64_t Address) override;
+ uint64_t Address,
+ const StackSizeRelocation<ELFT> *Reloc) override;
void printMipsGOT(const MipsGOTParser<ELFT> &Parser) override;
void printMipsPLT(const MipsGOTParser<ELFT> &Parser) override;
@@ -811,9 +825,16 @@ template <typename ELFT> class LLVMELFDumper : public ELFDumper<ELFT> {
void printProgramHeaders() override;
void printSectionMapping() override {}
void printStackSizeEntry(uint64_t Size, ArrayRef<std::string> FuncNames,
- uint64_t Address) override;
+ uint64_t Address,
+ const StackSizeRelocation<ELFT> *Reloc) override;
void printCallGraphRelocation(const CallGraphFunc<ELFT> &Func,
const Elf_Shdr &RelSec, const Elf_Shdr &SymTab);
+ // Prints R as a Relocation object: its symbol index, the name of its symbol
+ // Sym exactly as recorded in st_name if Sym could be read, and its addend.
+ // FieldValue is the value stored in the field that R applies to, which is
+ // the addend of a relocation without an explicit one.
+ void printRelocationObject(const Relocation<ELFT> &R, const Elf_Sym *Sym,
+ const Elf_Shdr &SymTab, uint64_t FieldValue);
// Returns the names of the functions at the address that the relocation for
// Func resolves to. Sym is the symbol of the relocation, and only functions
// in its section are looked up.
@@ -7238,7 +7259,8 @@ SmallVector<uint32_t> ELFDumper<ELFT>::getSymbolIndexesForFunctionAddress(
template <class ELFT>
bool ELFDumper<ELFT>::printFunctionStackSize(
uint64_t SymValue, std::optional<const Elf_Shdr *> FunctionSec,
- const Elf_Shdr &StackSizeSec, DataExtractor Data, uint64_t *Offset) {
+ const Elf_Shdr &StackSizeSec, DataExtractor Data, uint64_t *Offset,
+ const StackSizeRelocation<ELFT> *Reloc) {
// As in --call-graph-info, clear the Thumb bit, which is not part of the
// function's address.
if (Obj.getHeader().e_machine == ELF::EM_ARM)
@@ -7262,21 +7284,21 @@ bool ELFDumper<ELFT>::printFunctionStackSize(
}
if (FuncSymIndexes.empty()) {
- printStackSizeEntry(StackSize, {"?"}, SymValue);
+ printStackSizeEntry(StackSize, {"?"}, SymValue, Reloc);
} else {
SmallVector<std::string> FuncSymNames;
for (uint32_t Index : FuncSymIndexes)
FuncSymNames.push_back(this->getStaticSymbolName(Index));
- printStackSizeEntry(StackSize, FuncSymNames, SymValue);
+ printStackSizeEntry(StackSize, FuncSymNames, SymValue, Reloc);
}
return true;
}
template <class ELFT>
-void GNUELFDumper<ELFT>::printStackSizeEntry(uint64_t Size,
- ArrayRef<std::string> FuncNames,
- uint64_t /*Address*/) {
+void GNUELFDumper<ELFT>::printStackSizeEntry(
+ uint64_t Size, ArrayRef<std::string> FuncNames, uint64_t /*Address*/,
+ const StackSizeRelocation<ELFT> * /*Reloc*/) {
OS.PadToColumn(2);
OS << format_decimal(Size, 11);
OS.PadToColumn(18);
@@ -7331,11 +7353,12 @@ void ELFDumper<ELFT>::printStackSize(const Relocation<ELFT> &R,
return;
}
- uint64_t SymValue = Resolver(R.Type, Offset, RelocSymValue,
- Data.getUnsigned(&Offset, sizeof(Elf_Addr)),
+ uint64_t FieldValue = Data.getUnsigned(&Offset, sizeof(Elf_Addr));
+ uint64_t SymValue = Resolver(R.Type, R.Offset, RelocSymValue, FieldValue,
R.Addend.value_or(0));
+ StackSizeRelocation<ELFT> Reloc{R, Sym, *SymTab, FieldValue};
this->printFunctionStackSize(SymValue, FunctionSec, StackSizeSec, Data,
- &Offset);
+ &Offset, &Reloc);
}
template <class ELFT>
@@ -7362,7 +7385,7 @@ void ELFDumper<ELFT>::printNonRelocatableStackSizes(
}
uint64_t SymValue = Data.getUnsigned(&Offset, sizeof(Elf_Addr));
if (!printFunctionStackSize(SymValue, /*FunctionSec=*/std::nullopt, Sec,
- Data, &Offset))
+ Data, &Offset, /*Reloc=*/nullptr))
break;
}
}
@@ -8461,14 +8484,33 @@ void LLVMELFDumper<ELFT>::printCallGraphRelocation(
const CallGraphFunc<ELFT> &Func, const Elf_Shdr &RelSec,
const Elf_Shdr &SymTab) {
const Relocation<ELFT> &R = *Func.Reloc;
+ const Elf_Sym *Sym = nullptr;
+ Expected<RelSymbol<ELFT>> TargetOrErr = this->getRelocationTarget(R, &SymTab);
+ if (!TargetOrErr)
+ this->reportUniqueWarning(TargetOrErr.takeError());
+ else
+ Sym = TargetOrErr->Sym;
+
+ // As with Address, Names comes before the Relocation object.
+ if (Sym) {
+ SmallVector<std::string> Names =
+ getCallGraphTargetNames(Func, RelSec, SymTab, *Sym);
+ if (!Names.empty())
+ W.printList("Names", Names);
+ }
+ printRelocationObject(R, Sym, SymTab, Func.FieldValue);
+}
+
+template <class ELFT>
+void LLVMELFDumper<ELFT>::printRelocationObject(const Relocation<ELFT> &R,
+ const Elf_Sym *Sym,
+ const Elf_Shdr &SymTab,
+ uint64_t FieldValue) {
// Print the symbol name exactly as recorded in st_name. RelSymbol::Name is
// not used because it is demangled with --demangle, and is made up from the
// section name for an unnamed STT_SECTION symbol.
StringRef SymbolName;
- Expected<RelSymbol<ELFT>> TargetOrErr = this->getRelocationTarget(R, &SymTab);
- if (!TargetOrErr) {
- this->reportUniqueWarning(TargetOrErr.takeError());
- } else if (const Elf_Sym *Sym = TargetOrErr->Sym) {
+ if (Sym) {
Expected<StringRef> StrTabOrErr = this->Obj.getStringTableForSymtab(SymTab);
if (!StrTabOrErr)
this->reportUniqueWarning(StrTabOrErr.takeError());
@@ -8476,12 +8518,6 @@ void LLVMELFDumper<ELFT>::printCallGraphRelocation(
SymbolName = *NameOrErr;
else
this->reportUniqueWarning(NameOrErr.takeError());
-
- // As with Address, Names comes before the Relocation object.
- SmallVector<std::string> Names =
- getCallGraphTargetNames(Func, RelSec, SymTab, *Sym);
- if (!Names.empty())
- W.printList("Names", Names);
}
DictScope D(W, "Relocation");
@@ -8492,9 +8528,9 @@ void LLVMELFDumper<ELFT>::printCallGraphRelocation(
W.printString("DemangledName", demangle(SymbolName));
}
// Without an explicit addend, e.g. for SHT_REL, the addend is the value
- // stored in the address field.
+ // stored in the field.
int64_t Addend = R.Addend.value_or(
- SignExtend64<sizeof(typename ELFT::uint) * 8>(Func.FieldValue));
+ SignExtend64<sizeof(typename ELFT::uint) * 8>(FieldValue));
if (Addend != 0)
W.printNumber("Addend", Addend);
}
@@ -9005,14 +9041,17 @@ template <class ELFT> void LLVMELFDumper<ELFT>::printStackSizes() {
}
template <class ELFT>
-void LLVMELFDumper<ELFT>::printStackSizeEntry(uint64_t Size,
- ArrayRef<std::string> FuncNames,
- uint64_t Address) {
+void LLVMELFDumper<ELFT>::printStackSizeEntry(
+ uint64_t Size, ArrayRef<std::string> FuncNames, uint64_t Address,
+ const StackSizeRelocation<ELFT> *Reloc) {
DictScope D(W, "Entry");
W.printList("Functions", FuncNames);
- // In a linked file, the function is identified by its address, as in
- // --call-graph-info.
- if (this->Obj.getHeader().e_type != ELF::ET_REL)
+ // As in --call-graph-info, the function is identified by the relocation for
+ // the entry in a relocatable file, and by its address otherwise.
+ if (Reloc)
+ printRelocationObject(Reloc->R, Reloc->Sym, Reloc->SymTab,
+ Reloc->FieldValue);
+ else
W.printHex("Address", Address);
W.printHex("Size", Size);
}
More information about the llvm-branch-commits
mailing list