1*30fdc8d8SChris Lattner //===-- CommandObjectDisassemble.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 "CommandObjectDisassemble.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/Core/AddressRange.h" 17*30fdc8d8SChris Lattner #include "lldb/Core/Args.h" 18*30fdc8d8SChris Lattner #include "lldb/Interpreter/CommandCompletions.h" 19*30fdc8d8SChris Lattner #include "lldb/Interpreter/CommandInterpreter.h" 20*30fdc8d8SChris Lattner #include "lldb/Interpreter/CommandReturnObject.h" 21*30fdc8d8SChris Lattner #include "lldb/Core/Disassembler.h" 22*30fdc8d8SChris Lattner #include "lldb/Core/Options.h" 23*30fdc8d8SChris Lattner #include "lldb/Core/SourceManager.h" 24*30fdc8d8SChris Lattner #include "lldb/Target/StackFrame.h" 25*30fdc8d8SChris Lattner #include "lldb/Symbol/Symbol.h" 26*30fdc8d8SChris Lattner #include "lldb/Target/Process.h" 27*30fdc8d8SChris Lattner #include "lldb/Target/Target.h" 28*30fdc8d8SChris Lattner 29*30fdc8d8SChris Lattner #define DEFAULT_DISASM_BYTE_SIZE 32 30*30fdc8d8SChris Lattner 31*30fdc8d8SChris Lattner using namespace lldb; 32*30fdc8d8SChris Lattner using namespace lldb_private; 33*30fdc8d8SChris Lattner 34*30fdc8d8SChris Lattner CommandObjectDisassemble::CommandOptions::CommandOptions () : 35*30fdc8d8SChris Lattner Options(), 36*30fdc8d8SChris Lattner m_func_name(), 37*30fdc8d8SChris Lattner m_load_addr() 38*30fdc8d8SChris Lattner { 39*30fdc8d8SChris Lattner ResetOptionValues(); 40*30fdc8d8SChris Lattner } 41*30fdc8d8SChris Lattner 42*30fdc8d8SChris Lattner CommandObjectDisassemble::CommandOptions::~CommandOptions () 43*30fdc8d8SChris Lattner { 44*30fdc8d8SChris Lattner } 45*30fdc8d8SChris Lattner 46*30fdc8d8SChris Lattner Error 47*30fdc8d8SChris Lattner CommandObjectDisassemble::CommandOptions::SetOptionValue (int option_idx, const char *option_arg) 48*30fdc8d8SChris Lattner { 49*30fdc8d8SChris Lattner Error error; 50*30fdc8d8SChris Lattner 51*30fdc8d8SChris Lattner char short_option = (char) m_getopt_table[option_idx].val; 52*30fdc8d8SChris Lattner 53*30fdc8d8SChris Lattner switch (short_option) 54*30fdc8d8SChris Lattner { 55*30fdc8d8SChris Lattner case 'm': 56*30fdc8d8SChris Lattner show_mixed = true; 57*30fdc8d8SChris Lattner break; 58*30fdc8d8SChris Lattner 59*30fdc8d8SChris Lattner case 'c': 60*30fdc8d8SChris Lattner num_lines_context = Args::StringToUInt32(option_arg, 0, 0); 61*30fdc8d8SChris Lattner break; 62*30fdc8d8SChris Lattner 63*30fdc8d8SChris Lattner case 'b': 64*30fdc8d8SChris Lattner show_bytes = true; 65*30fdc8d8SChris Lattner break; 66*30fdc8d8SChris Lattner 67*30fdc8d8SChris Lattner case 'a': 68*30fdc8d8SChris Lattner m_load_addr = Args::StringToUInt64(optarg, LLDB_INVALID_ADDRESS, 0); 69*30fdc8d8SChris Lattner if (m_load_addr == LLDB_INVALID_ADDRESS) 70*30fdc8d8SChris Lattner m_load_addr = Args::StringToUInt64(optarg, LLDB_INVALID_ADDRESS, 16); 71*30fdc8d8SChris Lattner 72*30fdc8d8SChris Lattner if (m_load_addr == LLDB_INVALID_ADDRESS) 73*30fdc8d8SChris Lattner error.SetErrorStringWithFormat ("Invalid address string '%s'.\n", optarg); 74*30fdc8d8SChris Lattner break; 75*30fdc8d8SChris Lattner 76*30fdc8d8SChris Lattner case 'n': 77*30fdc8d8SChris Lattner m_func_name = option_arg; 78*30fdc8d8SChris Lattner break; 79*30fdc8d8SChris Lattner 80*30fdc8d8SChris Lattner case 'r': 81*30fdc8d8SChris Lattner raw = true; 82*30fdc8d8SChris Lattner break; 83*30fdc8d8SChris Lattner 84*30fdc8d8SChris Lattner default: 85*30fdc8d8SChris Lattner error.SetErrorStringWithFormat("Unrecognized short option '%c'.\n", short_option); 86*30fdc8d8SChris Lattner break; 87*30fdc8d8SChris Lattner } 88*30fdc8d8SChris Lattner 89*30fdc8d8SChris Lattner return error; 90*30fdc8d8SChris Lattner } 91*30fdc8d8SChris Lattner 92*30fdc8d8SChris Lattner void 93*30fdc8d8SChris Lattner CommandObjectDisassemble::CommandOptions::ResetOptionValues () 94*30fdc8d8SChris Lattner { 95*30fdc8d8SChris Lattner Options::ResetOptionValues(); 96*30fdc8d8SChris Lattner show_mixed = false; 97*30fdc8d8SChris Lattner show_bytes = false; 98*30fdc8d8SChris Lattner num_lines_context = 0; 99*30fdc8d8SChris Lattner m_func_name.clear(); 100*30fdc8d8SChris Lattner m_load_addr = LLDB_INVALID_ADDRESS; 101*30fdc8d8SChris Lattner } 102*30fdc8d8SChris Lattner 103*30fdc8d8SChris Lattner const lldb::OptionDefinition* 104*30fdc8d8SChris Lattner CommandObjectDisassemble::CommandOptions::GetDefinitions () 105*30fdc8d8SChris Lattner { 106*30fdc8d8SChris Lattner return g_option_table; 107*30fdc8d8SChris Lattner } 108*30fdc8d8SChris Lattner 109*30fdc8d8SChris Lattner lldb::OptionDefinition 110*30fdc8d8SChris Lattner CommandObjectDisassemble::CommandOptions::g_option_table[] = 111*30fdc8d8SChris Lattner { 112*30fdc8d8SChris Lattner { 0, false, "bytes", 'b', no_argument, NULL, 0, NULL, "Show opcode bytes when disassembling."}, 113*30fdc8d8SChris Lattner { 0, false, "context", 'c', required_argument, NULL, 0, "<num-lines>", "Number of context lines of source to show."}, 114*30fdc8d8SChris Lattner { 0, false, "mixed", 'm', no_argument, NULL, 0, NULL, "Enable mixed source and assembly display."}, 115*30fdc8d8SChris Lattner { 0, false, "raw", 'r', no_argument, NULL, 0, NULL, "Print raw disassembly with no symbol information."}, 116*30fdc8d8SChris Lattner 117*30fdc8d8SChris Lattner { 1, false, "address", 'a', required_argument, NULL, 0, "<address>", "Address to start disassembling."}, 118*30fdc8d8SChris Lattner { 1, false, "bytes", 'b', no_argument, NULL, 0, NULL, "Show opcode bytes when disassembling."}, 119*30fdc8d8SChris Lattner { 1, false, "context", 'c', required_argument, NULL, 0, "<num-lines>", "Number of context lines of source to show."}, 120*30fdc8d8SChris Lattner { 1, false, "mixed", 'm', no_argument, NULL, 0, NULL, "Enable mixed source and assembly display."}, 121*30fdc8d8SChris Lattner { 1, false, "raw", 'r', no_argument, NULL, 0, NULL, "Print raw disassembly with no symbol information."}, 122*30fdc8d8SChris Lattner 123*30fdc8d8SChris Lattner { 2, false, "name", 'n', required_argument, NULL, CommandCompletions::eSymbolCompletion, "<function-name>", "Disassemble entire contents of the given function name."}, 124*30fdc8d8SChris Lattner { 2, false, "bytes", 'b', no_argument, NULL, 0, NULL, "Show opcode bytes when disassembling."}, 125*30fdc8d8SChris Lattner { 2, false, "context", 'c', required_argument, NULL, 0, "<num-lines>", "Number of context lines of source to show."}, 126*30fdc8d8SChris Lattner { 2, false, "mixed", 'm', no_argument, NULL, 0, NULL, "Enable mixed source and assembly display."}, 127*30fdc8d8SChris Lattner { 2, false, "raw", 'r', no_argument, NULL, 0, NULL, "Print raw disassembly with no symbol information."}, 128*30fdc8d8SChris Lattner 129*30fdc8d8SChris Lattner { 0, false, NULL, 0, 0, NULL, 0, NULL, NULL } 130*30fdc8d8SChris Lattner }; 131*30fdc8d8SChris Lattner 132*30fdc8d8SChris Lattner 133*30fdc8d8SChris Lattner 134*30fdc8d8SChris Lattner //------------------------------------------------------------------------- 135*30fdc8d8SChris Lattner // CommandObjectDisassemble 136*30fdc8d8SChris Lattner //------------------------------------------------------------------------- 137*30fdc8d8SChris Lattner 138*30fdc8d8SChris Lattner CommandObjectDisassemble::CommandObjectDisassemble () : 139*30fdc8d8SChris Lattner CommandObject ("disassemble", 140*30fdc8d8SChris Lattner "Disassemble bytes in the current function or anywhere in the inferior program.", 141*30fdc8d8SChris Lattner "disassemble [[<start-addr> [<end-addr>]] | <function-name>] [<cmd-options>]") 142*30fdc8d8SChris Lattner { 143*30fdc8d8SChris Lattner } 144*30fdc8d8SChris Lattner 145*30fdc8d8SChris Lattner CommandObjectDisassemble::~CommandObjectDisassemble() 146*30fdc8d8SChris Lattner { 147*30fdc8d8SChris Lattner } 148*30fdc8d8SChris Lattner 149*30fdc8d8SChris Lattner void 150*30fdc8d8SChris Lattner CommandObjectDisassemble::Disassemble 151*30fdc8d8SChris Lattner ( 152*30fdc8d8SChris Lattner CommandContext *context, 153*30fdc8d8SChris Lattner CommandInterpreter *interpreter, 154*30fdc8d8SChris Lattner CommandReturnObject &result, 155*30fdc8d8SChris Lattner Disassembler *disassembler, 156*30fdc8d8SChris Lattner const SymbolContextList &sc_list 157*30fdc8d8SChris Lattner ) 158*30fdc8d8SChris Lattner { 159*30fdc8d8SChris Lattner const size_t count = sc_list.GetSize(); 160*30fdc8d8SChris Lattner SymbolContext sc; 161*30fdc8d8SChris Lattner AddressRange range; 162*30fdc8d8SChris Lattner for (size_t i=0; i<count; ++i) 163*30fdc8d8SChris Lattner { 164*30fdc8d8SChris Lattner if (sc_list.GetContextAtIndex(i, sc) == false) 165*30fdc8d8SChris Lattner break; 166*30fdc8d8SChris Lattner if (sc.GetAddressRange(eSymbolContextFunction | eSymbolContextSymbol, range)) 167*30fdc8d8SChris Lattner { 168*30fdc8d8SChris Lattner lldb::addr_t addr = range.GetBaseAddress().GetLoadAddress(context->GetExecutionContext().process); 169*30fdc8d8SChris Lattner if (addr != LLDB_INVALID_ADDRESS) 170*30fdc8d8SChris Lattner { 171*30fdc8d8SChris Lattner lldb::addr_t end_addr = addr + range.GetByteSize(); 172*30fdc8d8SChris Lattner Disassemble (context, interpreter, result, disassembler, addr, end_addr); 173*30fdc8d8SChris Lattner } 174*30fdc8d8SChris Lattner } 175*30fdc8d8SChris Lattner } 176*30fdc8d8SChris Lattner } 177*30fdc8d8SChris Lattner 178*30fdc8d8SChris Lattner void 179*30fdc8d8SChris Lattner CommandObjectDisassemble::Disassemble 180*30fdc8d8SChris Lattner ( 181*30fdc8d8SChris Lattner CommandContext *context, 182*30fdc8d8SChris Lattner CommandInterpreter *interpreter, 183*30fdc8d8SChris Lattner CommandReturnObject &result, 184*30fdc8d8SChris Lattner Disassembler *disassembler, 185*30fdc8d8SChris Lattner lldb::addr_t addr, 186*30fdc8d8SChris Lattner lldb::addr_t end_addr 187*30fdc8d8SChris Lattner ) 188*30fdc8d8SChris Lattner { 189*30fdc8d8SChris Lattner if (addr == LLDB_INVALID_ADDRESS) 190*30fdc8d8SChris Lattner return; 191*30fdc8d8SChris Lattner 192*30fdc8d8SChris Lattner if (end_addr == LLDB_INVALID_ADDRESS || addr >= end_addr) 193*30fdc8d8SChris Lattner end_addr = addr + DEFAULT_DISASM_BYTE_SIZE; 194*30fdc8d8SChris Lattner 195*30fdc8d8SChris Lattner ExecutionContext exe_ctx (context->GetExecutionContext()); 196*30fdc8d8SChris Lattner DataExtractor data; 197*30fdc8d8SChris Lattner size_t bytes_disassembled = disassembler->ParseInstructions (&exe_ctx, eAddressTypeLoad, addr, end_addr - addr, data); 198*30fdc8d8SChris Lattner if (bytes_disassembled == 0) 199*30fdc8d8SChris Lattner { 200*30fdc8d8SChris Lattner // Nothing got disassembled... 201*30fdc8d8SChris Lattner } 202*30fdc8d8SChris Lattner else 203*30fdc8d8SChris Lattner { 204*30fdc8d8SChris Lattner // We got some things disassembled... 205*30fdc8d8SChris Lattner size_t num_instructions = disassembler->GetInstructionList().GetSize(); 206*30fdc8d8SChris Lattner uint32_t offset = 0; 207*30fdc8d8SChris Lattner Stream &output_stream = result.GetOutputStream(); 208*30fdc8d8SChris Lattner SymbolContext sc; 209*30fdc8d8SChris Lattner SymbolContext prev_sc; 210*30fdc8d8SChris Lattner AddressRange sc_range; 211*30fdc8d8SChris Lattner if (m_options.show_mixed) 212*30fdc8d8SChris Lattner output_stream.IndentMore (); 213*30fdc8d8SChris Lattner 214*30fdc8d8SChris Lattner for (size_t i=0; i<num_instructions; ++i) 215*30fdc8d8SChris Lattner { 216*30fdc8d8SChris Lattner Disassembler::Instruction *inst = disassembler->GetInstructionList().GetInstructionAtIndex (i); 217*30fdc8d8SChris Lattner if (inst) 218*30fdc8d8SChris Lattner { 219*30fdc8d8SChris Lattner lldb::addr_t curr_addr = addr + offset; 220*30fdc8d8SChris Lattner if (m_options.show_mixed) 221*30fdc8d8SChris Lattner { 222*30fdc8d8SChris Lattner Process *process = context->GetExecutionContext().process; 223*30fdc8d8SChris Lattner if (!sc_range.ContainsLoadAddress (curr_addr, process)) 224*30fdc8d8SChris Lattner { 225*30fdc8d8SChris Lattner prev_sc = sc; 226*30fdc8d8SChris Lattner Address curr_so_addr; 227*30fdc8d8SChris Lattner if (process && process->ResolveLoadAddress (curr_addr, curr_so_addr)) 228*30fdc8d8SChris Lattner { 229*30fdc8d8SChris Lattner if (curr_so_addr.GetSection()) 230*30fdc8d8SChris Lattner { 231*30fdc8d8SChris Lattner Module *module = curr_so_addr.GetSection()->GetModule(); 232*30fdc8d8SChris Lattner uint32_t resolved_mask = module->ResolveSymbolContextForAddress(curr_so_addr, eSymbolContextEverything, sc); 233*30fdc8d8SChris Lattner if (resolved_mask) 234*30fdc8d8SChris Lattner { 235*30fdc8d8SChris Lattner sc.GetAddressRange (eSymbolContextEverything, sc_range); 236*30fdc8d8SChris Lattner if (sc != prev_sc) 237*30fdc8d8SChris Lattner { 238*30fdc8d8SChris Lattner if (offset != 0) 239*30fdc8d8SChris Lattner output_stream.EOL(); 240*30fdc8d8SChris Lattner 241*30fdc8d8SChris Lattner sc.DumpStopContext(&output_stream, process, curr_so_addr); 242*30fdc8d8SChris Lattner output_stream.EOL(); 243*30fdc8d8SChris Lattner if (sc.comp_unit && sc.line_entry.IsValid()) 244*30fdc8d8SChris Lattner { 245*30fdc8d8SChris Lattner interpreter->GetSourceManager().DisplaySourceLinesWithLineNumbers ( 246*30fdc8d8SChris Lattner sc.line_entry.file, 247*30fdc8d8SChris Lattner sc.line_entry.line, 248*30fdc8d8SChris Lattner m_options.num_lines_context, 249*30fdc8d8SChris Lattner m_options.num_lines_context, 250*30fdc8d8SChris Lattner m_options.num_lines_context ? "->" : "", 251*30fdc8d8SChris Lattner &output_stream); 252*30fdc8d8SChris Lattner } 253*30fdc8d8SChris Lattner } 254*30fdc8d8SChris Lattner } 255*30fdc8d8SChris Lattner } 256*30fdc8d8SChris Lattner } 257*30fdc8d8SChris Lattner } 258*30fdc8d8SChris Lattner } 259*30fdc8d8SChris Lattner if (m_options.show_mixed) 260*30fdc8d8SChris Lattner output_stream.IndentMore (); 261*30fdc8d8SChris Lattner output_stream.Indent(); 262*30fdc8d8SChris Lattner size_t inst_byte_size = inst->GetByteSize(); 263*30fdc8d8SChris Lattner inst->Dump(&output_stream, curr_addr, m_options.show_bytes ? &data : NULL, offset, exe_ctx, m_options.raw); 264*30fdc8d8SChris Lattner output_stream.EOL(); 265*30fdc8d8SChris Lattner offset += inst_byte_size; 266*30fdc8d8SChris Lattner if (m_options.show_mixed) 267*30fdc8d8SChris Lattner output_stream.IndentLess (); 268*30fdc8d8SChris Lattner } 269*30fdc8d8SChris Lattner else 270*30fdc8d8SChris Lattner { 271*30fdc8d8SChris Lattner break; 272*30fdc8d8SChris Lattner } 273*30fdc8d8SChris Lattner } 274*30fdc8d8SChris Lattner if (m_options.show_mixed) 275*30fdc8d8SChris Lattner output_stream.IndentLess (); 276*30fdc8d8SChris Lattner 277*30fdc8d8SChris Lattner } 278*30fdc8d8SChris Lattner } 279*30fdc8d8SChris Lattner 280*30fdc8d8SChris Lattner bool 281*30fdc8d8SChris Lattner CommandObjectDisassemble::Execute 282*30fdc8d8SChris Lattner ( 283*30fdc8d8SChris Lattner Args& command, 284*30fdc8d8SChris Lattner CommandContext *context, 285*30fdc8d8SChris Lattner CommandInterpreter *interpreter, 286*30fdc8d8SChris Lattner CommandReturnObject &result 287*30fdc8d8SChris Lattner ) 288*30fdc8d8SChris Lattner { 289*30fdc8d8SChris Lattner Target *target = context->GetTarget(); 290*30fdc8d8SChris Lattner if (target == NULL) 291*30fdc8d8SChris Lattner { 292*30fdc8d8SChris Lattner result.AppendError ("invalid target, set executable file using 'file' command"); 293*30fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 294*30fdc8d8SChris Lattner return false; 295*30fdc8d8SChris Lattner } 296*30fdc8d8SChris Lattner 297*30fdc8d8SChris Lattner ArchSpec arch(target->GetArchitecture()); 298*30fdc8d8SChris Lattner if (!arch.IsValid()) 299*30fdc8d8SChris Lattner { 300*30fdc8d8SChris Lattner result.AppendError ("target needs valid architecure in order to be able to disassemble"); 301*30fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 302*30fdc8d8SChris Lattner return false; 303*30fdc8d8SChris Lattner } 304*30fdc8d8SChris Lattner 305*30fdc8d8SChris Lattner Disassembler *disassembler = Disassembler::FindPlugin(arch); 306*30fdc8d8SChris Lattner 307*30fdc8d8SChris Lattner if (disassembler == NULL) 308*30fdc8d8SChris Lattner { 309*30fdc8d8SChris Lattner result.AppendErrorWithFormat ("Unable to find Disassembler plug-in for %s architecture.\n", arch.AsCString()); 310*30fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 311*30fdc8d8SChris Lattner return false; 312*30fdc8d8SChris Lattner } 313*30fdc8d8SChris Lattner 314*30fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessFinishResult); 315*30fdc8d8SChris Lattner 316*30fdc8d8SChris Lattner lldb::addr_t addr = LLDB_INVALID_ADDRESS; 317*30fdc8d8SChris Lattner lldb::addr_t end_addr = LLDB_INVALID_ADDRESS; 318*30fdc8d8SChris Lattner ConstString name; 319*30fdc8d8SChris Lattner const size_t argc = command.GetArgumentCount(); 320*30fdc8d8SChris Lattner if (argc == 0 && m_options.m_load_addr != LLDB_INVALID_ADDRESS) 321*30fdc8d8SChris Lattner { 322*30fdc8d8SChris Lattner addr = m_options.m_load_addr; 323*30fdc8d8SChris Lattner end_addr = addr + DEFAULT_DISASM_BYTE_SIZE; 324*30fdc8d8SChris Lattner } else if (argc == 0 && !m_options.m_func_name.empty()) 325*30fdc8d8SChris Lattner { 326*30fdc8d8SChris Lattner ConstString tmpname(m_options.m_func_name.c_str()); 327*30fdc8d8SChris Lattner name = tmpname; 328*30fdc8d8SChris Lattner } else if (argc == 0) 329*30fdc8d8SChris Lattner { 330*30fdc8d8SChris Lattner ExecutionContext exe_ctx(context->GetExecutionContext()); 331*30fdc8d8SChris Lattner if (exe_ctx.frame) 332*30fdc8d8SChris Lattner { 333*30fdc8d8SChris Lattner SymbolContext sc(exe_ctx.frame->GetSymbolContext(eSymbolContextFunction | eSymbolContextSymbol)); 334*30fdc8d8SChris Lattner if (sc.function) 335*30fdc8d8SChris Lattner { 336*30fdc8d8SChris Lattner addr = sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress(exe_ctx.process); 337*30fdc8d8SChris Lattner if (addr != LLDB_INVALID_ADDRESS) 338*30fdc8d8SChris Lattner end_addr = addr + sc.function->GetAddressRange().GetByteSize(); 339*30fdc8d8SChris Lattner } 340*30fdc8d8SChris Lattner else if (sc.symbol && sc.symbol->GetAddressRangePtr()) 341*30fdc8d8SChris Lattner { 342*30fdc8d8SChris Lattner addr = sc.symbol->GetAddressRangePtr()->GetBaseAddress().GetLoadAddress(exe_ctx.process); 343*30fdc8d8SChris Lattner if (addr != LLDB_INVALID_ADDRESS) 344*30fdc8d8SChris Lattner { 345*30fdc8d8SChris Lattner end_addr = addr + sc.symbol->GetAddressRangePtr()->GetByteSize(); 346*30fdc8d8SChris Lattner if (addr == end_addr) 347*30fdc8d8SChris Lattner end_addr += DEFAULT_DISASM_BYTE_SIZE; 348*30fdc8d8SChris Lattner } 349*30fdc8d8SChris Lattner } 350*30fdc8d8SChris Lattner else 351*30fdc8d8SChris Lattner { 352*30fdc8d8SChris Lattner addr = exe_ctx.frame->GetPC().GetLoadAddress(exe_ctx.process); 353*30fdc8d8SChris Lattner if (addr != LLDB_INVALID_ADDRESS) 354*30fdc8d8SChris Lattner end_addr = addr + DEFAULT_DISASM_BYTE_SIZE; 355*30fdc8d8SChris Lattner } 356*30fdc8d8SChris Lattner } 357*30fdc8d8SChris Lattner else 358*30fdc8d8SChris Lattner { 359*30fdc8d8SChris Lattner result.AppendError ("invalid frame"); 360*30fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 361*30fdc8d8SChris Lattner return false; 362*30fdc8d8SChris Lattner } 363*30fdc8d8SChris Lattner } 364*30fdc8d8SChris Lattner else if (argc == 1) 365*30fdc8d8SChris Lattner { 366*30fdc8d8SChris Lattner const char *arg = command.GetArgumentAtIndex(0); 367*30fdc8d8SChris Lattner addr = Args::StringToAddress (arg); 368*30fdc8d8SChris Lattner if (addr == LLDB_INVALID_ADDRESS) 369*30fdc8d8SChris Lattner { 370*30fdc8d8SChris Lattner // Lookup function or symbol name? 371*30fdc8d8SChris Lattner ConstString tmpname(arg); 372*30fdc8d8SChris Lattner name = tmpname; 373*30fdc8d8SChris Lattner } 374*30fdc8d8SChris Lattner else 375*30fdc8d8SChris Lattner { 376*30fdc8d8SChris Lattner end_addr = addr + DEFAULT_DISASM_BYTE_SIZE; 377*30fdc8d8SChris Lattner } 378*30fdc8d8SChris Lattner } 379*30fdc8d8SChris Lattner else if (argc >= 1 && argc <= 2) 380*30fdc8d8SChris Lattner { 381*30fdc8d8SChris Lattner addr = Args::StringToAddress (command.GetArgumentAtIndex(0)); 382*30fdc8d8SChris Lattner if (addr == LLDB_INVALID_ADDRESS) 383*30fdc8d8SChris Lattner { 384*30fdc8d8SChris Lattner result.AppendErrorWithFormat ("Unable to parse address '%s'.\n", command.GetArgumentAtIndex(0)); 385*30fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 386*30fdc8d8SChris Lattner return false; 387*30fdc8d8SChris Lattner } 388*30fdc8d8SChris Lattner end_addr = Args::StringToAddress (command.GetArgumentAtIndex(1), addr); 389*30fdc8d8SChris Lattner if (end_addr == LLDB_INVALID_ADDRESS) 390*30fdc8d8SChris Lattner { 391*30fdc8d8SChris Lattner result.AppendErrorWithFormat ("Unable to parse address '%s'.\n", command.GetArgumentAtIndex(1)); 392*30fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 393*30fdc8d8SChris Lattner return false; 394*30fdc8d8SChris Lattner } 395*30fdc8d8SChris Lattner } 396*30fdc8d8SChris Lattner 397*30fdc8d8SChris Lattner if (!name.IsEmpty()) 398*30fdc8d8SChris Lattner { 399*30fdc8d8SChris Lattner SymbolContextList sc_list; 400*30fdc8d8SChris Lattner 401*30fdc8d8SChris Lattner if (target->GetImages().FindFunctions(name, sc_list)) 402*30fdc8d8SChris Lattner { 403*30fdc8d8SChris Lattner Disassemble (context, interpreter, result, disassembler, sc_list); 404*30fdc8d8SChris Lattner } 405*30fdc8d8SChris Lattner else if (target->GetImages().FindSymbolsWithNameAndType(name, eSymbolTypeCode, sc_list)) 406*30fdc8d8SChris Lattner { 407*30fdc8d8SChris Lattner Disassemble (context, interpreter, result, disassembler, sc_list); 408*30fdc8d8SChris Lattner } 409*30fdc8d8SChris Lattner else 410*30fdc8d8SChris Lattner { 411*30fdc8d8SChris Lattner result.AppendErrorWithFormat ("Unable to find symbol with name '%s'.\n", name.GetCString()); 412*30fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 413*30fdc8d8SChris Lattner return false; 414*30fdc8d8SChris Lattner } 415*30fdc8d8SChris Lattner } 416*30fdc8d8SChris Lattner 417*30fdc8d8SChris Lattner if (addr < end_addr) 418*30fdc8d8SChris Lattner { 419*30fdc8d8SChris Lattner Disassemble (context, interpreter, result, disassembler, addr, end_addr); 420*30fdc8d8SChris Lattner } 421*30fdc8d8SChris Lattner 422*30fdc8d8SChris Lattner if (addr == LLDB_INVALID_ADDRESS && name.IsEmpty()) 423*30fdc8d8SChris Lattner { 424*30fdc8d8SChris Lattner result.AppendError ("No recognizable address of function name provided"); 425*30fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 426*30fdc8d8SChris Lattner return false; 427*30fdc8d8SChris Lattner } 428*30fdc8d8SChris Lattner { 429*30fdc8d8SChris Lattner return result.Succeeded(); 430*30fdc8d8SChris Lattner } 431*30fdc8d8SChris Lattner } 432