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