-
Notifications
You must be signed in to change notification settings - Fork 15.2k
[llvm-readobj] Dump callgraph section info for ELF #157499
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 58 commits
ac4b7bc
31c4d2b
4d1a7c7
f0810b2
5f20b7b
d991194
c2d8d22
2874918
9803c62
7285210
8236798
abe189e
0b9c46d
5b504fc
5b6bb00
937ff61
1b86857
7280ff3
bdb8683
09d3a87
b851b8d
fd50ff0
ee3a081
3c94a44
026b184
d1655c2
ff9535e
b7c56f9
e075175
876f7a6
33d06b4
5f6cf07
055139b
d1b41b5
6368f56
f1f9f6b
ce75c88
72b0d37
54b2004
dfd37f2
8ebe0a2
c429dd8
d04fbd0
75bffeb
77acb10
246275d
402c90f
87d3dd8
20ea016
c5823aa
8d3a27c
aaa2cd4
afc13ee
6e22254
5b3bff0
c4ea41d
53ffcaa
edc5eaa
14b5cf0
b56a17c
ae501fa
f454957
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,150 @@ | ||
| ## Tests --call-graph-info prints information from call graph section. | ||
|
|
||
| # REQUIRES: x86-registered-target | ||
|
|
||
| # RUN: llvm-mc %s -filetype=obj -triple=x86_64-pc-linux -o %t | ||
| # RUN: llvm-readelf --call-graph-info %t 2>&1 | FileCheck %s --allow-empty -DFILE=%t | ||
| # RUN: llvm-readelf --elf-output-style=LLVM --call-graph-info %t 2>&1 | FileCheck %s -DFILE=%t --check-prefix=LLVM | ||
| # RUN: llvm-readelf --elf-output-style=JSON --pretty-print --call-graph-info %t 2>&1 | FileCheck %s -DFILE=%t --check-prefix=JSON | ||
|
|
||
|
|
||
|
||
| ## We do not support GNU format console output for --call-graph-info as it is an LLVM only info. | ||
| # CHECK-NOT: . | ||
|
||
|
|
||
| # LLVM: warning: '[[FILE]]': .llvm.callgraph section has unknown type id for 2 indirect targets. | ||
| # LLVM-NEXT: CallGraph [ | ||
| # LLVM-NEXT: Function { | ||
| # LLVM-NEXT: Offset: 0x2 | ||
| # LLVM-NEXT: Version: 0 | ||
| # LLVM-NEXT: IsIndirectTarget: Yes | ||
| # LLVM-NEXT: TypeId: 0x0 | ||
| # LLVM-NEXT: NumDirectCallees: 1 | ||
| # LLVM-NEXT: DirectCallees [ | ||
| # LLVM-NEXT: { | ||
| # LLVM-NEXT: Offset: 0x13 | ||
| # LLVM-NEXT: } | ||
| # LLVM-NEXT: ] | ||
| # LLVM-NEXT: NumIndirectTargetTypeIDs: 0 | ||
| # LLVM-NEXT: IndirectTypeIDs: [] | ||
| # LLVM-NEXT: } | ||
| # LLVM-NEXT: Function { | ||
| # LLVM-NEXT: Offset: 0x1D | ||
| # LLVM-NEXT: Version: 0 | ||
| # LLVM-NEXT: IsIndirectTarget: Yes | ||
| # LLVM-NEXT: TypeId: 0x0 | ||
| # LLVM-NEXT: NumDirectCallees: 0 | ||
| # LLVM-NEXT: DirectCallees [ | ||
| # LLVM-NEXT: ] | ||
| # LLVM-NEXT: NumIndirectTargetTypeIDs: 1 | ||
| # LLVM-NEXT: IndirectTypeIDs: [0x10] | ||
| # LLVM-NEXT: } | ||
| # LLVM-NEXT: Function { | ||
| # LLVM-NEXT: Offset: 0x38 | ||
| # LLVM-NEXT: Version: 0 | ||
| # LLVM-NEXT: IsIndirectTarget: Yes | ||
| # LLVM-NEXT: TypeId: 0x20 | ||
| # LLVM-NEXT: NumDirectCallees: 0 | ||
| # LLVM-NEXT: DirectCallees [ | ||
| # LLVM-NEXT: ] | ||
| # LLVM-NEXT: NumIndirectTargetTypeIDs: 0 | ||
| # LLVM-NEXT: IndirectTypeIDs: [] | ||
| # LLVM-NEXT: } | ||
| # LLVM-NEXT: ] | ||
|
|
||
| # JSON: warning: '[[FILE]]': .llvm.callgraph section has unknown type id for 2 indirect targets. | ||
| # JSON: "CallGraph": [ | ||
| # JSON-NEXT: { | ||
| # JSON-NEXT: "Function": { | ||
| # JSON-NEXT: "Offset": 2, | ||
| # JSON-NEXT: "Version": 0, | ||
| # JSON-NEXT: "IsIndirectTarget": true, | ||
| # JSON-NEXT: "TypeId": 0, | ||
| # JSON-NEXT: "NumDirectCallees": 1, | ||
| # JSON-NEXT: "DirectCallees": [ | ||
| # JSON-NEXT: { | ||
| # JSON-NEXT: "Offset": 19 | ||
|
||
| # JSON-NEXT: } | ||
| # JSON-NEXT: ], | ||
| # JSON-NEXT: "NumIndirectTargetTypeIDs": 0, | ||
| # JSON-NEXT: "IndirectTypeIDs": [] | ||
| # JSON-NEXT: } | ||
| # JSON-NEXT: }, | ||
| # JSON-NEXT: { | ||
| # JSON-NEXT: "Function": { | ||
| # JSON-NEXT: "Offset": 29, | ||
| # JSON-NEXT: "Version": 0, | ||
| # JSON-NEXT: "IsIndirectTarget": true, | ||
| # JSON-NEXT: "TypeId": 0, | ||
| # JSON-NEXT: "NumDirectCallees": 0, | ||
| # JSON-NEXT: "DirectCallees": [], | ||
| # JSON-NEXT: "NumIndirectTargetTypeIDs": 1, | ||
| # JSON-NEXT: "IndirectTypeIDs": [ | ||
| # JSON-NEXT: 16 | ||
| # JSON-NEXT: ] | ||
| # JSON-NEXT: } | ||
| # JSON-NEXT: }, | ||
| # JSON-NEXT: { | ||
| # JSON-NEXT: "Function": { | ||
| # JSON-NEXT: "Offset": 56, | ||
| # JSON-NEXT: "Version": 0, | ||
| # JSON-NEXT: "IsIndirectTarget": true, | ||
| # JSON-NEXT: "TypeId": 32, | ||
| # JSON-NEXT: "NumDirectCallees": 0, | ||
| # JSON-NEXT: "DirectCallees": [], | ||
| # JSON-NEXT: "NumIndirectTargetTypeIDs": 0, | ||
| # JSON-NEXT: "IndirectTypeIDs": [] | ||
| # JSON-NEXT: } | ||
| # JSON-NEXT: } | ||
| # JSON-NEXT: ] | ||
| # JSON-NEXT: } | ||
| # JSON-NEXT:] | ||
|
|
||
| .text | ||
|
|
||
| .globl foo | ||
| .type foo,@function | ||
| foo: #< foo is at 0. | ||
| .Lfoo_begin: | ||
| callq foo #< direct call is at 5. target is foo (5). | ||
| retq | ||
|
|
||
| .globl bar | ||
| .type bar,@function | ||
| bar: #< bar is at 6. | ||
| callq *-40(%rbp) #< indirect call is at 9. | ||
| retq | ||
|
|
||
| .globl baz | ||
| .type baz,@function | ||
| baz: #< baz is at 10 (a). | ||
| retq | ||
|
|
||
| .globl qux | ||
| .type qux,@function | ||
| qux: #< qux is at 11 (b). | ||
| retq | ||
|
|
||
| .section .llvm.callgraph,"o",@llvm_call_graph,.text | ||
| .byte 0 #< Format version number. | ||
| .byte 3 #< Flag IsIndirectTarget true | ||
| .quad 0 #< foo()'s address. | ||
| .quad 0 #< TypeID: unknown. | ||
| .byte 1 #< Count of direct callees. | ||
| .quad 5 #< Direct callee foo's address> | ||
|
|
||
| .byte 0 #< Format version number. | ||
| .byte 5 #< Flag IsIndirectTarget true | ||
| .quad 6 #< bar()'s address. | ||
| .quad 0 #< TypeID: unknown. | ||
| .byte 1 #< Count of indirect target type IDs | ||
| .quad 16 #< Indirect call type id. | ||
|
|
||
|
|
||
| .byte 0 #< Format version number. | ||
| .byte 1 #< Flag IsIndirectTarget true | ||
| .quad 10 #< baz()'s address. | ||
| .quad 32 #< Indirect target type id. | ||
|
|
||
| # No call graph section entry for qux. | ||
|
|
||
| .text | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| ## Tests that --call-graph-info fails if .llvm.callgraph section has invalid | ||
| ## value for flags field. | ||
|
|
||
| # REQUIRES: x86-registered-target | ||
|
|
||
| # RUN: llvm-mc %s -filetype=obj -triple=x86_64-pc-linux -o %t | ||
| # RUN: not llvm-readelf --elf-output-style=LLVM --call-graph-info %t 2>&1 | FileCheck %s -DFILE=%t --check-prefix=ERR | ||
| # RUN: not llvm-readelf --elf-output-style=JSON --pretty-print --call-graph-info %t 2>&1 | FileCheck %s -DFILE=%t --check-prefix=ERR | ||
|
|
||
| # ERR: error: 'While reading call graph info's Flags': Unexpected value. Expected [0-7] but found [8] | ||
|
|
||
| .text | ||
| .globl _Z3foov | ||
| .type _Z3foov,@function | ||
| _Z3foov: | ||
| callq _Z3foov@PLT | ||
|
|
||
| .section .llvm.callgraph,"o",@llvm_call_graph,.text | ||
| .byte 0 #< Format version number. | ||
| .byte 8 #< Only valid values are 0 to 7 | ||
| # Missing direct callees info | ||
| .text |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| ## Tests that --call-graph-info fails if .llvm.callgraph section has unknown format | ||
| ## version number. | ||
|
|
||
| # REQUIRES: x86-registered-target | ||
|
|
||
| # RUN: llvm-mc %s -filetype=obj -triple=x86_64-pc-linux -o %t | ||
| # RUN: not llvm-readelf --elf-output-style=LLVM --call-graph-info %t 2>&1 | FileCheck %s -DFILE=%t --check-prefix=ERR | ||
| # RUN: not llvm-readelf --elf-output-style=JSON --pretty-print --call-graph-info %t 2>&1 | FileCheck %s -DFILE=%t --check-prefix=ERR | ||
|
|
||
| # ERR: error: 'Unknown value': Unknown format version value [1] in .llvm.callgraph section. | ||
|
|
||
| .text | ||
| .globl _Z3foov | ||
| .type _Z3foov,@function | ||
| _Z3foov: | ||
| callq _Z3foov@PLT | ||
|
|
||
| .section .llvm.callgraph,"o",@llvm_call_graph,.text | ||
| .byte 1 #< Invalid format version number: the only supported version is 0. | ||
| .text |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| ## Tests that --call-graph-info fails if .llvm.callgraph section has flags | ||
| ## that indicate there are direct calls but the direct call info is missing. | ||
|
|
||
| # REQUIRES: x86-registered-target | ||
|
|
||
| # RUN: llvm-mc %s -filetype=obj -triple=x86_64-pc-linux -o %t | ||
| # RUN: not llvm-readelf --elf-output-style=LLVM --call-graph-info %t 2>&1 | FileCheck %s -DFILE=%t --check-prefix=ERR | ||
| # RUN: not llvm-readelf --elf-output-style=JSON --pretty-print --call-graph-info %t 2>&1 | FileCheck %s -DFILE=%t --check-prefix=ERR | ||
|
|
||
| # ERR: error: 'While reading call graph info's [number of direct callsites] for function at [0x2]': unable to decode LEB128 at offset 0x00000012: malformed uleb128, extends past end | ||
|
|
||
| .text | ||
| .globl _Z3foov | ||
| .type _Z3foov,@function | ||
| _Z3foov: | ||
| callq _Z3foov@PLT | ||
|
|
||
| .section .llvm.callgraph,"o",@llvm_call_graph,.text | ||
| .byte 0 #< Format version number. | ||
| .byte 3 #< Flag IsIndirectTarget true and has direct calls | ||
| .quad 0 #< Function entry address. | ||
| .quad 0 #< TypeID: unknown. | ||
| # Missing direct callees info | ||
| .text |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| ## Tests that --call-graph-info fails if .llvm.callgraph section does not have | ||
| ## an expected value, e.g., not as much call sites as the given count. | ||
|
|
||
| # REQUIRES: x86-registered-target | ||
|
|
||
| # RUN: llvm-mc %s -filetype=obj -triple=x86_64-pc-linux -o %t | ||
| # RUN: not llvm-readelf --elf-output-style=LLVM --call-graph-info %t 2>&1 | FileCheck %s -DFILE=%t --check-prefix=ERR | ||
| # RUN: not llvm-readelf --elf-output-style=JSON --pretty-print --call-graph-info %t 2>&1 | FileCheck %s -DFILE=%t --check-prefix=ERR | ||
|
|
||
| # ERR: error: 'While reading call graph info's [indirect type ID] for function at [0x2]': unexpected end of data at offset 0x13 while reading [0x13, 0x1b) | ||
|
|
||
| .text | ||
| .globl _Z3foov | ||
| .type _Z3foov,@function | ||
| _Z3foov: | ||
| callq _Z3foov@PLT | ||
ilovepi marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| .section .llvm.callgraph,"o",@llvm_call_graph,.text | ||
| .byte 0 #< Format version number. | ||
| .byte 4 #< Flags | ||
| .quad 0 #< Function entry address. | ||
| .quad 0 #< Type ID | ||
| .byte 1 #< Indirect call site count that follows. | ||
| #< Missing indirect call entries here. | ||
| .text | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| ## Tests that --call-graph-info warns if there is no .llvm.callgraph section. | ||
|
|
||
| # REQUIRES: x86-registered-target | ||
|
|
||
| # RUN: llvm-mc %s -filetype=obj -triple=x86_64-pc-linux -o %t | ||
| # RUN: not llvm-readelf --elf-output-style=LLVM --call-graph-info %t 2>&1 | FileCheck %s -DFILE=%t | ||
| # RUN: not llvm-readelf --elf-output-style=JSON --pretty-print --call-graph-info %t 2>&1 | FileCheck %s -DFILE=%t | ||
|
|
||
| # CHECK: error: 'Missing section': No .llvm.callgraph section found. | ||
|
|
||
| .text | ||
| .globl _Z3foov | ||
| .type _Z3foov,@function | ||
| _Z3foov: | ||
| callq _Z3foov@PLT |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we convert the test input to use yaml2obj, instead of requiring x86? It looks like the file format is trivial enough that something like a YAML ELF input using ContentArray would be just as descriptive, whilst also allowing more precise control of everything.