Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions llvm/docs/CommandGuide/llvm-objdump.rst
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ combined with other commands:

Display the information contained within an archive's headers.

.. option:: --call-graph-info

Dump call graph information including indirect call and target IDs from call
graph section, if available.

.. option:: -d, --disassemble

Disassemble all executable sections found in the input files. On some
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
## Tests --call-graph-info warnings for missing/invalid .callgraph section
## contents.

# RUN: llvm-mc %s -filetype=obj -triple=x86_64-pc-linux -o %t
# RUN: llvm-objdump --call-graph-info %t 2>&1 | FileCheck %s -DFILE=%t

# CHECK: [[FILE]]: file format elf64-x86-64
# CHECK-NEXT: llvm-objdump: warning: '[[FILE]]': callgraph section has type ids for 1 instructions which are not indirect calls
# CHECK-NEXT: llvm-objdump: warning: '[[FILE]]': callgraph section does not have type ids for 1 indirect calls
# CHECK-NEXT: llvm-objdump: warning: '[[FILE]]': callgraph section does not have information for 1 functions
# CHECK-NEXT: llvm-objdump: warning: '[[FILE]]': callgraph section has unknown type id for 1 indirect targets

.text
.globl foo
.type foo,@function
foo:
.Lfoo_begin:
.Lnot_indirect_call:
retq

.globl bar
.type bar,@function
bar:
callq *%rcx

.section .callgraph,"o",@progbits,.text
.quad 0 #< Format version number.
.quad .Lfoo_begin #< foo()'s entry address.
.quad 1 #< A warning: function kind is 1: the type id for indirect target foo is unknown.
.quad 1 #< Count of indirect call sites that follow: 1.
.quad 0 #< Indirect call type id.
.quad .Lnot_indirect_call #< A warning: type id for non-indirect call instruction.
# A warning: .callgraph section does not have information for 1 function (bar).
# A warning: .callgraph section does not have type id for 1 indirect call (one in bar).
.text
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
## Tests --call-graph-info prints information from call graph section.

# RUN: llvm-mc %s -filetype=obj -triple=x86_64-pc-linux -o %t
# RUN: llvm-objdump --call-graph-info %t 2>&1 | FileCheck %s -DFILE=%t

# CHECK: [[FILE]]: file format elf64-x86-64

# CHECK: INDIRECT TARGET TYPES (TYPEID [FUNC_ADDR,])
# CHECK-NEXT: UNKNOWN 6 b
# CHECK-NEXT: 20 a
# CHECK-EMPTY:
# CHECK-NEXT: INDIRECT CALL TYPES (TYPEID [CALL_SITE_ADDR,])
# CHECK-NEXT: 10 9
# CHECK-EMPTY:
# CHECK-NEXT: INDIRECT CALL SITES (CALLER_ADDR [CALL_SITE_ADDR,])
# CHECK-NEXT: 6 9
# CHECK-EMPTY:
# CHECK-NEXT: DIRECT CALL SITES (CALLER_ADDR [(CALL_SITE_ADDR, TARGET_ADDR),])
# CHECK-NEXT: 0 5 5
# CHECK-EMPTY:
# CHECK-NEXT: FUNCTIONS (FUNC_ENTRY_ADDR, SYM_NAME)
# CHECK-NEXT: 0 foo
# CHECK-NEXT: 6 bar
# CHECK-NEXT: a baz
# CHECK-NEXT: b qux

.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 .callgraph,"o",@progbits,.text
.quad 0 #< Format version number.
.quad 0 #< foo()'s entry address.
.quad 0 #< Function kind: not an indirect target.
.quad 0 #< Count of indirect call sites that follow: 0.

.quad 0 #< Format version number.
.quad 6 #< bar()'s entry address.
.quad 1 #< Function kind: indirect target with unknown type id.
.quad 1 #< Count of indirect call sites that follow: 1.
.quad 16 #< Indirect call type id.
.quad 9 #< Indirect call site.

.quad 0 #< Format version number.
.quad 10 #< baz()'s entry address.
.quad 2 #< Function kind: indirect target with known type id.
.quad 32 #< Indirect target type id.
.quad 0 #< Count of indirect call sites that follow: 1.

# No call graph section entry for qux: will be printed as unknown target.

.text
40 changes: 40 additions & 0 deletions llvm/test/tools/llvm-objdump/ELF/call-graph-info-callsites.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
## Tests --call-graph-info prints call sites.

# RUN: llvm-mc %s -filetype=obj -triple=x86_64-pc-linux -o %t
# RUN: llvm-objdump --call-graph-info %t 2>&1 | FileCheck %s -DFILE=%t

# CHECK: [[FILE]]: file format elf64-x86-64

# CHECK: INDIRECT CALL SITES (CALLER_ADDR [CALL_SITE_ADDR,])
# CHECK-NEXT: 1 8
# CHECK-NEXT: 12 14
# CHECK-EMPTY:
# CHECK-NEXT: DIRECT CALL SITES (CALLER_ADDR [(CALL_SITE_ADDR, TARGET_ADDR),])
# CHECK-NEXT: 1 6 6 d d 12 12
# CHECK-NEXT: 12 19 19
# CHECK-EMPTY:
# CHECK-NEXT: FUNCTIONS (FUNC_ENTRY_ADDR, SYM_NAME)
# CHECK-NEXT: 0 foo
# CHECK-NEXT: 1 bar
# CHECK-NEXT: 12 baz

.text

.globl foo
.type foo,@function
foo:
retq

.globl bar
.type bar,@function
bar:
callq foo
callq *%rcx
callq bar
callq foo

.globl baz
.type baz,@function
baz:
callq *%rcx
callq foo
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
## Tests that --call-graph-info fails if .callgraph section has unknown format
## version number.

# RUN: llvm-mc %s -filetype=obj -triple=x86_64-pc-linux -o %t
# RUN: not llvm-objdump --call-graph-info %t 2>&1 | FileCheck %s -DFILE=%t --check-prefix=ERR

# CHECK: [[FILE]]: file format elf64-x86-64
# ERR: llvm-objdump: error: '[[FILE]]': Unknown format version in .callgraph section.

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

.section .callgraph,"o",@progbits,.text
.quad 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,19 @@
## Tests that --call-graph-info fails if .callgraph section has invalid
## function entry address.

# RUN: llvm-mc %s -filetype=obj -triple=x86_64-pc-linux -o %t
# RUN: not llvm-objdump --call-graph-info %t 2>&1 | FileCheck %s -DFILE=%t --check-prefix=ERR

# CHECK: [[FILE]]: file format elf64-x86-64
# ERR: llvm-objdump: error: '[[FILE]]': Invalid function entry pc in .callgraph section.

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

.section .callgraph,"o",@progbits,.text
.quad 0 #< Format version number.
.quad 12345 #< Invalid function entry address.
.text
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
## Tests that --call-graph-info fails if .callgraph section has invalid
## function kind value.

# RUN: llvm-mc %s -filetype=obj -triple=x86_64-pc-linux -o %t
# RUN: not llvm-objdump --call-graph-info %t 2>&1 | FileCheck %s -DFILE=%t --check-prefix=ERR

# CHECK: [[FILE]]: file format elf64-x86-64
# ERR: llvm-objdump: error: '[[FILE]]': Unknown function kind in .callgraph section.

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

.section .callgraph,"o",@progbits,.text
.quad 0 #< Format version number.
.quad 0 #< Function entry address.
.quad 3 #< Invalid function kind: must be one of 0, 1, 2.
.text
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
## Tests that --call-graph-info fails if .callgraph section has invalid size.

# RUN: llvm-mc %s -filetype=obj -triple=x86_64-pc-linux -o %t
# RUN: not llvm-objdump --call-graph-info %t 2>&1 | FileCheck %s -DFILE=%t --check-prefix=ERR

# CHECK: [[FILE]]: file format elf64-x86-64
# ERR: llvm-objdump: error: '[[FILE]]': Malformed .callgraph section.

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

.section .callgraph,"o",@progbits,.text
# Each unit in .callgraph section must have 64bit size. Therefore, byte size
# must be divisible by 64.
.quad 0
.quad 0
.quad 0
.byte 0
.text
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
## Tests that --call-graph-info fails if .callgraph section does not have
## an expected value, e.g., not as much call sites as the given count.

# RUN: llvm-mc %s -filetype=obj -triple=x86_64-pc-linux -o %t
# RUN: not llvm-objdump --call-graph-info %t 2>&1 | FileCheck %s -DFILE=%t --check-prefix=ERR

# CHECK: [[FILE]]: file format elf64-x86-64
# ERR: llvm-objdump: error: '[[FILE]]': Malformed .callgraph section.

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

.section .callgraph,"o",@progbits,.text
.quad 0 #< Format version number.
.quad 0 #< Function entry address.
.quad 0 #< Function kind.
.quad 2 #< Indirect call site count that follows.
#< Missing indirect calls?
.text
28 changes: 28 additions & 0 deletions llvm/test/tools/llvm-objdump/ELF/call-graph-info-functions.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
## Tests --call-graph-info prints functions.

# RUN: llvm-mc %s -filetype=obj -triple=x86_64-pc-linux -o %t
# RUN: llvm-objdump --call-graph-info %t 2>&1 | FileCheck %s -DFILE=%t

# CHECK: [[FILE]]: file format elf64-x86-64

# CHECK: FUNCTIONS (FUNC_ENTRY_ADDR, SYM_NAME)
# CHECK-NEXT: 0 foo
# CHECK-NEXT: 1 bar
# CHECK-NEXT: 2 baz

.text

.globl foo
.type foo,@function
foo:
retq

.globl bar
.type bar,@function
bar:
retq

.globl baz
.type baz,@function
baz:
retq
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
## Tests that --call-graph-info warns if there is no .callgraph section.

# RUN: llvm-mc %s -filetype=obj -triple=x86_64-pc-linux -o %t
# RUN: llvm-objdump --call-graph-info %t 2>&1 | FileCheck %s -DFILE=%t

# CHECK: [[FILE]]: file format elf64-x86-64
# CHECK-NEXT: llvm-objdump: warning: '[[FILE]]': there is no .callgraph section
# CHECK-NOT: INDIRECT TARGET TYPES (TYPEID [FUNC_ADDR,])
# CHECK-NOT: INDIRECT CALL TYPES (TYPEID [CALL_SITE_ADDR,])

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