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