From 52c0444e5ecd1c328b826573e4379081e5e37323 Mon Sep 17 00:00:00 2001 From: Davide Italiano Date: Thu, 1 Oct 2015 21:57:09 +0000 Subject: [PATCH] [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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@249083 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../AArch64/elf-aarch64-mapping-symbols.test | 30 ++++++++++++ tools/llvm-objdump/llvm-objdump.cpp | 49 +++++++++++++++++++ 2 files changed, 79 insertions(+) create mode 100644 test/tools/llvm-objdump/AArch64/elf-aarch64-mapping-symbols.test diff --git a/test/tools/llvm-objdump/AArch64/elf-aarch64-mapping-symbols.test b/test/tools/llvm-objdump/AArch64/elf-aarch64-mapping-symbols.test new file mode 100644 index 00000000000..cb9560d74df --- /dev/null +++ b/test/tools/llvm-objdump/AArch64/elf-aarch64-mapping-symbols.test @@ -0,0 +1,30 @@ +# RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-freebsd %s -o %t +# RUN: llvm-objdump -d %t | FileCheck %s + +.section .mysection,"ax",@progbits +.globl _start +_start: + adr x1,msg +msg: .asciz "Hello, world\n" +msgend: + +.section .myothersection,"ax",@progbits + adrp x1,mystr +mystr: + .asciz "blah" + .size mystr, 4 + +# CHECK: Disassembly of section .mysection: +# CHECK: _start: +# CHECK: 0: 21 00 00 10 adr x1, #4 +# CHECK: msg: +# CHECK: 4: 48 65 6c 6c .word +# CHECK: 8: 6f 2c 20 77 .word +# CHECK: c: 6f 72 6c 64 .word +# CHECK: 10: 0a 00 .short +# CHECK: Disassembly of section .myothersection: +# CHECK: $x.2: +# CHECK: 0: 01 00 00 90 adrp x1, #0 +# CHECK: mystr: +# CHECK: 4: 62 6c 61 68 .word +# CHECK: 8: 00 .byte diff --git a/tools/llvm-objdump/llvm-objdump.cpp b/tools/llvm-objdump/llvm-objdump.cpp index 09b6d8f3af7..169e5c0d9ac 100644 --- a/tools/llvm-objdump/llvm-objdump.cpp +++ b/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> Symbols; + std::vector DataMappingSymsAddr; + std::vector TextMappingSymsAddr; for (const SymbolRef &Symbol : Obj->symbols()) { if (Section.containsSymbol(Symbol)) { ErrorOr AddressOrErr = Symbol.getAddress(); @@ -929,11 +931,19 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) { ErrorOr 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 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)) { -- 2.34.1