1 //===-- Disassembler.cpp ----------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "lldb/lldb-python.h"
12 #include "lldb/Core/Disassembler.h"
16 // Other libraries and framework includes
18 #include "lldb/lldb-private.h"
19 #include "lldb/Core/Error.h"
20 #include "lldb/Core/DataBufferHeap.h"
21 #include "lldb/Core/DataExtractor.h"
22 #include "lldb/Core/Debugger.h"
23 #include "lldb/Core/EmulateInstruction.h"
24 #include "lldb/Core/Module.h"
25 #include "lldb/Core/PluginManager.h"
26 #include "lldb/Core/RegularExpression.h"
27 #include "lldb/Core/Timer.h"
28 #include "lldb/Interpreter/OptionValue.h"
29 #include "lldb/Interpreter/OptionValueArray.h"
30 #include "lldb/Interpreter/OptionValueDictionary.h"
31 #include "lldb/Interpreter/OptionValueString.h"
32 #include "lldb/Interpreter/OptionValueUInt64.h"
33 #include "lldb/Symbol/ClangNamespaceDecl.h"
34 #include "lldb/Symbol/Function.h"
35 #include "lldb/Symbol/ObjectFile.h"
36 #include "lldb/Target/ExecutionContext.h"
37 #include "lldb/Target/Process.h"
38 #include "lldb/Target/SectionLoadList.h"
39 #include "lldb/Target/StackFrame.h"
40 #include "lldb/Target/Target.h"
42 #define DEFAULT_DISASM_BYTE_SIZE 32
45 using namespace lldb_private;
49 Disassembler::FindPlugin (const ArchSpec &arch, const char *flavor, const char *plugin_name)
51 Timer scoped_timer (__PRETTY_FUNCTION__,
52 "Disassembler::FindPlugin (arch = %s, plugin_name = %s)",
53 arch.GetArchitectureName(),
56 DisassemblerCreateInstance create_callback = NULL;
60 ConstString const_plugin_name (plugin_name);
61 create_callback = PluginManager::GetDisassemblerCreateCallbackForPluginName (const_plugin_name);
64 DisassemblerSP disassembler_sp(create_callback(arch, flavor));
66 if (disassembler_sp.get())
67 return disassembler_sp;
72 for (uint32_t idx = 0; (create_callback = PluginManager::GetDisassemblerCreateCallbackAtIndex(idx)) != NULL; ++idx)
74 DisassemblerSP disassembler_sp(create_callback(arch, flavor));
76 if (disassembler_sp.get())
77 return disassembler_sp;
80 return DisassemblerSP();
84 Disassembler::FindPluginForTarget(const TargetSP target_sp, const ArchSpec &arch, const char *flavor, const char *plugin_name)
86 if (target_sp && flavor == NULL)
88 // FIXME - we don't have the mechanism in place to do per-architecture settings. But since we know that for now
89 // we only support flavors on x86 & x86_64,
90 if (arch.GetTriple().getArch() == llvm::Triple::x86
91 || arch.GetTriple().getArch() == llvm::Triple::x86_64)
92 flavor = target_sp->GetDisassemblyFlavor();
94 return FindPlugin(arch, flavor, plugin_name);
99 ResolveAddress (const ExecutionContext &exe_ctx,
101 Address &resolved_addr)
103 if (!addr.IsSectionOffset())
105 // If we weren't passed in a section offset address range,
106 // try and resolve it to something
107 Target *target = exe_ctx.GetTargetPtr();
110 if (target->GetSectionLoadList().IsEmpty())
112 target->GetImages().ResolveFileAddress (addr.GetOffset(), resolved_addr);
116 target->GetSectionLoadList().ResolveLoadAddress (addr.GetOffset(), resolved_addr);
118 // We weren't able to resolve the address, just treat it as a
120 if (resolved_addr.IsValid())
124 resolved_addr = addr;
128 Disassembler::Disassemble
131 const ArchSpec &arch,
132 const char *plugin_name,
134 const ExecutionContext &exe_ctx,
135 SymbolContextList &sc_list,
136 uint32_t num_instructions,
137 uint32_t num_mixed_context_lines,
142 size_t success_count = 0;
143 const size_t count = sc_list.GetSize();
146 const uint32_t scope = eSymbolContextBlock | eSymbolContextFunction | eSymbolContextSymbol;
147 const bool use_inline_block_range = true;
148 for (size_t i=0; i<count; ++i)
150 if (sc_list.GetContextAtIndex(i, sc) == false)
152 for (uint32_t range_idx = 0; sc.GetAddressRange(scope, range_idx, use_inline_block_range, range); ++range_idx)
154 if (Disassemble (debugger,
161 num_mixed_context_lines,
170 return success_count;
174 Disassembler::Disassemble
177 const ArchSpec &arch,
178 const char *plugin_name,
180 const ExecutionContext &exe_ctx,
181 const ConstString &name,
183 uint32_t num_instructions,
184 uint32_t num_mixed_context_lines,
189 SymbolContextList sc_list;
192 const bool include_symbols = true;
193 const bool include_inlines = true;
196 module->FindFunctions (name,
198 eFunctionNameTypeAuto,
204 else if (exe_ctx.GetTargetPtr())
206 exe_ctx.GetTargetPtr()->GetImages().FindFunctions (name,
207 eFunctionNameTypeAuto,
215 if (sc_list.GetSize ())
217 return Disassemble (debugger,
224 num_mixed_context_lines,
233 Disassembler::DisassembleRange
235 const ArchSpec &arch,
236 const char *plugin_name,
238 const ExecutionContext &exe_ctx,
239 const AddressRange &range,
240 bool prefer_file_cache
243 lldb::DisassemblerSP disasm_sp;
244 if (range.GetByteSize() > 0 && range.GetBaseAddress().IsValid())
246 disasm_sp = Disassembler::FindPluginForTarget(exe_ctx.GetTargetSP(), arch, flavor, plugin_name);
250 size_t bytes_disassembled = disasm_sp->ParseInstructions (&exe_ctx, range, NULL, prefer_file_cache);
251 if (bytes_disassembled == 0)
259 Disassembler::DisassembleBytes (const ArchSpec &arch,
260 const char *plugin_name,
262 const Address &start,
265 uint32_t num_instructions,
268 lldb::DisassemblerSP disasm_sp;
272 disasm_sp = Disassembler::FindPlugin(arch, flavor, plugin_name);
276 DataExtractor data(src, src_len, arch.GetByteOrder(), arch.GetAddressByteSize());
278 (void)disasm_sp->DecodeInstructions (start,
292 Disassembler::Disassemble
295 const ArchSpec &arch,
296 const char *plugin_name,
298 const ExecutionContext &exe_ctx,
299 const AddressRange &disasm_range,
300 uint32_t num_instructions,
301 uint32_t num_mixed_context_lines,
306 if (disasm_range.GetByteSize())
308 lldb::DisassemblerSP disasm_sp (Disassembler::FindPluginForTarget(exe_ctx.GetTargetSP(), arch, flavor, plugin_name));
313 ResolveAddress (exe_ctx, disasm_range.GetBaseAddress(), range.GetBaseAddress());
314 range.SetByteSize (disasm_range.GetByteSize());
315 const bool prefer_file_cache = false;
316 size_t bytes_disassembled = disasm_sp->ParseInstructions (&exe_ctx, range, &strm, prefer_file_cache);
317 if (bytes_disassembled == 0)
320 bool result = PrintInstructions (disasm_sp.get(),
325 num_mixed_context_lines,
329 // FIXME: The DisassemblerLLVMC has a reference cycle and won't go away if it has any active instructions.
330 // I'll fix that but for now, just clear the list and it will go away nicely.
331 disasm_sp->GetInstructionList().Clear();
339 Disassembler::Disassemble
342 const ArchSpec &arch,
343 const char *plugin_name,
345 const ExecutionContext &exe_ctx,
346 const Address &start_address,
347 uint32_t num_instructions,
348 uint32_t num_mixed_context_lines,
353 if (num_instructions > 0)
355 lldb::DisassemblerSP disasm_sp (Disassembler::FindPluginForTarget(exe_ctx.GetTargetSP(),
362 ResolveAddress (exe_ctx, start_address, addr);
363 const bool prefer_file_cache = false;
364 size_t bytes_disassembled = disasm_sp->ParseInstructions (&exe_ctx,
368 if (bytes_disassembled == 0)
370 bool result = PrintInstructions (disasm_sp.get(),
375 num_mixed_context_lines,
379 // FIXME: The DisassemblerLLVMC has a reference cycle and won't go away if it has any active instructions.
380 // I'll fix that but for now, just clear the list and it will go away nicely.
381 disasm_sp->GetInstructionList().Clear();
389 Disassembler::PrintInstructions
391 Disassembler *disasm_ptr,
393 const ArchSpec &arch,
394 const ExecutionContext &exe_ctx,
395 uint32_t num_instructions,
396 uint32_t num_mixed_context_lines,
401 // We got some things disassembled...
402 size_t num_instructions_found = disasm_ptr->GetInstructionList().GetSize();
404 if (num_instructions > 0 && num_instructions < num_instructions_found)
405 num_instructions_found = num_instructions;
407 const uint32_t max_opcode_byte_size = disasm_ptr->GetInstructionList().GetMaxOpcocdeByteSize ();
410 SymbolContext prev_sc;
411 AddressRange sc_range;
412 const Address *pc_addr_ptr = NULL;
413 StackFrame *frame = exe_ctx.GetFramePtr();
415 TargetSP target_sp (exe_ctx.GetTargetSP());
416 SourceManager &source_manager = target_sp ? target_sp->GetSourceManager() : debugger.GetSourceManager();
420 pc_addr_ptr = &frame->GetFrameCodeAddress();
422 const uint32_t scope = eSymbolContextLineEntry | eSymbolContextFunction | eSymbolContextSymbol;
423 const bool use_inline_block_range = false;
424 for (size_t i = 0; i < num_instructions_found; ++i)
426 Instruction *inst = disasm_ptr->GetInstructionList().GetInstructionAtIndex (i).get();
429 const Address &addr = inst->GetAddress();
430 const bool inst_is_at_pc = pc_addr_ptr && addr == *pc_addr_ptr;
434 ModuleSP module_sp (addr.GetModule());
437 uint32_t resolved_mask = module_sp->ResolveSymbolContextForAddress(addr, eSymbolContextEverything, sc);
440 if (num_mixed_context_lines)
442 if (!sc_range.ContainsFileAddress (addr))
444 sc.GetAddressRange (scope, 0, use_inline_block_range, sc_range);
451 sc.DumpStopContext(&strm, exe_ctx.GetProcessPtr(), addr, false, true, false, false);
454 if (sc.comp_unit && sc.line_entry.IsValid())
456 source_manager.DisplaySourceLinesWithLineNumbers (sc.line_entry.file,
458 num_mixed_context_lines,
459 num_mixed_context_lines,
460 ((inst_is_at_pc && (options & eOptionMarkPCSourceLine)) ? "->" : ""),
473 const bool show_bytes = (options & eOptionShowBytes) != 0;
474 const char *disassembly_format = "${addr-file-or-load}: ";
475 if (exe_ctx.HasTargetScope())
477 disassembly_format = exe_ctx.GetTargetRef().GetDebugger().GetDisassemblyFormat ();
479 inst->Dump (&strm, max_opcode_byte_size, true, show_bytes, &exe_ctx, &sc, &prev_sc, disassembly_format);
493 Disassembler::Disassemble
496 const ArchSpec &arch,
497 const char *plugin_name,
499 const ExecutionContext &exe_ctx,
500 uint32_t num_instructions,
501 uint32_t num_mixed_context_lines,
507 StackFrame *frame = exe_ctx.GetFramePtr();
510 SymbolContext sc(frame->GetSymbolContext(eSymbolContextFunction | eSymbolContextSymbol));
513 range = sc.function->GetAddressRange();
515 else if (sc.symbol && sc.symbol->ValueIsAddress())
517 range.GetBaseAddress() = sc.symbol->GetAddress();
518 range.SetByteSize (sc.symbol->GetByteSize());
522 range.GetBaseAddress() = frame->GetFrameCodeAddress();
525 if (range.GetBaseAddress().IsValid() && range.GetByteSize() == 0)
526 range.SetByteSize (DEFAULT_DISASM_BYTE_SIZE);
529 return Disassemble (debugger,
536 num_mixed_context_lines,
541 Instruction::Instruction(const Address &address, AddressClass addr_class) :
543 m_address_class (addr_class),
545 m_calculated_strings(false)
549 Instruction::~Instruction()
554 Instruction::GetAddressClass ()
556 if (m_address_class == eAddressClassInvalid)
557 m_address_class = m_address.GetAddressClass();
558 return m_address_class;
562 Instruction::Dump (lldb_private::Stream *s,
563 uint32_t max_opcode_byte_size,
566 const ExecutionContext* exe_ctx,
567 const SymbolContext *sym_ctx,
568 const SymbolContext *prev_sym_ctx,
569 const char *disassembly_addr_format_spec)
571 size_t opcode_column_width = 7;
572 const size_t operand_column_width = 25;
574 CalculateMnemonicOperandsAndCommentIfNeeded (exe_ctx);
580 Debugger::FormatDisassemblerAddress (disassembly_addr_format_spec, sym_ctx, prev_sym_ctx, exe_ctx, &m_address, ss);
585 if (m_opcode.GetType() == Opcode::eTypeBytes)
587 // x86_64 and i386 are the only ones that use bytes right now so
588 // pad out the byte dump to be able to always show 15 bytes (3 chars each)
590 if (max_opcode_byte_size > 0)
591 m_opcode.Dump (&ss, max_opcode_byte_size * 3 + 1);
593 m_opcode.Dump (&ss, 15 * 3 + 1);
597 // Else, we have ARM or MIPS which can show up to a uint32_t
598 // 0x00000000 (10 spaces) plus two for padding...
599 if (max_opcode_byte_size > 0)
600 m_opcode.Dump (&ss, max_opcode_byte_size * 3 + 1);
602 m_opcode.Dump (&ss, 12);
606 const size_t opcode_pos = ss.GetSizeOfLastLine();
608 // The default opcode size of 7 characters is plenty for most architectures
609 // but some like arm can pull out the occasional vqrshrun.s16. We won't get
610 // consistent column spacing in these cases, unfortunately.
611 if (m_opcode_name.length() >= opcode_column_width)
613 opcode_column_width = m_opcode_name.length() + 1;
616 ss.PutCString (m_opcode_name.c_str());
617 ss.FillLastLineToColumn (opcode_pos + opcode_column_width, ' ');
618 ss.PutCString (m_mnemonics.c_str());
620 if (!m_comment.empty())
622 ss.FillLastLineToColumn (opcode_pos + opcode_column_width + operand_column_width, ' ');
623 ss.PutCString (" ; ");
624 ss.PutCString (m_comment.c_str());
626 s->Write (ss.GetData(), ss.GetSize());
630 Instruction::DumpEmulation (const ArchSpec &arch)
632 std::unique_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL));
633 if (insn_emulator_ap.get())
635 insn_emulator_ap->SetInstruction (GetOpcode(), GetAddress(), NULL);
636 return insn_emulator_ap->EvaluateInstruction (0);
643 Instruction::ReadArray (FILE *in_file, Stream *out_stream, OptionValue::Type data_type)
648 OptionValueSP option_value_sp (new OptionValueArray (1u << data_type));
653 if (!fgets (buffer, 1023, in_file))
655 out_stream->Printf ("Instruction::ReadArray: Error reading file (fgets).\n");
656 option_value_sp.reset ();
657 return option_value_sp;
660 std::string line (buffer);
662 size_t len = line.size();
663 if (line[len-1] == '\n')
669 if ((line.size() == 1) && line[0] == ']')
678 static RegularExpression g_reg_exp ("^[ \t]*([^ \t]+)[ \t]*$");
679 RegularExpression::Match regex_match(1);
680 bool reg_exp_success = g_reg_exp.Execute (line.c_str(), ®ex_match);
682 regex_match.GetMatchAtIndex (line.c_str(), 1, value);
686 OptionValueSP data_value_sp;
689 case OptionValue::eTypeUInt64:
690 data_value_sp.reset (new OptionValueUInt64 (0, 0));
691 data_value_sp->SetValueFromCString (value.c_str());
693 // Other types can be added later as needed.
695 data_value_sp.reset (new OptionValueString (value.c_str(), ""));
699 option_value_sp->GetAsArray()->InsertValue (idx, data_value_sp);
704 return option_value_sp;
708 Instruction::ReadDictionary (FILE *in_file, Stream *out_stream)
713 OptionValueSP option_value_sp (new OptionValueDictionary());
714 static ConstString encoding_key ("data_encoding");
715 OptionValue::Type data_type = OptionValue::eTypeInvalid;
720 // Read the next line in the file
721 if (!fgets (buffer, 1023, in_file))
723 out_stream->Printf ("Instruction::ReadDictionary: Error reading file (fgets).\n");
724 option_value_sp.reset ();
725 return option_value_sp;
728 // Check to see if the line contains the end-of-dictionary marker ("}")
729 std::string line (buffer);
731 size_t len = line.size();
732 if (line[len-1] == '\n')
738 if ((line.size() == 1) && (line[0] == '}'))
744 // Try to find a key-value pair in the current line and add it to the dictionary.
747 static RegularExpression g_reg_exp ("^[ \t]*([a-zA-Z_][a-zA-Z0-9_]*)[ \t]*=[ \t]*(.*)[ \t]*$");
748 RegularExpression::Match regex_match(2);
750 bool reg_exp_success = g_reg_exp.Execute (line.c_str(), ®ex_match);
755 regex_match.GetMatchAtIndex (line.c_str(), 1, key);
756 regex_match.GetMatchAtIndex (line.c_str(), 2, value);
760 out_stream->Printf ("Instruction::ReadDictionary: Failure executing regular expression.\n");
761 option_value_sp.reset();
762 return option_value_sp;
765 ConstString const_key (key.c_str());
766 // Check value to see if it's the start of an array or dictionary.
768 lldb::OptionValueSP value_sp;
769 assert (value.empty() == false);
770 assert (key.empty() == false);
774 assert (value.size() == 1);
775 // value is a dictionary
776 value_sp = ReadDictionary (in_file, out_stream);
777 if (value_sp.get() == NULL)
779 option_value_sp.reset ();
780 return option_value_sp;
783 else if (value[0] == '[')
785 assert (value.size() == 1);
787 value_sp = ReadArray (in_file, out_stream, data_type);
788 if (value_sp.get() == NULL)
790 option_value_sp.reset ();
791 return option_value_sp;
793 // We've used the data_type to read an array; re-set the type to Invalid
794 data_type = OptionValue::eTypeInvalid;
796 else if ((value[0] == '0') && (value[1] == 'x'))
798 value_sp.reset (new OptionValueUInt64 (0, 0));
799 value_sp->SetValueFromCString (value.c_str());
803 size_t len = value.size();
804 if ((value[0] == '"') && (value[len-1] == '"'))
805 value = value.substr (1, len-2);
806 value_sp.reset (new OptionValueString (value.c_str(), ""));
811 if (const_key == encoding_key)
813 // A 'data_encoding=..." is NOT a normal key-value pair; it is meta-data indicating the
814 // data type of an upcoming array (usually the next bit of data to be read in).
815 if (strcmp (value.c_str(), "uint32_t") == 0)
816 data_type = OptionValue::eTypeUInt64;
819 option_value_sp->GetAsDictionary()->SetValueForKey (const_key, value_sp, false);
823 return option_value_sp;
827 Instruction::TestEmulation (Stream *out_stream, const char *file_name)
834 out_stream->Printf ("Instruction::TestEmulation: Missing file_name.");
838 FILE *test_file = fopen (file_name, "r");
841 out_stream->Printf ("Instruction::TestEmulation: Attempt to open test file failed.");
846 if (!fgets (buffer, 255, test_file))
848 out_stream->Printf ("Instruction::TestEmulation: Error reading first line of test file.\n");
853 if (strncmp (buffer, "InstructionEmulationState={", 27) != 0)
855 out_stream->Printf ("Instructin::TestEmulation: Test file does not contain emulation state dictionary\n");
860 // Read all the test information from the test file into an OptionValueDictionary.
862 OptionValueSP data_dictionary_sp (ReadDictionary (test_file, out_stream));
863 if (data_dictionary_sp.get() == NULL)
865 out_stream->Printf ("Instruction::TestEmulation: Error reading Dictionary Object.\n");
872 OptionValueDictionary *data_dictionary = data_dictionary_sp->GetAsDictionary();
873 static ConstString description_key ("assembly_string");
874 static ConstString triple_key ("triple");
876 OptionValueSP value_sp = data_dictionary->GetValueForKey (description_key);
878 if (value_sp.get() == NULL)
880 out_stream->Printf ("Instruction::TestEmulation: Test file does not contain description string.\n");
884 SetDescription (value_sp->GetStringValue());
887 value_sp = data_dictionary->GetValueForKey (triple_key);
888 if (value_sp.get() == NULL)
890 out_stream->Printf ("Instruction::TestEmulation: Test file does not contain triple.\n");
895 arch.SetTriple (llvm::Triple (value_sp->GetStringValue()));
897 bool success = false;
898 std::unique_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL));
899 if (insn_emulator_ap.get())
900 success = insn_emulator_ap->TestEmulation (out_stream, arch, data_dictionary);
903 out_stream->Printf ("Emulation test succeeded.");
905 out_stream->Printf ("Emulation test failed.");
911 Instruction::Emulate (const ArchSpec &arch,
912 uint32_t evaluate_options,
914 EmulateInstruction::ReadMemoryCallback read_mem_callback,
915 EmulateInstruction::WriteMemoryCallback write_mem_callback,
916 EmulateInstruction::ReadRegisterCallback read_reg_callback,
917 EmulateInstruction::WriteRegisterCallback write_reg_callback)
919 std::unique_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL));
920 if (insn_emulator_ap.get())
922 insn_emulator_ap->SetBaton (baton);
923 insn_emulator_ap->SetCallbacks (read_mem_callback, write_mem_callback, read_reg_callback, write_reg_callback);
924 insn_emulator_ap->SetInstruction (GetOpcode(), GetAddress(), NULL);
925 return insn_emulator_ap->EvaluateInstruction (evaluate_options);
933 Instruction::GetData (DataExtractor &data)
935 return m_opcode.GetData(data);
938 InstructionList::InstructionList() :
943 InstructionList::~InstructionList()
948 InstructionList::GetSize() const
950 return m_instructions.size();
954 InstructionList::GetMaxOpcocdeByteSize () const
956 uint32_t max_inst_size = 0;
957 collection::const_iterator pos, end;
958 for (pos = m_instructions.begin(), end = m_instructions.end();
962 uint32_t inst_size = (*pos)->GetOpcode().GetByteSize();
963 if (max_inst_size < inst_size)
964 max_inst_size = inst_size;
966 return max_inst_size;
972 InstructionList::GetInstructionAtIndex (size_t idx) const
974 InstructionSP inst_sp;
975 if (idx < m_instructions.size())
976 inst_sp = m_instructions[idx];
981 InstructionList::Dump (Stream *s,
984 const ExecutionContext* exe_ctx)
986 const uint32_t max_opcode_byte_size = GetMaxOpcocdeByteSize();
987 collection::const_iterator pos, begin, end;
988 const char *disassemble_format = "${addr-file-or-load}: ";
991 disassemble_format = exe_ctx->GetTargetRef().GetDebugger().GetDisassemblyFormat ();
993 for (begin = m_instructions.begin(), end = m_instructions.end(), pos = begin;
999 (*pos)->Dump(s, max_opcode_byte_size, show_address, show_bytes, exe_ctx, NULL, NULL, disassemble_format);
1005 InstructionList::Clear()
1007 m_instructions.clear();
1011 InstructionList::Append (lldb::InstructionSP &inst_sp)
1014 m_instructions.push_back(inst_sp);
1018 InstructionList::GetIndexOfNextBranchInstruction(uint32_t start) const
1020 size_t num_instructions = m_instructions.size();
1022 uint32_t next_branch = UINT32_MAX;
1023 for (size_t i = start; i < num_instructions; i++)
1025 if (m_instructions[i]->DoesBranch())
1035 InstructionList::GetIndexOfInstructionAtAddress (const Address &address)
1037 size_t num_instructions = m_instructions.size();
1038 uint32_t index = UINT32_MAX;
1039 for (size_t i = 0; i < num_instructions; i++)
1041 if (m_instructions[i]->GetAddress() == address)
1052 InstructionList::GetIndexOfInstructionAtLoadAddress (lldb::addr_t load_addr, Target &target)
1055 address.SetLoadAddress(load_addr, &target);
1056 return GetIndexOfInstructionAtAddress(address);
1060 Disassembler::ParseInstructions (const ExecutionContext *exe_ctx,
1061 const AddressRange &range,
1062 Stream *error_strm_ptr,
1063 bool prefer_file_cache)
1067 Target *target = exe_ctx->GetTargetPtr();
1068 const addr_t byte_size = range.GetByteSize();
1069 if (target == NULL || byte_size == 0 || !range.GetBaseAddress().IsValid())
1072 DataBufferHeap *heap_buffer = new DataBufferHeap (byte_size, '\0');
1073 DataBufferSP data_sp(heap_buffer);
1076 lldb::addr_t load_addr = LLDB_INVALID_ADDRESS;
1077 const size_t bytes_read = target->ReadMemory (range.GetBaseAddress(),
1079 heap_buffer->GetBytes(),
1080 heap_buffer->GetByteSize(),
1086 if (bytes_read != heap_buffer->GetByteSize())
1087 heap_buffer->SetByteSize (bytes_read);
1088 DataExtractor data (data_sp,
1089 m_arch.GetByteOrder(),
1090 m_arch.GetAddressByteSize());
1091 const bool data_from_file = load_addr == LLDB_INVALID_ADDRESS;
1092 return DecodeInstructions (range.GetBaseAddress(), data, 0, UINT32_MAX, false, data_from_file);
1094 else if (error_strm_ptr)
1096 const char *error_cstr = error.AsCString();
1099 error_strm_ptr->Printf("error: %s\n", error_cstr);
1103 else if (error_strm_ptr)
1105 error_strm_ptr->PutCString("error: invalid execution context\n");
1111 Disassembler::ParseInstructions (const ExecutionContext *exe_ctx,
1112 const Address &start,
1113 uint32_t num_instructions,
1114 bool prefer_file_cache)
1116 m_instruction_list.Clear();
1118 if (exe_ctx == NULL || num_instructions == 0 || !start.IsValid())
1121 Target *target = exe_ctx->GetTargetPtr();
1122 // Calculate the max buffer size we will need in order to disassemble
1123 const addr_t byte_size = num_instructions * m_arch.GetMaximumOpcodeByteSize();
1125 if (target == NULL || byte_size == 0)
1128 DataBufferHeap *heap_buffer = new DataBufferHeap (byte_size, '\0');
1129 DataBufferSP data_sp (heap_buffer);
1132 lldb::addr_t load_addr = LLDB_INVALID_ADDRESS;
1133 const size_t bytes_read = target->ReadMemory (start,
1135 heap_buffer->GetBytes(),
1140 const bool data_from_file = load_addr == LLDB_INVALID_ADDRESS;
1142 if (bytes_read == 0)
1144 DataExtractor data (data_sp,
1145 m_arch.GetByteOrder(),
1146 m_arch.GetAddressByteSize());
1148 const bool append_instructions = true;
1149 DecodeInstructions (start,
1153 append_instructions,
1156 return m_instruction_list.GetSize();
1159 //----------------------------------------------------------------------
1160 // Disassembler copy constructor
1161 //----------------------------------------------------------------------
1162 Disassembler::Disassembler(const ArchSpec& arch, const char *flavor) :
1164 m_instruction_list(),
1165 m_base_addr(LLDB_INVALID_ADDRESS),
1169 m_flavor.assign("default");
1171 m_flavor.assign(flavor);
1174 //----------------------------------------------------------------------
1176 //----------------------------------------------------------------------
1177 Disassembler::~Disassembler()
1182 Disassembler::GetInstructionList ()
1184 return m_instruction_list;
1187 const InstructionList &
1188 Disassembler::GetInstructionList () const
1190 return m_instruction_list;
1193 //----------------------------------------------------------------------
1194 // Class PseudoInstruction
1195 //----------------------------------------------------------------------
1196 PseudoInstruction::PseudoInstruction () :
1197 Instruction (Address(), eAddressClassUnknown),
1202 PseudoInstruction::~PseudoInstruction ()
1207 PseudoInstruction::DoesBranch ()
1209 // This is NOT a valid question for a pseudo instruction.
1214 PseudoInstruction::Decode (const lldb_private::Disassembler &disassembler,
1215 const lldb_private::DataExtractor &data,
1216 lldb::offset_t data_offset)
1218 return m_opcode.GetByteSize();
1223 PseudoInstruction::SetOpcode (size_t opcode_size, void *opcode_data)
1228 switch (opcode_size)
1232 uint8_t value8 = *((uint8_t *) opcode_data);
1233 m_opcode.SetOpcode8 (value8, eByteOrderInvalid);
1238 uint16_t value16 = *((uint16_t *) opcode_data);
1239 m_opcode.SetOpcode16 (value16, eByteOrderInvalid);
1244 uint32_t value32 = *((uint32_t *) opcode_data);
1245 m_opcode.SetOpcode32 (value32, eByteOrderInvalid);
1250 uint64_t value64 = *((uint64_t *) opcode_data);
1251 m_opcode.SetOpcode64 (value64, eByteOrderInvalid);
1260 PseudoInstruction::SetDescription (const char *description)
1262 if (description && strlen (description) > 0)
1263 m_description = description;