Author: Prabhu Rajasekaran Date: 2026-01-15T10:49:07-08:00 New Revision: a81fadc5c433aa8360bd2204f657e1236f2e19a8
URL: https://github.com/llvm/llvm-project/commit/a81fadc5c433aa8360bd2204f657e1236f2e19a8 DIFF: https://github.com/llvm/llvm-project/commit/a81fadc5c433aa8360bd2204f657e1236f2e19a8.diff LOG: Revert "[llvm-readobj] Dump callgraph section info for ELF (#157499)" This reverts commit f0275bd6ba888d409cf677d498233d3be75cbf6b. Added: Modified: llvm/docs/CommandGuide/llvm-readelf.rst llvm/docs/CommandGuide/llvm-readobj.rst llvm/tools/llvm-readobj/ELFDumper.cpp llvm/tools/llvm-readobj/ObjDumper.h llvm/tools/llvm-readobj/Opts.td llvm/tools/llvm-readobj/llvm-readobj.cpp Removed: llvm/test/tools/llvm-readobj/ELF/call-graph-info-warn-malformed.test 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) _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
