From b0e4b91660f4c04f9abf5022de547479282af9ca Mon Sep 17 00:00:00 2001 From: Rafael Auler Date: Fri, 9 Mar 2018 19:13:44 +0000 Subject: [PATCH] [llvm-objdump] Support disassembling by symbol name Summary: Add a new option -df to llvm-objdump that takes function names as arguments and instructs the disassembler to only dump those function contents. Based on code originally written by Bill Nell. Reviewers: espindola, JDevlieghere Differential Revision: https://reviews.llvm.org/D44224 llvm-svn: 327164 --- .../X86/disasm-specific-funcs.test | 20 +++++++++ llvm/tools/llvm-objdump/llvm-objdump.cpp | 44 +++++++++++++------ 2 files changed, 50 insertions(+), 14 deletions(-) create mode 100644 llvm/test/tools/llvm-objdump/X86/disasm-specific-funcs.test diff --git a/llvm/test/tools/llvm-objdump/X86/disasm-specific-funcs.test b/llvm/test/tools/llvm-objdump/X86/disasm-specific-funcs.test new file mode 100644 index 000000000000..c46147fbe276 --- /dev/null +++ b/llvm/test/tools/llvm-objdump/X86/disasm-specific-funcs.test @@ -0,0 +1,20 @@ +// RUN: yaml2obj -o %t.out %p/Inputs/simple-executable-x86_64.yaml +// RUN: llvm-objdump -d %t.out -df=main | FileCheck %s + +// CHECK: Disassembly of section .anothertext: +// CHECK-NEXT: main: +// CHECK-NEXT: 10: 55 pushq %rbp +// CHECK-NEXT: 11: 48 89 e5 movq %rsp, %rbp +// CHECK-NEXT: 14: 48 83 ec 20 subq $32, %rsp +// CHECK-NEXT: 18: 48 8d 04 25 a8 00 00 00 leaq 168, %rax +// CHECK-NEXT: 20: c7 45 fc 00 00 00 00 movl $0, -4(%rbp) +// CHECK-NEXT: 27: 48 89 45 f0 movq %rax, -16(%rbp) +// CHECK-NEXT: 2b: 48 8b 45 f0 movq -16(%rbp), %rax +// CHECK-NEXT: 2f: 8b 08 movl (%rax), %ecx +// CHECK-NEXT: 31: 89 4d ec movl %ecx, -20(%rbp) +// CHECK-NEXT: 34: e8 c7 ff ff ff callq -57 +// CHECK-NEXT: 39: 8b 4d ec movl -20(%rbp), %ecx +// CHECK-NEXT: 3c: 01 c1 addl %eax, %ecx +// CHECK-NEXT: 3e: 89 c8 movl %ecx, %eax +// CHECK-NEXT: 40: 48 83 c4 20 addq $32, %rsp +// CHECK-NEXT: 44: 5d popq %rbp diff --git a/llvm/tools/llvm-objdump/llvm-objdump.cpp b/llvm/tools/llvm-objdump/llvm-objdump.cpp index 3be2c423bb5c..7764c1d6e101 100644 --- a/llvm/tools/llvm-objdump/llvm-objdump.cpp +++ b/llvm/tools/llvm-objdump/llvm-objdump.cpp @@ -20,6 +20,7 @@ #include "llvm/ADT/Optional.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringExtras.h" +#include "llvm/ADT/StringSet.h" #include "llvm/ADT/Triple.h" #include "llvm/CodeGen/FaultMaps.h" #include "llvm/DebugInfo/DWARF/DWARFContext.h" @@ -85,6 +86,12 @@ static cl::alias DisassembleAlld("D", cl::desc("Alias for --disassemble-all"), cl::aliasopt(DisassembleAll)); +static cl::list +DisassembleFunctions("df", + cl::CommaSeparated, + cl::desc("List of functions to disassemble")); +static StringSet<> DisasmFuncsSet; + cl::opt llvm::Relocations("r", cl::desc("Display the relocation entries in the file")); @@ -1388,23 +1395,15 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) { DataRefImpl DR = Section.getRawDataRefImpl(); SegmentName = MachO->getSectionFinalSegmentName(DR); } - StringRef name; - error(Section.getName(name)); - - if ((SectionAddr <= StopAddress) && - (SectionAddr + SectSize) >= StartAddress) { - outs() << "Disassembly of section "; - if (!SegmentName.empty()) - outs() << SegmentName << ","; - outs() << name << ':'; - } + StringRef SectionName; + error(Section.getName(SectionName)); // If the section has no symbol at the start, just insert a dummy one. if (Symbols.empty() || std::get<0>(Symbols[0]) != 0) { - Symbols.insert(Symbols.begin(), - std::make_tuple(SectionAddr, name, Section.isText() - ? ELF::STT_FUNC - : ELF::STT_OBJECT)); + Symbols.insert( + Symbols.begin(), + std::make_tuple(SectionAddr, SectionName, + Section.isText() ? ELF::STT_FUNC : ELF::STT_OBJECT)); } SmallString<40> Comments; @@ -1417,6 +1416,7 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) { uint64_t Size; uint64_t Index; + bool PrintedSection = false; std::vector::const_iterator rel_cur = Rels.begin(); std::vector::const_iterator rel_end = Rels.end(); @@ -1441,6 +1441,19 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) { continue; } + /// Skip if user requested specific symbols and this is not in the list + if (!DisasmFuncsSet.empty() && + !DisasmFuncsSet.count(std::get<1>(Symbols[si]))) + continue; + + if (!PrintedSection) { + PrintedSection = true; + outs() << "Disassembly of section "; + if (!SegmentName.empty()) + outs() << SegmentName << ","; + outs() << SectionName << ':'; + } + // Stop disassembly at the stop address specified if (End + SectionAddr > StopAddress) End = StopAddress - SectionAddr; @@ -2203,6 +2216,9 @@ int main(int argc, char **argv) { return 2; } + DisasmFuncsSet.insert(DisassembleFunctions.begin(), + DisassembleFunctions.end()); + llvm::for_each(InputFilenames, DumpInput); return EXIT_SUCCESS;