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