[llvm] [llvm-readobj] Dump callgraph section info for ELF (PR #157499)
Prabhu Rajasekaran via llvm-commits
llvm-commits at lists.llvm.org
Wed Nov 5 11:04:21 PST 2025
================
@@ -0,0 +1,326 @@
+## Tests how --call-graph-info prints the call graph information.
+# RUN: yaml2obj --docnum=1 %s -o %t
+# RUN: llvm-readelf --call-graph-info %t 2>&1 | FileCheck %s --match-full-lines --allow-empty -DFILE=%t
+# RUN: llvm-readelf --elf-output-style=LLVM --call-graph-info %t 2>&1 | FileCheck %s --match-full-lines --check-prefix=LLVM -DFILE=%t
+# RUN: llvm-readelf --elf-output-style=JSON --pretty-print --call-graph-info %t 2>&1 | FileCheck %s --match-full-lines --check-prefix=JSON -DFILE=%t
+
+## Yaml input is obtained by compiling the below source to object with:
+## clang -fexperimental-call-graph-section test.c -o test.o
+## then to yaml with:
+## obj2yaml test.o > test.yaml
+## Remove ProgramHeaders if obj2yaml fails.
+
+## YAML output was generated from the following source:
+##
+## void foo() {}
+##
+## void bar() {}
+##
+## int baz(char a) { return 0; }
+##
+## int caller() {
+## void (*fp_foo)() = foo;
+## fp_foo();
+##
+## void (*fp_bar)() = bar;
+## fp_bar();
+##
+## char a;
+## int (*fp_baz)(char) = baz;
+## fp_baz(a);
+##
+## foo();
+## bar();
+## baz(a);
+##
+## return 0;
+## }
+##
+
+## We do not support GNU format console output for --call-graph-info as it is an LLVM only info.
+# CHECK-NOT: .
+
+# LLVM: CallGraph [
+# LLVM-NEXT: Function {
+# LLVM-NEXT: Name: _Z3foov
+# LLVM-NEXT: Version: 0
+# LLVM-NEXT: IsIndirectTarget: Yes
+# LLVM-NEXT: TypeId: 0xF85C699BB8EF20A2
+# LLVM-NEXT: NumDirectCallees: 0
+# LLVM-NEXT: DirectCallees [
+# LLVM-NEXT: ]
+# LLVM-NEXT: NumIndirectTargetTypeIDs: 0
+# LLVM-NEXT: IndirectTypeIDs: []
+# LLVM-NEXT: }
+# LLVM-NEXT: Function {
+# LLVM-NEXT: Name: _Z3barv
+# LLVM-NEXT: Version: 0
+# LLVM-NEXT: IsIndirectTarget: Yes
+# LLVM-NEXT: TypeId: 0xF85C699BB8EF20A2
+# LLVM-NEXT: NumDirectCallees: 0
+# LLVM-NEXT: DirectCallees [
+# LLVM-NEXT: ]
+# LLVM-NEXT: NumIndirectTargetTypeIDs: 0
+# LLVM-NEXT: IndirectTypeIDs: []
+# LLVM-NEXT: }
+# LLVM-NEXT: Function {
+# LLVM-NEXT: Name: _Z3bazc
+# LLVM-NEXT: Version: 0
+# LLVM-NEXT: IsIndirectTarget: Yes
+# LLVM-NEXT: TypeId: 0x308E4B8159BC8654
+# LLVM-NEXT: NumDirectCallees: 0
+# LLVM-NEXT: DirectCallees [
+# LLVM-NEXT: ]
+# LLVM-NEXT: NumIndirectTargetTypeIDs: 0
+# LLVM-NEXT: IndirectTypeIDs: []
+# LLVM-NEXT: }
+# LLVM-NEXT: Function {
+# LLVM-NEXT: Name: _Z6callerv
+# LLVM-NEXT: Version: 0
+# LLVM-NEXT: IsIndirectTarget: Yes
+# LLVM-NEXT: TypeId: 0xA9494DEF81A01DC
+# LLVM-NEXT: NumDirectCallees: 3
+# LLVM-NEXT: DirectCallees [
+# LLVM-NEXT: {
+# LLVM-NEXT: Name: _Z3foov
+# LLVM-NEXT: }
+# LLVM-NEXT: {
+# LLVM-NEXT: Name: _Z3barv
+# LLVM-NEXT: }
+# LLVM-NEXT: {
+# LLVM-NEXT: Name: _Z3bazc
+# LLVM-NEXT: }
+# LLVM-NEXT: ]
+# LLVM-NEXT: NumIndirectTargetTypeIDs: 2
+# LLVM-NEXT: IndirectTypeIDs: [0xF85C699BB8EF20A2, 0x308E4B8159BC8654]
+# LLVM-NEXT: }
+# LLVM-NEXT: ]
+
+# JSON: "CallGraph": [
+# JSON-NEXT: {
+# JSON-NEXT: "Function": {
+# JSON-NEXT: "Name": "_Z3foov",
+# JSON-NEXT: "Version": 0,
+# JSON-NEXT: "IsIndirectTarget": true,
+# JSON-NEXT: "TypeId": 17896295136807035042,
+# JSON-NEXT: "NumDirectCallees": 0,
+# JSON-NEXT: "DirectCallees": [],
+# JSON-NEXT: "NumIndirectTargetTypeIDs": 0,
+# JSON-NEXT: "IndirectTypeIDs": []
+# JSON-NEXT: }
+# JSON-NEXT: },
+# JSON-NEXT: {
+# JSON-NEXT: "Function": {
+# JSON-NEXT: "Name": "_Z3barv",
+# JSON-NEXT: "Version": 0,
+# JSON-NEXT: "IsIndirectTarget": true,
+# JSON-NEXT: "TypeId": 17896295136807035042,
+# JSON-NEXT: "NumDirectCallees": 0,
+# JSON-NEXT: "DirectCallees": [],
+# JSON-NEXT: "NumIndirectTargetTypeIDs": 0,
+# JSON-NEXT: "IndirectTypeIDs": []
+# JSON-NEXT: }
+# JSON-NEXT: },
+# JSON-NEXT: {
+# JSON-NEXT: "Function": {
+# JSON-NEXT: "Name": "_Z3bazc",
+# JSON-NEXT: "Version": 0,
+# JSON-NEXT: "IsIndirectTarget": true,
+# JSON-NEXT: "TypeId": 3498816979441845844,
+# JSON-NEXT: "NumDirectCallees": 0,
+# JSON-NEXT: "DirectCallees": [],
+# JSON-NEXT: "NumIndirectTargetTypeIDs": 0,
+# JSON-NEXT: "IndirectTypeIDs": []
+# JSON-NEXT: }
+# JSON-NEXT: },
+# JSON-NEXT: {
+# JSON-NEXT: "Function": {
+# JSON-NEXT: "Name": "_Z6callerv",
+# JSON-NEXT: "Version": 0,
+# JSON-NEXT: "IsIndirectTarget": true,
+# JSON-NEXT: "TypeId": 762397922298560988,
+# JSON-NEXT: "NumDirectCallees": 3,
+# JSON-NEXT: "DirectCallees": [
+# JSON-NEXT: {
+# JSON-NEXT: "Name": "_Z3foov"
----------------
Prabhuk wrote:
This object will have an address field whenever it is an output of a fully linked ELF binary which is our main use case.
https://github.com/llvm/llvm-project/pull/157499
More information about the llvm-commits
mailing list