diff --git a/llvm/test/tools/llvm-objdump/ELF/call-graph-info-warn-no-callgraph-section.test b/llvm/test/tools/llvm-objdump/ELF/call-graph-info-warn-no-callgraph-section.test new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-objdump/ELF/call-graph-info-warn-no-callgraph-section.test @@ -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 diff --git a/llvm/tools/llvm-objdump/llvm-objdump.cpp b/llvm/tools/llvm-objdump/llvm-objdump.cpp --- a/llvm/tools/llvm-objdump/llvm-objdump.cpp +++ b/llvm/tools/llvm-objdump/llvm-objdump.cpp @@ -2103,6 +2103,24 @@ // Get function info through disassembly. disassembleObject(Obj, /*InlineRelocs=*/false); + // Get the .callgraph section. + StringRef CallGraphSectionName(".callgraph"); + Optional CallGraphSection; + for (auto Sec : ToolSectionFilter(*Obj)) { + StringRef Name; + if (Expected NameOrErr = Sec.getName()) + Name = *NameOrErr; + else + consumeError(NameOrErr.takeError()); + + if (Name == CallGraphSectionName) { + CallGraphSection = Sec; + break; + } + } + if (!CallGraphSection) + reportWarning("there is no .callgraph section", Obj->getFileName()); + // Print function entry to indirect call site addresses mapping from disasm. outs() << "\n\nINDIRECT CALL SITES (CALLER_ADDR [CALL_SITE_ADDR,])"; for (const auto &El : FuncInfo) {