[llvm-branch-commits] [llvm] release/22.x: Revert "[llvm-readobj] Dump callgraph section info for ELF" (#176221) (PR #176228)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Thu Jan 15 11:34:35 PST 2026
https://github.com/llvmbot created https://github.com/llvm/llvm-project/pull/176228
Backport 97576a86eb25696a2b57cd42370991b172c08405
Requested by: @Prabhuk
>From 6323ec3c6e5a90ed5c62d892fec09391f48468f1 Mon Sep 17 00:00:00 2001
From: Prabhu Rajasekaran <prabhukr at google.com>
Date: Thu, 15 Jan 2026 11:24:19 -0800
Subject: [PATCH] Revert "[llvm-readobj] Dump callgraph section info for ELF"
(#176221)
Reverts llvm/llvm-project#157499
Following up on discourse post. Reverting this patch and will attempt a
reland addressing post merge comments.
(cherry picked from commit 97576a86eb25696a2b57cd42370991b172c08405)
---
llvm/docs/CommandGuide/llvm-readelf.rst | 16 +-
llvm/docs/CommandGuide/llvm-readobj.rst | 42 +-
.../ELF/call-graph-info-warn-malformed.test | 366 ------------
.../llvm-readobj/ELF/call-graph-info.test | 521 ------------------
llvm/tools/llvm-readobj/ELFDumper.cpp | 278 +---------
llvm/tools/llvm-readobj/ObjDumper.h | 1 -
llvm/tools/llvm-readobj/Opts.td | 1 -
llvm/tools/llvm-readobj/llvm-readobj.cpp | 4 -
8 files changed, 22 insertions(+), 1207 deletions(-)
delete mode 100644 llvm/test/tools/llvm-readobj/ELF/call-graph-info-warn-malformed.test
delete mode 100644 llvm/test/tools/llvm-readobj/ELF/call-graph-info.test
diff --git a/llvm/docs/CommandGuide/llvm-readelf.rst b/llvm/docs/CommandGuide/llvm-readelf.rst
index ed349d1d15761..5403fea60d5ee 100644
--- a/llvm/docs/CommandGuide/llvm-readelf.rst
+++ b/llvm/docs/CommandGuide/llvm-readelf.rst
@@ -38,18 +38,6 @@ OPTIONS
Display the contents of the basic block address map section(s), which contain the
address of each function, along with the relative offset of each basic block.
-.. option:: --call-graph-info
-
- Display the call graph section entries i.e. for each function
- its identifying information, each of its direct callees' information
- and for each indirect callee a 64 bit number representing the callee's
- function signature. This information can be used to reconstruct
- the program call graph.
-
-.. option:: --cg-profile
-
- Display the callgraph profile section.
-
.. option:: --decompress, -z
Dump decompressed section content when used with ``-x`` or ``-p``.
@@ -75,6 +63,10 @@ OPTIONS
Display the dynamic table.
+.. option:: --cg-profile
+
+ Display the callgraph profile section.
+
.. option:: --histogram, -I
Display a bucket list histogram for dynamic symbol hash tables.
diff --git a/llvm/docs/CommandGuide/llvm-readobj.rst b/llvm/docs/CommandGuide/llvm-readobj.rst
index 4fb2901676898..0d05b947a6b3e 100644
--- a/llvm/docs/CommandGuide/llvm-readobj.rst
+++ b/llvm/docs/CommandGuide/llvm-readobj.rst
@@ -181,17 +181,13 @@ The following options are implemented only for the ELF file format.
When pgo analysis maps are present, all analyses are printed as their raw
value.
- .. option:: --call-graph-info
-
- Display the call graph section entries i.e. for each function
- its identifying information, each of its direct callees' information
- and for each indirect callee a 64 bit number representing the callee's
- function signature. This information can be used to reconstruct
- the program call graph.
+.. option:: --pretty-pgo-analysis-map
-.. option:: --cg-profile
+ When pgo analysis maps are present in the basic block address map section(s),
+ analyses with special formats (i.e. BlockFrequency, BranchProbability, etc)
+ are printed using the same format as their respective analysis pass.
- Display the callgraph profile section.
+ Requires :option:`--bb-addr-map` to have an effect.
.. option:: --dependent-libraries
@@ -209,6 +205,14 @@ The following options are implemented only for the ELF file format.
Display the dynamic table.
+.. option:: --cg-profile
+
+ Display the callgraph profile section.
+
+.. option:: --histogram, -I
+
+ Display a bucket list histogram for dynamic symbol hash tables.
+
.. option:: --elf-linker-options
Display the linker options section.
@@ -220,6 +224,10 @@ The following options are implemented only for the ELF file format.
structured format. ``GNU`` output mimics the equivalent GNU :program:`readelf`
output. ``JSON`` is JSON formatted output intended for machine consumption.
+.. option:: --section-groups, -g
+
+ Display section groups.
+
.. option:: --gnu-hash-table
Display the GNU hash table for dynamic symbols.
@@ -232,10 +240,6 @@ The following options are implemented only for the ELF file format.
Display the hash table for dynamic symbols.
-.. option:: --histogram, -I
-
- Display a bucket list histogram for dynamic symbol hash tables.
-
.. option:: --memtag
Display information about memory tagging present in the binary. This includes
@@ -246,14 +250,6 @@ The following options are implemented only for the ELF file format.
Display all notes.
-.. option:: --pretty-pgo-analysis-map
-
- When pgo analysis maps are present in the basic block address map section(s),
- analyses with special formats (i.e. BlockFrequency, BranchProbability, etc)
- are printed using the same format as their respective analysis pass.
-
- Requires :option:`--bb-addr-map` to have an effect.
-
.. option:: --pretty-print
When used with :option:`--elf-output-style`, JSON output will be formatted in
@@ -263,10 +259,6 @@ The following options are implemented only for the ELF file format.
Display the program headers.
-.. option:: --section-groups, -g
-
- Display section groups.
-
.. option:: --section-mapping
Display the section to segment mapping.
diff --git a/llvm/test/tools/llvm-readobj/ELF/call-graph-info-warn-malformed.test b/llvm/test/tools/llvm-readobj/ELF/call-graph-info-warn-malformed.test
deleted file mode 100644
index 63ef662f1a45b..0000000000000
--- a/llvm/test/tools/llvm-readobj/ELF/call-graph-info-warn-malformed.test
+++ /dev/null
@@ -1,366 +0,0 @@
-## Tests that --call-graph-info produces useful warnings
-## if SHT_LLVM_CALL_GRAPH type section processing idenitifies
-## malformed content.
-
-## Tests that --call-graph-info warns if there is no section of type SHT_LLVM_CALL_GRAPH.
-# RUN: yaml2obj --docnum=1 %s -o %t1
-# RUN: llvm-readelf --elf-output-style=LLVM --call-graph-info %t1 2>&1 | FileCheck %s -DFILE=%t1 --check-prefix=WARN_NO_SECTION
-# RUN: llvm-readelf --elf-output-style=JSON --pretty-print --call-graph-info %t1 2>&1 | FileCheck %s -DFILE=%t1 --check-prefix=WARN_NO_SECTION
-
-# WARN_NO_SECTION: warning: '[[FILE]]': no SHT_LLVM_CALL_GRAPH section found
-
---- !ELF
-FileHeader:
- Class: ELFCLASS64
- Data: ELFDATA2LSB
- Type: ET_DYN
- Machine: EM_X86_64
-Sections:
- - Name: .text
- Type: SHT_PROGBITS
- Size: 5
-Symbols:
- - Name: foo
-...
-
-## Check format version number.
-# RUN: yaml2obj --docnum=2 %s -o %t2
-# RUN: llvm-readelf --elf-output-style=LLVM --call-graph-info %t2 2>&1 | FileCheck %s -DFILE=%t2 --check-prefix=WARN_FMT_VERSION
-# RUN: llvm-readelf --elf-output-style=JSON --pretty-print --call-graph-info %t2 2>&1 | FileCheck %s -DFILE=%t2 --check-prefix=WARN_FMT_VERSION
-
-# WARN_FMT_VERSION: warning: '[[FILE]]': unknown format version value [1] in SHT_LLVM_CALL_GRAPH type section
-
---- !ELF
-FileHeader:
- Class: ELFCLASS64
- Data: ELFDATA2LSB
- Type: ET_DYN
- Machine: EM_X86_64
-Sections:
- - Name: .text
- Type: SHT_PROGBITS
- Size: 5
- - Name: .llvm.callgraph
- Type: SHT_LLVM_CALL_GRAPH
- ContentArray: [
- # --- Entry 1: foo (foo) ---
- 0x01, # Format Version - only supported value is 0x00
- ]
-Symbols:
- - Name: foo
-...
-
-## Check missing flags.
-# RUN: yaml2obj --docnum=3 %s -o %t3
-# RUN: llvm-readelf --elf-output-style=LLVM --call-graph-info %t3 2>&1 | FileCheck %s -DFILE=%t3 --check-prefix=WARN_MISSING_FLAG
-# RUN: llvm-readelf --elf-output-style=JSON --pretty-print --call-graph-info %t3 2>&1 | FileCheck %s -DFILE=%t3 --check-prefix=WARN_MISSING_FLAG
-
-# WARN_MISSING_FLAG: warning: '[[FILE]]': failed while reading call graph info's Flags unexpected end of data at offset 0x1 while reading [0x1, 0x2)
-
---- !ELF
-FileHeader:
- Class: ELFCLASS64
- Data: ELFDATA2LSB
- Type: ET_DYN
- Machine: EM_X86_64
-Sections:
- - Name: .text
- Type: SHT_PROGBITS
- Size: 5
- - Name: .llvm.callgraph
- Type: SHT_LLVM_CALL_GRAPH
- ContentArray: [
- # --- Entry 1: foo (foo) ---
- 0x00, # Format Version
- #< Missing flags
- ]
-Symbols:
- - Name: foo
-...
-
-## Check Flags.
-# RUN: yaml2obj --docnum=4 %s -o %t4
-# RUN: llvm-readelf --elf-output-style=LLVM --call-graph-info %t4 2>&1 | FileCheck %s -DFILE=%t4 --check-prefix=WARN_FLAG
-# RUN: llvm-readelf --elf-output-style=JSON --pretty-print --call-graph-info %t4 2>&1 | FileCheck %s -DFILE=%t4 --check-prefix=WARN_FLAG
-
-# WARN_FLAG: warning: '[[FILE]]': unexpected Flags value [8]
-
---- !ELF
-FileHeader:
- Class: ELFCLASS64
- Data: ELFDATA2LSB
- Type: ET_DYN
- Machine: EM_X86_64
-Sections:
- - Name: .text
- Type: SHT_PROGBITS
- Size: 5
- - Name: .llvm.callgraph
- Type: SHT_LLVM_CALL_GRAPH
- ContentArray: [
- # --- Entry 1: foo (foo) ---
- 0x00, # Format Version
- 0x08, # Flags - only valid values are 0x00 to 0x07
- ]
-Symbols:
- - Name: foo
-...
-
-## Check missing function entry PC.
-# RUN: yaml2obj --docnum=5 %s -o %t5
-# RUN: llvm-readelf --elf-output-style=LLVM --call-graph-info %t5 2>&1 | FileCheck %s -DFILE=%t5 --check-prefix=WARN_MISSING_PC
-# RUN: llvm-readelf --elf-output-style=JSON --pretty-print --call-graph-info %t5 2>&1 | FileCheck %s -DFILE=%t5 --check-prefix=WARN_MISSING_PC
-
-# WARN_MISSING_PC: warning: '[[FILE]]': failed while reading call graph info function entry PC unexpected end of data at offset 0x2 while reading [0x2, 0xa)
-
---- !ELF
-FileHeader:
- Class: ELFCLASS64
- Data: ELFDATA2LSB
- Type: ET_DYN
- Machine: EM_X86_64
-Sections:
- - Name: .text
- Type: SHT_PROGBITS
- Size: 5
- - Name: .llvm.callgraph
- Type: SHT_LLVM_CALL_GRAPH
- ContentArray: [
- # --- Entry 1: foo (foo) ---
- 0x00, # Format Version
- 0x00, # Flags
- #< Missing function entry PC
- ]
-Symbols:
- - Name: foo
-...
-
-## Check missing function Type ID.
-# RUN: yaml2obj --docnum=6 %s -o %t6
-# RUN: llvm-readelf --elf-output-style=LLVM --call-graph-info %t6 2>&1 | FileCheck %s -DFILE=%t6 --check-prefix=WARN_MISSING_TYPEID
-# RUN: llvm-readelf --elf-output-style=JSON --pretty-print --call-graph-info %t6 2>&1 | FileCheck %s -DFILE=%t6 --check-prefix=WARN_MISSING_TYPEID
-
-# WARN_MISSING_TYPEID: warning: '[[FILE]]': failed while reading function type ID unexpected end of data at offset 0xa while reading [0xa, 0x12)
-
---- !ELF
-FileHeader:
- Class: ELFCLASS64
- Data: ELFDATA2LSB
- Type: ET_DYN
- Machine: EM_X86_64
-Sections:
- - Name: .text
- Type: SHT_PROGBITS
- Size: 5
- - Name: .llvm.callgraph
- Type: SHT_LLVM_CALL_GRAPH
- ContentArray: [
- # --- Entry 1: foo (foo) ---
- 0x00, # Format Version
- 0x00, # Flags
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, # Function entry address
- #< Missing Type ID
- ]
-Symbols:
- - Name: foo
-...
-
-## Check missing number of direct callees.
-# RUN: yaml2obj --docnum=7 %s -o %t7
-# RUN: llvm-readelf --elf-output-style=LLVM --call-graph-info %t7 2>&1 | FileCheck %s -DFILE=%t7 --check-prefix=WARN_MISSING_DIRECT
-# RUN: llvm-readelf --elf-output-style=JSON --pretty-print --call-graph-info %t7 2>&1 | FileCheck %s -DFILE=%t7 --check-prefix=WARN_MISSING_DIRECT
-
-# WARN_MISSING_DIRECT: warning: '[[FILE]]': failed while reading number of direct callees unable to decode LEB128 at offset 0x00000012: malformed uleb128, extends past end
-
---- !ELF
-FileHeader:
- Class: ELFCLASS64
- Data: ELFDATA2LSB
- Type: ET_DYN
- Machine: EM_X86_64
-Sections:
- - Name: .text
- Type: SHT_PROGBITS
- Size: 5
- - Name: .llvm.callgraph
- Type: SHT_LLVM_CALL_GRAPH
- ContentArray: [
- # --- Entry 1: foo (foo) ---
- 0x00, # Format Version
- 0x02, # Flags (HasDirectCallees)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, # Function entry address
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, # TypeID unknown
- #< Missing NumDirectCallees (ULEB128)
- ]
-Symbols:
- - Name: foo
-...
-
-## Check missing direct callee.
-# RUN: yaml2obj --docnum=8 %s -o %t8
-# RUN: llvm-readelf --elf-output-style=LLVM --call-graph-info %t8 2>&1 | FileCheck %s -DFILE=%t8 --check-prefix=WARN_MISSING_CALLEE
-# RUN: llvm-readelf --elf-output-style=JSON --pretty-print --call-graph-info %t8 2>&1 | FileCheck %s -DFILE=%t8 --check-prefix=WARN_MISSING_CALLEE
-
-# WARN_MISSING_CALLEE: warning: '[[FILE]]': failed while reading direct callee unexpected end of data at offset 0x13 while reading [0x13, 0x1b)
-
---- !ELF
-FileHeader:
- Class: ELFCLASS64
- Data: ELFDATA2LSB
- Type: ET_DYN
- Machine: EM_X86_64
-Sections:
- - Name: .text
- Type: SHT_PROGBITS
- Size: 5
- - Name: .llvm.callgraph
- Type: SHT_LLVM_CALL_GRAPH
- ContentArray: [
- # --- Entry 1: foo (foo) ---
- 0x00, # Format Version
- 0x02, # Flags (HasDirectCallees)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, # Function entry address
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, # TypeID unknown
- 0x01, # NumDirectCallees
- #< Missing direct callee address
- ]
-Symbols:
- - Name: foo
-...
-
-## Check missing number of indirect target type IDs.
-# RUN: yaml2obj --docnum=9 %s -o %t9
-# RUN: llvm-readelf --elf-output-style=LLVM --call-graph-info %t9 2>&1 | FileCheck %s -DFILE=%t9 --check-prefix=WARN_MISSING_NUM_INDIRECT
-# RUN: llvm-readelf --elf-output-style=JSON --pretty-print --call-graph-info %t9 2>&1 | FileCheck %s -DFILE=%t9 --check-prefix=WARN_MISSING_NUM_INDIRECT
-
-# WARN_MISSING_NUM_INDIRECT: warning: '[[FILE]]': failed while reading number of indirect target type IDs unable to decode LEB128 at offset 0x00000012: malformed uleb128, extends past end
-
---- !ELF
-FileHeader:
- Class: ELFCLASS64
- Data: ELFDATA2LSB
- Type: ET_DYN
- Machine: EM_X86_64
-Sections:
- - Name: .text
- Type: SHT_PROGBITS
- Size: 5
- - Name: .llvm.callgraph
- Type: SHT_LLVM_CALL_GRAPH
- ContentArray: [
- # --- Entry 1: foo (foo) ---
- 0x00, # Format Version
- 0x04, # Flags (HasIndirectCallees)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, # Function entry address
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, # TypeID unknown
- #< Missing NumIndirectTargetTypeIDs (ULEB128)
- ]
-Symbols:
- - Name: foo
-...
-
-## Check missing indirect target type ID.
-# RUN: yaml2obj --docnum=10 %s -o %t10
-# RUN: llvm-readelf --elf-output-style=LLVM --call-graph-info %t10 2>&1 | FileCheck %s -DFILE=%t10 --check-prefix=WARN_MISSING_INDIRECT_TARGET_TYPE_ID
-# RUN: llvm-readelf --elf-output-style=JSON --pretty-print --call-graph-info %t10 2>&1 | FileCheck %s -DFILE=%t10 --check-prefix=WARN_MISSING_INDIRECT_TARGET_TYPE_ID
-
-# WARN_MISSING_INDIRECT_TARGET_TYPE_ID: warning: '[[FILE]]': failed while reading indirect target type ID unexpected end of data at offset 0x13 while reading [0x13, 0x1b)
-
---- !ELF
-FileHeader:
- Class: ELFCLASS64
- Data: ELFDATA2LSB
- Type: ET_REL
- Machine: EM_X86_64
-Sections:
- - Name: .text
- Type: SHT_PROGBITS
- Size: 5
- - Name: .llvm.callgraph
- Type: SHT_LLVM_CALL_GRAPH
- ContentArray: [
- # --- Entry 1: foo (foo) ---
- 0x00, # Format Version
- 0x04, # Flags (HasIndirectCallees)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, # Function entry address
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, # TypeID unknown
- 0x01, # NumIndirectTargetTypeIDs (1)
- #< Missing indirect call entries here.
- ]
-Symbols:
- - Name: foo
-...
-
-## Check missing relocation information.
-# RUN: yaml2obj --docnum=11 %s -o %t11
-# RUN: llvm-readelf --call-graph-info %t11 2>&1 | count 0
-# RUN: llvm-readelf --elf-output-style=LLVM --call-graph-info %t11 2>&1 | FileCheck %s -DFILE=%t11 --check-prefix=WARN_NO_RELOC
-# RUN: llvm-readelf --elf-output-style=JSON --pretty-print --call-graph-info %t11 2>&1 | FileCheck %s -DFILE=%t11 --check-prefix=WARN_NO_RELOC
-
-# WARN_NO_RELOC: warning: '[[FILE]]': SHT_LLVM_CALL_GRAPH type section has unknown type id for 2 indirect targets
-# WARN_NO_RELOC: warning: '[[FILE]]': unknown relocation at offset 2
-# WARN_NO_RELOC: warning: '[[FILE]]': unknown relocation at offset 19
-# WARN_NO_RELOC: warning: '[[FILE]]': unknown relocation at offset 29
-# WARN_NO_RELOC: warning: '[[FILE]]': unknown relocation at offset 56
-
---- !ELF
-FileHeader:
- Class: ELFCLASS64
- Data: ELFDATA2LSB
- Type: ET_REL
- Machine: EM_X86_64
-Sections:
- - Name: .text
- Type: SHT_PROGBITS
- Size: 12 # or whatever size is needed for all the data
- - Name: .llvm.callgraph
- Type: SHT_LLVM_CALL_GRAPH
- ContentArray: [
- '0', # Format version number
- '3', # Flag IsIndirectTarget true, HasDirectCallees true
- '0', '0', '0', '0', '0', '0', '0', '0', # foo()'s address
- '0', '0', '0', '0', '0', '0', '0', '0', # foo()'s TypeID Unknown
- '1', # NumDirectCallees
- '0', '0', '0', '0', '0', '0', '0', '0', # Direct callee foo()'s address
- '0', # Format version number
- '5', # Flag IsIndirectTarget true, HasIndirectTargetTypeIDs true
- '6', '0', '0', '0', '0', '0', '0', '0', # bar()'s address
- '0', '0', '0', '0', '0', '0', '0', '0', # bar()'s TypeID Unknown
- '1', # NumIndirectTargetTypeIDs
- '16', '0', '0', '0', '0', '0', '0', '0', # Indirect callee type ID
- '0', # Format version number
- '1', # Flag IsIndirectTarget true
- '10', '0', '0', '0', '0', '0', '0', '0', # baz()'s address
- '32', '0', '0', '0', '0', '0', '0', '0', # baz()'s TypeID Unknown
- ]
- - Name: .rela.llvm.callgraph
- Type: SHT_RELA
- Flags: [ SHF_INFO_LINK ]
- Link: .symtab
- Relocations:
- # 1. Pointer to foo() definition
- - Offset: 0x2
- Symbol: foo
- Type: R_X86_64_64
-
- # 2. Pointer to the call site "callq foo" (offset 5 inside foo)
- # We relocate against 'foo' and add 5 to get the address of the instruction.
- - Offset: 0x13
- Symbol: foo
- Type: R_X86_64_64
- Addend: 5
-
- # 3. Pointer to bar() definition
- - Offset: 0x1D
- Symbol: bar
- Type: R_X86_64_64
-
- # 4. Pointer to baz() definition
- - Offset: 0x38
- Symbol: baz
- Type: R_X86_64_64
-Symbols:
- - Name: foo
- - Name: bar
- - Name: baz
-...
diff --git a/llvm/test/tools/llvm-readobj/ELF/call-graph-info.test b/llvm/test/tools/llvm-readobj/ELF/call-graph-info.test
deleted file mode 100644
index 7226dd8ddea89..0000000000000
--- a/llvm/test/tools/llvm-readobj/ELF/call-graph-info.test
+++ /dev/null
@@ -1,521 +0,0 @@
-## Tests how --call-graph-info prints the call graph information.
-
-## Check non-relocatable object file handling.
-# RUN: yaml2obj --docnum=1 %s -o %t1
-# RUN: llvm-readelf --call-graph-info %t1 2>&1 | FileCheck %s --match-full-lines --allow-empty --check-prefix=GNU_NONRELOC -DFILE=%t1
-# RUN: llvm-readelf --elf-output-style=LLVM --call-graph-info %t1 2>&1 | FileCheck %s --match-full-lines --check-prefix=LLVM_NONRELOC -DFILE=%t1
-# RUN: llvm-readelf --elf-output-style=JSON --pretty-print --call-graph-info %t1 2>&1 | FileCheck %s --match-full-lines --check-prefix=JSON_NONRELOC -DFILE=%t1
-
-## We do not support GNU format console output for --call-graph-info as it is an LLVM only info.
-# GNU_NONRELOC-NOT: .
-
-# LLVM_NONRELOC: CallGraph [
-# LLVM_NONRELOC-NEXT: Function {
-# LLVM_NONRELOC-NEXT: Names: [foo]
-# LLVM_NONRELOC-NEXT: Address: 0x1790
-# LLVM_NONRELOC-NEXT: Version: 0
-# LLVM_NONRELOC-NEXT: IsIndirectTarget: Yes
-# LLVM_NONRELOC-NEXT: TypeId: 0x3ECBEEF531F74424
-# LLVM_NONRELOC-NEXT: NumDirectCallees: 0
-# LLVM_NONRELOC-NEXT: DirectCallees [
-# LLVM_NONRELOC-NEXT: ]
-# LLVM_NONRELOC-NEXT: NumIndirectTargetTypeIDs: 0
-# LLVM_NONRELOC-NEXT: IndirectTypeIDs: []
-# LLVM_NONRELOC-NEXT: }
-# LLVM_NONRELOC-NEXT: Function {
-# LLVM_NONRELOC-NEXT: Names: [bar]
-# LLVM_NONRELOC-NEXT: Address: 0x17A0
-# LLVM_NONRELOC-NEXT: Version: 0
-# LLVM_NONRELOC-NEXT: IsIndirectTarget: Yes
-# LLVM_NONRELOC-NEXT: TypeId: 0x3ECBEEF531F74424
-# LLVM_NONRELOC-NEXT: NumDirectCallees: 0
-# LLVM_NONRELOC-NEXT: DirectCallees [
-# LLVM_NONRELOC-NEXT: ]
-# LLVM_NONRELOC-NEXT: NumIndirectTargetTypeIDs: 0
-# LLVM_NONRELOC-NEXT: IndirectTypeIDs: []
-# LLVM_NONRELOC-NEXT: }
-# LLVM_NONRELOC-NEXT: Function {
-# LLVM_NONRELOC-NEXT: Names: [baz]
-# LLVM_NONRELOC-NEXT: Address: 0x17B0
-# LLVM_NONRELOC-NEXT: Version: 0
-# LLVM_NONRELOC-NEXT: IsIndirectTarget: Yes
-# LLVM_NONRELOC-NEXT: TypeId: 0x308E4B8159BC8654
-# LLVM_NONRELOC-NEXT: NumDirectCallees: 0
-# LLVM_NONRELOC-NEXT: DirectCallees [
-# LLVM_NONRELOC-NEXT: ]
-# LLVM_NONRELOC-NEXT: NumIndirectTargetTypeIDs: 0
-# LLVM_NONRELOC-NEXT: IndirectTypeIDs: []
-# LLVM_NONRELOC-NEXT: }
-# LLVM_NONRELOC-NEXT: Function {
-# LLVM_NONRELOC-NEXT: Names: [main]
-# LLVM_NONRELOC-NEXT: Address: 0x17C0
-# LLVM_NONRELOC-NEXT: Version: 0
-# LLVM_NONRELOC-NEXT: IsIndirectTarget: Yes
-# LLVM_NONRELOC-NEXT: TypeId: 0xFA6809609A76AFCA
-# LLVM_NONRELOC-NEXT: NumDirectCallees: 3
-# LLVM_NONRELOC-NEXT: DirectCallees [
-# LLVM_NONRELOC-NEXT: {
-# LLVM_NONRELOC-NEXT: Names: [foo]
-# LLVM_NONRELOC-NEXT: Address: 0x1790
-# LLVM_NONRELOC-NEXT: }
-# LLVM_NONRELOC-NEXT: {
-# LLVM_NONRELOC-NEXT: Names: [bar]
-# LLVM_NONRELOC-NEXT: Address: 0x17A0
-# LLVM_NONRELOC-NEXT: }
-# LLVM_NONRELOC-NEXT: {
-# LLVM_NONRELOC-NEXT: Names: [baz]
-# LLVM_NONRELOC-NEXT: Address: 0x17B0
-# LLVM_NONRELOC-NEXT: }
-# LLVM_NONRELOC-NEXT: ]
-# LLVM_NONRELOC-NEXT: NumIndirectTargetTypeIDs: 2
-# LLVM_NONRELOC-NEXT: IndirectTypeIDs: [0x3ECBEEF531F74424, 0x308E4B8159BC8654]
-# LLVM_NONRELOC-NEXT: }
-# LLVM_NONRELOC-NEXT: ]
-
-# JSON_NONRELOC: "CallGraph": [
-# JSON_NONRELOC-NEXT: {
-# JSON_NONRELOC-NEXT: "Function": {
-# JSON_NONRELOC-NEXT: "Names": [
-# JSON_NONRELOC-NEXT: "foo"
-# JSON_NONRELOC-NEXT: ],
-# JSON_NONRELOC-NEXT: "Address": 6032,
-# JSON_NONRELOC-NEXT: "Version": 0,
-# JSON_NONRELOC-NEXT: "IsIndirectTarget": true,
-# JSON_NONRELOC-NEXT: "TypeId": 4524972987496481828,
-# JSON_NONRELOC-NEXT: "NumDirectCallees": 0,
-# JSON_NONRELOC-NEXT: "DirectCallees": [],
-# JSON_NONRELOC-NEXT: "NumIndirectTargetTypeIDs": 0,
-# JSON_NONRELOC-NEXT: "IndirectTypeIDs": []
-# JSON_NONRELOC-NEXT: }
-# JSON_NONRELOC-NEXT: },
-# JSON_NONRELOC-NEXT: {
-# JSON_NONRELOC-NEXT: "Function": {
-# JSON_NONRELOC-NEXT: "Names": [
-# JSON_NONRELOC-NEXT: "bar"
-# JSON_NONRELOC-NEXT: ],
-# JSON_NONRELOC-NEXT: "Address": 6048,
-# JSON_NONRELOC-NEXT: "Version": 0,
-# JSON_NONRELOC-NEXT: "IsIndirectTarget": true,
-# JSON_NONRELOC-NEXT: "TypeId": 4524972987496481828,
-# JSON_NONRELOC-NEXT: "NumDirectCallees": 0,
-# JSON_NONRELOC-NEXT: "DirectCallees": [],
-# JSON_NONRELOC-NEXT: "NumIndirectTargetTypeIDs": 0,
-# JSON_NONRELOC-NEXT: "IndirectTypeIDs": []
-# JSON_NONRELOC-NEXT: }
-# JSON_NONRELOC-NEXT: },
-# JSON_NONRELOC-NEXT: {
-# JSON_NONRELOC-NEXT: "Function": {
-# JSON_NONRELOC-NEXT: "Names": [
-# JSON_NONRELOC-NEXT: "baz"
-# JSON_NONRELOC-NEXT: ],
-# JSON_NONRELOC-NEXT: "Address": 6064,
-# JSON_NONRELOC-NEXT: "Version": 0,
-# JSON_NONRELOC-NEXT: "IsIndirectTarget": true,
-# JSON_NONRELOC-NEXT: "TypeId": 3498816979441845844,
-# JSON_NONRELOC-NEXT: "NumDirectCallees": 0,
-# JSON_NONRELOC-NEXT: "DirectCallees": [],
-# JSON_NONRELOC-NEXT: "NumIndirectTargetTypeIDs": 0,
-# JSON_NONRELOC-NEXT: "IndirectTypeIDs": []
-# JSON_NONRELOC-NEXT: }
-# JSON_NONRELOC-NEXT: },
-# JSON_NONRELOC-NEXT: {
-# JSON_NONRELOC-NEXT: "Function": {
-# JSON_NONRELOC-NEXT: "Names": [
-# JSON_NONRELOC-NEXT: "main"
-# JSON_NONRELOC-NEXT: ],
-# JSON_NONRELOC-NEXT: "Address": 6080,
-# JSON_NONRELOC-NEXT: "Version": 0,
-# JSON_NONRELOC-NEXT: "IsIndirectTarget": true,
-# JSON_NONRELOC-NEXT: "TypeId": 18043682217572872138,
-# JSON_NONRELOC-NEXT: "NumDirectCallees": 3,
-# JSON_NONRELOC-NEXT: "DirectCallees": [
-# JSON_NONRELOC-NEXT: {
-# JSON_NONRELOC-NEXT: "Names": [
-# JSON_NONRELOC-NEXT: "foo"
-# JSON_NONRELOC-NEXT: ],
-# JSON_NONRELOC-NEXT: "Address": 6032
-# JSON_NONRELOC-NEXT: },
-# JSON_NONRELOC-NEXT: {
-# JSON_NONRELOC-NEXT: "Names": [
-# JSON_NONRELOC-NEXT: "bar"
-# JSON_NONRELOC-NEXT: ],
-# JSON_NONRELOC-NEXT: "Address": 6048
-# JSON_NONRELOC-NEXT: },
-# JSON_NONRELOC-NEXT: {
-# JSON_NONRELOC-NEXT: "Names": [
-# JSON_NONRELOC-NEXT: "baz"
-# JSON_NONRELOC-NEXT: ],
-# JSON_NONRELOC-NEXT: "Address": 6064
-# JSON_NONRELOC-NEXT: }
-# JSON_NONRELOC-NEXT: ],
-# JSON_NONRELOC-NEXT: "NumIndirectTargetTypeIDs": 2,
-# JSON_NONRELOC-NEXT: "IndirectTypeIDs": [
-# JSON_NONRELOC-NEXT: 4524972987496481828,
-# JSON_NONRELOC-NEXT: 3498816979441845844
-# JSON_NONRELOC-NEXT: ]
-# JSON_NONRELOC-NEXT: }
-# JSON_NONRELOC-NEXT: }
-# JSON_NONRELOC-NEXT: ]
-
---- !ELF
-FileHeader:
- Class: ELFCLASS64
- Data: ELFDATA2LSB
- Type: ET_DYN
- Machine: EM_X86_64
-Sections:
- - Name: .text
- Type: SHT_PROGBITS
- Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
- Size: 0x2000
- - Name: .llvm.callgraph
- Type: SHT_LLVM_CALL_GRAPH
- Flags: [ SHF_LINK_ORDER ]
- Link: .text
- ContentArray: [
- # --- foo ---
- 0x00, # Version
- 0x01, # Flags
- 0x90, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, # FunctionEntryPC: 0x1790
- 0x24, 0x44, 0xF7, 0x31, 0xF5, 0xEE, 0xCB, 0x3E, # FunctionTypeID: 0x3ECBEEF531F74424
-
- # --- bar ---
- 0x00, # Version
- 0x01, # Flags
- 0xA0, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, # FunctionEntryPC: 0x17A0
- 0x24, 0x44, 0xF7, 0x31, 0xF5, 0xEE, 0xCB, 0x3E, # FunctionTypeID: 0x3ECBEEF531F74424
-
- # --- baz ---
- 0x00, # Version
- 0x01, # Flags
- 0xB0, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, # FunctionEntryPC: 0x17B0
- 0x54, 0x86, 0xBC, 0x59, 0x81, 0x4B, 0x8E, 0x30, # FunctionTypeID: 0x308E4B8159BC8654
-
- # --- main ---
- 0x00, # Version
- 0x07, # Flags
- 0xC0, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, # FunctionEntryPC: 0x17C0
- 0xCA, 0xAF, 0x76, 0x9A, 0x60, 0x09, 0x68, 0xFA, # FunctionTypeID: 0xFA6809609A76AFCA
-
- # Direct Callees
- 0x03, # NumDirectCallees
- 0x90, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, # Callee 1: 0x1790 (foo)
- 0xA0, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, # Callee 2: 0x17A0 (bar)
- 0xB0, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, # Callee 3: 0x17B0 (baz)
-
- # Indirect Callees
- 0x02, # NumIndirectTargetTypeIDs
- 0x24, 0x44, 0xF7, 0x31, 0xF5, 0xEE, 0xCB, 0x3E, # TypeID 1
- 0x54, 0x86, 0xBC, 0x59, 0x81, 0x4B, 0x8E, 0x30 # TypeID 2
- ]
-Symbols:
- - Name: foo
- Type: STT_FUNC
- Section: .text
- Value: 0x1790
- - Name: bar
- Type: STT_FUNC
- Section: .text
- Value: 0x17A0
- - Name: baz
- Type: STT_FUNC
- Section: .text
- Value: 0x17B0
- - Name: main
- Type: STT_FUNC
- Section: .text
- Value: 0x17C0
-...
-
-## Check relocatable object file handling.
-# RUN: yaml2obj --docnum=2 %s -o %t2
-# RUN: llvm-readelf --call-graph-info %t2 2>&1 | FileCheck %s --match-full-lines --allow-empty -check-prefix=GNU_RELOC -DFILE=%t2
-# RUN: llvm-readelf --elf-output-style=LLVM --call-graph-info %t2 2>&1 | FileCheck %s --match-full-lines --check-prefix=LLVM_RELOC -DFILE=%t2
-# RUN: llvm-readelf --elf-output-style=JSON --pretty-print --call-graph-info %t2 2>&1 | FileCheck %s --match-full-lines --check-prefix=JSON_RELOC -DFILE=%t2
-
-## We do not support GNU format console output for --call-graph-info as it is an LLVM only info.
-# GNU_RELOC-NOT: .
-
-# LLVM_RELOC: CallGraph [
-# LLVM_RELOC-NEXT: Function {
-# LLVM_RELOC-NEXT: Name: foo
-# LLVM_RELOC-NEXT: Version: 0
-# LLVM_RELOC-NEXT: IsIndirectTarget: Yes
-# LLVM_RELOC-NEXT: TypeId: 0xF85C699BB8EF20A2
-# LLVM_RELOC-NEXT: NumDirectCallees: 0
-# LLVM_RELOC-NEXT: DirectCallees [
-# LLVM_RELOC-NEXT: ]
-# LLVM_RELOC-NEXT: NumIndirectTargetTypeIDs: 0
-# LLVM_RELOC-NEXT: IndirectTypeIDs: []
-# LLVM_RELOC-NEXT: }
-# LLVM_RELOC-NEXT: Function {
-# LLVM_RELOC-NEXT: Name: bar
-# LLVM_RELOC-NEXT: Version: 0
-# LLVM_RELOC-NEXT: IsIndirectTarget: Yes
-# LLVM_RELOC-NEXT: TypeId: 0xF85C699BB8EF20A2
-# LLVM_RELOC-NEXT: NumDirectCallees: 0
-# LLVM_RELOC-NEXT: DirectCallees [
-# LLVM_RELOC-NEXT: ]
-# LLVM_RELOC-NEXT: NumIndirectTargetTypeIDs: 0
-# LLVM_RELOC-NEXT: IndirectTypeIDs: []
-# LLVM_RELOC-NEXT: }
-# LLVM_RELOC-NEXT: Function {
-# LLVM_RELOC-NEXT: Name: baz
-# LLVM_RELOC-NEXT: Version: 0
-# LLVM_RELOC-NEXT: IsIndirectTarget: Yes
-# LLVM_RELOC-NEXT: TypeId: 0x308E4B8159BC8654
-# LLVM_RELOC-NEXT: NumDirectCallees: 0
-# LLVM_RELOC-NEXT: DirectCallees [
-# LLVM_RELOC-NEXT: ]
-# LLVM_RELOC-NEXT: NumIndirectTargetTypeIDs: 0
-# LLVM_RELOC-NEXT: IndirectTypeIDs: []
-# LLVM_RELOC-NEXT: }
-# LLVM_RELOC-NEXT: Function {
-# LLVM_RELOC-NEXT: Name: caller
-# LLVM_RELOC-NEXT: Version: 0
-# LLVM_RELOC-NEXT: IsIndirectTarget: Yes
-# LLVM_RELOC-NEXT: TypeId: 0xA9494DEF81A01DC
-# LLVM_RELOC-NEXT: NumDirectCallees: 3
-# LLVM_RELOC-NEXT: DirectCallees [
-# LLVM_RELOC-NEXT: {
-# LLVM_RELOC-NEXT: Name: foo
-# LLVM_RELOC-NEXT: }
-# LLVM_RELOC-NEXT: {
-# LLVM_RELOC-NEXT: Name: bar
-# LLVM_RELOC-NEXT: }
-# LLVM_RELOC-NEXT: {
-# LLVM_RELOC-NEXT: Name: baz
-# LLVM_RELOC-NEXT: }
-# LLVM_RELOC-NEXT: ]
-# LLVM_RELOC-NEXT: NumIndirectTargetTypeIDs: 2
-# LLVM_RELOC-NEXT: IndirectTypeIDs: [0xF85C699BB8EF20A2, 0x308E4B8159BC8654]
-# LLVM_RELOC-NEXT: }
-# LLVM_RELOC-NEXT: ]
-
-# JSON_RELOC: "CallGraph": [
-# JSON_RELOC-NEXT: {
-# JSON_RELOC-NEXT: "Function": {
-# JSON_RELOC-NEXT: "Name": "foo",
-# JSON_RELOC-NEXT: "Version": 0,
-# JSON_RELOC-NEXT: "IsIndirectTarget": true,
-# JSON_RELOC-NEXT: "TypeId": 17896295136807035042,
-# JSON_RELOC-NEXT: "NumDirectCallees": 0,
-# JSON_RELOC-NEXT: "DirectCallees": [],
-# JSON_RELOC-NEXT: "NumIndirectTargetTypeIDs": 0,
-# JSON_RELOC-NEXT: "IndirectTypeIDs": []
-# JSON_RELOC-NEXT: }
-# JSON_RELOC-NEXT: },
-# JSON_RELOC-NEXT: {
-# JSON_RELOC-NEXT: "Function": {
-# JSON_RELOC-NEXT: "Name": "bar",
-# JSON_RELOC-NEXT: "Version": 0,
-# JSON_RELOC-NEXT: "IsIndirectTarget": true,
-# JSON_RELOC-NEXT: "TypeId": 17896295136807035042,
-# JSON_RELOC-NEXT: "NumDirectCallees": 0,
-# JSON_RELOC-NEXT: "DirectCallees": [],
-# JSON_RELOC-NEXT: "NumIndirectTargetTypeIDs": 0,
-# JSON_RELOC-NEXT: "IndirectTypeIDs": []
-# JSON_RELOC-NEXT: }
-# JSON_RELOC-NEXT: },
-# JSON_RELOC-NEXT: {
-# JSON_RELOC-NEXT: "Function": {
-# JSON_RELOC-NEXT: "Name": "baz",
-# JSON_RELOC-NEXT: "Version": 0,
-# JSON_RELOC-NEXT: "IsIndirectTarget": true,
-# JSON_RELOC-NEXT: "TypeId": 3498816979441845844,
-# JSON_RELOC-NEXT: "NumDirectCallees": 0,
-# JSON_RELOC-NEXT: "DirectCallees": [],
-# JSON_RELOC-NEXT: "NumIndirectTargetTypeIDs": 0,
-# JSON_RELOC-NEXT: "IndirectTypeIDs": []
-# JSON_RELOC-NEXT: }
-# JSON_RELOC-NEXT: },
-# JSON_RELOC-NEXT: {
-# JSON_RELOC-NEXT: "Function": {
-# JSON_RELOC-NEXT: "Name": "caller",
-# JSON_RELOC-NEXT: "Version": 0,
-# JSON_RELOC-NEXT: "IsIndirectTarget": true,
-# JSON_RELOC-NEXT: "TypeId": 762397922298560988,
-# JSON_RELOC-NEXT: "NumDirectCallees": 3,
-# JSON_RELOC-NEXT: "DirectCallees": [
-# JSON_RELOC-NEXT: {
-# JSON_RELOC-NEXT: "Name": "foo"
-# JSON_RELOC-NEXT: },
-# JSON_RELOC-NEXT: {
-# JSON_RELOC-NEXT: "Name": "bar"
-# JSON_RELOC-NEXT: },
-# JSON_RELOC-NEXT: {
-# JSON_RELOC-NEXT: "Name": "baz"
-# JSON_RELOC-NEXT: }
-# JSON_RELOC-NEXT: ],
-# JSON_RELOC-NEXT: "NumIndirectTargetTypeIDs": 2,
-# JSON_RELOC-NEXT: "IndirectTypeIDs": [
-# JSON_RELOC-NEXT: 17896295136807035042,
-# JSON_RELOC-NEXT: 3498816979441845844
-# JSON_RELOC-NEXT: ]
-# JSON_RELOC-NEXT: }
-# JSON_RELOC-NEXT: }
-# JSON_RELOC-NEXT: ]
-
---- !ELF
-FileHeader:
- Class: ELFCLASS64
- Data: ELFDATA2LSB
- Type: ET_REL
- Machine: EM_X86_64
-Sections:
- - Name: .text
- Type: SHT_PROGBITS
- Size: 0x84
- - Name: .llvm.callgraph
- Type: SHT_LLVM_CALL_GRAPH
- Flags: [ SHF_LINK_ORDER ]
- Link: .text
- ContentArray: [
- # --- Entry 1: foo (foo) ---
- # Offset 0x0
- 0x00, # Format Version
- 0x01, # Flags
- # Offset 0x2 (Matches Reloc: foo)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, # Address of foo
- 0xA2, 0x20, 0xEF, 0xB8, 0x9B, 0x69, 0x5C, 0xF8, # TypeID of foo
-
- # --- Entry 2: bar (bar) ---
- # Offset 0x12
- 0x00, # Format Version
- 0x01, # Flags
- # Offset 0x14 (Matches Reloc: bar)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, # Address of bar
- 0xA2, 0x20, 0xEF, 0xB8, 0x9B, 0x69, 0x5C, 0xF8, # TypeID of bar
-
- # --- Entry 3: baz (baz) ---
- # Offset 0x24
- 0x00, # Format Version
- 0x01, # Flags
- # Offset 0x26 (Matches Reloc: baz)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, # Address of baz
- 0x54, 0x86, 0xBC, 0x59, 0x81, 0x4B, 0x8E, 0x30, # TypeID of baz
-
- # --- Entry 4: caller (caller) ---
- # Offset 0x36
- 0x00, # Format Version
- 0x07, # Flags (HasDirectCallees | IsIndirectTarget | ...)
- # Offset 0x38 (Matches Reloc: caller)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, # Address of caller
- 0xDC, 0x01, 0x1A, 0xF8, 0xDE, 0x94, 0x94, 0x0A, # TypeID of caller
-
- # Direct Callees List
- 0x03, # NumDirectCallees (3)
- # Offset 0x49 (Matches Reloc: foo)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, # Callee 1: foo
- # Offset 0x51 (Matches Reloc: bar)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, # Callee 2: bar
- # Offset 0x59 (Matches Reloc: baz)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, # Callee 3: baz
-
- # Indirect Callees List
- 0x02, # NumIndirectTargetTypeIDs (2)
- 0xA2, 0x20, 0xEF, 0xB8, 0x9B, 0x69, 0x5C, 0xF8, # Indirect TypeID 1 (matches foo/bar)
- 0x54, 0x86, 0xBC, 0x59, 0x81, 0x4B, 0x8E, 0x30 # Indirect TypeID 2 (matches baz)
- ]
- - Name: .rela.llvm.callgraph
- Type: SHT_RELA
- Flags: [ SHF_INFO_LINK ]
- Info: .llvm.callgraph
- Relocations:
- - Offset: 0x2
- Symbol: foo
- Type: R_X86_64_64
- - Offset: 0x14
- Symbol: bar
- Type: R_X86_64_64
- - Offset: 0x26
- Symbol: baz
- Type: R_X86_64_64
- - Offset: 0x38
- Symbol: caller
- Type: R_X86_64_64
- - Offset: 0x49
- Symbol: foo
- Type: R_X86_64_64
- - Offset: 0x51
- Symbol: bar
- Type: R_X86_64_64
- - Offset: 0x59
- Symbol: baz
- Type: R_X86_64_64
-Symbols:
- - Name: foo
- - Name: bar
- - Name: baz
- - Name: caller
-...
-
-## Check ARM 32-bit Thumb address handling.
-# RUN: yaml2obj --docnum=3 %s -o %t3
-# RUN: llvm-readelf --elf-output-style=LLVM --call-graph-info %t3 2>&1 | FileCheck %s --match-full-lines --check-prefix=LLVM_ARM_THUMB -DFILE=%t3
-# RUN: llvm-readelf --elf-output-style=JSON --pretty-print --call-graph-info %t3 2>&1 | FileCheck %s --match-full-lines --check-prefix=JSON_ARM_THUMB -DFILE=%t3
-
-# LLVM_ARM_THUMB: CallGraph [
-# LLVM_ARM_THUMB-NEXT: Function {
-# LLVM_ARM_THUMB-NEXT: Name: foo
-# LLVM_ARM_THUMB-NEXT: Version: 0
-# LLVM_ARM_THUMB-NEXT: IsIndirectTarget: No
-# LLVM_ARM_THUMB-NEXT: TypeId: 0x123456789ABCDEF0
-# LLVM_ARM_THUMB-NEXT: NumDirectCallees: 0
-# LLVM_ARM_THUMB-NEXT: DirectCallees [
-# LLVM_ARM_THUMB-NEXT: ]
-# LLVM_ARM_THUMB-NEXT: NumIndirectTargetTypeIDs: 0
-# LLVM_ARM_THUMB-NEXT: IndirectTypeIDs: []
-# LLVM_ARM_THUMB-NEXT: }
-# LLVM_ARM_THUMB-NEXT: ]
-
-# JSON_ARM_THUMB: "CallGraph": [
-# JSON_ARM_THUMB-NEXT: {
-# JSON_ARM_THUMB-NEXT: "Function": {
-# JSON_ARM_THUMB-NEXT: "Name": "foo",
-# JSON_ARM_THUMB-NEXT: "Version": 0,
-# JSON_ARM_THUMB-NEXT: "IsIndirectTarget": false,
-# JSON_ARM_THUMB-NEXT: "TypeId": 1311768467463790320,
-# JSON_ARM_THUMB-NEXT: "NumDirectCallees": 0,
-# JSON_ARM_THUMB-NEXT: "DirectCallees": [],
-# JSON_ARM_THUMB-NEXT: "NumIndirectTargetTypeIDs": 0,
-# JSON_ARM_THUMB-NEXT: "IndirectTypeIDs": []
-# JSON_ARM_THUMB-NEXT: }
-# JSON_ARM_THUMB-NEXT: }
-# JSON_ARM_THUMB-NEXT: ]
-
---- !ELF
-FileHeader:
- Class: ELFCLASS32
- Data: ELFDATA2LSB
- Type: ET_REL
- Machine: EM_ARM
-Sections:
- - Name: .text
- Type: SHT_PROGBITS
- Size: 0x100
- - Name: .llvm.callgraph
- Type: SHT_LLVM_CALL_GRAPH
- Flags: [ SHF_LINK_ORDER ]
- Link: .text
- ContentArray: [
- # --- foo+1 (Thumb address) ---
- 0x00, # Version
- 0x00, # Flags
- 0x01, 0x00, 0x00, 0x00, # FunctionEntryPC: 0x1 (relative to foo)
- 0xF0, 0xDE, 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12 # FunctionTypeID: 0x123456789ABCDEF0
- ]
- - Name: .rela.llvm.callgraph
- Type: SHT_RELA
- Flags: [ SHF_INFO_LINK ]
- Info: .llvm.callgraph
- Relocations:
- - Offset: 0x2 # Offset to FunctionEntryPC
- Symbol: foo
- Type: R_ARM_ABS32
-Symbols:
- - Name: foo
- Type: STT_FUNC
- Section: .text
- Value: 0x0
-...
diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp
index 7239230704678..96c4668984965 100644
--- a/llvm/tools/llvm-readobj/ELFDumper.cpp
+++ b/llvm/tools/llvm-readobj/ELFDumper.cpp
@@ -22,7 +22,6 @@
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
@@ -37,6 +36,7 @@
#include "llvm/Object/ELF.h"
#include "llvm/Object/ELFObjectFile.h"
#include "llvm/Object/ELFTypes.h"
+#include "llvm/Object/Error.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Object/RelocationResolver.h"
#include "llvm/Object/SFrameParser.h"
@@ -182,16 +182,6 @@ struct GroupSection {
std::vector<GroupMember> Members;
};
-// Per-function call graph information.
-struct FunctionCallgraphInfo {
- uint64_t FunctionAddress;
- uint8_t FormatVersionNumber;
- bool IsIndirectTarget;
- uint64_t FunctionTypeId;
- SmallSet<uint64_t, 4> DirectCallees;
- SmallSet<uint64_t, 4> IndirectTypeIDs;
-};
-
namespace {
struct NoteType {
@@ -451,15 +441,6 @@ template <typename ELFT> class ELFDumper : public ObjDumper {
const SFrameParser<ELFT::Endianness> &Parser,
const typename SFrameParser<ELFT::Endianness>::FDERange::iterator FDE,
ArrayRef<Relocation<ELFT>> Relocations, const Elf_Shdr *RelocSymTab);
- // Callgraph - Main data structure to maintain per function callgraph
- // information.
- SmallVector<FunctionCallgraphInfo, 16> FuncCGInfos;
-
- // Read the SHT_LLVM_CALL_GRAPH type section and process its contents to
- // populate call graph related data structures which will be used to dump call
- // graph info. Returns false if there is no SHT_LLVM_CALL_GRAPH type section
- // in the input file.
- bool processCallGraphSection(const Elf_Shdr *CGSection);
private:
mutable SmallVector<std::optional<VersionEntry>, 0> VersionMap;
@@ -758,7 +739,6 @@ template <typename ELFT> class LLVMELFDumper : public ELFDumper<ELFT> {
void printVersionDefinitionSection(const Elf_Shdr *Sec) override;
void printVersionDependencySection(const Elf_Shdr *Sec) override;
void printCGProfile() override;
- void printCallGraphInfo() override;
void printBBAddrMaps(bool PrettyPGOAnalysis) override;
void printAddrsig() override;
void printNotes() override;
@@ -5337,158 +5317,6 @@ template <class ELFT> void GNUELFDumper<ELFT>::printCGProfile() {
OS << "GNUStyle::printCGProfile not implemented\n";
}
-namespace callgraph {
-LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();
-enum Flags : uint8_t {
- None = 0,
- IsIndirectTarget = 1u << 0,
- HasDirectCallees = 1u << 1,
- HasIndirectCallees = 1u << 2,
- LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue*/ HasIndirectCallees)
-};
-} // namespace callgraph
-
-template <class ELFT>
-bool ELFDumper<ELFT>::processCallGraphSection(const Elf_Shdr *CGSection) {
- Expected<ArrayRef<uint8_t>> SectionBytesOrErr =
- Obj.getSectionContents(*CGSection);
- if (!SectionBytesOrErr) {
- reportWarning(
- createError("unable to read the SHT_LLVM_CALL_GRAPH type section " +
- toString(SectionBytesOrErr.takeError())),
- FileName);
- return false;
- }
-
- DataExtractor Data(SectionBytesOrErr.get(), Obj.isLE(),
- ObjF.getBytesInAddress());
- DataExtractor::Cursor C(0);
- uint64_t UnknownCount = 0;
- while (C && C.tell() < CGSection->sh_size) {
- uint8_t FormatVersionNumber = Data.getU8(C);
- if (!C) {
- reportWarning(createError("failed while reading FormatVersionNumber " +
- toString(C.takeError())),
- FileName);
- return false;
- }
- if (FormatVersionNumber != 0) {
- reportWarning(createError("unknown format version value [" +
- std::to_string(FormatVersionNumber) +
- "] in SHT_LLVM_CALL_GRAPH type section"),
- FileName);
- return false;
- }
-
- uint8_t FlagsVal = Data.getU8(C);
- if (!C) {
- reportWarning(
- createError("failed while reading call graph info's Flags " +
- toString(C.takeError())),
- FileName);
- return false;
- }
- callgraph::Flags CGFlags = static_cast<callgraph::Flags>(FlagsVal);
- constexpr callgraph::Flags ValidFlags = callgraph::IsIndirectTarget |
- callgraph::HasDirectCallees |
- callgraph::HasIndirectCallees;
- constexpr uint8_t ValidMask = static_cast<uint8_t>(ValidFlags);
- if ((FlagsVal & ~ValidMask) != 0) {
- reportWarning(createError("unexpected Flags value [" +
- std::to_string(FlagsVal) + "] "),
- FileName);
- return false;
- }
-
- uint64_t FuncAddrOffset = C.tell();
- uint64_t FuncAddr =
- static_cast<uint64_t>(Data.getUnsigned(C, sizeof(typename ELFT::uint)));
- if (!C) {
- reportWarning(
- createError(
- "failed while reading call graph info function entry PC " +
- toString(C.takeError())),
- FileName);
- return false;
- }
-
- bool IsETREL = this->Obj.getHeader().e_type == ELF::ET_REL;
- // Create a new entry for this function.
- FunctionCallgraphInfo CGInfo;
- CGInfo.FunctionAddress = IsETREL ? FuncAddrOffset : FuncAddr;
- CGInfo.FormatVersionNumber = FormatVersionNumber;
- bool IsIndirectTarget =
- (CGFlags & callgraph::IsIndirectTarget) != callgraph::None;
- CGInfo.IsIndirectTarget = IsIndirectTarget;
- uint64_t TypeId = Data.getU64(C);
- if (!C) {
- reportWarning(createError("failed while reading function type ID " +
- toString(C.takeError())),
- FileName);
- return false;
- }
- CGInfo.FunctionTypeId = TypeId;
- if (IsIndirectTarget && TypeId == 0)
- ++UnknownCount;
-
- if (CGFlags & callgraph::HasDirectCallees) {
- // Read number of direct call sites for this function.
- uint64_t NumDirectCallees = Data.getULEB128(C);
- if (!C) {
- reportWarning(
- createError("failed while reading number of direct callees " +
- toString(C.takeError())),
- FileName);
- return false;
- }
- // Read unique direct callees and populate FuncCGInfos.
- for (uint64_t I = 0; I < NumDirectCallees; ++I) {
- uint64_t CalleeOffset = C.tell();
- uint64_t Callee = static_cast<uint64_t>(
- Data.getUnsigned(C, sizeof(typename ELFT::uint)));
- if (!C) {
- reportWarning(createError("failed while reading direct callee " +
- toString(C.takeError())),
- FileName);
- return false;
- }
- CGInfo.DirectCallees.insert((IsETREL ? CalleeOffset : Callee));
- }
- }
-
- if (CGFlags & callgraph::HasIndirectCallees) {
- uint64_t NumIndirectTargetTypeIDs = Data.getULEB128(C);
- if (!C) {
- reportWarning(
- createError(
- "failed while reading number of indirect target type IDs " +
- toString(C.takeError())),
- FileName);
- return false;
- }
- // Read unique indirect target type IDs and populate FuncCGInfos.
- for (uint64_t I = 0; I < NumIndirectTargetTypeIDs; ++I) {
- uint64_t TargetType = Data.getU64(C);
- if (!C) {
- reportWarning(
- createError("failed while reading indirect target type ID " +
- toString(C.takeError())),
- FileName);
- return false;
- }
- CGInfo.IndirectTypeIDs.insert(TargetType);
- }
- }
- FuncCGInfos.push_back(CGInfo);
- }
-
- if (UnknownCount)
- reportUniqueWarning(
- "SHT_LLVM_CALL_GRAPH type section has unknown type id for " +
- std::to_string(UnknownCount) + " indirect targets");
- return true;
-}
-
template <class ELFT>
void GNUELFDumper<ELFT>::printBBAddrMaps(bool /*PrettyPGOAnalysis*/) {
OS << "GNUStyle::printBBAddrMaps not implemented\n";
@@ -8320,110 +8148,6 @@ template <class ELFT> void LLVMELFDumper<ELFT>::printCGProfile() {
}
}
-template <class ELFT> void LLVMELFDumper<ELFT>::printCallGraphInfo() {
- // Call graph section is of type SHT_LLVM_CALL_GRAPH. Typically named
- // ".llvm.callgraph". First fetch the section by its type.
- using Elf_Shdr = typename ELFT::Shdr;
- Expected<MapVector<const Elf_Shdr *, const Elf_Shdr *>> MapOrErr =
- this->Obj.getSectionAndRelocations([](const Elf_Shdr &Sec) {
- return Sec.sh_type == ELF::SHT_LLVM_CALL_GRAPH;
- });
- if (!MapOrErr || MapOrErr->empty()) {
- reportWarning(createError("no SHT_LLVM_CALL_GRAPH section found " +
- toString(MapOrErr.takeError())),
- this->FileName);
- return;
- }
- if (!this->processCallGraphSection(MapOrErr->begin()->first) ||
- this->FuncCGInfos.empty())
- return;
-
- std::vector<Relocation<ELFT>> Relocations;
- const Elf_Shdr *RelocSymTab = nullptr;
- if (this->Obj.getHeader().e_type == ELF::ET_REL) {
- const Elf_Shdr *CGRelSection = MapOrErr->front().second;
- if (CGRelSection) {
- this->forEachRelocationDo(
- *CGRelSection, [&](const Relocation<ELFT> &R, unsigned Ndx,
- const Elf_Shdr &Sec, const Elf_Shdr *SymTab) {
- RelocSymTab = SymTab;
- Relocations.push_back(R);
- });
- llvm::stable_sort(Relocations, [](const auto &LHS, const auto &RHS) {
- return LHS.Offset < RHS.Offset;
- });
- }
- }
-
- auto GetFunctionNames = [&](uint64_t FuncAddr) {
- SmallVector<uint32_t> FuncSymIndexes =
- this->getSymbolIndexesForFunctionAddress(FuncAddr, std::nullopt);
- SmallVector<std::string> FuncSymNames;
- FuncSymNames.reserve(FuncSymIndexes.size());
- for (uint32_t Index : FuncSymIndexes)
- FuncSymNames.push_back(this->getStaticSymbolName(Index));
- return FuncSymNames;
- };
-
- auto PrintNonRelocatableFuncSymbol = [&](uint64_t FuncEntryPC) {
- SmallVector<std::string> FuncSymNames = GetFunctionNames(FuncEntryPC);
- if (!FuncSymNames.empty())
- W.printList("Names", FuncSymNames);
- W.printHex("Address", FuncEntryPC);
- };
-
- auto PrintRelocatableFuncSymbol = [&](uint64_t RelocOffset) {
- auto R = llvm::find_if(Relocations, [&](const Relocation<ELFT> &R) {
- return R.Offset == RelocOffset;
- });
- if (R == Relocations.end()) {
- this->reportUniqueWarning("unknown relocation at offset " +
- Twine(RelocOffset));
- return;
- }
- Expected<RelSymbol<ELFT>> RelSymOrErr =
- this->getRelocationTarget(*R, RelocSymTab);
- if (!RelSymOrErr) {
- this->reportUniqueWarning(RelSymOrErr.takeError());
- return;
- }
- if (!RelSymOrErr->Name.empty())
- W.printString("Name", RelSymOrErr->Name);
- };
-
- auto PrintFunc = [&](uint64_t FuncPC) {
- uint64_t FuncEntryPC = FuncPC;
- // Clear Thumb bit if it was set before symbol lookup.
- if (this->Obj.getHeader().e_machine == ELF::EM_ARM)
- FuncEntryPC = FuncPC & ~1;
- if (this->Obj.getHeader().e_type == ELF::ET_REL)
- PrintRelocatableFuncSymbol(FuncEntryPC);
- else
- PrintNonRelocatableFuncSymbol(FuncEntryPC);
- };
-
- ListScope CGI(W, "CallGraph");
- for (const auto &CGInfo : this->FuncCGInfos) {
- DictScope D(W, "Function");
- PrintFunc(CGInfo.FunctionAddress);
- W.printNumber("Version", CGInfo.FormatVersionNumber);
- W.printBoolean("IsIndirectTarget", CGInfo.IsIndirectTarget);
- W.printHex("TypeId", CGInfo.FunctionTypeId);
- W.printNumber("NumDirectCallees", CGInfo.DirectCallees.size());
- {
- ListScope DCs(W, "DirectCallees");
- for (auto CalleePC : CGInfo.DirectCallees) {
- DictScope D(W);
- PrintFunc(CalleePC);
- }
- }
- W.printNumber("NumIndirectTargetTypeIDs", CGInfo.IndirectTypeIDs.size());
- SmallVector<uint64_t, 4> IndirectTypeIdsList(CGInfo.IndirectTypeIDs.begin(),
- CGInfo.IndirectTypeIDs.end());
- W.printHexList("IndirectTypeIDs", ArrayRef(IndirectTypeIdsList));
- }
-}
-
template <class ELFT>
void LLVMELFDumper<ELFT>::printBBAddrMaps(bool PrettyPGOAnalysis) {
bool IsRelocatable = this->Obj.getHeader().e_type == ELF::ET_REL;
diff --git a/llvm/tools/llvm-readobj/ObjDumper.h b/llvm/tools/llvm-readobj/ObjDumper.h
index 0dba8252fd466..d26439435a82b 100644
--- a/llvm/tools/llvm-readobj/ObjDumper.h
+++ b/llvm/tools/llvm-readobj/ObjDumper.h
@@ -130,7 +130,6 @@ class ObjDumper {
virtual void printGroupSections() {}
virtual void printHashHistograms() {}
virtual void printCGProfile() {}
- virtual void printCallGraphInfo() {}
// If PrettyPGOAnalysis is true, prints BFI as relative frequency and BPI as
// percentage. Otherwise raw values are displayed.
virtual void printBBAddrMaps(bool PrettyPGOAnalysis) {}
diff --git a/llvm/tools/llvm-readobj/Opts.td b/llvm/tools/llvm-readobj/Opts.td
index f489e564d3182..97d5d7f96dc32 100644
--- a/llvm/tools/llvm-readobj/Opts.td
+++ b/llvm/tools/llvm-readobj/Opts.td
@@ -20,7 +20,6 @@ def all : FF<"all", "Equivalent to setting: --file-header, --program-headers, --
def arch_specific : FF<"arch-specific", "Display architecture-specific information">;
def bb_addr_map : FF<"bb-addr-map", "Display the BB address map section">;
def pretty_pgo_analysis_map : FF<"pretty-pgo-analysis-map", "Display PGO analysis values with formatting rather than raw numbers">;
-def call_graph_info : FF<"call-graph-info", "Display call graph information">;
def cg_profile : FF<"cg-profile", "Display call graph profile section">;
def decompress : FF<"decompress", "Dump decompressed section content when used with -x or -p">;
defm demangle : BB<"demangle", "Demangle symbol names", "Do not demangle symbol names (default)">;
diff --git a/llvm/tools/llvm-readobj/llvm-readobj.cpp b/llvm/tools/llvm-readobj/llvm-readobj.cpp
index 95fb283940c17..5327731805010 100644
--- a/llvm/tools/llvm-readobj/llvm-readobj.cpp
+++ b/llvm/tools/llvm-readobj/llvm-readobj.cpp
@@ -99,7 +99,6 @@ static bool ArchSpecificInfo;
static bool BBAddrMap;
static bool PrettyPGOAnalysisMap;
bool ExpandRelocs;
-static bool CallGraphInfo;
static bool CGProfile;
static bool Decompress;
bool Demangle;
@@ -223,7 +222,6 @@ static void parseOptions(const opt::InputArgList &Args) {
WithColor::warning(errs(), ToolName)
<< "--bb-addr-map must be enabled for --pretty-pgo-analysis-map to "
"have an effect\n";
- opts::CallGraphInfo = Args.hasArg(OPT_call_graph_info);
opts::CGProfile = Args.hasArg(OPT_cg_profile);
opts::Decompress = Args.hasArg(OPT_decompress);
opts::Demangle = Args.hasFlag(OPT_demangle, OPT_no_demangle, false);
@@ -480,8 +478,6 @@ static void dumpObject(ObjectFile &Obj, ScopedPrinter &Writer,
Dumper->printHashHistograms();
if (opts::CGProfile)
Dumper->printCGProfile();
- if (opts::CallGraphInfo)
- Dumper->printCallGraphInfo();
if (opts::BBAddrMap)
Dumper->printBBAddrMaps(opts::PrettyPGOAnalysisMap);
if (opts::Addrsig)
More information about the llvm-branch-commits
mailing list