1*30fdc8d8SChris Lattner //===-- Disassembler.cpp ----------------------------------------*- C++ -*-===// 2*30fdc8d8SChris Lattner // 3*30fdc8d8SChris Lattner // The LLVM Compiler Infrastructure 4*30fdc8d8SChris Lattner // 5*30fdc8d8SChris Lattner // This file is distributed under the University of Illinois Open Source 6*30fdc8d8SChris Lattner // License. See LICENSE.TXT for details. 7*30fdc8d8SChris Lattner // 8*30fdc8d8SChris Lattner //===----------------------------------------------------------------------===// 9*30fdc8d8SChris Lattner 10*30fdc8d8SChris Lattner #include "lldb/Core/Disassembler.h" 11*30fdc8d8SChris Lattner 12*30fdc8d8SChris Lattner // C Includes 13*30fdc8d8SChris Lattner // C++ Includes 14*30fdc8d8SChris Lattner // Other libraries and framework includes 15*30fdc8d8SChris Lattner // Project includes 16*30fdc8d8SChris Lattner #include "lldb/lldb-private.h" 17*30fdc8d8SChris Lattner #include "lldb/Core/Error.h" 18*30fdc8d8SChris Lattner #include "lldb/Core/DataBufferHeap.h" 19*30fdc8d8SChris Lattner #include "lldb/Core/DataExtractor.h" 20*30fdc8d8SChris Lattner #include "lldb/Core/Debugger.h" 21*30fdc8d8SChris Lattner #include "lldb/Core/Module.h" 22*30fdc8d8SChris Lattner #include "lldb/Core/PluginManager.h" 23*30fdc8d8SChris Lattner #include "lldb/Core/Timer.h" 24*30fdc8d8SChris Lattner #include "lldb/Symbol/ObjectFile.h" 25*30fdc8d8SChris Lattner #include "lldb/Target/ExecutionContext.h" 26*30fdc8d8SChris Lattner #include "lldb/Target/Process.h" 27*30fdc8d8SChris Lattner #include "lldb/Target/StackFrame.h" 28*30fdc8d8SChris Lattner #include "lldb/Target/Target.h" 29*30fdc8d8SChris Lattner 30*30fdc8d8SChris Lattner #define DEFAULT_DISASM_BYTE_SIZE 32 31*30fdc8d8SChris Lattner 32*30fdc8d8SChris Lattner using namespace lldb; 33*30fdc8d8SChris Lattner using namespace lldb_private; 34*30fdc8d8SChris Lattner 35*30fdc8d8SChris Lattner 36*30fdc8d8SChris Lattner Disassembler* 37*30fdc8d8SChris Lattner Disassembler::FindPlugin (const ArchSpec &arch) 38*30fdc8d8SChris Lattner { 39*30fdc8d8SChris Lattner Timer scoped_timer (__PRETTY_FUNCTION__, 40*30fdc8d8SChris Lattner "Disassembler::FindPlugin (arch = %s)", 41*30fdc8d8SChris Lattner arch.AsCString()); 42*30fdc8d8SChris Lattner 43*30fdc8d8SChris Lattner std::auto_ptr<Disassembler> disassembler_ap; 44*30fdc8d8SChris Lattner DisassemblerCreateInstance create_callback; 45*30fdc8d8SChris Lattner for (uint32_t idx = 0; (create_callback = PluginManager::GetDisassemblerCreateCallbackAtIndex(idx)) != NULL; ++idx) 46*30fdc8d8SChris Lattner { 47*30fdc8d8SChris Lattner disassembler_ap.reset (create_callback(arch)); 48*30fdc8d8SChris Lattner 49*30fdc8d8SChris Lattner if (disassembler_ap.get()) 50*30fdc8d8SChris Lattner return disassembler_ap.release(); 51*30fdc8d8SChris Lattner } 52*30fdc8d8SChris Lattner return NULL; 53*30fdc8d8SChris Lattner } 54*30fdc8d8SChris Lattner 55*30fdc8d8SChris Lattner bool 56*30fdc8d8SChris Lattner Disassembler::Disassemble 57*30fdc8d8SChris Lattner ( 58*30fdc8d8SChris Lattner const ArchSpec &arch, 59*30fdc8d8SChris Lattner const ExecutionContext &exe_ctx, 60*30fdc8d8SChris Lattner uint32_t mixed_context_lines, 61*30fdc8d8SChris Lattner Stream &strm 62*30fdc8d8SChris Lattner ) 63*30fdc8d8SChris Lattner { 64*30fdc8d8SChris Lattner Disassembler *disassembler = Disassembler::FindPlugin(arch); 65*30fdc8d8SChris Lattner 66*30fdc8d8SChris Lattner if (disassembler) 67*30fdc8d8SChris Lattner { 68*30fdc8d8SChris Lattner lldb::addr_t addr = LLDB_INVALID_ADDRESS; 69*30fdc8d8SChris Lattner size_t byte_size = 0; 70*30fdc8d8SChris Lattner if (exe_ctx.frame) 71*30fdc8d8SChris Lattner { 72*30fdc8d8SChris Lattner SymbolContext sc(exe_ctx.frame->GetSymbolContext(eSymbolContextFunction | eSymbolContextSymbol)); 73*30fdc8d8SChris Lattner if (sc.function) 74*30fdc8d8SChris Lattner { 75*30fdc8d8SChris Lattner addr = sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress(exe_ctx.process); 76*30fdc8d8SChris Lattner if (addr != LLDB_INVALID_ADDRESS) 77*30fdc8d8SChris Lattner byte_size = sc.function->GetAddressRange().GetByteSize(); 78*30fdc8d8SChris Lattner } 79*30fdc8d8SChris Lattner else if (sc.symbol && sc.symbol->GetAddressRangePtr()) 80*30fdc8d8SChris Lattner { 81*30fdc8d8SChris Lattner addr = sc.symbol->GetAddressRangePtr()->GetBaseAddress().GetLoadAddress(exe_ctx.process); 82*30fdc8d8SChris Lattner if (addr != LLDB_INVALID_ADDRESS) 83*30fdc8d8SChris Lattner { 84*30fdc8d8SChris Lattner byte_size = sc.symbol->GetAddressRangePtr()->GetByteSize(); 85*30fdc8d8SChris Lattner if (byte_size == 0) 86*30fdc8d8SChris Lattner byte_size = DEFAULT_DISASM_BYTE_SIZE; 87*30fdc8d8SChris Lattner } 88*30fdc8d8SChris Lattner } 89*30fdc8d8SChris Lattner else 90*30fdc8d8SChris Lattner { 91*30fdc8d8SChris Lattner addr = exe_ctx.frame->GetPC().GetLoadAddress(exe_ctx.process); 92*30fdc8d8SChris Lattner if (addr != LLDB_INVALID_ADDRESS) 93*30fdc8d8SChris Lattner byte_size = DEFAULT_DISASM_BYTE_SIZE; 94*30fdc8d8SChris Lattner } 95*30fdc8d8SChris Lattner } 96*30fdc8d8SChris Lattner 97*30fdc8d8SChris Lattner if (byte_size) 98*30fdc8d8SChris Lattner { 99*30fdc8d8SChris Lattner DataExtractor data; 100*30fdc8d8SChris Lattner size_t bytes_disassembled = disassembler->ParseInstructions (&exe_ctx, eAddressTypeLoad, addr, byte_size, data); 101*30fdc8d8SChris Lattner if (bytes_disassembled == 0) 102*30fdc8d8SChris Lattner { 103*30fdc8d8SChris Lattner return false; 104*30fdc8d8SChris Lattner } 105*30fdc8d8SChris Lattner else 106*30fdc8d8SChris Lattner { 107*30fdc8d8SChris Lattner // We got some things disassembled... 108*30fdc8d8SChris Lattner size_t num_instructions = disassembler->GetInstructionList().GetSize(); 109*30fdc8d8SChris Lattner uint32_t offset = 0; 110*30fdc8d8SChris Lattner SymbolContext sc; 111*30fdc8d8SChris Lattner SymbolContext prev_sc; 112*30fdc8d8SChris Lattner AddressRange sc_range; 113*30fdc8d8SChris Lattner if (mixed_context_lines) 114*30fdc8d8SChris Lattner strm.IndentMore (); 115*30fdc8d8SChris Lattner 116*30fdc8d8SChris Lattner for (size_t i=0; i<num_instructions; ++i) 117*30fdc8d8SChris Lattner { 118*30fdc8d8SChris Lattner Disassembler::Instruction *inst = disassembler->GetInstructionList().GetInstructionAtIndex (i); 119*30fdc8d8SChris Lattner if (inst) 120*30fdc8d8SChris Lattner { 121*30fdc8d8SChris Lattner lldb::addr_t curr_addr = addr + offset; 122*30fdc8d8SChris Lattner if (mixed_context_lines) 123*30fdc8d8SChris Lattner { 124*30fdc8d8SChris Lattner if (!sc_range.ContainsLoadAddress (curr_addr, exe_ctx.process)) 125*30fdc8d8SChris Lattner { 126*30fdc8d8SChris Lattner prev_sc = sc; 127*30fdc8d8SChris Lattner Address curr_so_addr; 128*30fdc8d8SChris Lattner Process *process = exe_ctx.process; 129*30fdc8d8SChris Lattner if (process && process->ResolveLoadAddress (curr_addr, curr_so_addr)) 130*30fdc8d8SChris Lattner { 131*30fdc8d8SChris Lattner if (curr_so_addr.GetSection()) 132*30fdc8d8SChris Lattner { 133*30fdc8d8SChris Lattner Module *module = curr_so_addr.GetSection()->GetModule(); 134*30fdc8d8SChris Lattner uint32_t resolved_mask = module->ResolveSymbolContextForAddress(curr_so_addr, eSymbolContextEverything, sc); 135*30fdc8d8SChris Lattner if (resolved_mask) 136*30fdc8d8SChris Lattner { 137*30fdc8d8SChris Lattner sc.GetAddressRange (eSymbolContextEverything, sc_range); 138*30fdc8d8SChris Lattner if (sc != prev_sc) 139*30fdc8d8SChris Lattner { 140*30fdc8d8SChris Lattner if (offset != 0) 141*30fdc8d8SChris Lattner strm.EOL(); 142*30fdc8d8SChris Lattner 143*30fdc8d8SChris Lattner sc.DumpStopContext(&strm, process, curr_so_addr); 144*30fdc8d8SChris Lattner 145*30fdc8d8SChris Lattner if (sc.comp_unit && sc.line_entry.IsValid()) 146*30fdc8d8SChris Lattner { 147*30fdc8d8SChris Lattner Debugger::GetSharedInstance().GetSourceManager().DisplaySourceLinesWithLineNumbers ( 148*30fdc8d8SChris Lattner sc.line_entry.file, 149*30fdc8d8SChris Lattner sc.line_entry.line, 150*30fdc8d8SChris Lattner mixed_context_lines, 151*30fdc8d8SChris Lattner mixed_context_lines, 152*30fdc8d8SChris Lattner mixed_context_lines ? "->" : "", 153*30fdc8d8SChris Lattner &strm); 154*30fdc8d8SChris Lattner } 155*30fdc8d8SChris Lattner } 156*30fdc8d8SChris Lattner } 157*30fdc8d8SChris Lattner } 158*30fdc8d8SChris Lattner } 159*30fdc8d8SChris Lattner } 160*30fdc8d8SChris Lattner } 161*30fdc8d8SChris Lattner if (mixed_context_lines) 162*30fdc8d8SChris Lattner strm.IndentMore (); 163*30fdc8d8SChris Lattner strm.Indent(); 164*30fdc8d8SChris Lattner size_t inst_byte_size = inst->GetByteSize(); 165*30fdc8d8SChris Lattner //inst->Dump(&strm, curr_addr, &data, offset); // Do dump opcode bytes 166*30fdc8d8SChris Lattner inst->Dump(&strm, curr_addr, NULL, offset, exe_ctx, false); // Don't dump opcode bytes 167*30fdc8d8SChris Lattner strm.EOL(); 168*30fdc8d8SChris Lattner offset += inst_byte_size; 169*30fdc8d8SChris Lattner if (mixed_context_lines) 170*30fdc8d8SChris Lattner strm.IndentLess (); 171*30fdc8d8SChris Lattner } 172*30fdc8d8SChris Lattner else 173*30fdc8d8SChris Lattner { 174*30fdc8d8SChris Lattner break; 175*30fdc8d8SChris Lattner } 176*30fdc8d8SChris Lattner } 177*30fdc8d8SChris Lattner if (mixed_context_lines) 178*30fdc8d8SChris Lattner strm.IndentLess (); 179*30fdc8d8SChris Lattner 180*30fdc8d8SChris Lattner } 181*30fdc8d8SChris Lattner } 182*30fdc8d8SChris Lattner return true; 183*30fdc8d8SChris Lattner } 184*30fdc8d8SChris Lattner return false; 185*30fdc8d8SChris Lattner } 186*30fdc8d8SChris Lattner 187*30fdc8d8SChris Lattner Disassembler::Instruction::Instruction() 188*30fdc8d8SChris Lattner { 189*30fdc8d8SChris Lattner } 190*30fdc8d8SChris Lattner 191*30fdc8d8SChris Lattner Disassembler::Instruction::~Instruction() 192*30fdc8d8SChris Lattner { 193*30fdc8d8SChris Lattner } 194*30fdc8d8SChris Lattner 195*30fdc8d8SChris Lattner 196*30fdc8d8SChris Lattner Disassembler::InstructionList::InstructionList() : 197*30fdc8d8SChris Lattner m_instructions() 198*30fdc8d8SChris Lattner { 199*30fdc8d8SChris Lattner } 200*30fdc8d8SChris Lattner 201*30fdc8d8SChris Lattner Disassembler::InstructionList::~InstructionList() 202*30fdc8d8SChris Lattner { 203*30fdc8d8SChris Lattner } 204*30fdc8d8SChris Lattner 205*30fdc8d8SChris Lattner size_t 206*30fdc8d8SChris Lattner Disassembler::InstructionList::GetSize() const 207*30fdc8d8SChris Lattner { 208*30fdc8d8SChris Lattner return m_instructions.size(); 209*30fdc8d8SChris Lattner } 210*30fdc8d8SChris Lattner 211*30fdc8d8SChris Lattner 212*30fdc8d8SChris Lattner Disassembler::Instruction * 213*30fdc8d8SChris Lattner Disassembler::InstructionList::GetInstructionAtIndex (uint32_t idx) 214*30fdc8d8SChris Lattner { 215*30fdc8d8SChris Lattner if (idx < m_instructions.size()) 216*30fdc8d8SChris Lattner return m_instructions[idx].get(); 217*30fdc8d8SChris Lattner return NULL; 218*30fdc8d8SChris Lattner } 219*30fdc8d8SChris Lattner 220*30fdc8d8SChris Lattner const Disassembler::Instruction * 221*30fdc8d8SChris Lattner Disassembler::InstructionList::GetInstructionAtIndex (uint32_t idx) const 222*30fdc8d8SChris Lattner { 223*30fdc8d8SChris Lattner if (idx < m_instructions.size()) 224*30fdc8d8SChris Lattner return m_instructions[idx].get(); 225*30fdc8d8SChris Lattner return NULL; 226*30fdc8d8SChris Lattner } 227*30fdc8d8SChris Lattner 228*30fdc8d8SChris Lattner void 229*30fdc8d8SChris Lattner Disassembler::InstructionList::Clear() 230*30fdc8d8SChris Lattner { 231*30fdc8d8SChris Lattner m_instructions.clear(); 232*30fdc8d8SChris Lattner } 233*30fdc8d8SChris Lattner 234*30fdc8d8SChris Lattner void 235*30fdc8d8SChris Lattner Disassembler::InstructionList::AppendInstruction (Instruction::shared_ptr &inst_sp) 236*30fdc8d8SChris Lattner { 237*30fdc8d8SChris Lattner if (inst_sp) 238*30fdc8d8SChris Lattner m_instructions.push_back(inst_sp); 239*30fdc8d8SChris Lattner } 240*30fdc8d8SChris Lattner 241*30fdc8d8SChris Lattner 242*30fdc8d8SChris Lattner size_t 243*30fdc8d8SChris Lattner Disassembler::ParseInstructions 244*30fdc8d8SChris Lattner ( 245*30fdc8d8SChris Lattner const ExecutionContext *exe_ctx, 246*30fdc8d8SChris Lattner lldb::AddressType addr_type, 247*30fdc8d8SChris Lattner lldb::addr_t addr, 248*30fdc8d8SChris Lattner size_t byte_size, 249*30fdc8d8SChris Lattner DataExtractor& data 250*30fdc8d8SChris Lattner ) 251*30fdc8d8SChris Lattner { 252*30fdc8d8SChris Lattner Process *process = exe_ctx->process; 253*30fdc8d8SChris Lattner 254*30fdc8d8SChris Lattner if (process == NULL) 255*30fdc8d8SChris Lattner return 0; 256*30fdc8d8SChris Lattner 257*30fdc8d8SChris Lattner DataBufferSP data_sp(new DataBufferHeap (byte_size, '\0')); 258*30fdc8d8SChris Lattner 259*30fdc8d8SChris Lattner Error error; 260*30fdc8d8SChris Lattner if (process->GetTarget().ReadMemory (addr_type, addr, data_sp->GetBytes(), data_sp->GetByteSize(), error, NULL)) 261*30fdc8d8SChris Lattner { 262*30fdc8d8SChris Lattner data.SetData(data_sp); 263*30fdc8d8SChris Lattner data.SetByteOrder(process->GetByteOrder()); 264*30fdc8d8SChris Lattner data.SetAddressByteSize(process->GetAddressByteSize()); 265*30fdc8d8SChris Lattner return ParseInstructions (data, 0, UINT32_MAX, addr); 266*30fdc8d8SChris Lattner } 267*30fdc8d8SChris Lattner 268*30fdc8d8SChris Lattner return 0; 269*30fdc8d8SChris Lattner } 270*30fdc8d8SChris Lattner 271*30fdc8d8SChris Lattner //---------------------------------------------------------------------- 272*30fdc8d8SChris Lattner // Disassembler copy constructor 273*30fdc8d8SChris Lattner //---------------------------------------------------------------------- 274*30fdc8d8SChris Lattner Disassembler::Disassembler(const ArchSpec& arch) : 275*30fdc8d8SChris Lattner m_arch (arch), 276*30fdc8d8SChris Lattner m_instruction_list(), 277*30fdc8d8SChris Lattner m_base_addr(LLDB_INVALID_ADDRESS) 278*30fdc8d8SChris Lattner { 279*30fdc8d8SChris Lattner 280*30fdc8d8SChris Lattner } 281*30fdc8d8SChris Lattner 282*30fdc8d8SChris Lattner //---------------------------------------------------------------------- 283*30fdc8d8SChris Lattner // Destructor 284*30fdc8d8SChris Lattner //---------------------------------------------------------------------- 285*30fdc8d8SChris Lattner Disassembler::~Disassembler() 286*30fdc8d8SChris Lattner { 287*30fdc8d8SChris Lattner } 288*30fdc8d8SChris Lattner 289*30fdc8d8SChris Lattner Disassembler::InstructionList & 290*30fdc8d8SChris Lattner Disassembler::GetInstructionList () 291*30fdc8d8SChris Lattner { 292*30fdc8d8SChris Lattner return m_instruction_list; 293*30fdc8d8SChris Lattner } 294*30fdc8d8SChris Lattner 295*30fdc8d8SChris Lattner const Disassembler::InstructionList & 296*30fdc8d8SChris Lattner Disassembler::GetInstructionList () const 297*30fdc8d8SChris Lattner { 298*30fdc8d8SChris Lattner return m_instruction_list; 299*30fdc8d8SChris Lattner } 300