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