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