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