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