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