diff options
author | Davide Italiano <davide@freebsd.org> | 2015-10-01 21:57:09 +0000 |
---|---|---|
committer | Davide Italiano <davide@freebsd.org> | 2015-10-01 21:57:09 +0000 |
commit | f070688ecfc6428cf58d9eb794358bff2c5c5a15 (patch) | |
tree | 5430fe29f150baaefa97f27562518b52cc91d4e7 /llvm/tools/llvm-objdump/llvm-objdump.cpp | |
parent | d2c7589f932e301717e6b08cf5efb8700e793075 (diff) | |
download | bcm5719-llvm-f070688ecfc6428cf58d9eb794358bff2c5c5a15.tar.gz bcm5719-llvm-f070688ecfc6428cf58d9eb794358bff2c5c5a15.zip |
[PATCH] D13360: [llvm-objdump] Teach -d about AArch64 mapping symbols
AArch64 uses $d* and $x* to interleave between text and data.
llvm-objdump didn't know about this so it ended up printing garbage.
This patch is a first step towards a solution of the problem.
Differential Revision: http://reviews.llvm.org/D13360
llvm-svn: 249083
Diffstat (limited to 'llvm/tools/llvm-objdump/llvm-objdump.cpp')
-rw-r--r-- | llvm/tools/llvm-objdump/llvm-objdump.cpp | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/llvm/tools/llvm-objdump/llvm-objdump.cpp b/llvm/tools/llvm-objdump/llvm-objdump.cpp index 09b6d8f3af7..169e5c0d9ac 100644 --- a/llvm/tools/llvm-objdump/llvm-objdump.cpp +++ b/llvm/tools/llvm-objdump/llvm-objdump.cpp @@ -917,6 +917,8 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) { // Make a list of all the symbols in this section. std::vector<std::pair<uint64_t, StringRef>> Symbols; + std::vector<uint64_t> DataMappingSymsAddr; + std::vector<uint64_t> TextMappingSymsAddr; for (const SymbolRef &Symbol : Obj->symbols()) { if (Section.containsSymbol(Symbol)) { ErrorOr<uint64_t> AddressOrErr = Symbol.getAddress(); @@ -929,11 +931,19 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) { ErrorOr<StringRef> Name = Symbol.getName(); error(Name.getError()); Symbols.push_back(std::make_pair(Address, *Name)); + if (Obj->isELF() && Obj->getArch() == Triple::aarch64) { + if (Name->startswith("$d")) + DataMappingSymsAddr.push_back(Address); + if (Name->startswith("$x")) + TextMappingSymsAddr.push_back(Address); + } } } // Sort the symbols by address, just in case they didn't come in that way. array_pod_sort(Symbols.begin(), Symbols.end()); + std::sort(DataMappingSymsAddr.begin(), DataMappingSymsAddr.end()); + std::sort(TextMappingSymsAddr.begin(), TextMappingSymsAddr.end()); // Make a list of all the relocations for this section. std::vector<RelocationRef> Rels; @@ -998,6 +1008,45 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) { for (Index = Start; Index < End; Index += Size) { MCInst Inst; + // 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 (Obj->isELF() && Obj->getArch() == Triple::aarch64) { + uint64_t Stride = 0; + + auto DAI = std::lower_bound(DataMappingSymsAddr.begin(), + DataMappingSymsAddr.end(), Index); + if (DAI != DataMappingSymsAddr.end() && *DAI == Index) { + // Switch to data. + while (Index < End) { + outs() << format("%8" PRIx64 ":", SectionAddr + Index); + outs() << "\t"; + if (Index + 4 <= End) { + Stride = 4; + dumpBytes(Bytes.slice(Index, 4), outs()); + outs() << "\t.word"; + } else if (Index + 2 <= End) { + Stride = 2; + dumpBytes(Bytes.slice(Index, 2), outs()); + outs() << "\t.short"; + } else { + Stride = 1; + dumpBytes(Bytes.slice(Index, 1), outs()); + outs() << "\t.byte"; + } + Index += Stride; + outs() << "\n"; + auto TAI = std::lower_bound(TextMappingSymsAddr.begin(), + TextMappingSymsAddr.end(), Index); + if (TAI != TextMappingSymsAddr.end() && *TAI == Index) + break; + } + } + } + + if (Index >= End) + break; + if (DisAsm->getInstruction(Inst, Size, Bytes.slice(Index), SectionAddr + Index, DebugOut, CommentStream)) { |