forked from OSchip/llvm-project
[llvm-objdump] Print the call target next to the instruction
GNU binutils provides this behavior. objdump -r doesn't really help when you aren't dealing with relocation object files. llvm-svn: 241631
This commit is contained in:
parent
683c4943e6
commit
81afca6bf7
|
@ -6,7 +6,7 @@
|
|||
# Will be bundle-aligning to 16 byte boundaries
|
||||
.bundle_align_mode 4
|
||||
.text
|
||||
# CHECK-LABEL: foo
|
||||
# CHECK-LABEL: foo:
|
||||
foo:
|
||||
# Test that bundle alignment mode can be set more than once.
|
||||
.bundle_align_mode 4
|
||||
|
@ -19,11 +19,11 @@ foo:
|
|||
callq bar
|
||||
.bundle_unlock
|
||||
.bundle_unlock
|
||||
# CHECK: 10: callq
|
||||
# CHECK-NEXT: 15: callq
|
||||
# CHECK: 10: callq {{.*}} <bar>
|
||||
# CHECK-NEXT: 15: callq {{.*}} <bar>
|
||||
|
||||
.p2align 4
|
||||
# CHECK-LABEL: bar
|
||||
# CHECK-LABEL: bar:
|
||||
bar:
|
||||
callq foo
|
||||
callq foo
|
||||
|
@ -35,10 +35,10 @@ bar:
|
|||
callq bar
|
||||
.bundle_unlock
|
||||
.bundle_unlock
|
||||
# CHECK: 36: callq
|
||||
# CHECK-NEXT: 3b: callq
|
||||
# CHECK: 36: callq {{.*}} <bar>
|
||||
# CHECK-NEXT: 3b: callq {{.*}} <bar>
|
||||
|
||||
# CHECK-LABEL: baz
|
||||
# CHECK-LABEL: baz:
|
||||
baz:
|
||||
callq foo
|
||||
callq foo
|
||||
|
@ -50,8 +50,8 @@ baz:
|
|||
callq bar
|
||||
.bundle_unlock
|
||||
.bundle_unlock
|
||||
# CHECK: 56: callq
|
||||
# CHECK-NEXT: 5b: callq
|
||||
# CHECK: 56: callq {{.*}} <bar>
|
||||
# CHECK-NEXT: 5b: callq {{.*}} <bar>
|
||||
|
||||
# CHECK-LABEL: quux
|
||||
quux:
|
||||
|
@ -65,5 +65,5 @@ quux:
|
|||
.bundle_unlock
|
||||
# Check that the calls are bundled together when the second one is after the
|
||||
# inner nest is closed.
|
||||
# CHECK: 70: callq
|
||||
# CHECK-NEXT: 75: callq
|
||||
# CHECK: 70: callq {{.*}} <bar>
|
||||
# CHECK-NEXT: 75: callq {{.*}} <bar>
|
||||
|
|
|
@ -808,6 +808,27 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) {
|
|||
SectionRelocMap[*Sec2].push_back(Section);
|
||||
}
|
||||
|
||||
// Create a mapping from virtual address to symbol name. This is used to
|
||||
// pretty print the target of a call.
|
||||
std::vector<std::pair<uint64_t, StringRef>> AllSymbols;
|
||||
if (MIA) {
|
||||
for (const SymbolRef &Symbol : Obj->symbols()) {
|
||||
ErrorOr<uint64_t> AddressOrErr = Symbol.getAddress();
|
||||
if (error(AddressOrErr.getError()))
|
||||
break;
|
||||
uint64_t Address = *AddressOrErr;
|
||||
|
||||
ErrorOr<StringRef> Name = Symbol.getName();
|
||||
if (error(Name.getError()))
|
||||
break;
|
||||
if (Name->empty())
|
||||
continue;
|
||||
AllSymbols.push_back(std::make_pair(Address, *Name));
|
||||
}
|
||||
|
||||
array_pod_sort(AllSymbols.begin(), AllSymbols.end());
|
||||
}
|
||||
|
||||
for (const SectionRef &Section : Obj->sections()) {
|
||||
if (!Section.isText() || Section.isVirtual())
|
||||
continue;
|
||||
|
@ -912,6 +933,21 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) {
|
|||
SectionAddr + Index, outs(), "", *STI);
|
||||
outs() << CommentStream.str();
|
||||
Comments.clear();
|
||||
if (MIA && (MIA->isCall(Inst) || MIA->isUnconditionalBranch(Inst))) {
|
||||
uint64_t Target;
|
||||
if (MIA->evaluateBranch(Inst, SectionAddr + Index, Size, Target)) {
|
||||
const auto &TargetSym =
|
||||
std::lower_bound(AllSymbols.begin(), AllSymbols.end(),
|
||||
std::make_pair(Target, StringRef()));
|
||||
if (TargetSym != AllSymbols.end()) {
|
||||
outs() << " <" << TargetSym->second;
|
||||
uint64_t Disp = TargetSym->first - Target;
|
||||
if (Disp)
|
||||
outs() << '-' << Disp;
|
||||
outs() << '>';
|
||||
}
|
||||
}
|
||||
}
|
||||
outs() << "\n";
|
||||
} else {
|
||||
errs() << ToolName << ": warning: invalid instruction encoding\n";
|
||||
|
|
Loading…
Reference in New Issue