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