diff options
Diffstat (limited to 'source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp')
-rw-r--r-- | source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp | 105 |
1 files changed, 91 insertions, 14 deletions
diff --git a/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp b/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp index 2f90122..75ee8aa 100644 --- a/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp +++ b/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp @@ -415,7 +415,7 @@ protected: -DisassemblerLLVMC::LLVMCDisassembler::LLVMCDisassembler (const char *triple, unsigned flavor, DisassemblerLLVMC &owner): +DisassemblerLLVMC::LLVMCDisassembler::LLVMCDisassembler (const char *triple, const char *cpu, unsigned flavor, DisassemblerLLVMC &owner): m_is_valid(true) { std::string Error; @@ -431,7 +431,7 @@ DisassemblerLLVMC::LLVMCDisassembler::LLVMCDisassembler (const char *triple, uns std::string features_str; - m_subtarget_info_ap.reset(curr_target->createMCSubtargetInfo(triple, "", + m_subtarget_info_ap.reset(curr_target->createMCSubtargetInfo(triple, cpu, features_str)); std::unique_ptr<llvm::MCRegisterInfo> reg_info(curr_target->createMCRegInfo(triple)); @@ -469,11 +469,11 @@ DisassemblerLLVMC::LLVMCDisassembler::LLVMCDisassembler (const char *triple, uns asm_printer_variant = flavor; } - m_instr_printer_ap.reset(curr_target->createMCInstPrinter(asm_printer_variant, + m_instr_printer_ap.reset(curr_target->createMCInstPrinter(llvm::Triple{triple}, + asm_printer_variant, *m_asm_info_ap.get(), *m_instr_info_ap.get(), - *m_reg_info_ap.get(), - *m_subtarget_info_ap.get())); + *m_reg_info_ap.get())); if (m_instr_printer_ap.get() == NULL) { m_disasm_ap.reset(); @@ -518,7 +518,8 @@ DisassemblerLLVMC::LLVMCDisassembler::PrintMCInst (llvm::MCInst &mc_inst, llvm::StringRef unused_annotations; llvm::SmallString<64> inst_string; llvm::raw_svector_ostream inst_stream(inst_string); - m_instr_printer_ap->printInst (&mc_inst, inst_stream, unused_annotations); + m_instr_printer_ap->printInst (&mc_inst, inst_stream, unused_annotations, + *m_subtarget_info_ap); inst_stream.flush(); const size_t output_size = std::min(dst_len - 1, inst_string.size()); std::memcpy(dst, inst_string.data(), output_size); @@ -533,8 +534,8 @@ DisassemblerLLVMC::LLVMCDisassembler::SetStyle (bool use_hex_immed, HexImmediate m_instr_printer_ap->setPrintImmHex(use_hex_immed); switch(hex_style) { - case eHexStyleC: m_instr_printer_ap->setPrintImmHex(llvm::HexStyle::C); break; - case eHexStyleAsm: m_instr_printer_ap->setPrintImmHex(llvm::HexStyle::Asm); break; + case eHexStyleC: m_instr_printer_ap->setPrintHexStyle(llvm::HexStyle::C); break; + case eHexStyleAsm: m_instr_printer_ap->setPrintHexStyle(llvm::HexStyle::Asm); break; } } @@ -636,7 +637,45 @@ DisassemblerLLVMC::DisassemblerLLVMC (const ArchSpec &arch, const char *flavor_s triple = thumb_arch.GetTriple().getTriple().c_str(); } - m_disasm_ap.reset (new LLVMCDisassembler(triple, flavor, *this)); + const char *cpu = ""; + + switch (arch.GetCore()) + { + case ArchSpec::eCore_mips32: + case ArchSpec::eCore_mips32el: + cpu = "mips32"; break; + case ArchSpec::eCore_mips32r2: + case ArchSpec::eCore_mips32r2el: + cpu = "mips32r2"; break; + case ArchSpec::eCore_mips32r3: + case ArchSpec::eCore_mips32r3el: + cpu = "mips32r3"; break; + case ArchSpec::eCore_mips32r5: + case ArchSpec::eCore_mips32r5el: + cpu = "mips32r5"; break; + case ArchSpec::eCore_mips32r6: + case ArchSpec::eCore_mips32r6el: + cpu = "mips32r6"; break; + case ArchSpec::eCore_mips64: + case ArchSpec::eCore_mips64el: + cpu = "mips64"; break; + case ArchSpec::eCore_mips64r2: + case ArchSpec::eCore_mips64r2el: + cpu = "mips64r2"; break; + case ArchSpec::eCore_mips64r3: + case ArchSpec::eCore_mips64r3el: + cpu = "mips64r3"; break; + case ArchSpec::eCore_mips64r5: + case ArchSpec::eCore_mips64r5el: + cpu = "mips64r5"; break; + case ArchSpec::eCore_mips64r6: + case ArchSpec::eCore_mips64r6el: + cpu = "mips64r6"; break; + default: + cpu = ""; break; + } + + m_disasm_ap.reset (new LLVMCDisassembler(triple, cpu, flavor, *this)); if (!m_disasm_ap->IsValid()) { // We use m_disasm_ap.get() to tell whether we are valid or not, so if this isn't good for some reason, @@ -648,7 +687,7 @@ DisassemblerLLVMC::DisassemblerLLVMC (const ArchSpec &arch, const char *flavor_s if (arch.GetTriple().getArch() == llvm::Triple::arm) { std::string thumb_triple(thumb_arch.GetTriple().getTriple()); - m_alternate_disasm_ap.reset(new LLVMCDisassembler(thumb_triple.c_str(), flavor, *this)); + m_alternate_disasm_ap.reset(new LLVMCDisassembler(thumb_triple.c_str(), "", flavor, *this)); if (!m_alternate_disasm_ap->IsValid()) { m_disasm_ap.reset(); @@ -792,25 +831,63 @@ const char *DisassemblerLLVMC::SymbolLookup (uint64_t value, //std::string remove_this_prior_to_checkin; Target *target = m_exe_ctx ? m_exe_ctx->GetTargetPtr() : NULL; Address value_so_addr; + Address pc_so_addr; if (m_inst->UsingFileAddress()) { ModuleSP module_sp(m_inst->GetAddress().GetModule()); if (module_sp) + { module_sp->ResolveFileAddress(value, value_so_addr); + module_sp->ResolveFileAddress(pc, pc_so_addr); + } } else if (target && !target->GetSectionLoadList().IsEmpty()) { target->GetSectionLoadList().ResolveLoadAddress(value, value_so_addr); + target->GetSectionLoadList().ResolveLoadAddress(pc, pc_so_addr); + } + + SymbolContext sym_ctx; + const uint32_t resolve_scope = eSymbolContextFunction | eSymbolContextSymbol; + if (pc_so_addr.IsValid() && pc_so_addr.GetModule()) + { + pc_so_addr.GetModule()->ResolveSymbolContextForAddress (pc_so_addr, resolve_scope, sym_ctx); } if (value_so_addr.IsValid() && value_so_addr.GetSection()) { StreamString ss; - value_so_addr.Dump (&ss, - target, - Address::DumpStyleResolvedDescriptionNoFunctionArguments, - Address::DumpStyleSectionNameOffset); + bool format_omitting_current_func_name = false; + if (sym_ctx.symbol || sym_ctx.function) + { + AddressRange range; + if (sym_ctx.GetAddressRange (resolve_scope, 0, false, range) + && range.GetBaseAddress().IsValid() + && range.ContainsLoadAddress (value_so_addr, target)) + { + format_omitting_current_func_name = true; + } + } + + // If the "value" address (the target address we're symbolicating) + // is inside the same SymbolContext as the current instruction pc + // (pc_so_addr), don't print the full function name - just print it + // with DumpStyleNoFunctionName style, e.g. "<+36>". + if (format_omitting_current_func_name) + { + value_so_addr.Dump (&ss, + target, + Address::DumpStyleNoFunctionName, + Address::DumpStyleSectionNameOffset); + } + else + { + value_so_addr.Dump (&ss, + target, + Address::DumpStyleResolvedDescriptionNoFunctionArguments, + Address::DumpStyleSectionNameOffset); + } if (!ss.GetString().empty()) { |