From 3605e121fbd4283246005545767fa4583f8f297a Mon Sep 17 00:00:00 2001 From: Sterling Augustine Date: Thu, 28 Jun 2018 18:57:13 +0000 Subject: [PATCH] Handle absolute symbols as branch targets in disassembly. https://reviews.llvm.org/D48554 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@335903 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../llvm-objdump/call-absolute-symbol-elf.test | 4 ++ tools/llvm-objdump/llvm-objdump.cpp | 56 ++++++++++++++-------- 2 files changed, 39 insertions(+), 21 deletions(-) create mode 100644 test/tools/llvm-objdump/call-absolute-symbol-elf.test diff --git a/test/tools/llvm-objdump/call-absolute-symbol-elf.test b/test/tools/llvm-objdump/call-absolute-symbol-elf.test new file mode 100644 index 00000000000..aa3482b4b87 --- /dev/null +++ b/test/tools/llvm-objdump/call-absolute-symbol-elf.test @@ -0,0 +1,4 @@ +// RUN: echo -e ".text\ncallq foo\n" | llvm-mc -filetype=obj -triple=x86_64-pc-linux - -o %t1.o +// RUN: ld.lld --defsym foo=0x100 %t1.o -o %t2 +// RUN: llvm-objdump --disassemble %t2 | FileCheck %s +CHECK: 201000: e8 fb f0 df ff callq -2100997 diff --git a/tools/llvm-objdump/llvm-objdump.cpp b/tools/llvm-objdump/llvm-objdump.cpp index 2edd65be2ed..2598d930417 100644 --- a/tools/llvm-objdump/llvm-objdump.cpp +++ b/tools/llvm-objdump/llvm-objdump.cpp @@ -1282,6 +1282,7 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) { // Create a mapping from virtual address to symbol name. This is used to // pretty print the symbols while disassembling. std::map AllSymbols; + SectionSymbolsTy AbsoluteSymbols; for (const SymbolRef &Symbol : Obj->symbols()) { Expected AddressOrErr = Symbol.getAddress(); if (!AddressOrErr) @@ -1297,15 +1298,17 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) { Expected SectionOrErr = Symbol.getSection(); if (!SectionOrErr) report_error(Obj->getFileName(), SectionOrErr.takeError()); - section_iterator SecI = *SectionOrErr; - if (SecI == Obj->section_end()) - continue; uint8_t SymbolType = ELF::STT_NOTYPE; if (Obj->isELF()) SymbolType = getElfSymbolType(Obj, Symbol); - AllSymbols[*SecI].emplace_back(Address, *Name, SymbolType); + section_iterator SecI = *SectionOrErr; + if (SecI != Obj->section_end()) + AllSymbols[*SecI].emplace_back(Address, *Name, SymbolType); + else + AbsoluteSymbols.emplace_back(Address, *Name, SymbolType); + } if (AllSymbols.empty() && Obj->isELF()) @@ -1341,6 +1344,8 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) { if (Sec != SectionAddresses.end()) AllSymbols[Sec->second].emplace_back(VA, Name, ELF::STT_NOTYPE); + else + AbsoluteSymbols.emplace_back(VA, Name, ELF::STT_NOTYPE); } } @@ -1348,6 +1353,7 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) { // a symbol near an address. for (std::pair &SecSyms : AllSymbols) array_pod_sort(SecSyms.second.begin(), SecSyms.second.end()); + array_pod_sort(AbsoluteSymbols.begin(), AbsoluteSymbols.end()); for (const SectionRef &Section : ToolSectionFilter(*Obj)) { if (!DisassembleAll && (!Section.isText() || Section.isVirtual())) @@ -1662,29 +1668,37 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) { --SectionAddress; TargetSectionSymbols = &AllSymbols[SectionAddress->second]; } else { - TargetSectionSymbols = nullptr; + TargetSectionSymbols = &AbsoluteSymbols; } } // Find the first symbol in the section whose offset is less than - // or equal to the target. - if (TargetSectionSymbols) { - auto TargetSym = std::upper_bound( - TargetSectionSymbols->begin(), TargetSectionSymbols->end(), + // or equal to the target. If there isn't a section that contains + // the target, find the nearest preceding absolute symbol. + auto TargetSym = std::upper_bound( + TargetSectionSymbols->begin(), TargetSectionSymbols->end(), + Target, [](uint64_t LHS, + const std::tuple &RHS) { + return LHS < std::get<0>(RHS); + }); + if (TargetSym == TargetSectionSymbols->begin()) { + TargetSectionSymbols = &AbsoluteSymbols; + TargetSym = std::upper_bound( + AbsoluteSymbols.begin(), AbsoluteSymbols.end(), Target, [](uint64_t LHS, const std::tuple &RHS) { - return LHS < std::get<0>(RHS); - }); - if (TargetSym != TargetSectionSymbols->begin()) { - --TargetSym; - uint64_t TargetAddress = std::get<0>(*TargetSym); - StringRef TargetName = std::get<1>(*TargetSym); - outs() << " <" << TargetName; - uint64_t Disp = Target - TargetAddress; - if (Disp) - outs() << "+0x" << Twine::utohexstr(Disp); - outs() << '>'; - } + return LHS < std::get<0>(RHS); + }); + } + if (TargetSym != TargetSectionSymbols->begin()) { + --TargetSym; + uint64_t TargetAddress = std::get<0>(*TargetSym); + StringRef TargetName = std::get<1>(*TargetSym); + outs() << " <" << TargetName; + uint64_t Disp = Target - TargetAddress; + if (Disp) + outs() << "+0x" << Twine::utohexstr(Disp); + outs() << '>'; } } } -- 2.11.0