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