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