1 //===-- Disassembler.cpp ----------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "lldb/Core/Disassembler.h"
11 
12 // C Includes
13 // C++ Includes
14 // Other libraries and framework includes
15 // Project includes
16 #include "lldb/lldb-private.h"
17 #include "lldb/Core/Error.h"
18 #include "lldb/Core/DataBufferHeap.h"
19 #include "lldb/Core/DataExtractor.h"
20 #include "lldb/Core/Debugger.h"
21 #include "lldb/Core/EmulateInstruction.h"
22 #include "lldb/Core/Module.h"
23 #include "lldb/Core/PluginManager.h"
24 #include "lldb/Core/RegularExpression.h"
25 #include "lldb/Core/Timer.h"
26 #include "lldb/Interpreter/NamedOptionValue.h"
27 #include "lldb/Symbol/ObjectFile.h"
28 #include "lldb/Target/ExecutionContext.h"
29 #include "lldb/Target/Process.h"
30 #include "lldb/Target/StackFrame.h"
31 #include "lldb/Target/Target.h"
32 
33 #define DEFAULT_DISASM_BYTE_SIZE 32
34 
35 using namespace lldb;
36 using namespace lldb_private;
37 
38 
39 Disassembler*
40 Disassembler::FindPlugin (const ArchSpec &arch, const char *plugin_name)
41 {
42     Timer scoped_timer (__PRETTY_FUNCTION__,
43                         "Disassembler::FindPlugin (arch = %s, plugin_name = %s)",
44                         arch.GetArchitectureName(),
45                         plugin_name);
46 
47     std::auto_ptr<Disassembler> disassembler_ap;
48     DisassemblerCreateInstance create_callback = NULL;
49 
50     if (plugin_name)
51     {
52         create_callback = PluginManager::GetDisassemblerCreateCallbackForPluginName (plugin_name);
53         if (create_callback)
54         {
55             disassembler_ap.reset (create_callback(arch));
56 
57             if (disassembler_ap.get())
58                 return disassembler_ap.release();
59         }
60     }
61     else
62     {
63         for (uint32_t idx = 0; (create_callback = PluginManager::GetDisassemblerCreateCallbackAtIndex(idx)) != NULL; ++idx)
64         {
65             disassembler_ap.reset (create_callback(arch));
66 
67             if (disassembler_ap.get())
68                 return disassembler_ap.release();
69         }
70     }
71     return NULL;
72 }
73 
74 
75 static void
76 ResolveAddress (const ExecutionContext &exe_ctx,
77                 const Address &addr,
78                 Address &resolved_addr)
79 {
80     if (!addr.IsSectionOffset())
81     {
82         // If we weren't passed in a section offset address range,
83         // try and resolve it to something
84         Target *target = exe_ctx.GetTargetPtr();
85         if (target)
86         {
87             if (target->GetSectionLoadList().IsEmpty())
88             {
89                 target->GetImages().ResolveFileAddress (addr.GetOffset(), resolved_addr);
90             }
91             else
92             {
93                 target->GetSectionLoadList().ResolveLoadAddress (addr.GetOffset(), resolved_addr);
94             }
95             // We weren't able to resolve the address, just treat it as a
96             // raw address
97             if (resolved_addr.IsValid())
98                 return;
99         }
100     }
101     resolved_addr = addr;
102 }
103 
104 size_t
105 Disassembler::Disassemble
106 (
107     Debugger &debugger,
108     const ArchSpec &arch,
109     const char *plugin_name,
110     const ExecutionContext &exe_ctx,
111     SymbolContextList &sc_list,
112     uint32_t num_instructions,
113     uint32_t num_mixed_context_lines,
114     uint32_t options,
115     Stream &strm
116 )
117 {
118     size_t success_count = 0;
119     const size_t count = sc_list.GetSize();
120     SymbolContext sc;
121     AddressRange range;
122     const uint32_t scope = eSymbolContextBlock | eSymbolContextFunction | eSymbolContextSymbol;
123     const bool use_inline_block_range = true;
124     for (size_t i=0; i<count; ++i)
125     {
126         if (sc_list.GetContextAtIndex(i, sc) == false)
127             break;
128         for (uint32_t range_idx = 0; sc.GetAddressRange(scope, range_idx, use_inline_block_range, range); ++range_idx)
129         {
130             if (Disassemble (debugger,
131                              arch,
132                              plugin_name,
133                              exe_ctx,
134                              range,
135                              num_instructions,
136                              num_mixed_context_lines,
137                              options,
138                              strm))
139             {
140                 ++success_count;
141                 strm.EOL();
142             }
143         }
144     }
145     return success_count;
146 }
147 
148 bool
149 Disassembler::Disassemble
150 (
151     Debugger &debugger,
152     const ArchSpec &arch,
153     const char *plugin_name,
154     const ExecutionContext &exe_ctx,
155     const ConstString &name,
156     Module *module,
157     uint32_t num_instructions,
158     uint32_t num_mixed_context_lines,
159     uint32_t options,
160     Stream &strm
161 )
162 {
163     SymbolContextList sc_list;
164     if (name)
165     {
166         const bool include_symbols = true;
167         if (module)
168         {
169             module->FindFunctions (name,
170                                    eFunctionNameTypeBase |
171                                    eFunctionNameTypeFull |
172                                    eFunctionNameTypeMethod |
173                                    eFunctionNameTypeSelector,
174                                    include_symbols,
175                                    true,
176                                    sc_list);
177         }
178         else if (exe_ctx.GetTargetPtr())
179         {
180             exe_ctx.GetTargetPtr()->GetImages().FindFunctions (name,
181                                                                eFunctionNameTypeBase |
182                                                                eFunctionNameTypeFull |
183                                                                eFunctionNameTypeMethod |
184                                                                eFunctionNameTypeSelector,
185                                                                include_symbols,
186                                                                false,
187                                                                sc_list);
188         }
189     }
190 
191     if (sc_list.GetSize ())
192     {
193         return Disassemble (debugger,
194                             arch,
195                             plugin_name,
196                             exe_ctx,
197                             sc_list,
198                             num_instructions,
199                             num_mixed_context_lines,
200                             options,
201                             strm);
202     }
203     return false;
204 }
205 
206 
207 lldb::DisassemblerSP
208 Disassembler::DisassembleRange
209 (
210     const ArchSpec &arch,
211     const char *plugin_name,
212     const ExecutionContext &exe_ctx,
213     const AddressRange &range
214 )
215 {
216     lldb::DisassemblerSP disasm_sp;
217     if (range.GetByteSize() > 0 && range.GetBaseAddress().IsValid())
218     {
219         disasm_sp.reset (Disassembler::FindPlugin(arch, plugin_name));
220 
221         if (disasm_sp)
222         {
223             size_t bytes_disassembled = disasm_sp->ParseInstructions (&exe_ctx, range);
224             if (bytes_disassembled == 0)
225                 disasm_sp.reset();
226         }
227     }
228     return disasm_sp;
229 }
230 
231 
232 bool
233 Disassembler::Disassemble
234 (
235     Debugger &debugger,
236     const ArchSpec &arch,
237     const char *plugin_name,
238     const ExecutionContext &exe_ctx,
239     const AddressRange &disasm_range,
240     uint32_t num_instructions,
241     uint32_t num_mixed_context_lines,
242     uint32_t options,
243     Stream &strm
244 )
245 {
246     if (disasm_range.GetByteSize())
247     {
248         std::auto_ptr<Disassembler> disasm_ap (Disassembler::FindPlugin(arch, plugin_name));
249 
250         if (disasm_ap.get())
251         {
252             AddressRange range;
253             ResolveAddress (exe_ctx, disasm_range.GetBaseAddress(), range.GetBaseAddress());
254             range.SetByteSize (disasm_range.GetByteSize());
255 
256             size_t bytes_disassembled = disasm_ap->ParseInstructions (&exe_ctx, range);
257             if (bytes_disassembled == 0)
258                 return false;
259 
260             return PrintInstructions (disasm_ap.get(),
261                                       debugger,
262                                       arch,
263                                       exe_ctx,
264                                       num_instructions,
265                                       num_mixed_context_lines,
266                                       options,
267                                       strm);
268         }
269     }
270     return false;
271 }
272 
273 bool
274 Disassembler::Disassemble
275 (
276     Debugger &debugger,
277     const ArchSpec &arch,
278     const char *plugin_name,
279     const ExecutionContext &exe_ctx,
280     const Address &start_address,
281     uint32_t num_instructions,
282     uint32_t num_mixed_context_lines,
283     uint32_t options,
284     Stream &strm
285 )
286 {
287     if (num_instructions > 0)
288     {
289         std::auto_ptr<Disassembler> disasm_ap (Disassembler::FindPlugin(arch, plugin_name));
290         if (disasm_ap.get())
291         {
292             Address addr;
293             ResolveAddress (exe_ctx, start_address, addr);
294 
295             size_t bytes_disassembled = disasm_ap->ParseInstructions (&exe_ctx, addr, num_instructions);
296             if (bytes_disassembled == 0)
297                 return false;
298             return PrintInstructions (disasm_ap.get(),
299                                       debugger,
300                                       arch,
301                                       exe_ctx,
302                                       num_instructions,
303                                       num_mixed_context_lines,
304                                       options,
305                                       strm);
306         }
307     }
308     return false;
309 }
310 
311 bool
312 Disassembler::PrintInstructions
313 (
314     Disassembler *disasm_ptr,
315     Debugger &debugger,
316     const ArchSpec &arch,
317     const ExecutionContext &exe_ctx,
318     uint32_t num_instructions,
319     uint32_t num_mixed_context_lines,
320     uint32_t options,
321     Stream &strm
322 )
323 {
324     // We got some things disassembled...
325     size_t num_instructions_found = disasm_ptr->GetInstructionList().GetSize();
326 
327     if (num_instructions > 0 && num_instructions < num_instructions_found)
328         num_instructions_found = num_instructions;
329 
330     const uint32_t max_opcode_byte_size = disasm_ptr->GetInstructionList().GetMaxOpcocdeByteSize ();
331     uint32_t offset = 0;
332     SymbolContext sc;
333     SymbolContext prev_sc;
334     AddressRange sc_range;
335     const Address *pc_addr_ptr = NULL;
336     ExecutionContextScope *exe_scope = exe_ctx.GetBestExecutionContextScope();
337     StackFrame *frame = exe_ctx.GetFramePtr();
338 
339     if (frame)
340         pc_addr_ptr = &frame->GetFrameCodeAddress();
341     const uint32_t scope = eSymbolContextLineEntry | eSymbolContextFunction | eSymbolContextSymbol;
342     const bool use_inline_block_range = false;
343     for (size_t i=0; i<num_instructions_found; ++i)
344     {
345         Instruction *inst = disasm_ptr->GetInstructionList().GetInstructionAtIndex (i).get();
346         if (inst)
347         {
348             const Address &addr = inst->GetAddress();
349             const bool inst_is_at_pc = pc_addr_ptr && addr == *pc_addr_ptr;
350 
351             prev_sc = sc;
352 
353             Module *module = addr.GetModule();
354             if (module)
355             {
356                 uint32_t resolved_mask = module->ResolveSymbolContextForAddress(addr, eSymbolContextEverything, sc);
357                 if (resolved_mask)
358                 {
359                     if (num_mixed_context_lines)
360                     {
361                         if (!sc_range.ContainsFileAddress (addr))
362                         {
363                             sc.GetAddressRange (scope, 0, use_inline_block_range, sc_range);
364 
365                             if (sc != prev_sc)
366                             {
367                                 if (offset != 0)
368                                     strm.EOL();
369 
370                                 sc.DumpStopContext(&strm, exe_ctx.GetProcessPtr(), addr, false, true, false);
371                                 strm.EOL();
372 
373                                 if (sc.comp_unit && sc.line_entry.IsValid())
374                                 {
375                                     debugger.GetSourceManager().DisplaySourceLinesWithLineNumbers (sc.line_entry.file,
376                                                                                                    sc.line_entry.line,
377                                                                                                    num_mixed_context_lines,
378                                                                                                    num_mixed_context_lines,
379                                                                                                    ((inst_is_at_pc && (options & eOptionMarkPCSourceLine)) ? "->" : ""),
380                                                                                                    &strm);
381                                 }
382                             }
383                         }
384                     }
385                     else if (!(prev_sc.function == sc.function || prev_sc.symbol == sc.symbol))
386                     {
387                         if (prev_sc.function || prev_sc.symbol)
388                             strm.EOL();
389 
390                         bool show_fullpaths = false;
391                         bool show_module = true;
392                         bool show_inlined_frames = true;
393                         sc.DumpStopContext (&strm,
394                                             exe_scope,
395                                             addr,
396                                             show_fullpaths,
397                                             show_module,
398                                             show_inlined_frames);
399 
400                         strm << ":\n";
401                     }
402                 }
403                 else
404                 {
405                     sc.Clear();
406                 }
407             }
408 
409             if ((options & eOptionMarkPCAddress) && pc_addr_ptr)
410             {
411                 strm.PutCString(inst_is_at_pc ? "-> " : "   ");
412             }
413             const bool show_bytes = (options & eOptionShowBytes) != 0;
414             const bool raw = (options & eOptionRawOuput) != 0;
415             inst->Dump(&strm, max_opcode_byte_size, true, show_bytes, &exe_ctx, raw);
416             strm.EOL();
417         }
418         else
419         {
420             break;
421         }
422     }
423 
424     return true;
425 }
426 
427 
428 bool
429 Disassembler::Disassemble
430 (
431     Debugger &debugger,
432     const ArchSpec &arch,
433     const char *plugin_name,
434     const ExecutionContext &exe_ctx,
435     uint32_t num_instructions,
436     uint32_t num_mixed_context_lines,
437     uint32_t options,
438     Stream &strm
439 )
440 {
441     AddressRange range;
442     StackFrame *frame = exe_ctx.GetFramePtr();
443     if (frame)
444     {
445         SymbolContext sc(frame->GetSymbolContext(eSymbolContextFunction | eSymbolContextSymbol));
446         if (sc.function)
447         {
448             range = sc.function->GetAddressRange();
449         }
450         else if (sc.symbol && sc.symbol->GetAddressRangePtr())
451         {
452             range = *sc.symbol->GetAddressRangePtr();
453         }
454         else
455         {
456             range.GetBaseAddress() = frame->GetFrameCodeAddress();
457         }
458 
459         if (range.GetBaseAddress().IsValid() && range.GetByteSize() == 0)
460             range.SetByteSize (DEFAULT_DISASM_BYTE_SIZE);
461     }
462 
463     return Disassemble (debugger,
464                         arch,
465                         plugin_name,
466                         exe_ctx,
467                         range,
468                         num_instructions,
469                         num_mixed_context_lines,
470                         options,
471                         strm);
472 }
473 
474 Instruction::Instruction(const Address &address, AddressClass addr_class) :
475     m_address (address),
476     m_address_class (addr_class),
477     m_opcode()
478 {
479 }
480 
481 Instruction::~Instruction()
482 {
483 }
484 
485 AddressClass
486 Instruction::GetAddressClass ()
487 {
488     if (m_address_class == eAddressClassInvalid)
489         m_address_class = m_address.GetAddressClass();
490     return m_address_class;
491 }
492 
493 bool
494 Instruction::DumpEmulation (const ArchSpec &arch)
495 {
496 	std::auto_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL));
497 	if (insn_emulator_ap.get())
498 	{
499         insn_emulator_ap->SetInstruction (GetOpcode(), GetAddress(), NULL);
500         return insn_emulator_ap->EvaluateInstruction (0);
501 	}
502 
503     return false;
504 }
505 
506 OptionValueSP
507 Instruction::ReadArray (FILE *in_file, Stream *out_stream, OptionValue::Type data_type)
508 {
509     bool done = false;
510     char buffer[1024];
511 
512     OptionValueSP option_value_sp (new OptionValueArray (1u << data_type));
513 
514     int idx = 0;
515     while (!done)
516     {
517         if (!fgets (buffer, 1023, in_file))
518         {
519             out_stream->Printf ("Instruction::ReadArray:  Error reading file (fgets).\n");
520             option_value_sp.reset ();
521             return option_value_sp;
522         }
523 
524         std::string line (buffer);
525 
526         int len = line.size();
527         if (line[len-1] == '\n')
528         {
529             line[len-1] = '\0';
530             line.resize (len-1);
531         }
532 
533         if ((line.size() == 1) && line[0] == ']')
534         {
535             done = true;
536             line.clear();
537         }
538 
539         if (line.size() > 0)
540         {
541             std::string value;
542             RegularExpression reg_exp ("^[ \t]*([^ \t]+)[ \t]*$");
543             bool reg_exp_success = reg_exp.Execute (line.c_str(), 1);
544             if (reg_exp_success)
545                 reg_exp.GetMatchAtIndex (line.c_str(), 1, value);
546             else
547                 value = line;
548 
549             OptionValueSP data_value_sp;
550             switch (data_type)
551             {
552             case OptionValue::eTypeUInt64:
553                 data_value_sp.reset (new OptionValueUInt64 (0, 0));
554                 data_value_sp->SetValueFromCString (value.c_str());
555                 break;
556             // Other types can be added later as needed.
557             default:
558                 data_value_sp.reset (new OptionValueString (value.c_str(), ""));
559                 break;
560             }
561 
562             option_value_sp->GetAsArray()->InsertValue (idx, data_value_sp);
563             ++idx;
564         }
565     }
566 
567     return option_value_sp;
568 }
569 
570 OptionValueSP
571 Instruction::ReadDictionary (FILE *in_file, Stream *out_stream)
572 {
573     bool done = false;
574     char buffer[1024];
575 
576     OptionValueSP option_value_sp (new OptionValueDictionary());
577     static ConstString encoding_key ("data_encoding");
578     OptionValue::Type data_type = OptionValue::eTypeInvalid;
579 
580 
581     while (!done)
582     {
583         // Read the next line in the file
584         if (!fgets (buffer, 1023, in_file))
585         {
586             out_stream->Printf ("Instruction::ReadDictionary: Error reading file (fgets).\n");
587             option_value_sp.reset ();
588             return option_value_sp;
589         }
590 
591         // Check to see if the line contains the end-of-dictionary marker ("}")
592         std::string line (buffer);
593 
594         int len = line.size();
595         if (line[len-1] == '\n')
596         {
597             line[len-1] = '\0';
598             line.resize (len-1);
599         }
600 
601         if ((line.size() == 1) && (line[0] == '}'))
602         {
603             done = true;
604             line.clear();
605         }
606 
607         // Try to find a key-value pair in the current line and add it to the dictionary.
608         if (line.size() > 0)
609         {
610             RegularExpression reg_exp ("^[ \t]*([a-zA-Z_][a-zA-Z0-9_]*)[ \t]*=[ \t]*(.*)[ \t]*$");
611             bool reg_exp_success = reg_exp.Execute (line.c_str(), 2);
612             std::string key;
613             std::string value;
614             if (reg_exp_success)
615             {
616                 reg_exp.GetMatchAtIndex (line.c_str(), 1, key);
617                 reg_exp.GetMatchAtIndex (line.c_str(), 2, value);
618             }
619             else
620             {
621                 out_stream->Printf ("Instruction::ReadDictionary: Failure executing regular expression.\n");
622                 option_value_sp.reset();
623                 return option_value_sp;
624             }
625 
626             ConstString const_key (key.c_str());
627             // Check value to see if it's the start of an array or dictionary.
628 
629             lldb::OptionValueSP value_sp;
630             assert (value.empty() == false);
631             assert (key.empty() == false);
632 
633             if (value[0] == '{')
634             {
635                 assert (value.size() == 1);
636                 // value is a dictionary
637                 value_sp = ReadDictionary (in_file, out_stream);
638                 if (value_sp.get() == NULL)
639                 {
640                     option_value_sp.reset ();
641                     return option_value_sp;
642                 }
643             }
644             else if (value[0] == '[')
645             {
646                 assert (value.size() == 1);
647                 // value is an array
648                 value_sp = ReadArray (in_file, out_stream, data_type);
649                 if (value_sp.get() == NULL)
650                 {
651                     option_value_sp.reset ();
652                     return option_value_sp;
653                 }
654                 // We've used the data_type to read an array; re-set the type to Invalid
655                 data_type = OptionValue::eTypeInvalid;
656             }
657             else if ((value[0] == '0') && (value[1] == 'x'))
658             {
659                 value_sp.reset (new OptionValueUInt64 (0, 0));
660                 value_sp->SetValueFromCString (value.c_str());
661             }
662             else
663             {
664                 int len = value.size();
665                 if ((value[0] == '"') && (value[len-1] == '"'))
666                     value = value.substr (1, len-2);
667                 value_sp.reset (new OptionValueString (value.c_str(), ""));
668             }
669 
670 
671 
672             if (const_key == encoding_key)
673             {
674                 // A 'data_encoding=..." is NOT a normal key-value pair; it is meta-data indicating the
675                 // data type of an upcoming array (usually the next bit of data to be read in).
676                 if (strcmp (value.c_str(), "uint32_t") == 0)
677                     data_type = OptionValue::eTypeUInt64;
678             }
679             else
680                 option_value_sp->GetAsDictionary()->SetValueForKey (const_key, value_sp, false);
681         }
682     }
683 
684     return option_value_sp;
685 }
686 
687 bool
688 Instruction::TestEmulation (Stream *out_stream, const char *file_name)
689 {
690     if (!out_stream)
691         return false;
692 
693     if (!file_name)
694     {
695         out_stream->Printf ("Instruction::TestEmulation:  Missing file_name.");
696         return false;
697     }
698 
699     FILE *test_file = fopen (file_name, "r");
700     if (!test_file)
701     {
702         out_stream->Printf ("Instruction::TestEmulation: Attempt to open test file failed.");
703         return false;
704     }
705 
706     char buffer[256];
707     if (!fgets (buffer, 255, test_file))
708     {
709         out_stream->Printf ("Instruction::TestEmulation: Error reading first line of test file.\n");
710         fclose (test_file);
711         return false;
712     }
713 
714     if (strncmp (buffer, "InstructionEmulationState={", 27) != 0)
715     {
716         out_stream->Printf ("Instructin::TestEmulation: Test file does not contain emulation state dictionary\n");
717         fclose (test_file);
718         return false;
719     }
720 
721     // Read all the test information from the test file into an OptionValueDictionary.
722 
723     OptionValueSP data_dictionary_sp (ReadDictionary (test_file, out_stream));
724     if (data_dictionary_sp.get() == NULL)
725     {
726         out_stream->Printf ("Instruction::TestEmulation:  Error reading Dictionary Object.\n");
727         fclose (test_file);
728         return false;
729     }
730 
731     fclose (test_file);
732 
733     OptionValueDictionary *data_dictionary = data_dictionary_sp->GetAsDictionary();
734     static ConstString description_key ("assembly_string");
735     static ConstString triple_key ("triple");
736 
737     OptionValueSP value_sp = data_dictionary->GetValueForKey (description_key);
738 
739     if (value_sp.get() == NULL)
740     {
741         out_stream->Printf ("Instruction::TestEmulation:  Test file does not contain description string.\n");
742         return false;
743     }
744 
745     SetDescription (value_sp->GetStringValue());
746 
747 
748     value_sp = data_dictionary->GetValueForKey (triple_key);
749     if (value_sp.get() == NULL)
750     {
751         out_stream->Printf ("Instruction::TestEmulation: Test file does not contain triple.\n");
752         return false;
753     }
754 
755     ArchSpec arch;
756     arch.SetTriple (llvm::Triple (value_sp->GetStringValue()));
757 
758     bool success = false;
759     std::auto_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL));
760     if (insn_emulator_ap.get())
761         success = insn_emulator_ap->TestEmulation (out_stream, arch, data_dictionary);
762 
763     if (success)
764         out_stream->Printf ("Emulation test succeeded.");
765     else
766         out_stream->Printf ("Emulation test failed.");
767 
768     return success;
769 }
770 
771 bool
772 Instruction::Emulate (const ArchSpec &arch,
773                       uint32_t evaluate_options,
774                       void *baton,
775                       EmulateInstruction::ReadMemoryCallback read_mem_callback,
776                       EmulateInstruction::WriteMemoryCallback write_mem_callback,
777                       EmulateInstruction::ReadRegisterCallback read_reg_callback,
778                       EmulateInstruction::WriteRegisterCallback write_reg_callback)
779 {
780 	std::auto_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL));
781 	if (insn_emulator_ap.get())
782 	{
783 		insn_emulator_ap->SetBaton (baton);
784 		insn_emulator_ap->SetCallbacks (read_mem_callback, write_mem_callback, read_reg_callback, write_reg_callback);
785         insn_emulator_ap->SetInstruction (GetOpcode(), GetAddress(), NULL);
786         return insn_emulator_ap->EvaluateInstruction (evaluate_options);
787 	}
788 
789     return false;
790 }
791 
792 InstructionList::InstructionList() :
793     m_instructions()
794 {
795 }
796 
797 InstructionList::~InstructionList()
798 {
799 }
800 
801 size_t
802 InstructionList::GetSize() const
803 {
804     return m_instructions.size();
805 }
806 
807 uint32_t
808 InstructionList::GetMaxOpcocdeByteSize () const
809 {
810     uint32_t max_inst_size = 0;
811     collection::const_iterator pos, end;
812     for (pos = m_instructions.begin(), end = m_instructions.end();
813          pos != end;
814          ++pos)
815     {
816         uint32_t inst_size = (*pos)->GetOpcode().GetByteSize();
817         if (max_inst_size < inst_size)
818             max_inst_size = inst_size;
819     }
820     return max_inst_size;
821 }
822 
823 
824 
825 InstructionSP
826 InstructionList::GetInstructionAtIndex (uint32_t idx) const
827 {
828     InstructionSP inst_sp;
829     if (idx < m_instructions.size())
830         inst_sp = m_instructions[idx];
831     return inst_sp;
832 }
833 
834 void
835 InstructionList::Clear()
836 {
837   m_instructions.clear();
838 }
839 
840 void
841 InstructionList::Append (lldb::InstructionSP &inst_sp)
842 {
843     if (inst_sp)
844         m_instructions.push_back(inst_sp);
845 }
846 
847 
848 size_t
849 Disassembler::ParseInstructions
850 (
851     const ExecutionContext *exe_ctx,
852     const AddressRange &range
853 )
854 {
855     if (exe_ctx)
856     {
857         Target *target = exe_ctx->GetTargetPtr();
858         const addr_t byte_size = range.GetByteSize();
859         if (target == NULL || byte_size == 0 || !range.GetBaseAddress().IsValid())
860             return 0;
861 
862         DataBufferHeap *heap_buffer = new DataBufferHeap (byte_size, '\0');
863         DataBufferSP data_sp(heap_buffer);
864 
865         Error error;
866         const bool prefer_file_cache = true;
867         const size_t bytes_read = target->ReadMemory (range.GetBaseAddress(),
868                                                       prefer_file_cache,
869                                                       heap_buffer->GetBytes(),
870                                                       heap_buffer->GetByteSize(),
871                                                       error);
872 
873         if (bytes_read > 0)
874         {
875             if (bytes_read != heap_buffer->GetByteSize())
876                 heap_buffer->SetByteSize (bytes_read);
877             DataExtractor data (data_sp,
878                                 m_arch.GetByteOrder(),
879                                 m_arch.GetAddressByteSize());
880             return DecodeInstructions (range.GetBaseAddress(), data, 0, UINT32_MAX, false);
881         }
882     }
883     return 0;
884 }
885 
886 size_t
887 Disassembler::ParseInstructions
888 (
889     const ExecutionContext *exe_ctx,
890     const Address &start,
891     uint32_t num_instructions
892 )
893 {
894     m_instruction_list.Clear();
895 
896     if (exe_ctx == NULL || num_instructions == 0 || !start.IsValid())
897         return 0;
898 
899     Target *target = exe_ctx->GetTargetPtr();
900     // Calculate the max buffer size we will need in order to disassemble
901     const addr_t byte_size = num_instructions * m_arch.GetMaximumOpcodeByteSize();
902 
903     if (target == NULL || byte_size == 0)
904         return 0;
905 
906     DataBufferHeap *heap_buffer = new DataBufferHeap (byte_size, '\0');
907     DataBufferSP data_sp (heap_buffer);
908 
909     Error error;
910     bool prefer_file_cache = true;
911     const size_t bytes_read = target->ReadMemory (start,
912                                                   prefer_file_cache,
913                                                   heap_buffer->GetBytes(),
914                                                   byte_size,
915                                                   error);
916 
917     if (bytes_read == 0)
918         return 0;
919     DataExtractor data (data_sp,
920                         m_arch.GetByteOrder(),
921                         m_arch.GetAddressByteSize());
922 
923     const bool append_instructions = true;
924     DecodeInstructions (start,
925                         data,
926                         0,
927                         num_instructions,
928                         append_instructions);
929 
930     return m_instruction_list.GetSize();
931 }
932 
933 //----------------------------------------------------------------------
934 // Disassembler copy constructor
935 //----------------------------------------------------------------------
936 Disassembler::Disassembler(const ArchSpec& arch) :
937     m_arch (arch),
938     m_instruction_list(),
939     m_base_addr(LLDB_INVALID_ADDRESS)
940 {
941 
942 }
943 
944 //----------------------------------------------------------------------
945 // Destructor
946 //----------------------------------------------------------------------
947 Disassembler::~Disassembler()
948 {
949 }
950 
951 InstructionList &
952 Disassembler::GetInstructionList ()
953 {
954     return m_instruction_list;
955 }
956 
957 const InstructionList &
958 Disassembler::GetInstructionList () const
959 {
960     return m_instruction_list;
961 }
962 
963 //----------------------------------------------------------------------
964 // Class PseudoInstruction
965 //----------------------------------------------------------------------
966 PseudoInstruction::PseudoInstruction () :
967     Instruction (Address(), eAddressClassUnknown),
968     m_description ()
969 {
970 }
971 
972 PseudoInstruction::~PseudoInstruction ()
973 {
974 }
975 
976 void
977 PseudoInstruction::Dump (lldb_private::Stream *s,
978                         uint32_t max_opcode_byte_size,
979                         bool show_address,
980                         bool show_bytes,
981                         const lldb_private::ExecutionContext* exe_ctx,
982                         bool raw)
983 {
984     if (!s)
985         return;
986 
987     if (show_bytes)
988         m_opcode.Dump (s, max_opcode_byte_size);
989 
990     if (m_description.size() > 0)
991         s->Printf ("%s", m_description.c_str());
992     else
993         s->Printf ("<unknown>");
994 
995 }
996 
997 bool
998 PseudoInstruction::DoesBranch () const
999 {
1000     // This is NOT a valid question for a pseudo instruction.
1001     return false;
1002 }
1003 
1004 size_t
1005 PseudoInstruction::Decode (const lldb_private::Disassembler &disassembler,
1006                            const lldb_private::DataExtractor &data,
1007                            uint32_t data_offset)
1008 {
1009     return m_opcode.GetByteSize();
1010 }
1011 
1012 
1013 void
1014 PseudoInstruction::SetOpcode (size_t opcode_size, void *opcode_data)
1015 {
1016     if (!opcode_data)
1017         return;
1018 
1019     switch (opcode_size)
1020     {
1021         case 8:
1022         {
1023             uint8_t value8 = *((uint8_t *) opcode_data);
1024             m_opcode.SetOpcode8 (value8);
1025             break;
1026          }
1027         case 16:
1028         {
1029             uint16_t value16 = *((uint16_t *) opcode_data);
1030             m_opcode.SetOpcode16 (value16);
1031             break;
1032          }
1033         case 32:
1034         {
1035             uint32_t value32 = *((uint32_t *) opcode_data);
1036             m_opcode.SetOpcode32 (value32);
1037             break;
1038          }
1039         case 64:
1040         {
1041             uint64_t value64 = *((uint64_t *) opcode_data);
1042             m_opcode.SetOpcode64 (value64);
1043             break;
1044          }
1045         default:
1046             break;
1047     }
1048 }
1049 
1050 void
1051 PseudoInstruction::SetDescription (const char *description)
1052 {
1053     if (description && strlen (description) > 0)
1054         m_description = description;
1055 }
1056