1254721Semaste//===-- Disassembler.cpp ----------------------------------------*- C++ -*-===// 2254721Semaste// 3254721Semaste// The LLVM Compiler Infrastructure 4254721Semaste// 5254721Semaste// This file is distributed under the University of Illinois Open Source 6254721Semaste// License. See LICENSE.TXT for details. 7254721Semaste// 8254721Semaste//===----------------------------------------------------------------------===// 9254721Semaste 10254721Semaste#include "lldb/lldb-python.h" 11254721Semaste 12254721Semaste#include "lldb/Core/Disassembler.h" 13254721Semaste 14254721Semaste// C Includes 15254721Semaste// C++ Includes 16254721Semaste// Other libraries and framework includes 17254721Semaste// Project includes 18254721Semaste#include "lldb/lldb-private.h" 19254721Semaste#include "lldb/Core/Error.h" 20254721Semaste#include "lldb/Core/DataBufferHeap.h" 21254721Semaste#include "lldb/Core/DataExtractor.h" 22254721Semaste#include "lldb/Core/Debugger.h" 23254721Semaste#include "lldb/Core/EmulateInstruction.h" 24254721Semaste#include "lldb/Core/Module.h" 25254721Semaste#include "lldb/Core/PluginManager.h" 26254721Semaste#include "lldb/Core/RegularExpression.h" 27254721Semaste#include "lldb/Core/Timer.h" 28254721Semaste#include "lldb/Interpreter/OptionValue.h" 29254721Semaste#include "lldb/Interpreter/OptionValueArray.h" 30254721Semaste#include "lldb/Interpreter/OptionValueDictionary.h" 31254721Semaste#include "lldb/Interpreter/OptionValueString.h" 32254721Semaste#include "lldb/Interpreter/OptionValueUInt64.h" 33254721Semaste#include "lldb/Symbol/ClangNamespaceDecl.h" 34254721Semaste#include "lldb/Symbol/Function.h" 35254721Semaste#include "lldb/Symbol/ObjectFile.h" 36254721Semaste#include "lldb/Target/ExecutionContext.h" 37254721Semaste#include "lldb/Target/Process.h" 38269024Semaste#include "lldb/Target/SectionLoadList.h" 39254721Semaste#include "lldb/Target/StackFrame.h" 40254721Semaste#include "lldb/Target/Target.h" 41254721Semaste 42254721Semaste#define DEFAULT_DISASM_BYTE_SIZE 32 43254721Semaste 44254721Semasteusing namespace lldb; 45254721Semasteusing namespace lldb_private; 46254721Semaste 47254721Semaste 48254721SemasteDisassemblerSP 49254721SemasteDisassembler::FindPlugin (const ArchSpec &arch, const char *flavor, const char *plugin_name) 50254721Semaste{ 51254721Semaste Timer scoped_timer (__PRETTY_FUNCTION__, 52254721Semaste "Disassembler::FindPlugin (arch = %s, plugin_name = %s)", 53254721Semaste arch.GetArchitectureName(), 54254721Semaste plugin_name); 55254721Semaste 56254721Semaste DisassemblerCreateInstance create_callback = NULL; 57254721Semaste 58254721Semaste if (plugin_name) 59254721Semaste { 60254721Semaste ConstString const_plugin_name (plugin_name); 61254721Semaste create_callback = PluginManager::GetDisassemblerCreateCallbackForPluginName (const_plugin_name); 62254721Semaste if (create_callback) 63254721Semaste { 64254721Semaste DisassemblerSP disassembler_sp(create_callback(arch, flavor)); 65254721Semaste 66254721Semaste if (disassembler_sp.get()) 67254721Semaste return disassembler_sp; 68254721Semaste } 69254721Semaste } 70254721Semaste else 71254721Semaste { 72254721Semaste for (uint32_t idx = 0; (create_callback = PluginManager::GetDisassemblerCreateCallbackAtIndex(idx)) != NULL; ++idx) 73254721Semaste { 74254721Semaste DisassemblerSP disassembler_sp(create_callback(arch, flavor)); 75254721Semaste 76254721Semaste if (disassembler_sp.get()) 77254721Semaste return disassembler_sp; 78254721Semaste } 79254721Semaste } 80254721Semaste return DisassemblerSP(); 81254721Semaste} 82254721Semaste 83254721SemasteDisassemblerSP 84254721SemasteDisassembler::FindPluginForTarget(const TargetSP target_sp, const ArchSpec &arch, const char *flavor, const char *plugin_name) 85254721Semaste{ 86254721Semaste if (target_sp && flavor == NULL) 87254721Semaste { 88254721Semaste // FIXME - we don't have the mechanism in place to do per-architecture settings. But since we know that for now 89254721Semaste // we only support flavors on x86 & x86_64, 90254721Semaste if (arch.GetTriple().getArch() == llvm::Triple::x86 91254721Semaste || arch.GetTriple().getArch() == llvm::Triple::x86_64) 92254721Semaste flavor = target_sp->GetDisassemblyFlavor(); 93254721Semaste } 94254721Semaste return FindPlugin(arch, flavor, plugin_name); 95254721Semaste} 96254721Semaste 97254721Semaste 98254721Semastestatic void 99254721SemasteResolveAddress (const ExecutionContext &exe_ctx, 100254721Semaste const Address &addr, 101254721Semaste Address &resolved_addr) 102254721Semaste{ 103254721Semaste if (!addr.IsSectionOffset()) 104254721Semaste { 105254721Semaste // If we weren't passed in a section offset address range, 106254721Semaste // try and resolve it to something 107254721Semaste Target *target = exe_ctx.GetTargetPtr(); 108254721Semaste if (target) 109254721Semaste { 110254721Semaste if (target->GetSectionLoadList().IsEmpty()) 111254721Semaste { 112254721Semaste target->GetImages().ResolveFileAddress (addr.GetOffset(), resolved_addr); 113254721Semaste } 114254721Semaste else 115254721Semaste { 116254721Semaste target->GetSectionLoadList().ResolveLoadAddress (addr.GetOffset(), resolved_addr); 117254721Semaste } 118254721Semaste // We weren't able to resolve the address, just treat it as a 119254721Semaste // raw address 120254721Semaste if (resolved_addr.IsValid()) 121254721Semaste return; 122254721Semaste } 123254721Semaste } 124254721Semaste resolved_addr = addr; 125254721Semaste} 126254721Semaste 127254721Semastesize_t 128254721SemasteDisassembler::Disassemble 129254721Semaste( 130254721Semaste Debugger &debugger, 131254721Semaste const ArchSpec &arch, 132254721Semaste const char *plugin_name, 133254721Semaste const char *flavor, 134254721Semaste const ExecutionContext &exe_ctx, 135254721Semaste SymbolContextList &sc_list, 136254721Semaste uint32_t num_instructions, 137254721Semaste uint32_t num_mixed_context_lines, 138254721Semaste uint32_t options, 139254721Semaste Stream &strm 140254721Semaste) 141254721Semaste{ 142254721Semaste size_t success_count = 0; 143254721Semaste const size_t count = sc_list.GetSize(); 144254721Semaste SymbolContext sc; 145254721Semaste AddressRange range; 146254721Semaste const uint32_t scope = eSymbolContextBlock | eSymbolContextFunction | eSymbolContextSymbol; 147254721Semaste const bool use_inline_block_range = true; 148254721Semaste for (size_t i=0; i<count; ++i) 149254721Semaste { 150254721Semaste if (sc_list.GetContextAtIndex(i, sc) == false) 151254721Semaste break; 152254721Semaste for (uint32_t range_idx = 0; sc.GetAddressRange(scope, range_idx, use_inline_block_range, range); ++range_idx) 153254721Semaste { 154254721Semaste if (Disassemble (debugger, 155254721Semaste arch, 156254721Semaste plugin_name, 157254721Semaste flavor, 158254721Semaste exe_ctx, 159254721Semaste range, 160254721Semaste num_instructions, 161254721Semaste num_mixed_context_lines, 162254721Semaste options, 163254721Semaste strm)) 164254721Semaste { 165254721Semaste ++success_count; 166254721Semaste strm.EOL(); 167254721Semaste } 168254721Semaste } 169254721Semaste } 170254721Semaste return success_count; 171254721Semaste} 172254721Semaste 173254721Semastebool 174254721SemasteDisassembler::Disassemble 175254721Semaste( 176254721Semaste Debugger &debugger, 177254721Semaste const ArchSpec &arch, 178254721Semaste const char *plugin_name, 179254721Semaste const char *flavor, 180254721Semaste const ExecutionContext &exe_ctx, 181254721Semaste const ConstString &name, 182254721Semaste Module *module, 183254721Semaste uint32_t num_instructions, 184254721Semaste uint32_t num_mixed_context_lines, 185254721Semaste uint32_t options, 186254721Semaste Stream &strm 187254721Semaste) 188254721Semaste{ 189254721Semaste SymbolContextList sc_list; 190254721Semaste if (name) 191254721Semaste { 192254721Semaste const bool include_symbols = true; 193254721Semaste const bool include_inlines = true; 194254721Semaste if (module) 195254721Semaste { 196254721Semaste module->FindFunctions (name, 197254721Semaste NULL, 198254721Semaste eFunctionNameTypeAuto, 199254721Semaste include_symbols, 200254721Semaste include_inlines, 201254721Semaste true, 202254721Semaste sc_list); 203254721Semaste } 204254721Semaste else if (exe_ctx.GetTargetPtr()) 205254721Semaste { 206254721Semaste exe_ctx.GetTargetPtr()->GetImages().FindFunctions (name, 207254721Semaste eFunctionNameTypeAuto, 208254721Semaste include_symbols, 209254721Semaste include_inlines, 210254721Semaste false, 211254721Semaste sc_list); 212254721Semaste } 213254721Semaste } 214254721Semaste 215254721Semaste if (sc_list.GetSize ()) 216254721Semaste { 217254721Semaste return Disassemble (debugger, 218254721Semaste arch, 219254721Semaste plugin_name, 220254721Semaste flavor, 221254721Semaste exe_ctx, 222254721Semaste sc_list, 223254721Semaste num_instructions, 224254721Semaste num_mixed_context_lines, 225254721Semaste options, 226254721Semaste strm); 227254721Semaste } 228254721Semaste return false; 229254721Semaste} 230254721Semaste 231254721Semaste 232254721Semastelldb::DisassemblerSP 233254721SemasteDisassembler::DisassembleRange 234254721Semaste( 235254721Semaste const ArchSpec &arch, 236254721Semaste const char *plugin_name, 237254721Semaste const char *flavor, 238254721Semaste const ExecutionContext &exe_ctx, 239263363Semaste const AddressRange &range, 240263363Semaste bool prefer_file_cache 241254721Semaste) 242254721Semaste{ 243254721Semaste lldb::DisassemblerSP disasm_sp; 244254721Semaste if (range.GetByteSize() > 0 && range.GetBaseAddress().IsValid()) 245254721Semaste { 246254721Semaste disasm_sp = Disassembler::FindPluginForTarget(exe_ctx.GetTargetSP(), arch, flavor, plugin_name); 247254721Semaste 248254721Semaste if (disasm_sp) 249254721Semaste { 250254721Semaste size_t bytes_disassembled = disasm_sp->ParseInstructions (&exe_ctx, range, NULL, prefer_file_cache); 251254721Semaste if (bytes_disassembled == 0) 252254721Semaste disasm_sp.reset(); 253254721Semaste } 254254721Semaste } 255254721Semaste return disasm_sp; 256254721Semaste} 257254721Semaste 258254721Semastelldb::DisassemblerSP 259254721SemasteDisassembler::DisassembleBytes (const ArchSpec &arch, 260254721Semaste const char *plugin_name, 261254721Semaste const char *flavor, 262254721Semaste const Address &start, 263254721Semaste const void *src, 264254721Semaste size_t src_len, 265254721Semaste uint32_t num_instructions, 266254721Semaste bool data_from_file) 267254721Semaste{ 268254721Semaste lldb::DisassemblerSP disasm_sp; 269254721Semaste 270254721Semaste if (src) 271254721Semaste { 272254721Semaste disasm_sp = Disassembler::FindPlugin(arch, flavor, plugin_name); 273254721Semaste 274254721Semaste if (disasm_sp) 275254721Semaste { 276254721Semaste DataExtractor data(src, src_len, arch.GetByteOrder(), arch.GetAddressByteSize()); 277254721Semaste 278254721Semaste (void)disasm_sp->DecodeInstructions (start, 279254721Semaste data, 280254721Semaste 0, 281254721Semaste num_instructions, 282254721Semaste false, 283254721Semaste data_from_file); 284254721Semaste } 285254721Semaste } 286254721Semaste 287254721Semaste return disasm_sp; 288254721Semaste} 289254721Semaste 290254721Semaste 291254721Semastebool 292254721SemasteDisassembler::Disassemble 293254721Semaste( 294254721Semaste Debugger &debugger, 295254721Semaste const ArchSpec &arch, 296254721Semaste const char *plugin_name, 297254721Semaste const char *flavor, 298254721Semaste const ExecutionContext &exe_ctx, 299254721Semaste const AddressRange &disasm_range, 300254721Semaste uint32_t num_instructions, 301254721Semaste uint32_t num_mixed_context_lines, 302254721Semaste uint32_t options, 303254721Semaste Stream &strm 304254721Semaste) 305254721Semaste{ 306254721Semaste if (disasm_range.GetByteSize()) 307254721Semaste { 308254721Semaste lldb::DisassemblerSP disasm_sp (Disassembler::FindPluginForTarget(exe_ctx.GetTargetSP(), arch, flavor, plugin_name)); 309254721Semaste 310254721Semaste if (disasm_sp.get()) 311254721Semaste { 312254721Semaste AddressRange range; 313254721Semaste ResolveAddress (exe_ctx, disasm_range.GetBaseAddress(), range.GetBaseAddress()); 314254721Semaste range.SetByteSize (disasm_range.GetByteSize()); 315254721Semaste const bool prefer_file_cache = false; 316254721Semaste size_t bytes_disassembled = disasm_sp->ParseInstructions (&exe_ctx, range, &strm, prefer_file_cache); 317254721Semaste if (bytes_disassembled == 0) 318254721Semaste return false; 319254721Semaste 320254721Semaste bool result = PrintInstructions (disasm_sp.get(), 321254721Semaste debugger, 322254721Semaste arch, 323254721Semaste exe_ctx, 324254721Semaste num_instructions, 325254721Semaste num_mixed_context_lines, 326254721Semaste options, 327254721Semaste strm); 328254721Semaste 329254721Semaste // FIXME: The DisassemblerLLVMC has a reference cycle and won't go away if it has any active instructions. 330254721Semaste // I'll fix that but for now, just clear the list and it will go away nicely. 331254721Semaste disasm_sp->GetInstructionList().Clear(); 332254721Semaste return result; 333254721Semaste } 334254721Semaste } 335254721Semaste return false; 336254721Semaste} 337254721Semaste 338254721Semastebool 339254721SemasteDisassembler::Disassemble 340254721Semaste( 341254721Semaste Debugger &debugger, 342254721Semaste const ArchSpec &arch, 343254721Semaste const char *plugin_name, 344254721Semaste const char *flavor, 345254721Semaste const ExecutionContext &exe_ctx, 346254721Semaste const Address &start_address, 347254721Semaste uint32_t num_instructions, 348254721Semaste uint32_t num_mixed_context_lines, 349254721Semaste uint32_t options, 350254721Semaste Stream &strm 351254721Semaste) 352254721Semaste{ 353254721Semaste if (num_instructions > 0) 354254721Semaste { 355254721Semaste lldb::DisassemblerSP disasm_sp (Disassembler::FindPluginForTarget(exe_ctx.GetTargetSP(), 356254721Semaste arch, 357254721Semaste flavor, 358254721Semaste plugin_name)); 359254721Semaste if (disasm_sp.get()) 360254721Semaste { 361254721Semaste Address addr; 362254721Semaste ResolveAddress (exe_ctx, start_address, addr); 363254721Semaste const bool prefer_file_cache = false; 364254721Semaste size_t bytes_disassembled = disasm_sp->ParseInstructions (&exe_ctx, 365254721Semaste addr, 366254721Semaste num_instructions, 367254721Semaste prefer_file_cache); 368254721Semaste if (bytes_disassembled == 0) 369254721Semaste return false; 370254721Semaste bool result = PrintInstructions (disasm_sp.get(), 371254721Semaste debugger, 372254721Semaste arch, 373254721Semaste exe_ctx, 374254721Semaste num_instructions, 375254721Semaste num_mixed_context_lines, 376254721Semaste options, 377254721Semaste strm); 378254721Semaste 379254721Semaste // FIXME: The DisassemblerLLVMC has a reference cycle and won't go away if it has any active instructions. 380254721Semaste // I'll fix that but for now, just clear the list and it will go away nicely. 381254721Semaste disasm_sp->GetInstructionList().Clear(); 382254721Semaste return result; 383254721Semaste } 384254721Semaste } 385254721Semaste return false; 386254721Semaste} 387254721Semaste 388254721Semastebool 389254721SemasteDisassembler::PrintInstructions 390254721Semaste( 391254721Semaste Disassembler *disasm_ptr, 392254721Semaste Debugger &debugger, 393254721Semaste const ArchSpec &arch, 394254721Semaste const ExecutionContext &exe_ctx, 395254721Semaste uint32_t num_instructions, 396254721Semaste uint32_t num_mixed_context_lines, 397254721Semaste uint32_t options, 398254721Semaste Stream &strm 399254721Semaste) 400254721Semaste{ 401254721Semaste // We got some things disassembled... 402254721Semaste size_t num_instructions_found = disasm_ptr->GetInstructionList().GetSize(); 403254721Semaste 404254721Semaste if (num_instructions > 0 && num_instructions < num_instructions_found) 405254721Semaste num_instructions_found = num_instructions; 406254721Semaste 407254721Semaste const uint32_t max_opcode_byte_size = disasm_ptr->GetInstructionList().GetMaxOpcocdeByteSize (); 408254721Semaste uint32_t offset = 0; 409254721Semaste SymbolContext sc; 410254721Semaste SymbolContext prev_sc; 411254721Semaste AddressRange sc_range; 412254721Semaste const Address *pc_addr_ptr = NULL; 413254721Semaste ExecutionContextScope *exe_scope = exe_ctx.GetBestExecutionContextScope(); 414254721Semaste StackFrame *frame = exe_ctx.GetFramePtr(); 415254721Semaste 416254721Semaste TargetSP target_sp (exe_ctx.GetTargetSP()); 417254721Semaste SourceManager &source_manager = target_sp ? target_sp->GetSourceManager() : debugger.GetSourceManager(); 418254721Semaste 419254721Semaste if (frame) 420254721Semaste pc_addr_ptr = &frame->GetFrameCodeAddress(); 421254721Semaste const uint32_t scope = eSymbolContextLineEntry | eSymbolContextFunction | eSymbolContextSymbol; 422254721Semaste const bool use_inline_block_range = false; 423254721Semaste for (size_t i=0; i<num_instructions_found; ++i) 424254721Semaste { 425254721Semaste Instruction *inst = disasm_ptr->GetInstructionList().GetInstructionAtIndex (i).get(); 426254721Semaste if (inst) 427254721Semaste { 428254721Semaste const Address &addr = inst->GetAddress(); 429254721Semaste const bool inst_is_at_pc = pc_addr_ptr && addr == *pc_addr_ptr; 430254721Semaste 431254721Semaste prev_sc = sc; 432254721Semaste 433254721Semaste ModuleSP module_sp (addr.GetModule()); 434254721Semaste if (module_sp) 435254721Semaste { 436254721Semaste uint32_t resolved_mask = module_sp->ResolveSymbolContextForAddress(addr, eSymbolContextEverything, sc); 437254721Semaste if (resolved_mask) 438254721Semaste { 439254721Semaste if (num_mixed_context_lines) 440254721Semaste { 441254721Semaste if (!sc_range.ContainsFileAddress (addr)) 442254721Semaste { 443254721Semaste sc.GetAddressRange (scope, 0, use_inline_block_range, sc_range); 444254721Semaste 445254721Semaste if (sc != prev_sc) 446254721Semaste { 447254721Semaste if (offset != 0) 448254721Semaste strm.EOL(); 449254721Semaste 450254721Semaste sc.DumpStopContext(&strm, exe_ctx.GetProcessPtr(), addr, false, true, false); 451254721Semaste strm.EOL(); 452254721Semaste 453254721Semaste if (sc.comp_unit && sc.line_entry.IsValid()) 454254721Semaste { 455254721Semaste source_manager.DisplaySourceLinesWithLineNumbers (sc.line_entry.file, 456254721Semaste sc.line_entry.line, 457254721Semaste num_mixed_context_lines, 458254721Semaste num_mixed_context_lines, 459254721Semaste ((inst_is_at_pc && (options & eOptionMarkPCSourceLine)) ? "->" : ""), 460254721Semaste &strm); 461254721Semaste } 462254721Semaste } 463254721Semaste } 464254721Semaste } 465254721Semaste else if ((sc.function || sc.symbol) && (sc.function != prev_sc.function || sc.symbol != prev_sc.symbol)) 466254721Semaste { 467254721Semaste if (prev_sc.function || prev_sc.symbol) 468254721Semaste strm.EOL(); 469254721Semaste 470254721Semaste bool show_fullpaths = false; 471254721Semaste bool show_module = true; 472254721Semaste bool show_inlined_frames = true; 473254721Semaste sc.DumpStopContext (&strm, 474254721Semaste exe_scope, 475254721Semaste addr, 476254721Semaste show_fullpaths, 477254721Semaste show_module, 478254721Semaste show_inlined_frames); 479254721Semaste 480254721Semaste strm << ":\n"; 481254721Semaste } 482254721Semaste } 483254721Semaste else 484254721Semaste { 485254721Semaste sc.Clear(true); 486254721Semaste } 487254721Semaste } 488254721Semaste 489254721Semaste if ((options & eOptionMarkPCAddress) && pc_addr_ptr) 490254721Semaste { 491254721Semaste strm.PutCString(inst_is_at_pc ? "-> " : " "); 492254721Semaste } 493254721Semaste const bool show_bytes = (options & eOptionShowBytes) != 0; 494254721Semaste inst->Dump(&strm, max_opcode_byte_size, true, show_bytes, &exe_ctx); 495254721Semaste strm.EOL(); 496254721Semaste } 497254721Semaste else 498254721Semaste { 499254721Semaste break; 500254721Semaste } 501254721Semaste } 502254721Semaste 503254721Semaste return true; 504254721Semaste} 505254721Semaste 506254721Semaste 507254721Semastebool 508254721SemasteDisassembler::Disassemble 509254721Semaste( 510254721Semaste Debugger &debugger, 511254721Semaste const ArchSpec &arch, 512254721Semaste const char *plugin_name, 513254721Semaste const char *flavor, 514254721Semaste const ExecutionContext &exe_ctx, 515254721Semaste uint32_t num_instructions, 516254721Semaste uint32_t num_mixed_context_lines, 517254721Semaste uint32_t options, 518254721Semaste Stream &strm 519254721Semaste) 520254721Semaste{ 521254721Semaste AddressRange range; 522254721Semaste StackFrame *frame = exe_ctx.GetFramePtr(); 523254721Semaste if (frame) 524254721Semaste { 525254721Semaste SymbolContext sc(frame->GetSymbolContext(eSymbolContextFunction | eSymbolContextSymbol)); 526254721Semaste if (sc.function) 527254721Semaste { 528254721Semaste range = sc.function->GetAddressRange(); 529254721Semaste } 530254721Semaste else if (sc.symbol && sc.symbol->ValueIsAddress()) 531254721Semaste { 532254721Semaste range.GetBaseAddress() = sc.symbol->GetAddress(); 533254721Semaste range.SetByteSize (sc.symbol->GetByteSize()); 534254721Semaste } 535254721Semaste else 536254721Semaste { 537254721Semaste range.GetBaseAddress() = frame->GetFrameCodeAddress(); 538254721Semaste } 539254721Semaste 540254721Semaste if (range.GetBaseAddress().IsValid() && range.GetByteSize() == 0) 541254721Semaste range.SetByteSize (DEFAULT_DISASM_BYTE_SIZE); 542254721Semaste } 543254721Semaste 544254721Semaste return Disassemble (debugger, 545254721Semaste arch, 546254721Semaste plugin_name, 547254721Semaste flavor, 548254721Semaste exe_ctx, 549254721Semaste range, 550254721Semaste num_instructions, 551254721Semaste num_mixed_context_lines, 552254721Semaste options, 553254721Semaste strm); 554254721Semaste} 555254721Semaste 556254721SemasteInstruction::Instruction(const Address &address, AddressClass addr_class) : 557254721Semaste m_address (address), 558254721Semaste m_address_class (addr_class), 559254721Semaste m_opcode(), 560254721Semaste m_calculated_strings(false) 561254721Semaste{ 562254721Semaste} 563254721Semaste 564254721SemasteInstruction::~Instruction() 565254721Semaste{ 566254721Semaste} 567254721Semaste 568254721SemasteAddressClass 569254721SemasteInstruction::GetAddressClass () 570254721Semaste{ 571254721Semaste if (m_address_class == eAddressClassInvalid) 572254721Semaste m_address_class = m_address.GetAddressClass(); 573254721Semaste return m_address_class; 574254721Semaste} 575254721Semaste 576254721Semastevoid 577254721SemasteInstruction::Dump (lldb_private::Stream *s, 578254721Semaste uint32_t max_opcode_byte_size, 579254721Semaste bool show_address, 580254721Semaste bool show_bytes, 581254721Semaste const ExecutionContext* exe_ctx) 582254721Semaste{ 583254721Semaste size_t opcode_column_width = 7; 584254721Semaste const size_t operand_column_width = 25; 585254721Semaste 586254721Semaste CalculateMnemonicOperandsAndCommentIfNeeded (exe_ctx); 587254721Semaste 588254721Semaste StreamString ss; 589254721Semaste 590254721Semaste if (show_address) 591254721Semaste { 592254721Semaste m_address.Dump(&ss, 593254721Semaste exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL, 594254721Semaste Address::DumpStyleLoadAddress, 595254721Semaste Address::DumpStyleModuleWithFileAddress, 596254721Semaste 0); 597254721Semaste 598254721Semaste ss.PutCString(": "); 599254721Semaste } 600254721Semaste 601254721Semaste if (show_bytes) 602254721Semaste { 603254721Semaste if (m_opcode.GetType() == Opcode::eTypeBytes) 604254721Semaste { 605254721Semaste // x86_64 and i386 are the only ones that use bytes right now so 606254721Semaste // pad out the byte dump to be able to always show 15 bytes (3 chars each) 607254721Semaste // plus a space 608254721Semaste if (max_opcode_byte_size > 0) 609254721Semaste m_opcode.Dump (&ss, max_opcode_byte_size * 3 + 1); 610254721Semaste else 611254721Semaste m_opcode.Dump (&ss, 15 * 3 + 1); 612254721Semaste } 613254721Semaste else 614254721Semaste { 615263363Semaste // Else, we have ARM or MIPS which can show up to a uint32_t 616263363Semaste // 0x00000000 (10 spaces) plus two for padding... 617254721Semaste if (max_opcode_byte_size > 0) 618254721Semaste m_opcode.Dump (&ss, max_opcode_byte_size * 3 + 1); 619254721Semaste else 620254721Semaste m_opcode.Dump (&ss, 12); 621254721Semaste } 622254721Semaste } 623254721Semaste 624254721Semaste const size_t opcode_pos = ss.GetSize(); 625254721Semaste 626254721Semaste // The default opcode size of 7 characters is plenty for most architectures 627254721Semaste // but some like arm can pull out the occasional vqrshrun.s16. We won't get 628254721Semaste // consistent column spacing in these cases, unfortunately. 629254721Semaste if (m_opcode_name.length() >= opcode_column_width) 630254721Semaste { 631254721Semaste opcode_column_width = m_opcode_name.length() + 1; 632254721Semaste } 633254721Semaste 634254721Semaste ss.PutCString (m_opcode_name.c_str()); 635254721Semaste ss.FillLastLineToColumn (opcode_pos + opcode_column_width, ' '); 636254721Semaste ss.PutCString (m_mnemonics.c_str()); 637254721Semaste 638254721Semaste if (!m_comment.empty()) 639254721Semaste { 640254721Semaste ss.FillLastLineToColumn (opcode_pos + opcode_column_width + operand_column_width, ' '); 641254721Semaste ss.PutCString (" ; "); 642254721Semaste ss.PutCString (m_comment.c_str()); 643254721Semaste } 644254721Semaste s->Write (ss.GetData(), ss.GetSize()); 645254721Semaste} 646254721Semaste 647254721Semastebool 648254721SemasteInstruction::DumpEmulation (const ArchSpec &arch) 649254721Semaste{ 650254721Semaste std::unique_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL)); 651254721Semaste if (insn_emulator_ap.get()) 652254721Semaste { 653254721Semaste insn_emulator_ap->SetInstruction (GetOpcode(), GetAddress(), NULL); 654254721Semaste return insn_emulator_ap->EvaluateInstruction (0); 655254721Semaste } 656254721Semaste 657254721Semaste return false; 658254721Semaste} 659254721Semaste 660254721SemasteOptionValueSP 661254721SemasteInstruction::ReadArray (FILE *in_file, Stream *out_stream, OptionValue::Type data_type) 662254721Semaste{ 663254721Semaste bool done = false; 664254721Semaste char buffer[1024]; 665254721Semaste 666254721Semaste OptionValueSP option_value_sp (new OptionValueArray (1u << data_type)); 667254721Semaste 668254721Semaste int idx = 0; 669254721Semaste while (!done) 670254721Semaste { 671254721Semaste if (!fgets (buffer, 1023, in_file)) 672254721Semaste { 673254721Semaste out_stream->Printf ("Instruction::ReadArray: Error reading file (fgets).\n"); 674254721Semaste option_value_sp.reset (); 675254721Semaste return option_value_sp; 676254721Semaste } 677254721Semaste 678254721Semaste std::string line (buffer); 679254721Semaste 680254721Semaste size_t len = line.size(); 681254721Semaste if (line[len-1] == '\n') 682254721Semaste { 683254721Semaste line[len-1] = '\0'; 684254721Semaste line.resize (len-1); 685254721Semaste } 686254721Semaste 687254721Semaste if ((line.size() == 1) && line[0] == ']') 688254721Semaste { 689254721Semaste done = true; 690254721Semaste line.clear(); 691254721Semaste } 692254721Semaste 693254721Semaste if (line.size() > 0) 694254721Semaste { 695254721Semaste std::string value; 696254721Semaste static RegularExpression g_reg_exp ("^[ \t]*([^ \t]+)[ \t]*$"); 697254721Semaste RegularExpression::Match regex_match(1); 698254721Semaste bool reg_exp_success = g_reg_exp.Execute (line.c_str(), ®ex_match); 699254721Semaste if (reg_exp_success) 700254721Semaste regex_match.GetMatchAtIndex (line.c_str(), 1, value); 701254721Semaste else 702254721Semaste value = line; 703254721Semaste 704254721Semaste OptionValueSP data_value_sp; 705254721Semaste switch (data_type) 706254721Semaste { 707254721Semaste case OptionValue::eTypeUInt64: 708254721Semaste data_value_sp.reset (new OptionValueUInt64 (0, 0)); 709254721Semaste data_value_sp->SetValueFromCString (value.c_str()); 710254721Semaste break; 711254721Semaste // Other types can be added later as needed. 712254721Semaste default: 713254721Semaste data_value_sp.reset (new OptionValueString (value.c_str(), "")); 714254721Semaste break; 715254721Semaste } 716254721Semaste 717254721Semaste option_value_sp->GetAsArray()->InsertValue (idx, data_value_sp); 718254721Semaste ++idx; 719254721Semaste } 720254721Semaste } 721254721Semaste 722254721Semaste return option_value_sp; 723254721Semaste} 724254721Semaste 725254721SemasteOptionValueSP 726254721SemasteInstruction::ReadDictionary (FILE *in_file, Stream *out_stream) 727254721Semaste{ 728254721Semaste bool done = false; 729254721Semaste char buffer[1024]; 730254721Semaste 731254721Semaste OptionValueSP option_value_sp (new OptionValueDictionary()); 732254721Semaste static ConstString encoding_key ("data_encoding"); 733254721Semaste OptionValue::Type data_type = OptionValue::eTypeInvalid; 734254721Semaste 735254721Semaste 736254721Semaste while (!done) 737254721Semaste { 738254721Semaste // Read the next line in the file 739254721Semaste if (!fgets (buffer, 1023, in_file)) 740254721Semaste { 741254721Semaste out_stream->Printf ("Instruction::ReadDictionary: Error reading file (fgets).\n"); 742254721Semaste option_value_sp.reset (); 743254721Semaste return option_value_sp; 744254721Semaste } 745254721Semaste 746254721Semaste // Check to see if the line contains the end-of-dictionary marker ("}") 747254721Semaste std::string line (buffer); 748254721Semaste 749254721Semaste size_t len = line.size(); 750254721Semaste if (line[len-1] == '\n') 751254721Semaste { 752254721Semaste line[len-1] = '\0'; 753254721Semaste line.resize (len-1); 754254721Semaste } 755254721Semaste 756254721Semaste if ((line.size() == 1) && (line[0] == '}')) 757254721Semaste { 758254721Semaste done = true; 759254721Semaste line.clear(); 760254721Semaste } 761254721Semaste 762254721Semaste // Try to find a key-value pair in the current line and add it to the dictionary. 763254721Semaste if (line.size() > 0) 764254721Semaste { 765254721Semaste static RegularExpression g_reg_exp ("^[ \t]*([a-zA-Z_][a-zA-Z0-9_]*)[ \t]*=[ \t]*(.*)[ \t]*$"); 766254721Semaste RegularExpression::Match regex_match(2); 767254721Semaste 768254721Semaste bool reg_exp_success = g_reg_exp.Execute (line.c_str(), ®ex_match); 769254721Semaste std::string key; 770254721Semaste std::string value; 771254721Semaste if (reg_exp_success) 772254721Semaste { 773254721Semaste regex_match.GetMatchAtIndex (line.c_str(), 1, key); 774254721Semaste regex_match.GetMatchAtIndex (line.c_str(), 2, value); 775254721Semaste } 776254721Semaste else 777254721Semaste { 778254721Semaste out_stream->Printf ("Instruction::ReadDictionary: Failure executing regular expression.\n"); 779254721Semaste option_value_sp.reset(); 780254721Semaste return option_value_sp; 781254721Semaste } 782254721Semaste 783254721Semaste ConstString const_key (key.c_str()); 784254721Semaste // Check value to see if it's the start of an array or dictionary. 785254721Semaste 786254721Semaste lldb::OptionValueSP value_sp; 787254721Semaste assert (value.empty() == false); 788254721Semaste assert (key.empty() == false); 789254721Semaste 790254721Semaste if (value[0] == '{') 791254721Semaste { 792254721Semaste assert (value.size() == 1); 793254721Semaste // value is a dictionary 794254721Semaste value_sp = ReadDictionary (in_file, out_stream); 795254721Semaste if (value_sp.get() == NULL) 796254721Semaste { 797254721Semaste option_value_sp.reset (); 798254721Semaste return option_value_sp; 799254721Semaste } 800254721Semaste } 801254721Semaste else if (value[0] == '[') 802254721Semaste { 803254721Semaste assert (value.size() == 1); 804254721Semaste // value is an array 805254721Semaste value_sp = ReadArray (in_file, out_stream, data_type); 806254721Semaste if (value_sp.get() == NULL) 807254721Semaste { 808254721Semaste option_value_sp.reset (); 809254721Semaste return option_value_sp; 810254721Semaste } 811254721Semaste // We've used the data_type to read an array; re-set the type to Invalid 812254721Semaste data_type = OptionValue::eTypeInvalid; 813254721Semaste } 814254721Semaste else if ((value[0] == '0') && (value[1] == 'x')) 815254721Semaste { 816254721Semaste value_sp.reset (new OptionValueUInt64 (0, 0)); 817254721Semaste value_sp->SetValueFromCString (value.c_str()); 818254721Semaste } 819254721Semaste else 820254721Semaste { 821254721Semaste size_t len = value.size(); 822254721Semaste if ((value[0] == '"') && (value[len-1] == '"')) 823254721Semaste value = value.substr (1, len-2); 824254721Semaste value_sp.reset (new OptionValueString (value.c_str(), "")); 825254721Semaste } 826254721Semaste 827254721Semaste 828254721Semaste 829254721Semaste if (const_key == encoding_key) 830254721Semaste { 831254721Semaste // A 'data_encoding=..." is NOT a normal key-value pair; it is meta-data indicating the 832254721Semaste // data type of an upcoming array (usually the next bit of data to be read in). 833254721Semaste if (strcmp (value.c_str(), "uint32_t") == 0) 834254721Semaste data_type = OptionValue::eTypeUInt64; 835254721Semaste } 836254721Semaste else 837254721Semaste option_value_sp->GetAsDictionary()->SetValueForKey (const_key, value_sp, false); 838254721Semaste } 839254721Semaste } 840254721Semaste 841254721Semaste return option_value_sp; 842254721Semaste} 843254721Semaste 844254721Semastebool 845254721SemasteInstruction::TestEmulation (Stream *out_stream, const char *file_name) 846254721Semaste{ 847254721Semaste if (!out_stream) 848254721Semaste return false; 849254721Semaste 850254721Semaste if (!file_name) 851254721Semaste { 852254721Semaste out_stream->Printf ("Instruction::TestEmulation: Missing file_name."); 853254721Semaste return false; 854254721Semaste } 855254721Semaste 856254721Semaste FILE *test_file = fopen (file_name, "r"); 857254721Semaste if (!test_file) 858254721Semaste { 859254721Semaste out_stream->Printf ("Instruction::TestEmulation: Attempt to open test file failed."); 860254721Semaste return false; 861254721Semaste } 862254721Semaste 863254721Semaste char buffer[256]; 864254721Semaste if (!fgets (buffer, 255, test_file)) 865254721Semaste { 866254721Semaste out_stream->Printf ("Instruction::TestEmulation: Error reading first line of test file.\n"); 867254721Semaste fclose (test_file); 868254721Semaste return false; 869254721Semaste } 870254721Semaste 871254721Semaste if (strncmp (buffer, "InstructionEmulationState={", 27) != 0) 872254721Semaste { 873254721Semaste out_stream->Printf ("Instructin::TestEmulation: Test file does not contain emulation state dictionary\n"); 874254721Semaste fclose (test_file); 875254721Semaste return false; 876254721Semaste } 877254721Semaste 878254721Semaste // Read all the test information from the test file into an OptionValueDictionary. 879254721Semaste 880254721Semaste OptionValueSP data_dictionary_sp (ReadDictionary (test_file, out_stream)); 881254721Semaste if (data_dictionary_sp.get() == NULL) 882254721Semaste { 883254721Semaste out_stream->Printf ("Instruction::TestEmulation: Error reading Dictionary Object.\n"); 884254721Semaste fclose (test_file); 885254721Semaste return false; 886254721Semaste } 887254721Semaste 888254721Semaste fclose (test_file); 889254721Semaste 890254721Semaste OptionValueDictionary *data_dictionary = data_dictionary_sp->GetAsDictionary(); 891254721Semaste static ConstString description_key ("assembly_string"); 892254721Semaste static ConstString triple_key ("triple"); 893254721Semaste 894254721Semaste OptionValueSP value_sp = data_dictionary->GetValueForKey (description_key); 895254721Semaste 896254721Semaste if (value_sp.get() == NULL) 897254721Semaste { 898254721Semaste out_stream->Printf ("Instruction::TestEmulation: Test file does not contain description string.\n"); 899254721Semaste return false; 900254721Semaste } 901254721Semaste 902254721Semaste SetDescription (value_sp->GetStringValue()); 903254721Semaste 904254721Semaste 905254721Semaste value_sp = data_dictionary->GetValueForKey (triple_key); 906254721Semaste if (value_sp.get() == NULL) 907254721Semaste { 908254721Semaste out_stream->Printf ("Instruction::TestEmulation: Test file does not contain triple.\n"); 909254721Semaste return false; 910254721Semaste } 911254721Semaste 912254721Semaste ArchSpec arch; 913254721Semaste arch.SetTriple (llvm::Triple (value_sp->GetStringValue())); 914254721Semaste 915254721Semaste bool success = false; 916254721Semaste std::unique_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL)); 917254721Semaste if (insn_emulator_ap.get()) 918254721Semaste success = insn_emulator_ap->TestEmulation (out_stream, arch, data_dictionary); 919254721Semaste 920254721Semaste if (success) 921254721Semaste out_stream->Printf ("Emulation test succeeded."); 922254721Semaste else 923254721Semaste out_stream->Printf ("Emulation test failed."); 924254721Semaste 925254721Semaste return success; 926254721Semaste} 927254721Semaste 928254721Semastebool 929254721SemasteInstruction::Emulate (const ArchSpec &arch, 930254721Semaste uint32_t evaluate_options, 931254721Semaste void *baton, 932254721Semaste EmulateInstruction::ReadMemoryCallback read_mem_callback, 933254721Semaste EmulateInstruction::WriteMemoryCallback write_mem_callback, 934254721Semaste EmulateInstruction::ReadRegisterCallback read_reg_callback, 935254721Semaste EmulateInstruction::WriteRegisterCallback write_reg_callback) 936254721Semaste{ 937254721Semaste std::unique_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL)); 938254721Semaste if (insn_emulator_ap.get()) 939254721Semaste { 940254721Semaste insn_emulator_ap->SetBaton (baton); 941254721Semaste insn_emulator_ap->SetCallbacks (read_mem_callback, write_mem_callback, read_reg_callback, write_reg_callback); 942254721Semaste insn_emulator_ap->SetInstruction (GetOpcode(), GetAddress(), NULL); 943254721Semaste return insn_emulator_ap->EvaluateInstruction (evaluate_options); 944254721Semaste } 945254721Semaste 946254721Semaste return false; 947254721Semaste} 948254721Semaste 949254721Semaste 950254721Semasteuint32_t 951254721SemasteInstruction::GetData (DataExtractor &data) 952254721Semaste{ 953254721Semaste return m_opcode.GetData(data); 954254721Semaste} 955254721Semaste 956254721SemasteInstructionList::InstructionList() : 957254721Semaste m_instructions() 958254721Semaste{ 959254721Semaste} 960254721Semaste 961254721SemasteInstructionList::~InstructionList() 962254721Semaste{ 963254721Semaste} 964254721Semaste 965254721Semastesize_t 966254721SemasteInstructionList::GetSize() const 967254721Semaste{ 968254721Semaste return m_instructions.size(); 969254721Semaste} 970254721Semaste 971254721Semasteuint32_t 972254721SemasteInstructionList::GetMaxOpcocdeByteSize () const 973254721Semaste{ 974254721Semaste uint32_t max_inst_size = 0; 975254721Semaste collection::const_iterator pos, end; 976254721Semaste for (pos = m_instructions.begin(), end = m_instructions.end(); 977254721Semaste pos != end; 978254721Semaste ++pos) 979254721Semaste { 980254721Semaste uint32_t inst_size = (*pos)->GetOpcode().GetByteSize(); 981254721Semaste if (max_inst_size < inst_size) 982254721Semaste max_inst_size = inst_size; 983254721Semaste } 984254721Semaste return max_inst_size; 985254721Semaste} 986254721Semaste 987254721Semaste 988254721Semaste 989254721SemasteInstructionSP 990254721SemasteInstructionList::GetInstructionAtIndex (size_t idx) const 991254721Semaste{ 992254721Semaste InstructionSP inst_sp; 993254721Semaste if (idx < m_instructions.size()) 994254721Semaste inst_sp = m_instructions[idx]; 995254721Semaste return inst_sp; 996254721Semaste} 997254721Semaste 998254721Semastevoid 999254721SemasteInstructionList::Dump (Stream *s, 1000254721Semaste bool show_address, 1001254721Semaste bool show_bytes, 1002254721Semaste const ExecutionContext* exe_ctx) 1003254721Semaste{ 1004254721Semaste const uint32_t max_opcode_byte_size = GetMaxOpcocdeByteSize(); 1005254721Semaste collection::const_iterator pos, begin, end; 1006254721Semaste for (begin = m_instructions.begin(), end = m_instructions.end(), pos = begin; 1007254721Semaste pos != end; 1008254721Semaste ++pos) 1009254721Semaste { 1010254721Semaste if (pos != begin) 1011254721Semaste s->EOL(); 1012254721Semaste (*pos)->Dump(s, max_opcode_byte_size, show_address, show_bytes, exe_ctx); 1013254721Semaste } 1014254721Semaste} 1015254721Semaste 1016254721Semaste 1017254721Semastevoid 1018254721SemasteInstructionList::Clear() 1019254721Semaste{ 1020254721Semaste m_instructions.clear(); 1021254721Semaste} 1022254721Semaste 1023254721Semastevoid 1024254721SemasteInstructionList::Append (lldb::InstructionSP &inst_sp) 1025254721Semaste{ 1026254721Semaste if (inst_sp) 1027254721Semaste m_instructions.push_back(inst_sp); 1028254721Semaste} 1029254721Semaste 1030254721Semasteuint32_t 1031254721SemasteInstructionList::GetIndexOfNextBranchInstruction(uint32_t start) const 1032254721Semaste{ 1033254721Semaste size_t num_instructions = m_instructions.size(); 1034254721Semaste 1035254721Semaste uint32_t next_branch = UINT32_MAX; 1036254721Semaste for (size_t i = start; i < num_instructions; i++) 1037254721Semaste { 1038254721Semaste if (m_instructions[i]->DoesBranch()) 1039254721Semaste { 1040254721Semaste next_branch = i; 1041254721Semaste break; 1042254721Semaste } 1043254721Semaste } 1044254721Semaste return next_branch; 1045254721Semaste} 1046254721Semaste 1047254721Semasteuint32_t 1048269024SemasteInstructionList::GetIndexOfInstructionAtAddress (const Address &address) 1049254721Semaste{ 1050254721Semaste size_t num_instructions = m_instructions.size(); 1051254721Semaste uint32_t index = UINT32_MAX; 1052254721Semaste for (size_t i = 0; i < num_instructions; i++) 1053254721Semaste { 1054254721Semaste if (m_instructions[i]->GetAddress() == address) 1055254721Semaste { 1056254721Semaste index = i; 1057254721Semaste break; 1058254721Semaste } 1059254721Semaste } 1060254721Semaste return index; 1061254721Semaste} 1062254721Semaste 1063269024Semaste 1064269024Semasteuint32_t 1065269024SemasteInstructionList::GetIndexOfInstructionAtLoadAddress (lldb::addr_t load_addr, Target &target) 1066269024Semaste{ 1067269024Semaste Address address; 1068269024Semaste address.SetLoadAddress(load_addr, &target); 1069269024Semaste return GetIndexOfInstructionAtAddress(address); 1070269024Semaste} 1071269024Semaste 1072254721Semastesize_t 1073254721SemasteDisassembler::ParseInstructions (const ExecutionContext *exe_ctx, 1074254721Semaste const AddressRange &range, 1075254721Semaste Stream *error_strm_ptr, 1076254721Semaste bool prefer_file_cache) 1077254721Semaste{ 1078254721Semaste if (exe_ctx) 1079254721Semaste { 1080254721Semaste Target *target = exe_ctx->GetTargetPtr(); 1081254721Semaste const addr_t byte_size = range.GetByteSize(); 1082254721Semaste if (target == NULL || byte_size == 0 || !range.GetBaseAddress().IsValid()) 1083254721Semaste return 0; 1084254721Semaste 1085254721Semaste DataBufferHeap *heap_buffer = new DataBufferHeap (byte_size, '\0'); 1086254721Semaste DataBufferSP data_sp(heap_buffer); 1087254721Semaste 1088254721Semaste Error error; 1089254721Semaste lldb::addr_t load_addr = LLDB_INVALID_ADDRESS; 1090254721Semaste const size_t bytes_read = target->ReadMemory (range.GetBaseAddress(), 1091254721Semaste prefer_file_cache, 1092254721Semaste heap_buffer->GetBytes(), 1093254721Semaste heap_buffer->GetByteSize(), 1094254721Semaste error, 1095254721Semaste &load_addr); 1096254721Semaste 1097254721Semaste if (bytes_read > 0) 1098254721Semaste { 1099254721Semaste if (bytes_read != heap_buffer->GetByteSize()) 1100254721Semaste heap_buffer->SetByteSize (bytes_read); 1101254721Semaste DataExtractor data (data_sp, 1102254721Semaste m_arch.GetByteOrder(), 1103254721Semaste m_arch.GetAddressByteSize()); 1104254721Semaste const bool data_from_file = load_addr == LLDB_INVALID_ADDRESS; 1105254721Semaste return DecodeInstructions (range.GetBaseAddress(), data, 0, UINT32_MAX, false, data_from_file); 1106254721Semaste } 1107254721Semaste else if (error_strm_ptr) 1108254721Semaste { 1109254721Semaste const char *error_cstr = error.AsCString(); 1110254721Semaste if (error_cstr) 1111254721Semaste { 1112254721Semaste error_strm_ptr->Printf("error: %s\n", error_cstr); 1113254721Semaste } 1114254721Semaste } 1115254721Semaste } 1116254721Semaste else if (error_strm_ptr) 1117254721Semaste { 1118254721Semaste error_strm_ptr->PutCString("error: invalid execution context\n"); 1119254721Semaste } 1120254721Semaste return 0; 1121254721Semaste} 1122254721Semaste 1123254721Semastesize_t 1124254721SemasteDisassembler::ParseInstructions (const ExecutionContext *exe_ctx, 1125254721Semaste const Address &start, 1126254721Semaste uint32_t num_instructions, 1127254721Semaste bool prefer_file_cache) 1128254721Semaste{ 1129254721Semaste m_instruction_list.Clear(); 1130254721Semaste 1131254721Semaste if (exe_ctx == NULL || num_instructions == 0 || !start.IsValid()) 1132254721Semaste return 0; 1133254721Semaste 1134254721Semaste Target *target = exe_ctx->GetTargetPtr(); 1135254721Semaste // Calculate the max buffer size we will need in order to disassemble 1136254721Semaste const addr_t byte_size = num_instructions * m_arch.GetMaximumOpcodeByteSize(); 1137254721Semaste 1138254721Semaste if (target == NULL || byte_size == 0) 1139254721Semaste return 0; 1140254721Semaste 1141254721Semaste DataBufferHeap *heap_buffer = new DataBufferHeap (byte_size, '\0'); 1142254721Semaste DataBufferSP data_sp (heap_buffer); 1143254721Semaste 1144254721Semaste Error error; 1145254721Semaste lldb::addr_t load_addr = LLDB_INVALID_ADDRESS; 1146254721Semaste const size_t bytes_read = target->ReadMemory (start, 1147254721Semaste prefer_file_cache, 1148254721Semaste heap_buffer->GetBytes(), 1149254721Semaste byte_size, 1150254721Semaste error, 1151254721Semaste &load_addr); 1152254721Semaste 1153254721Semaste const bool data_from_file = load_addr == LLDB_INVALID_ADDRESS; 1154254721Semaste 1155254721Semaste if (bytes_read == 0) 1156254721Semaste return 0; 1157254721Semaste DataExtractor data (data_sp, 1158254721Semaste m_arch.GetByteOrder(), 1159254721Semaste m_arch.GetAddressByteSize()); 1160254721Semaste 1161254721Semaste const bool append_instructions = true; 1162254721Semaste DecodeInstructions (start, 1163254721Semaste data, 1164254721Semaste 0, 1165254721Semaste num_instructions, 1166254721Semaste append_instructions, 1167254721Semaste data_from_file); 1168254721Semaste 1169254721Semaste return m_instruction_list.GetSize(); 1170254721Semaste} 1171254721Semaste 1172254721Semaste//---------------------------------------------------------------------- 1173254721Semaste// Disassembler copy constructor 1174254721Semaste//---------------------------------------------------------------------- 1175254721SemasteDisassembler::Disassembler(const ArchSpec& arch, const char *flavor) : 1176254721Semaste m_arch (arch), 1177254721Semaste m_instruction_list(), 1178254721Semaste m_base_addr(LLDB_INVALID_ADDRESS), 1179254721Semaste m_flavor () 1180254721Semaste{ 1181254721Semaste if (flavor == NULL) 1182254721Semaste m_flavor.assign("default"); 1183254721Semaste else 1184254721Semaste m_flavor.assign(flavor); 1185254721Semaste} 1186254721Semaste 1187254721Semaste//---------------------------------------------------------------------- 1188254721Semaste// Destructor 1189254721Semaste//---------------------------------------------------------------------- 1190254721SemasteDisassembler::~Disassembler() 1191254721Semaste{ 1192254721Semaste} 1193254721Semaste 1194254721SemasteInstructionList & 1195254721SemasteDisassembler::GetInstructionList () 1196254721Semaste{ 1197254721Semaste return m_instruction_list; 1198254721Semaste} 1199254721Semaste 1200254721Semasteconst InstructionList & 1201254721SemasteDisassembler::GetInstructionList () const 1202254721Semaste{ 1203254721Semaste return m_instruction_list; 1204254721Semaste} 1205254721Semaste 1206254721Semaste//---------------------------------------------------------------------- 1207254721Semaste// Class PseudoInstruction 1208254721Semaste//---------------------------------------------------------------------- 1209254721SemastePseudoInstruction::PseudoInstruction () : 1210254721Semaste Instruction (Address(), eAddressClassUnknown), 1211254721Semaste m_description () 1212254721Semaste{ 1213254721Semaste} 1214254721Semaste 1215254721SemastePseudoInstruction::~PseudoInstruction () 1216254721Semaste{ 1217254721Semaste} 1218254721Semaste 1219254721Semastebool 1220254721SemastePseudoInstruction::DoesBranch () 1221254721Semaste{ 1222254721Semaste // This is NOT a valid question for a pseudo instruction. 1223254721Semaste return false; 1224254721Semaste} 1225254721Semaste 1226254721Semastesize_t 1227254721SemastePseudoInstruction::Decode (const lldb_private::Disassembler &disassembler, 1228254721Semaste const lldb_private::DataExtractor &data, 1229254721Semaste lldb::offset_t data_offset) 1230254721Semaste{ 1231254721Semaste return m_opcode.GetByteSize(); 1232254721Semaste} 1233254721Semaste 1234254721Semaste 1235254721Semastevoid 1236254721SemastePseudoInstruction::SetOpcode (size_t opcode_size, void *opcode_data) 1237254721Semaste{ 1238254721Semaste if (!opcode_data) 1239254721Semaste return; 1240254721Semaste 1241254721Semaste switch (opcode_size) 1242254721Semaste { 1243254721Semaste case 8: 1244254721Semaste { 1245254721Semaste uint8_t value8 = *((uint8_t *) opcode_data); 1246269024Semaste m_opcode.SetOpcode8 (value8, eByteOrderInvalid); 1247254721Semaste break; 1248254721Semaste } 1249254721Semaste case 16: 1250254721Semaste { 1251254721Semaste uint16_t value16 = *((uint16_t *) opcode_data); 1252269024Semaste m_opcode.SetOpcode16 (value16, eByteOrderInvalid); 1253254721Semaste break; 1254254721Semaste } 1255254721Semaste case 32: 1256254721Semaste { 1257254721Semaste uint32_t value32 = *((uint32_t *) opcode_data); 1258269024Semaste m_opcode.SetOpcode32 (value32, eByteOrderInvalid); 1259254721Semaste break; 1260254721Semaste } 1261254721Semaste case 64: 1262254721Semaste { 1263254721Semaste uint64_t value64 = *((uint64_t *) opcode_data); 1264269024Semaste m_opcode.SetOpcode64 (value64, eByteOrderInvalid); 1265254721Semaste break; 1266254721Semaste } 1267254721Semaste default: 1268254721Semaste break; 1269254721Semaste } 1270254721Semaste} 1271254721Semaste 1272254721Semastevoid 1273254721SemastePseudoInstruction::SetDescription (const char *description) 1274254721Semaste{ 1275254721Semaste if (description && strlen (description) > 0) 1276254721Semaste m_description = description; 1277254721Semaste} 1278