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