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