Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
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