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