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