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