Skip to content
Open
Show file tree
Hide file tree
Changes from 58 commits
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
ac4b7bc
[llvm-readobj] Dump callgraph section info for ELF
Prabhuk Sep 6, 2025
31c4d2b
Format code
Prabhuk Sep 8, 2025
4d1a7c7
Implement JSON output for printCallGraph()
Prabhuk Sep 8, 2025
f0810b2
ELFDumper cleanups
Prabhuk Sep 8, 2025
5f20b7b
Add readelf callgraph info tests.
Prabhuk Sep 9, 2025
d991194
more tests
Prabhuk Sep 9, 2025
c2d8d22
Extend tests to json
Prabhuk Sep 9, 2025
2874918
Expand all tests to include JSON and LLVM formats.
Prabhuk Sep 9, 2025
9803c62
Improve tests. Match full lines.
Prabhuk Sep 9, 2025
7285210
Make call graph processing agnostic of target architecture pointer wi…
Prabhuk Sep 17, 2025
8236798
Remove unnecessary function returns after reportError calls which bot…
Prabhuk Sep 17, 2025
abe189e
Formatting fixes.
Prabhuk Sep 17, 2025
0b9c46d
Remove callsites from direct call data.
Prabhuk Sep 18, 2025
5b504fc
Format
Prabhuk Sep 18, 2025
5b6bb00
Simplify readelf output.
Prabhuk Sep 18, 2025
937ff61
format
Prabhuk Sep 18, 2025
1b86857
Clean up callgraph output
Prabhuk Sep 18, 2025
7280ff3
Format
Prabhuk Sep 18, 2025
bdb8683
Show symbol names.
Prabhuk Sep 18, 2025
09d3a87
Format
Prabhuk Sep 18, 2025
b851b8d
Make llvm output better.
Prabhuk Sep 18, 2025
fd50ff0
format source.
Prabhuk Sep 18, 2025
ee3a081
Minor improvements to LLVM output.
Prabhuk Sep 18, 2025
3c94a44
Fix tests to match the new output.
Prabhuk Sep 18, 2025
026b184
Add REQUIRES: x86-registered-target to tests.
Prabhuk Sep 19, 2025
d1655c2
Account for windows binary name extension.
Prabhuk Sep 19, 2025
ff9535e
Merge remote-tracking branch 'upstream/main' into readelf_callgraph_info
Prabhuk Oct 20, 2025
b7c56f9
Update callgraph section handling to match the new format.
Prabhuk Oct 20, 2025
e075175
Handle relocations in callgraph section.
Prabhuk Oct 20, 2025
876f7a6
New format for GNU printer.
Prabhuk Oct 21, 2025
33d06b4
Extract relocations handling to a common function.
Prabhuk Oct 21, 2025
5f6cf07
minor cleanups.
Prabhuk Oct 21, 2025
055139b
Merge remote-tracking branch 'upstream/main' into readelf_callgraph_info
Prabhuk Oct 21, 2025
d1b41b5
Fix readelf tests. callgraph section type.
Prabhuk Oct 21, 2025
6368f56
Fix call graph tests.
Prabhuk Oct 22, 2025
f1f9f6b
Merge remote-tracking branch 'upstream/main' into readelf_callgraph_info
Prabhuk Oct 22, 2025
ce75c88
Fix tests. Address review comments.
Prabhuk Oct 22, 2025
72b0d37
Merge remote-tracking branch 'upstream/main' into readelf_callgraph_info
Prabhuk Oct 22, 2025
54b2004
Address review comments.
Prabhuk Oct 22, 2025
dfd37f2
Cleanup ELFDumper.cpp
Prabhuk Oct 22, 2025
8ebe0a2
Use enum for handling Callgraph Flags
Prabhuk Oct 22, 2025
c429dd8
Update error message.
Prabhuk Oct 23, 2025
d04fbd0
Address review comments.
Prabhuk Oct 31, 2025
75bffeb
Function name printing to match stack size printing behavior.
Prabhuk Oct 31, 2025
77acb10
Refactor getCalGraphSection function as suggested in review.
Prabhuk Oct 31, 2025
246275d
Declutter ouput format. Remove GNU output.
Prabhuk Nov 4, 2025
402c90f
Remove unnecessary header includes.
Prabhuk Nov 4, 2025
87d3dd8
More header include cleanups.
Prabhuk Nov 4, 2025
20ea016
Rename test files to .S
Prabhuk Nov 4, 2025
c5823aa
Fix relocation printing handling.
Prabhuk Nov 5, 2025
8d3a27c
Remove addend, type and offset info from relocations.
Prabhuk Nov 5, 2025
aaa2cd4
Fix tests.
Prabhuk Nov 5, 2025
afc13ee
Fix tests.
Prabhuk Nov 5, 2025
6e22254
Rename files to .s
Prabhuk Nov 5, 2025
5b3bff0
Make relocatable test to be built from YAML.
Prabhuk Nov 5, 2025
c4ea41d
Relocatable file tests fixed.
Prabhuk Nov 5, 2025
53ffcaa
Nits. Alignment within test files.
Prabhuk Nov 5, 2025
edc5eaa
Merge remote-tracking branch 'upstream/main' into readelf_callgraph_info
Prabhuk Nov 5, 2025
14b5cf0
Merge branch 'main' into readelf_callgraph_info
Prabhuk Nov 13, 2025
b56a17c
Warn for unknown relocations instead of printing the offset as part o…
Prabhuk Nov 21, 2025
ae501fa
Address review comments.
Prabhuk Nov 21, 2025
f454957
Fix messages. Remove unnecessary errors and unused functions.
Prabhuk Nov 21, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
150 changes: 150 additions & 0 deletions llvm/test/tools/llvm-readobj/ELF/call-graph-info-callgraph-section.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
## Tests --call-graph-info prints information from call graph section.

# REQUIRES: x86-registered-target
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we convert the test input to use yaml2obj, instead of requiring x86? It looks like the file format is trivial enough that something like a YAML ELF input using ContentArray would be just as descriptive, whilst also allowing more precise control of everything.


# RUN: llvm-mc %s -filetype=obj -triple=x86_64-pc-linux -o %t
# RUN: llvm-readelf --call-graph-info %t 2>&1 | FileCheck %s --allow-empty -DFILE=%t
# RUN: llvm-readelf --elf-output-style=LLVM --call-graph-info %t 2>&1 | FileCheck %s -DFILE=%t --check-prefix=LLVM
# RUN: llvm-readelf --elf-output-style=JSON --pretty-print --call-graph-info %t 2>&1 | FileCheck %s -DFILE=%t --check-prefix=JSON


Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: why the double blank line?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

## We do not support GNU format console output for --call-graph-info as it is an LLVM only info.
# CHECK-NOT: .
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't going to do what you think it will. This checks simply that the character "." doesn't appear anywhere in the output. What you probably wanted was {{.}} which is a regex pattern of any character. However, if the output is truly empty, the better method is to use count 0. You should find other examples elsewhere in the testsuite.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Neat. Thank you. Done.


# LLVM: warning: '[[FILE]]': .llvm.callgraph section has unknown type id for 2 indirect targets.
# LLVM-NEXT: CallGraph [
# LLVM-NEXT: Function {
# LLVM-NEXT: Offset: 0x2
# LLVM-NEXT: Version: 0
# LLVM-NEXT: IsIndirectTarget: Yes
# LLVM-NEXT: TypeId: 0x0
# LLVM-NEXT: NumDirectCallees: 1
# LLVM-NEXT: DirectCallees [
# LLVM-NEXT: {
# LLVM-NEXT: Offset: 0x13
# LLVM-NEXT: }
# LLVM-NEXT: ]
# LLVM-NEXT: NumIndirectTargetTypeIDs: 0
# LLVM-NEXT: IndirectTypeIDs: []
# LLVM-NEXT: }
# LLVM-NEXT: Function {
# LLVM-NEXT: Offset: 0x1D
# LLVM-NEXT: Version: 0
# LLVM-NEXT: IsIndirectTarget: Yes
# LLVM-NEXT: TypeId: 0x0
# LLVM-NEXT: NumDirectCallees: 0
# LLVM-NEXT: DirectCallees [
# LLVM-NEXT: ]
# LLVM-NEXT: NumIndirectTargetTypeIDs: 1
# LLVM-NEXT: IndirectTypeIDs: [0x10]
# LLVM-NEXT: }
# LLVM-NEXT: Function {
# LLVM-NEXT: Offset: 0x38
# LLVM-NEXT: Version: 0
# LLVM-NEXT: IsIndirectTarget: Yes
# LLVM-NEXT: TypeId: 0x20
# LLVM-NEXT: NumDirectCallees: 0
# LLVM-NEXT: DirectCallees [
# LLVM-NEXT: ]
# LLVM-NEXT: NumIndirectTargetTypeIDs: 0
# LLVM-NEXT: IndirectTypeIDs: []
# LLVM-NEXT: }
# LLVM-NEXT: ]

# JSON: warning: '[[FILE]]': .llvm.callgraph section has unknown type id for 2 indirect targets.
# JSON: "CallGraph": [
# JSON-NEXT: {
# JSON-NEXT: "Function": {
# JSON-NEXT: "Offset": 2,
# JSON-NEXT: "Version": 0,
# JSON-NEXT: "IsIndirectTarget": true,
# JSON-NEXT: "TypeId": 0,
# JSON-NEXT: "NumDirectCallees": 1,
# JSON-NEXT: "DirectCallees": [
# JSON-NEXT: {
# JSON-NEXT: "Offset": 19
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is Offset here? is it the address? offset from the start of the section?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Offset is pointless actually. It's the offset of the symbol for which we couldn't find corresponding relocation. I removed "offset" and turned it into a warning for this scenario.

# JSON-NEXT: }
# JSON-NEXT: ],
# JSON-NEXT: "NumIndirectTargetTypeIDs": 0,
# JSON-NEXT: "IndirectTypeIDs": []
# JSON-NEXT: }
# JSON-NEXT: },
# JSON-NEXT: {
# JSON-NEXT: "Function": {
# JSON-NEXT: "Offset": 29,
# JSON-NEXT: "Version": 0,
# JSON-NEXT: "IsIndirectTarget": true,
# JSON-NEXT: "TypeId": 0,
# JSON-NEXT: "NumDirectCallees": 0,
# JSON-NEXT: "DirectCallees": [],
# JSON-NEXT: "NumIndirectTargetTypeIDs": 1,
# JSON-NEXT: "IndirectTypeIDs": [
# JSON-NEXT: 16
# JSON-NEXT: ]
# JSON-NEXT: }
# JSON-NEXT: },
# JSON-NEXT: {
# JSON-NEXT: "Function": {
# JSON-NEXT: "Offset": 56,
# JSON-NEXT: "Version": 0,
# JSON-NEXT: "IsIndirectTarget": true,
# JSON-NEXT: "TypeId": 32,
# JSON-NEXT: "NumDirectCallees": 0,
# JSON-NEXT: "DirectCallees": [],
# JSON-NEXT: "NumIndirectTargetTypeIDs": 0,
# JSON-NEXT: "IndirectTypeIDs": []
# JSON-NEXT: }
# JSON-NEXT: }
# JSON-NEXT: ]
# JSON-NEXT: }
# JSON-NEXT:]

.text

.globl foo
.type foo,@function
foo: #< foo is at 0.
.Lfoo_begin:
callq foo #< direct call is at 5. target is foo (5).
retq

.globl bar
.type bar,@function
bar: #< bar is at 6.
callq *-40(%rbp) #< indirect call is at 9.
retq

.globl baz
.type baz,@function
baz: #< baz is at 10 (a).
retq

.globl qux
.type qux,@function
qux: #< qux is at 11 (b).
retq

.section .llvm.callgraph,"o",@llvm_call_graph,.text
.byte 0 #< Format version number.
.byte 3 #< Flag IsIndirectTarget true
.quad 0 #< foo()'s address.
.quad 0 #< TypeID: unknown.
.byte 1 #< Count of direct callees.
.quad 5 #< Direct callee foo's address>

.byte 0 #< Format version number.
.byte 5 #< Flag IsIndirectTarget true
.quad 6 #< bar()'s address.
.quad 0 #< TypeID: unknown.
.byte 1 #< Count of indirect target type IDs
.quad 16 #< Indirect call type id.


.byte 0 #< Format version number.
.byte 1 #< Flag IsIndirectTarget true
.quad 10 #< baz()'s address.
.quad 32 #< Indirect target type id.

# No call graph section entry for qux.

.text
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
## Tests that --call-graph-info fails if .llvm.callgraph section has invalid
## value for flags field.

# REQUIRES: x86-registered-target

# RUN: llvm-mc %s -filetype=obj -triple=x86_64-pc-linux -o %t
# RUN: not llvm-readelf --elf-output-style=LLVM --call-graph-info %t 2>&1 | FileCheck %s -DFILE=%t --check-prefix=ERR
# RUN: not llvm-readelf --elf-output-style=JSON --pretty-print --call-graph-info %t 2>&1 | FileCheck %s -DFILE=%t --check-prefix=ERR

# ERR: error: 'While reading call graph info's Flags': Unexpected value. Expected [0-7] but found [8]

.text
.globl _Z3foov
.type _Z3foov,@function
_Z3foov:
callq _Z3foov@PLT

.section .llvm.callgraph,"o",@llvm_call_graph,.text
.byte 0 #< Format version number.
.byte 8 #< Only valid values are 0 to 7
# Missing direct callees info
.text
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
## Tests that --call-graph-info fails if .llvm.callgraph section has unknown format
## version number.

# REQUIRES: x86-registered-target

# RUN: llvm-mc %s -filetype=obj -triple=x86_64-pc-linux -o %t
# RUN: not llvm-readelf --elf-output-style=LLVM --call-graph-info %t 2>&1 | FileCheck %s -DFILE=%t --check-prefix=ERR
# RUN: not llvm-readelf --elf-output-style=JSON --pretty-print --call-graph-info %t 2>&1 | FileCheck %s -DFILE=%t --check-prefix=ERR

# ERR: error: 'Unknown value': Unknown format version value [1] in .llvm.callgraph section.

.text
.globl _Z3foov
.type _Z3foov,@function
_Z3foov:
callq _Z3foov@PLT

.section .llvm.callgraph,"o",@llvm_call_graph,.text
.byte 1 #< Invalid format version number: the only supported version is 0.
.text
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
## Tests that --call-graph-info fails if .llvm.callgraph section has flags
## that indicate there are direct calls but the direct call info is missing.

# REQUIRES: x86-registered-target

# RUN: llvm-mc %s -filetype=obj -triple=x86_64-pc-linux -o %t
# RUN: not llvm-readelf --elf-output-style=LLVM --call-graph-info %t 2>&1 | FileCheck %s -DFILE=%t --check-prefix=ERR
# RUN: not llvm-readelf --elf-output-style=JSON --pretty-print --call-graph-info %t 2>&1 | FileCheck %s -DFILE=%t --check-prefix=ERR

# ERR: error: 'While reading call graph info's [number of direct callsites] for function at [0x2]': unable to decode LEB128 at offset 0x00000012: malformed uleb128, extends past end

.text
.globl _Z3foov
.type _Z3foov,@function
_Z3foov:
callq _Z3foov@PLT

.section .llvm.callgraph,"o",@llvm_call_graph,.text
.byte 0 #< Format version number.
.byte 3 #< Flag IsIndirectTarget true and has direct calls
.quad 0 #< Function entry address.
.quad 0 #< TypeID: unknown.
# Missing direct callees info
.text
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
## Tests that --call-graph-info fails if .llvm.callgraph section does not have
## an expected value, e.g., not as much call sites as the given count.

# REQUIRES: x86-registered-target

# RUN: llvm-mc %s -filetype=obj -triple=x86_64-pc-linux -o %t
# RUN: not llvm-readelf --elf-output-style=LLVM --call-graph-info %t 2>&1 | FileCheck %s -DFILE=%t --check-prefix=ERR
# RUN: not llvm-readelf --elf-output-style=JSON --pretty-print --call-graph-info %t 2>&1 | FileCheck %s -DFILE=%t --check-prefix=ERR

# ERR: error: 'While reading call graph info's [indirect type ID] for function at [0x2]': unexpected end of data at offset 0x13 while reading [0x13, 0x1b)

.text
.globl _Z3foov
.type _Z3foov,@function
_Z3foov:
callq _Z3foov@PLT

.section .llvm.callgraph,"o",@llvm_call_graph,.text
.byte 0 #< Format version number.
.byte 4 #< Flags
.quad 0 #< Function entry address.
.quad 0 #< Type ID
.byte 1 #< Indirect call site count that follows.
#< Missing indirect call entries here.
.text
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
## Tests that --call-graph-info warns if there is no .llvm.callgraph section.

# REQUIRES: x86-registered-target

# RUN: llvm-mc %s -filetype=obj -triple=x86_64-pc-linux -o %t
# RUN: not llvm-readelf --elf-output-style=LLVM --call-graph-info %t 2>&1 | FileCheck %s -DFILE=%t
# RUN: not llvm-readelf --elf-output-style=JSON --pretty-print --call-graph-info %t 2>&1 | FileCheck %s -DFILE=%t

# CHECK: error: 'Missing section': No .llvm.callgraph section found.

.text
.globl _Z3foov
.type _Z3foov,@function
_Z3foov:
callq _Z3foov@PLT
Loading