[llvm] ac9e8b3 - [llvm-objdump][ARM] Print inline relocations when dumping ARM data
Fangrui Song via llvm-commits
llvm-commits at lists.llvm.org
Mon May 4 11:51:49 PDT 2020
Author: Fangrui Song
Date: 2020-05-04T11:51:39-07:00
New Revision: ac9e8b3a7e295afdebcd9fff69e720f04e026bff
URL: https://github.com/llvm/llvm-project/commit/ac9e8b3a7e295afdebcd9fff69e720f04e026bff
DIFF: https://github.com/llvm/llvm-project/commit/ac9e8b3a7e295afdebcd9fff69e720f04e026bff.diff
LOG: [llvm-objdump][ARM] Print inline relocations when dumping ARM data
Fixes PR44357
For ARM ELF, regions covered by data mapping symbols `$d` are dumped as `.byte`, `.short` or `.word` but inline relocations are not printed. This patch merges its loop into the normal instruction printing loop so that inline relocations are printed.
Reviewed By: nickdesaulniers
Differential Revision: https://reviews.llvm.org/D79284
Added:
Modified:
llvm/test/tools/llvm-objdump/ELF/ARM/disassemble-code-data-mix.s
llvm/tools/llvm-objdump/llvm-objdump.cpp
Removed:
################################################################################
diff --git a/llvm/test/tools/llvm-objdump/ELF/ARM/disassemble-code-data-mix.s b/llvm/test/tools/llvm-objdump/ELF/ARM/disassemble-code-data-mix.s
index b0d5d7a53eae..52cb0677c780 100644
--- a/llvm/test/tools/llvm-objdump/ELF/ARM/disassemble-code-data-mix.s
+++ b/llvm/test/tools/llvm-objdump/ELF/ARM/disassemble-code-data-mix.s
@@ -1,4 +1,6 @@
- at RUN: llvm-mc -triple arm-unknown-linux -filetype=obj %s | llvm-objdump -d - | FileCheck %s
+@ RUN: llvm-mc -triple arm-unknown-linux -filetype=obj %s -o %t
+@ RUN: llvm-objdump -d %t | FileCheck %s
+@ RUN: llvm-objdump -d -r %t | FileCheck --check-prefixes=CHECK,RELOC %s
.cpu arm7tdmi
.global myInt
@@ -32,5 +34,8 @@ myStr:
.string "test string"
- at CHECK: .word 0x00000000
- at CHECK-DAG: 74 65 73 74 20 73 74 72 test str
+@ CHECK: .word 0x00000000
+@ RELOC-NEXT: R_ARM_ABS32 myInt
+@ CHECK-EMPTY:
+@ CHECK-NEXT: <myStr>:
+@ CHECK-NEXT: 74 65 73 74 20 73 74 72 test str
diff --git a/llvm/tools/llvm-objdump/llvm-objdump.cpp b/llvm/tools/llvm-objdump/llvm-objdump.cpp
index 5cb3a54b50b5..6eebf98744aa 100644
--- a/llvm/tools/llvm-objdump/llvm-objdump.cpp
+++ b/llvm/tools/llvm-objdump/llvm-objdump.cpp
@@ -1091,37 +1091,30 @@ static char getMappingSymbolKind(ArrayRef<MappingSymbolPair> MappingSymbols,
return (It - 1)->second;
}
-static uint64_t
-dumpARMELFData(uint64_t SectionAddr, uint64_t Index, uint64_t End,
- const ObjectFile *Obj, ArrayRef<uint8_t> Bytes,
- ArrayRef<MappingSymbolPair> MappingSymbols) {
+static uint64_t dumpARMELFData(uint64_t SectionAddr, uint64_t Index,
+ uint64_t End, const ObjectFile *Obj,
+ ArrayRef<uint8_t> Bytes,
+ ArrayRef<MappingSymbolPair> MappingSymbols) {
support::endianness Endian =
Obj->isLittleEndian() ? support::little : support::big;
- while (Index < End) {
- outs() << format("%8" PRIx64 ":", SectionAddr + Index);
- outs() << "\t";
- if (Index + 4 <= End) {
- dumpBytes(Bytes.slice(Index, 4), outs());
- outs() << "\t.word\t"
- << format_hex(
- support::endian::read32(Bytes.data() + Index, Endian), 10);
- Index += 4;
- } else if (Index + 2 <= End) {
- dumpBytes(Bytes.slice(Index, 2), outs());
- outs() << "\t\t.short\t"
- << format_hex(
- support::endian::read16(Bytes.data() + Index, Endian), 6);
- Index += 2;
- } else {
- dumpBytes(Bytes.slice(Index, 1), outs());
- outs() << "\t\t.byte\t" << format_hex(Bytes[0], 4);
- ++Index;
- }
- outs() << "\n";
- if (getMappingSymbolKind(MappingSymbols, Index) != 'd')
- break;
+ outs() << format("%8" PRIx64 ":\t", SectionAddr + Index);
+ if (Index + 4 <= End) {
+ dumpBytes(Bytes.slice(Index, 4), outs());
+ outs() << "\t.word\t"
+ << format_hex(support::endian::read32(Bytes.data() + Index, Endian),
+ 10);
+ return 4;
+ }
+ if (Index + 2 <= End) {
+ dumpBytes(Bytes.slice(Index, 2), outs());
+ outs() << "\t\t.short\t"
+ << format_hex(support::endian::read16(Bytes.data() + Index, Endian),
+ 6);
+ return 2;
}
- return Index;
+ dumpBytes(Bytes.slice(Index, 1), outs());
+ outs() << "\t\t.byte\t" << format_hex(Bytes[0], 4);
+ return 1;
}
static void dumpELFData(uint64_t SectionAddr, uint64_t Index, uint64_t End,
@@ -1458,134 +1451,139 @@ static void disassembleObject(const Target *TheTarget, const ObjectFile *Obj,
bool CheckARMELFData = hasMappingSymbols(Obj) &&
Symbols[SI].Type != ELF::STT_OBJECT &&
!DisassembleAll;
+ bool DumpARMELFData = false;
while (Index < End) {
// ARM and AArch64 ELF binaries can interleave data and text in the
// same section. We rely on the markers introduced to understand what
// we need to dump. If the data marker is within a function, it is
// denoted as a word/short etc.
- if (CheckARMELFData &&
- getMappingSymbolKind(MappingSymbols, Index) == 'd') {
- Index = dumpARMELFData(SectionAddr, Index, End, Obj, Bytes,
- MappingSymbols);
- continue;
- }
-
- // When -z or --disassemble-zeroes are given we always dissasemble
- // them. Otherwise we might want to skip zero bytes we see.
- if (!DisassembleZeroes) {
- uint64_t MaxOffset = End - Index;
- // For --reloc: print zero blocks patched by relocations, so that
- // relocations can be shown in the dump.
- if (RelCur != RelEnd)
- MaxOffset = RelCur->getOffset() - Index;
-
- if (size_t N =
- countSkippableZeroBytes(Bytes.slice(Index, MaxOffset))) {
- outs() << "\t\t..." << '\n';
- Index += N;
- continue;
+ if (CheckARMELFData) {
+ char Kind = getMappingSymbolKind(MappingSymbols, Index);
+ DumpARMELFData = Kind == 'd';
+ if (SecondarySTI) {
+ if (Kind == 'a') {
+ STI = PrimaryIsThumb ? SecondarySTI : PrimarySTI;
+ DisAsm = PrimaryIsThumb ? SecondaryDisAsm : PrimaryDisAsm;
+ } else if (Kind == 't') {
+ STI = PrimaryIsThumb ? PrimarySTI : SecondarySTI;
+ DisAsm = PrimaryIsThumb ? PrimaryDisAsm : SecondaryDisAsm;
+ }
}
}
- if (SecondarySTI) {
- if (getMappingSymbolKind(MappingSymbols, Index) == 'a') {
- STI = PrimaryIsThumb ? SecondarySTI : PrimarySTI;
- DisAsm = PrimaryIsThumb ? SecondaryDisAsm : PrimaryDisAsm;
- } else if (getMappingSymbolKind(MappingSymbols, Index) == 't') {
- STI = PrimaryIsThumb ? PrimarySTI : SecondarySTI;
- DisAsm = PrimaryIsThumb ? PrimaryDisAsm : SecondaryDisAsm;
+ if (DumpARMELFData) {
+ Size = dumpARMELFData(SectionAddr, Index, End, Obj, Bytes,
+ MappingSymbols);
+ } else {
+ // When -z or --disassemble-zeroes are given we always dissasemble
+ // them. Otherwise we might want to skip zero bytes we see.
+ if (!DisassembleZeroes) {
+ uint64_t MaxOffset = End - Index;
+ // For --reloc: print zero blocks patched by relocations, so that
+ // relocations can be shown in the dump.
+ if (RelCur != RelEnd)
+ MaxOffset = RelCur->getOffset() - Index;
+
+ if (size_t N =
+ countSkippableZeroBytes(Bytes.slice(Index, MaxOffset))) {
+ outs() << "\t\t..." << '\n';
+ Index += N;
+ continue;
+ }
}
- }
- // Disassemble a real instruction or a data when disassemble all is
- // provided
- MCInst Inst;
- bool Disassembled = DisAsm->getInstruction(
- Inst, Size, Bytes.slice(Index), SectionAddr + Index, CommentStream);
- if (Size == 0)
- Size = 1;
-
- PIP.printInst(*IP, Disassembled ? &Inst : nullptr,
- Bytes.slice(Index, Size),
- {SectionAddr + Index + VMAAdjustment, Section.getIndex()},
- outs(), "", *STI, &SP, Obj->getFileName(), &Rels);
- outs() << CommentStream.str();
- Comments.clear();
-
- // If disassembly has failed, avoid analysing invalid/incomplete
- // instruction information. Otherwise, try to resolve the target address
- // (jump target or memory operand address) and print it on the right of
- // the instruction.
- if (Disassembled && MIA) {
- uint64_t Target;
- bool PrintTarget =
- MIA->evaluateBranch(Inst, SectionAddr + Index, Size, Target);
- if (!PrintTarget)
- if (Optional<uint64_t> MaybeTarget =
- MIA->evaluateMemoryOperandAddress(Inst, SectionAddr + Index,
- Size)) {
- Target = *MaybeTarget;
- PrintTarget = true;
- outs() << " # " << Twine::utohexstr(Target);
- }
- if (PrintTarget) {
- // In a relocatable object, the target's section must reside in
- // the same section as the call instruction or it is accessed
- // through a relocation.
- //
- // In a non-relocatable object, the target may be in any section.
- // In that case, locate the section(s) containing the target address
- // and find the symbol in one of those, if possible.
- //
- // N.B. We don't walk the relocations in the relocatable case yet.
- std::vector<const SectionSymbolsTy *> TargetSectionSymbols;
- if (!Obj->isRelocatableObject()) {
- auto It = llvm::partition_point(
- SectionAddresses,
- [=](const std::pair<uint64_t, SectionRef> &O) {
- return O.first <= Target;
- });
- uint64_t TargetSecAddr = 0;
- while (It != SectionAddresses.begin()) {
- --It;
- if (TargetSecAddr == 0)
- TargetSecAddr = It->first;
- if (It->first != TargetSecAddr)
- break;
- TargetSectionSymbols.push_back(&AllSymbols[It->second]);
+ // Disassemble a real instruction or a data when disassemble all is
+ // provided
+ MCInst Inst;
+ bool Disassembled =
+ DisAsm->getInstruction(Inst, Size, Bytes.slice(Index),
+ SectionAddr + Index, CommentStream);
+ if (Size == 0)
+ Size = 1;
+
+ PIP.printInst(
+ *IP, Disassembled ? &Inst : nullptr, Bytes.slice(Index, Size),
+ {SectionAddr + Index + VMAAdjustment, Section.getIndex()}, outs(),
+ "", *STI, &SP, Obj->getFileName(), &Rels);
+ outs() << CommentStream.str();
+ Comments.clear();
+
+ // If disassembly has failed, avoid analysing invalid/incomplete
+ // instruction information. Otherwise, try to resolve the target
+ // address (jump target or memory operand address) and print it on the
+ // right of the instruction.
+ if (Disassembled && MIA) {
+ uint64_t Target;
+ bool PrintTarget =
+ MIA->evaluateBranch(Inst, SectionAddr + Index, Size, Target);
+ if (!PrintTarget)
+ if (Optional<uint64_t> MaybeTarget =
+ MIA->evaluateMemoryOperandAddress(
+ Inst, SectionAddr + Index, Size)) {
+ Target = *MaybeTarget;
+ PrintTarget = true;
+ outs() << " # " << Twine::utohexstr(Target);
}
- } else {
- TargetSectionSymbols.push_back(&Symbols);
- }
- TargetSectionSymbols.push_back(&AbsoluteSymbols);
-
- // Find the last symbol in the first candidate section whose offset
- // is less than or equal to the target. If there are no such
- // symbols, try in the next section and so on, before finally using
- // the nearest preceding absolute symbol (if any), if there are no
- // other valid symbols.
- const SymbolInfoTy *TargetSym = nullptr;
- for (const SectionSymbolsTy *TargetSymbols : TargetSectionSymbols) {
- auto It = llvm::partition_point(
- *TargetSymbols,
- [=](const SymbolInfoTy &O) { return O.Addr <= Target; });
- if (It != TargetSymbols->begin()) {
- TargetSym = &*(It - 1);
- break;
+ if (PrintTarget) {
+ // In a relocatable object, the target's section must reside in
+ // the same section as the call instruction or it is accessed
+ // through a relocation.
+ //
+ // In a non-relocatable object, the target may be in any section.
+ // In that case, locate the section(s) containing the target
+ // address and find the symbol in one of those, if possible.
+ //
+ // N.B. We don't walk the relocations in the relocatable case yet.
+ std::vector<const SectionSymbolsTy *> TargetSectionSymbols;
+ if (!Obj->isRelocatableObject()) {
+ auto It = llvm::partition_point(
+ SectionAddresses,
+ [=](const std::pair<uint64_t, SectionRef> &O) {
+ return O.first <= Target;
+ });
+ uint64_t TargetSecAddr = 0;
+ while (It != SectionAddresses.begin()) {
+ --It;
+ if (TargetSecAddr == 0)
+ TargetSecAddr = It->first;
+ if (It->first != TargetSecAddr)
+ break;
+ TargetSectionSymbols.push_back(&AllSymbols[It->second]);
+ }
+ } else {
+ TargetSectionSymbols.push_back(&Symbols);
+ }
+ TargetSectionSymbols.push_back(&AbsoluteSymbols);
+
+ // Find the last symbol in the first candidate section whose
+ // offset is less than or equal to the target. If there are no
+ // such symbols, try in the next section and so on, before finally
+ // using the nearest preceding absolute symbol (if any), if there
+ // are no other valid symbols.
+ const SymbolInfoTy *TargetSym = nullptr;
+ for (const SectionSymbolsTy *TargetSymbols :
+ TargetSectionSymbols) {
+ auto It = llvm::partition_point(
+ *TargetSymbols,
+ [=](const SymbolInfoTy &O) { return O.Addr <= Target; });
+ if (It != TargetSymbols->begin()) {
+ TargetSym = &*(It - 1);
+ break;
+ }
}
- }
- if (TargetSym != nullptr) {
- uint64_t TargetAddress = TargetSym->Addr;
- std::string TargetName = TargetSym->Name.str();
- if (Demangle)
- TargetName = demangle(TargetName);
-
- outs() << " <" << TargetName;
- uint64_t Disp = Target - TargetAddress;
- if (Disp)
- outs() << "+0x" << Twine::utohexstr(Disp);
- outs() << '>';
+ if (TargetSym != nullptr) {
+ uint64_t TargetAddress = TargetSym->Addr;
+ std::string TargetName = TargetSym->Name.str();
+ if (Demangle)
+ TargetName = demangle(TargetName);
+
+ outs() << " <" << TargetName;
+ uint64_t Disp = Target - TargetAddress;
+ if (Disp)
+ outs() << "+0x" << Twine::utohexstr(Disp);
+ outs() << '>';
+ }
}
}
}
More information about the llvm-commits
mailing list