1254721Semaste//===-- Disassembler.cpp ----------------------------------------*- C++ -*-===//
2254721Semaste//
3254721Semaste//                     The LLVM Compiler Infrastructure
4254721Semaste//
5254721Semaste// This file is distributed under the University of Illinois Open Source
6254721Semaste// License. See LICENSE.TXT for details.
7254721Semaste//
8254721Semaste//===----------------------------------------------------------------------===//
9254721Semaste
10254721Semaste#include "lldb/lldb-python.h"
11254721Semaste
12254721Semaste#include "lldb/Core/Disassembler.h"
13254721Semaste
14254721Semaste// C Includes
15254721Semaste// C++ Includes
16254721Semaste// Other libraries and framework includes
17254721Semaste// Project includes
18254721Semaste#include "lldb/lldb-private.h"
19254721Semaste#include "lldb/Core/Error.h"
20254721Semaste#include "lldb/Core/DataBufferHeap.h"
21254721Semaste#include "lldb/Core/DataExtractor.h"
22254721Semaste#include "lldb/Core/Debugger.h"
23254721Semaste#include "lldb/Core/EmulateInstruction.h"
24254721Semaste#include "lldb/Core/Module.h"
25254721Semaste#include "lldb/Core/PluginManager.h"
26254721Semaste#include "lldb/Core/RegularExpression.h"
27254721Semaste#include "lldb/Core/Timer.h"
28254721Semaste#include "lldb/Interpreter/OptionValue.h"
29254721Semaste#include "lldb/Interpreter/OptionValueArray.h"
30254721Semaste#include "lldb/Interpreter/OptionValueDictionary.h"
31254721Semaste#include "lldb/Interpreter/OptionValueString.h"
32254721Semaste#include "lldb/Interpreter/OptionValueUInt64.h"
33254721Semaste#include "lldb/Symbol/ClangNamespaceDecl.h"
34254721Semaste#include "lldb/Symbol/Function.h"
35254721Semaste#include "lldb/Symbol/ObjectFile.h"
36254721Semaste#include "lldb/Target/ExecutionContext.h"
37254721Semaste#include "lldb/Target/Process.h"
38269024Semaste#include "lldb/Target/SectionLoadList.h"
39254721Semaste#include "lldb/Target/StackFrame.h"
40254721Semaste#include "lldb/Target/Target.h"
41254721Semaste
42254721Semaste#define DEFAULT_DISASM_BYTE_SIZE 32
43254721Semaste
44254721Semasteusing namespace lldb;
45254721Semasteusing namespace lldb_private;
46254721Semaste
47254721Semaste
48254721SemasteDisassemblerSP
49254721SemasteDisassembler::FindPlugin (const ArchSpec &arch, const char *flavor, const char *plugin_name)
50254721Semaste{
51254721Semaste    Timer scoped_timer (__PRETTY_FUNCTION__,
52254721Semaste                        "Disassembler::FindPlugin (arch = %s, plugin_name = %s)",
53254721Semaste                        arch.GetArchitectureName(),
54254721Semaste                        plugin_name);
55254721Semaste
56254721Semaste    DisassemblerCreateInstance create_callback = NULL;
57254721Semaste
58254721Semaste    if (plugin_name)
59254721Semaste    {
60254721Semaste        ConstString const_plugin_name (plugin_name);
61254721Semaste        create_callback = PluginManager::GetDisassemblerCreateCallbackForPluginName (const_plugin_name);
62254721Semaste        if (create_callback)
63254721Semaste        {
64254721Semaste            DisassemblerSP disassembler_sp(create_callback(arch, flavor));
65254721Semaste
66254721Semaste            if (disassembler_sp.get())
67254721Semaste                return disassembler_sp;
68254721Semaste        }
69254721Semaste    }
70254721Semaste    else
71254721Semaste    {
72254721Semaste        for (uint32_t idx = 0; (create_callback = PluginManager::GetDisassemblerCreateCallbackAtIndex(idx)) != NULL; ++idx)
73254721Semaste        {
74254721Semaste            DisassemblerSP disassembler_sp(create_callback(arch, flavor));
75254721Semaste
76254721Semaste            if (disassembler_sp.get())
77254721Semaste                return disassembler_sp;
78254721Semaste        }
79254721Semaste    }
80254721Semaste    return DisassemblerSP();
81254721Semaste}
82254721Semaste
83254721SemasteDisassemblerSP
84254721SemasteDisassembler::FindPluginForTarget(const TargetSP target_sp, const ArchSpec &arch, const char *flavor, const char *plugin_name)
85254721Semaste{
86254721Semaste    if (target_sp && flavor == NULL)
87254721Semaste    {
88254721Semaste        // FIXME - we don't have the mechanism in place to do per-architecture settings.  But since we know that for now
89254721Semaste        // we only support flavors on x86 & x86_64,
90254721Semaste        if (arch.GetTriple().getArch() == llvm::Triple::x86
91254721Semaste            || arch.GetTriple().getArch() == llvm::Triple::x86_64)
92254721Semaste           flavor = target_sp->GetDisassemblyFlavor();
93254721Semaste    }
94254721Semaste    return FindPlugin(arch, flavor, plugin_name);
95254721Semaste}
96254721Semaste
97254721Semaste
98254721Semastestatic void
99254721SemasteResolveAddress (const ExecutionContext &exe_ctx,
100254721Semaste                const Address &addr,
101254721Semaste                Address &resolved_addr)
102254721Semaste{
103254721Semaste    if (!addr.IsSectionOffset())
104254721Semaste    {
105254721Semaste        // If we weren't passed in a section offset address range,
106254721Semaste        // try and resolve it to something
107254721Semaste        Target *target = exe_ctx.GetTargetPtr();
108254721Semaste        if (target)
109254721Semaste        {
110254721Semaste            if (target->GetSectionLoadList().IsEmpty())
111254721Semaste            {
112254721Semaste                target->GetImages().ResolveFileAddress (addr.GetOffset(), resolved_addr);
113254721Semaste            }
114254721Semaste            else
115254721Semaste            {
116254721Semaste                target->GetSectionLoadList().ResolveLoadAddress (addr.GetOffset(), resolved_addr);
117254721Semaste            }
118254721Semaste            // We weren't able to resolve the address, just treat it as a
119254721Semaste            // raw address
120254721Semaste            if (resolved_addr.IsValid())
121254721Semaste                return;
122254721Semaste        }
123254721Semaste    }
124254721Semaste    resolved_addr = addr;
125254721Semaste}
126254721Semaste
127254721Semastesize_t
128254721SemasteDisassembler::Disassemble
129254721Semaste(
130254721Semaste    Debugger &debugger,
131254721Semaste    const ArchSpec &arch,
132254721Semaste    const char *plugin_name,
133254721Semaste    const char *flavor,
134254721Semaste    const ExecutionContext &exe_ctx,
135254721Semaste    SymbolContextList &sc_list,
136254721Semaste    uint32_t num_instructions,
137254721Semaste    uint32_t num_mixed_context_lines,
138254721Semaste    uint32_t options,
139254721Semaste    Stream &strm
140254721Semaste)
141254721Semaste{
142254721Semaste    size_t success_count = 0;
143254721Semaste    const size_t count = sc_list.GetSize();
144254721Semaste    SymbolContext sc;
145254721Semaste    AddressRange range;
146254721Semaste    const uint32_t scope = eSymbolContextBlock | eSymbolContextFunction | eSymbolContextSymbol;
147254721Semaste    const bool use_inline_block_range = true;
148254721Semaste    for (size_t i=0; i<count; ++i)
149254721Semaste    {
150254721Semaste        if (sc_list.GetContextAtIndex(i, sc) == false)
151254721Semaste            break;
152254721Semaste        for (uint32_t range_idx = 0; sc.GetAddressRange(scope, range_idx, use_inline_block_range, range); ++range_idx)
153254721Semaste        {
154254721Semaste            if (Disassemble (debugger,
155254721Semaste                             arch,
156254721Semaste                             plugin_name,
157254721Semaste                             flavor,
158254721Semaste                             exe_ctx,
159254721Semaste                             range,
160254721Semaste                             num_instructions,
161254721Semaste                             num_mixed_context_lines,
162254721Semaste                             options,
163254721Semaste                             strm))
164254721Semaste            {
165254721Semaste                ++success_count;
166254721Semaste                strm.EOL();
167254721Semaste            }
168254721Semaste        }
169254721Semaste    }
170254721Semaste    return success_count;
171254721Semaste}
172254721Semaste
173254721Semastebool
174254721SemasteDisassembler::Disassemble
175254721Semaste(
176254721Semaste    Debugger &debugger,
177254721Semaste    const ArchSpec &arch,
178254721Semaste    const char *plugin_name,
179254721Semaste    const char *flavor,
180254721Semaste    const ExecutionContext &exe_ctx,
181254721Semaste    const ConstString &name,
182254721Semaste    Module *module,
183254721Semaste    uint32_t num_instructions,
184254721Semaste    uint32_t num_mixed_context_lines,
185254721Semaste    uint32_t options,
186254721Semaste    Stream &strm
187254721Semaste)
188254721Semaste{
189254721Semaste    SymbolContextList sc_list;
190254721Semaste    if (name)
191254721Semaste    {
192254721Semaste        const bool include_symbols = true;
193254721Semaste        const bool include_inlines = true;
194254721Semaste        if (module)
195254721Semaste        {
196254721Semaste            module->FindFunctions (name,
197254721Semaste                                   NULL,
198254721Semaste                                   eFunctionNameTypeAuto,
199254721Semaste                                   include_symbols,
200254721Semaste                                   include_inlines,
201254721Semaste                                   true,
202254721Semaste                                   sc_list);
203254721Semaste        }
204254721Semaste        else if (exe_ctx.GetTargetPtr())
205254721Semaste        {
206254721Semaste            exe_ctx.GetTargetPtr()->GetImages().FindFunctions (name,
207254721Semaste                                                               eFunctionNameTypeAuto,
208254721Semaste                                                               include_symbols,
209254721Semaste                                                               include_inlines,
210254721Semaste                                                               false,
211254721Semaste                                                               sc_list);
212254721Semaste        }
213254721Semaste    }
214254721Semaste
215254721Semaste    if (sc_list.GetSize ())
216254721Semaste    {
217254721Semaste        return Disassemble (debugger,
218254721Semaste                            arch,
219254721Semaste                            plugin_name,
220254721Semaste                            flavor,
221254721Semaste                            exe_ctx,
222254721Semaste                            sc_list,
223254721Semaste                            num_instructions,
224254721Semaste                            num_mixed_context_lines,
225254721Semaste                            options,
226254721Semaste                            strm);
227254721Semaste    }
228254721Semaste    return false;
229254721Semaste}
230254721Semaste
231254721Semaste
232254721Semastelldb::DisassemblerSP
233254721SemasteDisassembler::DisassembleRange
234254721Semaste(
235254721Semaste    const ArchSpec &arch,
236254721Semaste    const char *plugin_name,
237254721Semaste    const char *flavor,
238254721Semaste    const ExecutionContext &exe_ctx,
239263363Semaste    const AddressRange &range,
240263363Semaste    bool prefer_file_cache
241254721Semaste)
242254721Semaste{
243254721Semaste    lldb::DisassemblerSP disasm_sp;
244254721Semaste    if (range.GetByteSize() > 0 && range.GetBaseAddress().IsValid())
245254721Semaste    {
246254721Semaste        disasm_sp = Disassembler::FindPluginForTarget(exe_ctx.GetTargetSP(), arch, flavor, plugin_name);
247254721Semaste
248254721Semaste        if (disasm_sp)
249254721Semaste        {
250254721Semaste            size_t bytes_disassembled = disasm_sp->ParseInstructions (&exe_ctx, range, NULL, prefer_file_cache);
251254721Semaste            if (bytes_disassembled == 0)
252254721Semaste                disasm_sp.reset();
253254721Semaste        }
254254721Semaste    }
255254721Semaste    return disasm_sp;
256254721Semaste}
257254721Semaste
258254721Semastelldb::DisassemblerSP
259254721SemasteDisassembler::DisassembleBytes (const ArchSpec &arch,
260254721Semaste                                const char *plugin_name,
261254721Semaste                                const char *flavor,
262254721Semaste                                const Address &start,
263254721Semaste                                const void *src,
264254721Semaste                                size_t src_len,
265254721Semaste                                uint32_t num_instructions,
266254721Semaste                                bool data_from_file)
267254721Semaste{
268254721Semaste    lldb::DisassemblerSP disasm_sp;
269254721Semaste
270254721Semaste    if (src)
271254721Semaste    {
272254721Semaste        disasm_sp = Disassembler::FindPlugin(arch, flavor, plugin_name);
273254721Semaste
274254721Semaste        if (disasm_sp)
275254721Semaste        {
276254721Semaste            DataExtractor data(src, src_len, arch.GetByteOrder(), arch.GetAddressByteSize());
277254721Semaste
278254721Semaste            (void)disasm_sp->DecodeInstructions (start,
279254721Semaste                                                 data,
280254721Semaste                                                 0,
281254721Semaste                                                 num_instructions,
282254721Semaste                                                 false,
283254721Semaste                                                 data_from_file);
284254721Semaste        }
285254721Semaste    }
286254721Semaste
287254721Semaste    return disasm_sp;
288254721Semaste}
289254721Semaste
290254721Semaste
291254721Semastebool
292254721SemasteDisassembler::Disassemble
293254721Semaste(
294254721Semaste    Debugger &debugger,
295254721Semaste    const ArchSpec &arch,
296254721Semaste    const char *plugin_name,
297254721Semaste    const char *flavor,
298254721Semaste    const ExecutionContext &exe_ctx,
299254721Semaste    const AddressRange &disasm_range,
300254721Semaste    uint32_t num_instructions,
301254721Semaste    uint32_t num_mixed_context_lines,
302254721Semaste    uint32_t options,
303254721Semaste    Stream &strm
304254721Semaste)
305254721Semaste{
306254721Semaste    if (disasm_range.GetByteSize())
307254721Semaste    {
308254721Semaste        lldb::DisassemblerSP disasm_sp (Disassembler::FindPluginForTarget(exe_ctx.GetTargetSP(), arch, flavor, plugin_name));
309254721Semaste
310254721Semaste        if (disasm_sp.get())
311254721Semaste        {
312254721Semaste            AddressRange range;
313254721Semaste            ResolveAddress (exe_ctx, disasm_range.GetBaseAddress(), range.GetBaseAddress());
314254721Semaste            range.SetByteSize (disasm_range.GetByteSize());
315254721Semaste            const bool prefer_file_cache = false;
316254721Semaste            size_t bytes_disassembled = disasm_sp->ParseInstructions (&exe_ctx, range, &strm, prefer_file_cache);
317254721Semaste            if (bytes_disassembled == 0)
318254721Semaste                return false;
319254721Semaste
320254721Semaste            bool result = PrintInstructions (disasm_sp.get(),
321254721Semaste                                             debugger,
322254721Semaste                                             arch,
323254721Semaste                                             exe_ctx,
324254721Semaste                                             num_instructions,
325254721Semaste                                             num_mixed_context_lines,
326254721Semaste                                             options,
327254721Semaste                                             strm);
328254721Semaste
329254721Semaste            // FIXME: The DisassemblerLLVMC has a reference cycle and won't go away if it has any active instructions.
330254721Semaste            // I'll fix that but for now, just clear the list and it will go away nicely.
331254721Semaste            disasm_sp->GetInstructionList().Clear();
332254721Semaste            return result;
333254721Semaste        }
334254721Semaste    }
335254721Semaste    return false;
336254721Semaste}
337254721Semaste
338254721Semastebool
339254721SemasteDisassembler::Disassemble
340254721Semaste(
341254721Semaste    Debugger &debugger,
342254721Semaste    const ArchSpec &arch,
343254721Semaste    const char *plugin_name,
344254721Semaste    const char *flavor,
345254721Semaste    const ExecutionContext &exe_ctx,
346254721Semaste    const Address &start_address,
347254721Semaste    uint32_t num_instructions,
348254721Semaste    uint32_t num_mixed_context_lines,
349254721Semaste    uint32_t options,
350254721Semaste    Stream &strm
351254721Semaste)
352254721Semaste{
353254721Semaste    if (num_instructions > 0)
354254721Semaste    {
355254721Semaste        lldb::DisassemblerSP disasm_sp (Disassembler::FindPluginForTarget(exe_ctx.GetTargetSP(),
356254721Semaste                                                                          arch,
357254721Semaste                                                                          flavor,
358254721Semaste                                                                          plugin_name));
359254721Semaste        if (disasm_sp.get())
360254721Semaste        {
361254721Semaste            Address addr;
362254721Semaste            ResolveAddress (exe_ctx, start_address, addr);
363254721Semaste            const bool prefer_file_cache = false;
364254721Semaste            size_t bytes_disassembled = disasm_sp->ParseInstructions (&exe_ctx,
365254721Semaste                                                                      addr,
366254721Semaste                                                                      num_instructions,
367254721Semaste                                                                      prefer_file_cache);
368254721Semaste            if (bytes_disassembled == 0)
369254721Semaste                return false;
370254721Semaste            bool result = PrintInstructions (disasm_sp.get(),
371254721Semaste                                             debugger,
372254721Semaste                                             arch,
373254721Semaste                                             exe_ctx,
374254721Semaste                                             num_instructions,
375254721Semaste                                             num_mixed_context_lines,
376254721Semaste                                             options,
377254721Semaste                                             strm);
378254721Semaste
379254721Semaste            // FIXME: The DisassemblerLLVMC has a reference cycle and won't go away if it has any active instructions.
380254721Semaste            // I'll fix that but for now, just clear the list and it will go away nicely.
381254721Semaste            disasm_sp->GetInstructionList().Clear();
382254721Semaste            return result;
383254721Semaste        }
384254721Semaste    }
385254721Semaste    return false;
386254721Semaste}
387254721Semaste
388254721Semastebool
389254721SemasteDisassembler::PrintInstructions
390254721Semaste(
391254721Semaste    Disassembler *disasm_ptr,
392254721Semaste    Debugger &debugger,
393254721Semaste    const ArchSpec &arch,
394254721Semaste    const ExecutionContext &exe_ctx,
395254721Semaste    uint32_t num_instructions,
396254721Semaste    uint32_t num_mixed_context_lines,
397254721Semaste    uint32_t options,
398254721Semaste    Stream &strm
399254721Semaste)
400254721Semaste{
401254721Semaste    // We got some things disassembled...
402254721Semaste    size_t num_instructions_found = disasm_ptr->GetInstructionList().GetSize();
403254721Semaste
404254721Semaste    if (num_instructions > 0 && num_instructions < num_instructions_found)
405254721Semaste        num_instructions_found = num_instructions;
406254721Semaste
407254721Semaste    const uint32_t max_opcode_byte_size = disasm_ptr->GetInstructionList().GetMaxOpcocdeByteSize ();
408254721Semaste    uint32_t offset = 0;
409254721Semaste    SymbolContext sc;
410254721Semaste    SymbolContext prev_sc;
411254721Semaste    AddressRange sc_range;
412254721Semaste    const Address *pc_addr_ptr = NULL;
413254721Semaste    ExecutionContextScope *exe_scope = exe_ctx.GetBestExecutionContextScope();
414254721Semaste    StackFrame *frame = exe_ctx.GetFramePtr();
415254721Semaste
416254721Semaste    TargetSP target_sp (exe_ctx.GetTargetSP());
417254721Semaste    SourceManager &source_manager = target_sp ? target_sp->GetSourceManager() : debugger.GetSourceManager();
418254721Semaste
419254721Semaste    if (frame)
420254721Semaste        pc_addr_ptr = &frame->GetFrameCodeAddress();
421254721Semaste    const uint32_t scope = eSymbolContextLineEntry | eSymbolContextFunction | eSymbolContextSymbol;
422254721Semaste    const bool use_inline_block_range = false;
423254721Semaste    for (size_t i=0; i<num_instructions_found; ++i)
424254721Semaste    {
425254721Semaste        Instruction *inst = disasm_ptr->GetInstructionList().GetInstructionAtIndex (i).get();
426254721Semaste        if (inst)
427254721Semaste        {
428254721Semaste            const Address &addr = inst->GetAddress();
429254721Semaste            const bool inst_is_at_pc = pc_addr_ptr && addr == *pc_addr_ptr;
430254721Semaste
431254721Semaste            prev_sc = sc;
432254721Semaste
433254721Semaste            ModuleSP module_sp (addr.GetModule());
434254721Semaste            if (module_sp)
435254721Semaste            {
436254721Semaste                uint32_t resolved_mask = module_sp->ResolveSymbolContextForAddress(addr, eSymbolContextEverything, sc);
437254721Semaste                if (resolved_mask)
438254721Semaste                {
439254721Semaste                    if (num_mixed_context_lines)
440254721Semaste                    {
441254721Semaste                        if (!sc_range.ContainsFileAddress (addr))
442254721Semaste                        {
443254721Semaste                            sc.GetAddressRange (scope, 0, use_inline_block_range, sc_range);
444254721Semaste
445254721Semaste                            if (sc != prev_sc)
446254721Semaste                            {
447254721Semaste                                if (offset != 0)
448254721Semaste                                    strm.EOL();
449254721Semaste
450254721Semaste                                sc.DumpStopContext(&strm, exe_ctx.GetProcessPtr(), addr, false, true, false);
451254721Semaste                                strm.EOL();
452254721Semaste
453254721Semaste                                if (sc.comp_unit && sc.line_entry.IsValid())
454254721Semaste                                {
455254721Semaste                                    source_manager.DisplaySourceLinesWithLineNumbers (sc.line_entry.file,
456254721Semaste                                                                                      sc.line_entry.line,
457254721Semaste                                                                                      num_mixed_context_lines,
458254721Semaste                                                                                      num_mixed_context_lines,
459254721Semaste                                                                                      ((inst_is_at_pc && (options & eOptionMarkPCSourceLine)) ? "->" : ""),
460254721Semaste                                                                                      &strm);
461254721Semaste                                }
462254721Semaste                            }
463254721Semaste                        }
464254721Semaste                    }
465254721Semaste                    else if ((sc.function || sc.symbol) && (sc.function != prev_sc.function || sc.symbol != prev_sc.symbol))
466254721Semaste                    {
467254721Semaste                        if (prev_sc.function || prev_sc.symbol)
468254721Semaste                            strm.EOL();
469254721Semaste
470254721Semaste                        bool show_fullpaths = false;
471254721Semaste                        bool show_module = true;
472254721Semaste                        bool show_inlined_frames = true;
473254721Semaste                        sc.DumpStopContext (&strm,
474254721Semaste                                            exe_scope,
475254721Semaste                                            addr,
476254721Semaste                                            show_fullpaths,
477254721Semaste                                            show_module,
478254721Semaste                                            show_inlined_frames);
479254721Semaste
480254721Semaste                        strm << ":\n";
481254721Semaste                    }
482254721Semaste                }
483254721Semaste                else
484254721Semaste                {
485254721Semaste                    sc.Clear(true);
486254721Semaste                }
487254721Semaste            }
488254721Semaste
489254721Semaste            if ((options & eOptionMarkPCAddress) && pc_addr_ptr)
490254721Semaste            {
491254721Semaste                strm.PutCString(inst_is_at_pc ? "-> " : "   ");
492254721Semaste            }
493254721Semaste            const bool show_bytes = (options & eOptionShowBytes) != 0;
494254721Semaste            inst->Dump(&strm, max_opcode_byte_size, true, show_bytes, &exe_ctx);
495254721Semaste            strm.EOL();
496254721Semaste        }
497254721Semaste        else
498254721Semaste        {
499254721Semaste            break;
500254721Semaste        }
501254721Semaste    }
502254721Semaste
503254721Semaste    return true;
504254721Semaste}
505254721Semaste
506254721Semaste
507254721Semastebool
508254721SemasteDisassembler::Disassemble
509254721Semaste(
510254721Semaste    Debugger &debugger,
511254721Semaste    const ArchSpec &arch,
512254721Semaste    const char *plugin_name,
513254721Semaste    const char *flavor,
514254721Semaste    const ExecutionContext &exe_ctx,
515254721Semaste    uint32_t num_instructions,
516254721Semaste    uint32_t num_mixed_context_lines,
517254721Semaste    uint32_t options,
518254721Semaste    Stream &strm
519254721Semaste)
520254721Semaste{
521254721Semaste    AddressRange range;
522254721Semaste    StackFrame *frame = exe_ctx.GetFramePtr();
523254721Semaste    if (frame)
524254721Semaste    {
525254721Semaste        SymbolContext sc(frame->GetSymbolContext(eSymbolContextFunction | eSymbolContextSymbol));
526254721Semaste        if (sc.function)
527254721Semaste        {
528254721Semaste            range = sc.function->GetAddressRange();
529254721Semaste        }
530254721Semaste        else if (sc.symbol && sc.symbol->ValueIsAddress())
531254721Semaste        {
532254721Semaste            range.GetBaseAddress() = sc.symbol->GetAddress();
533254721Semaste            range.SetByteSize (sc.symbol->GetByteSize());
534254721Semaste        }
535254721Semaste        else
536254721Semaste        {
537254721Semaste            range.GetBaseAddress() = frame->GetFrameCodeAddress();
538254721Semaste        }
539254721Semaste
540254721Semaste        if (range.GetBaseAddress().IsValid() && range.GetByteSize() == 0)
541254721Semaste            range.SetByteSize (DEFAULT_DISASM_BYTE_SIZE);
542254721Semaste    }
543254721Semaste
544254721Semaste    return Disassemble (debugger,
545254721Semaste                        arch,
546254721Semaste                        plugin_name,
547254721Semaste                        flavor,
548254721Semaste                        exe_ctx,
549254721Semaste                        range,
550254721Semaste                        num_instructions,
551254721Semaste                        num_mixed_context_lines,
552254721Semaste                        options,
553254721Semaste                        strm);
554254721Semaste}
555254721Semaste
556254721SemasteInstruction::Instruction(const Address &address, AddressClass addr_class) :
557254721Semaste    m_address (address),
558254721Semaste    m_address_class (addr_class),
559254721Semaste    m_opcode(),
560254721Semaste    m_calculated_strings(false)
561254721Semaste{
562254721Semaste}
563254721Semaste
564254721SemasteInstruction::~Instruction()
565254721Semaste{
566254721Semaste}
567254721Semaste
568254721SemasteAddressClass
569254721SemasteInstruction::GetAddressClass ()
570254721Semaste{
571254721Semaste    if (m_address_class == eAddressClassInvalid)
572254721Semaste        m_address_class = m_address.GetAddressClass();
573254721Semaste    return m_address_class;
574254721Semaste}
575254721Semaste
576254721Semastevoid
577254721SemasteInstruction::Dump (lldb_private::Stream *s,
578254721Semaste                   uint32_t max_opcode_byte_size,
579254721Semaste                   bool show_address,
580254721Semaste                   bool show_bytes,
581254721Semaste                   const ExecutionContext* exe_ctx)
582254721Semaste{
583254721Semaste    size_t opcode_column_width = 7;
584254721Semaste    const size_t operand_column_width = 25;
585254721Semaste
586254721Semaste    CalculateMnemonicOperandsAndCommentIfNeeded (exe_ctx);
587254721Semaste
588254721Semaste    StreamString ss;
589254721Semaste
590254721Semaste    if (show_address)
591254721Semaste    {
592254721Semaste        m_address.Dump(&ss,
593254721Semaste                       exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL,
594254721Semaste                       Address::DumpStyleLoadAddress,
595254721Semaste                       Address::DumpStyleModuleWithFileAddress,
596254721Semaste                       0);
597254721Semaste
598254721Semaste        ss.PutCString(":  ");
599254721Semaste    }
600254721Semaste
601254721Semaste    if (show_bytes)
602254721Semaste    {
603254721Semaste        if (m_opcode.GetType() == Opcode::eTypeBytes)
604254721Semaste        {
605254721Semaste            // x86_64 and i386 are the only ones that use bytes right now so
606254721Semaste            // pad out the byte dump to be able to always show 15 bytes (3 chars each)
607254721Semaste            // plus a space
608254721Semaste            if (max_opcode_byte_size > 0)
609254721Semaste                m_opcode.Dump (&ss, max_opcode_byte_size * 3 + 1);
610254721Semaste            else
611254721Semaste                m_opcode.Dump (&ss, 15 * 3 + 1);
612254721Semaste        }
613254721Semaste        else
614254721Semaste        {
615263363Semaste            // Else, we have ARM or MIPS which can show up to a uint32_t
616263363Semaste            // 0x00000000 (10 spaces) plus two for padding...
617254721Semaste            if (max_opcode_byte_size > 0)
618254721Semaste                m_opcode.Dump (&ss, max_opcode_byte_size * 3 + 1);
619254721Semaste            else
620254721Semaste                m_opcode.Dump (&ss, 12);
621254721Semaste        }
622254721Semaste    }
623254721Semaste
624254721Semaste    const size_t opcode_pos = ss.GetSize();
625254721Semaste
626254721Semaste    // The default opcode size of 7 characters is plenty for most architectures
627254721Semaste    // but some like arm can pull out the occasional vqrshrun.s16.  We won't get
628254721Semaste    // consistent column spacing in these cases, unfortunately.
629254721Semaste    if (m_opcode_name.length() >= opcode_column_width)
630254721Semaste    {
631254721Semaste        opcode_column_width = m_opcode_name.length() + 1;
632254721Semaste    }
633254721Semaste
634254721Semaste    ss.PutCString (m_opcode_name.c_str());
635254721Semaste    ss.FillLastLineToColumn (opcode_pos + opcode_column_width, ' ');
636254721Semaste    ss.PutCString (m_mnemonics.c_str());
637254721Semaste
638254721Semaste    if (!m_comment.empty())
639254721Semaste    {
640254721Semaste        ss.FillLastLineToColumn (opcode_pos + opcode_column_width + operand_column_width, ' ');
641254721Semaste        ss.PutCString (" ; ");
642254721Semaste        ss.PutCString (m_comment.c_str());
643254721Semaste    }
644254721Semaste    s->Write (ss.GetData(), ss.GetSize());
645254721Semaste}
646254721Semaste
647254721Semastebool
648254721SemasteInstruction::DumpEmulation (const ArchSpec &arch)
649254721Semaste{
650254721Semaste	std::unique_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL));
651254721Semaste	if (insn_emulator_ap.get())
652254721Semaste	{
653254721Semaste        insn_emulator_ap->SetInstruction (GetOpcode(), GetAddress(), NULL);
654254721Semaste        return insn_emulator_ap->EvaluateInstruction (0);
655254721Semaste	}
656254721Semaste
657254721Semaste    return false;
658254721Semaste}
659254721Semaste
660254721SemasteOptionValueSP
661254721SemasteInstruction::ReadArray (FILE *in_file, Stream *out_stream, OptionValue::Type data_type)
662254721Semaste{
663254721Semaste    bool done = false;
664254721Semaste    char buffer[1024];
665254721Semaste
666254721Semaste    OptionValueSP option_value_sp (new OptionValueArray (1u << data_type));
667254721Semaste
668254721Semaste    int idx = 0;
669254721Semaste    while (!done)
670254721Semaste    {
671254721Semaste        if (!fgets (buffer, 1023, in_file))
672254721Semaste        {
673254721Semaste            out_stream->Printf ("Instruction::ReadArray:  Error reading file (fgets).\n");
674254721Semaste            option_value_sp.reset ();
675254721Semaste            return option_value_sp;
676254721Semaste        }
677254721Semaste
678254721Semaste        std::string line (buffer);
679254721Semaste
680254721Semaste        size_t len = line.size();
681254721Semaste        if (line[len-1] == '\n')
682254721Semaste        {
683254721Semaste            line[len-1] = '\0';
684254721Semaste            line.resize (len-1);
685254721Semaste        }
686254721Semaste
687254721Semaste        if ((line.size() == 1) && line[0] == ']')
688254721Semaste        {
689254721Semaste            done = true;
690254721Semaste            line.clear();
691254721Semaste        }
692254721Semaste
693254721Semaste        if (line.size() > 0)
694254721Semaste        {
695254721Semaste            std::string value;
696254721Semaste            static RegularExpression g_reg_exp ("^[ \t]*([^ \t]+)[ \t]*$");
697254721Semaste            RegularExpression::Match regex_match(1);
698254721Semaste            bool reg_exp_success = g_reg_exp.Execute (line.c_str(), &regex_match);
699254721Semaste            if (reg_exp_success)
700254721Semaste                regex_match.GetMatchAtIndex (line.c_str(), 1, value);
701254721Semaste            else
702254721Semaste                value = line;
703254721Semaste
704254721Semaste            OptionValueSP data_value_sp;
705254721Semaste            switch (data_type)
706254721Semaste            {
707254721Semaste            case OptionValue::eTypeUInt64:
708254721Semaste                data_value_sp.reset (new OptionValueUInt64 (0, 0));
709254721Semaste                data_value_sp->SetValueFromCString (value.c_str());
710254721Semaste                break;
711254721Semaste            // Other types can be added later as needed.
712254721Semaste            default:
713254721Semaste                data_value_sp.reset (new OptionValueString (value.c_str(), ""));
714254721Semaste                break;
715254721Semaste            }
716254721Semaste
717254721Semaste            option_value_sp->GetAsArray()->InsertValue (idx, data_value_sp);
718254721Semaste            ++idx;
719254721Semaste        }
720254721Semaste    }
721254721Semaste
722254721Semaste    return option_value_sp;
723254721Semaste}
724254721Semaste
725254721SemasteOptionValueSP
726254721SemasteInstruction::ReadDictionary (FILE *in_file, Stream *out_stream)
727254721Semaste{
728254721Semaste    bool done = false;
729254721Semaste    char buffer[1024];
730254721Semaste
731254721Semaste    OptionValueSP option_value_sp (new OptionValueDictionary());
732254721Semaste    static ConstString encoding_key ("data_encoding");
733254721Semaste    OptionValue::Type data_type = OptionValue::eTypeInvalid;
734254721Semaste
735254721Semaste
736254721Semaste    while (!done)
737254721Semaste    {
738254721Semaste        // Read the next line in the file
739254721Semaste        if (!fgets (buffer, 1023, in_file))
740254721Semaste        {
741254721Semaste            out_stream->Printf ("Instruction::ReadDictionary: Error reading file (fgets).\n");
742254721Semaste            option_value_sp.reset ();
743254721Semaste            return option_value_sp;
744254721Semaste        }
745254721Semaste
746254721Semaste        // Check to see if the line contains the end-of-dictionary marker ("}")
747254721Semaste        std::string line (buffer);
748254721Semaste
749254721Semaste        size_t len = line.size();
750254721Semaste        if (line[len-1] == '\n')
751254721Semaste        {
752254721Semaste            line[len-1] = '\0';
753254721Semaste            line.resize (len-1);
754254721Semaste        }
755254721Semaste
756254721Semaste        if ((line.size() == 1) && (line[0] == '}'))
757254721Semaste        {
758254721Semaste            done = true;
759254721Semaste            line.clear();
760254721Semaste        }
761254721Semaste
762254721Semaste        // Try to find a key-value pair in the current line and add it to the dictionary.
763254721Semaste        if (line.size() > 0)
764254721Semaste        {
765254721Semaste            static RegularExpression g_reg_exp ("^[ \t]*([a-zA-Z_][a-zA-Z0-9_]*)[ \t]*=[ \t]*(.*)[ \t]*$");
766254721Semaste            RegularExpression::Match regex_match(2);
767254721Semaste
768254721Semaste            bool reg_exp_success = g_reg_exp.Execute (line.c_str(), &regex_match);
769254721Semaste            std::string key;
770254721Semaste            std::string value;
771254721Semaste            if (reg_exp_success)
772254721Semaste            {
773254721Semaste                regex_match.GetMatchAtIndex (line.c_str(), 1, key);
774254721Semaste                regex_match.GetMatchAtIndex (line.c_str(), 2, value);
775254721Semaste            }
776254721Semaste            else
777254721Semaste            {
778254721Semaste                out_stream->Printf ("Instruction::ReadDictionary: Failure executing regular expression.\n");
779254721Semaste                option_value_sp.reset();
780254721Semaste                return option_value_sp;
781254721Semaste            }
782254721Semaste
783254721Semaste            ConstString const_key (key.c_str());
784254721Semaste            // Check value to see if it's the start of an array or dictionary.
785254721Semaste
786254721Semaste            lldb::OptionValueSP value_sp;
787254721Semaste            assert (value.empty() == false);
788254721Semaste            assert (key.empty() == false);
789254721Semaste
790254721Semaste            if (value[0] == '{')
791254721Semaste            {
792254721Semaste                assert (value.size() == 1);
793254721Semaste                // value is a dictionary
794254721Semaste                value_sp = ReadDictionary (in_file, out_stream);
795254721Semaste                if (value_sp.get() == NULL)
796254721Semaste                {
797254721Semaste                    option_value_sp.reset ();
798254721Semaste                    return option_value_sp;
799254721Semaste                }
800254721Semaste            }
801254721Semaste            else if (value[0] == '[')
802254721Semaste            {
803254721Semaste                assert (value.size() == 1);
804254721Semaste                // value is an array
805254721Semaste                value_sp = ReadArray (in_file, out_stream, data_type);
806254721Semaste                if (value_sp.get() == NULL)
807254721Semaste                {
808254721Semaste                    option_value_sp.reset ();
809254721Semaste                    return option_value_sp;
810254721Semaste                }
811254721Semaste                // We've used the data_type to read an array; re-set the type to Invalid
812254721Semaste                data_type = OptionValue::eTypeInvalid;
813254721Semaste            }
814254721Semaste            else if ((value[0] == '0') && (value[1] == 'x'))
815254721Semaste            {
816254721Semaste                value_sp.reset (new OptionValueUInt64 (0, 0));
817254721Semaste                value_sp->SetValueFromCString (value.c_str());
818254721Semaste            }
819254721Semaste            else
820254721Semaste            {
821254721Semaste                size_t len = value.size();
822254721Semaste                if ((value[0] == '"') && (value[len-1] == '"'))
823254721Semaste                    value = value.substr (1, len-2);
824254721Semaste                value_sp.reset (new OptionValueString (value.c_str(), ""));
825254721Semaste            }
826254721Semaste
827254721Semaste
828254721Semaste
829254721Semaste            if (const_key == encoding_key)
830254721Semaste            {
831254721Semaste                // A 'data_encoding=..." is NOT a normal key-value pair; it is meta-data indicating the
832254721Semaste                // data type of an upcoming array (usually the next bit of data to be read in).
833254721Semaste                if (strcmp (value.c_str(), "uint32_t") == 0)
834254721Semaste                    data_type = OptionValue::eTypeUInt64;
835254721Semaste            }
836254721Semaste            else
837254721Semaste                option_value_sp->GetAsDictionary()->SetValueForKey (const_key, value_sp, false);
838254721Semaste        }
839254721Semaste    }
840254721Semaste
841254721Semaste    return option_value_sp;
842254721Semaste}
843254721Semaste
844254721Semastebool
845254721SemasteInstruction::TestEmulation (Stream *out_stream, const char *file_name)
846254721Semaste{
847254721Semaste    if (!out_stream)
848254721Semaste        return false;
849254721Semaste
850254721Semaste    if (!file_name)
851254721Semaste    {
852254721Semaste        out_stream->Printf ("Instruction::TestEmulation:  Missing file_name.");
853254721Semaste        return false;
854254721Semaste    }
855254721Semaste
856254721Semaste    FILE *test_file = fopen (file_name, "r");
857254721Semaste    if (!test_file)
858254721Semaste    {
859254721Semaste        out_stream->Printf ("Instruction::TestEmulation: Attempt to open test file failed.");
860254721Semaste        return false;
861254721Semaste    }
862254721Semaste
863254721Semaste    char buffer[256];
864254721Semaste    if (!fgets (buffer, 255, test_file))
865254721Semaste    {
866254721Semaste        out_stream->Printf ("Instruction::TestEmulation: Error reading first line of test file.\n");
867254721Semaste        fclose (test_file);
868254721Semaste        return false;
869254721Semaste    }
870254721Semaste
871254721Semaste    if (strncmp (buffer, "InstructionEmulationState={", 27) != 0)
872254721Semaste    {
873254721Semaste        out_stream->Printf ("Instructin::TestEmulation: Test file does not contain emulation state dictionary\n");
874254721Semaste        fclose (test_file);
875254721Semaste        return false;
876254721Semaste    }
877254721Semaste
878254721Semaste    // Read all the test information from the test file into an OptionValueDictionary.
879254721Semaste
880254721Semaste    OptionValueSP data_dictionary_sp (ReadDictionary (test_file, out_stream));
881254721Semaste    if (data_dictionary_sp.get() == NULL)
882254721Semaste    {
883254721Semaste        out_stream->Printf ("Instruction::TestEmulation:  Error reading Dictionary Object.\n");
884254721Semaste        fclose (test_file);
885254721Semaste        return false;
886254721Semaste    }
887254721Semaste
888254721Semaste    fclose (test_file);
889254721Semaste
890254721Semaste    OptionValueDictionary *data_dictionary = data_dictionary_sp->GetAsDictionary();
891254721Semaste    static ConstString description_key ("assembly_string");
892254721Semaste    static ConstString triple_key ("triple");
893254721Semaste
894254721Semaste    OptionValueSP value_sp = data_dictionary->GetValueForKey (description_key);
895254721Semaste
896254721Semaste    if (value_sp.get() == NULL)
897254721Semaste    {
898254721Semaste        out_stream->Printf ("Instruction::TestEmulation:  Test file does not contain description string.\n");
899254721Semaste        return false;
900254721Semaste    }
901254721Semaste
902254721Semaste    SetDescription (value_sp->GetStringValue());
903254721Semaste
904254721Semaste
905254721Semaste    value_sp = data_dictionary->GetValueForKey (triple_key);
906254721Semaste    if (value_sp.get() == NULL)
907254721Semaste    {
908254721Semaste        out_stream->Printf ("Instruction::TestEmulation: Test file does not contain triple.\n");
909254721Semaste        return false;
910254721Semaste    }
911254721Semaste
912254721Semaste    ArchSpec arch;
913254721Semaste    arch.SetTriple (llvm::Triple (value_sp->GetStringValue()));
914254721Semaste
915254721Semaste    bool success = false;
916254721Semaste    std::unique_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL));
917254721Semaste    if (insn_emulator_ap.get())
918254721Semaste        success = insn_emulator_ap->TestEmulation (out_stream, arch, data_dictionary);
919254721Semaste
920254721Semaste    if (success)
921254721Semaste        out_stream->Printf ("Emulation test succeeded.");
922254721Semaste    else
923254721Semaste        out_stream->Printf ("Emulation test failed.");
924254721Semaste
925254721Semaste    return success;
926254721Semaste}
927254721Semaste
928254721Semastebool
929254721SemasteInstruction::Emulate (const ArchSpec &arch,
930254721Semaste                      uint32_t evaluate_options,
931254721Semaste                      void *baton,
932254721Semaste                      EmulateInstruction::ReadMemoryCallback read_mem_callback,
933254721Semaste                      EmulateInstruction::WriteMemoryCallback write_mem_callback,
934254721Semaste                      EmulateInstruction::ReadRegisterCallback read_reg_callback,
935254721Semaste                      EmulateInstruction::WriteRegisterCallback write_reg_callback)
936254721Semaste{
937254721Semaste	std::unique_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL));
938254721Semaste	if (insn_emulator_ap.get())
939254721Semaste	{
940254721Semaste		insn_emulator_ap->SetBaton (baton);
941254721Semaste		insn_emulator_ap->SetCallbacks (read_mem_callback, write_mem_callback, read_reg_callback, write_reg_callback);
942254721Semaste        insn_emulator_ap->SetInstruction (GetOpcode(), GetAddress(), NULL);
943254721Semaste        return insn_emulator_ap->EvaluateInstruction (evaluate_options);
944254721Semaste	}
945254721Semaste
946254721Semaste    return false;
947254721Semaste}
948254721Semaste
949254721Semaste
950254721Semasteuint32_t
951254721SemasteInstruction::GetData (DataExtractor &data)
952254721Semaste{
953254721Semaste    return m_opcode.GetData(data);
954254721Semaste}
955254721Semaste
956254721SemasteInstructionList::InstructionList() :
957254721Semaste    m_instructions()
958254721Semaste{
959254721Semaste}
960254721Semaste
961254721SemasteInstructionList::~InstructionList()
962254721Semaste{
963254721Semaste}
964254721Semaste
965254721Semastesize_t
966254721SemasteInstructionList::GetSize() const
967254721Semaste{
968254721Semaste    return m_instructions.size();
969254721Semaste}
970254721Semaste
971254721Semasteuint32_t
972254721SemasteInstructionList::GetMaxOpcocdeByteSize () const
973254721Semaste{
974254721Semaste    uint32_t max_inst_size = 0;
975254721Semaste    collection::const_iterator pos, end;
976254721Semaste    for (pos = m_instructions.begin(), end = m_instructions.end();
977254721Semaste         pos != end;
978254721Semaste         ++pos)
979254721Semaste    {
980254721Semaste        uint32_t inst_size = (*pos)->GetOpcode().GetByteSize();
981254721Semaste        if (max_inst_size < inst_size)
982254721Semaste            max_inst_size = inst_size;
983254721Semaste    }
984254721Semaste    return max_inst_size;
985254721Semaste}
986254721Semaste
987254721Semaste
988254721Semaste
989254721SemasteInstructionSP
990254721SemasteInstructionList::GetInstructionAtIndex (size_t idx) const
991254721Semaste{
992254721Semaste    InstructionSP inst_sp;
993254721Semaste    if (idx < m_instructions.size())
994254721Semaste        inst_sp = m_instructions[idx];
995254721Semaste    return inst_sp;
996254721Semaste}
997254721Semaste
998254721Semastevoid
999254721SemasteInstructionList::Dump (Stream *s,
1000254721Semaste                       bool show_address,
1001254721Semaste                       bool show_bytes,
1002254721Semaste                       const ExecutionContext* exe_ctx)
1003254721Semaste{
1004254721Semaste    const uint32_t max_opcode_byte_size = GetMaxOpcocdeByteSize();
1005254721Semaste    collection::const_iterator pos, begin, end;
1006254721Semaste    for (begin = m_instructions.begin(), end = m_instructions.end(), pos = begin;
1007254721Semaste         pos != end;
1008254721Semaste         ++pos)
1009254721Semaste    {
1010254721Semaste        if (pos != begin)
1011254721Semaste            s->EOL();
1012254721Semaste        (*pos)->Dump(s, max_opcode_byte_size, show_address, show_bytes, exe_ctx);
1013254721Semaste    }
1014254721Semaste}
1015254721Semaste
1016254721Semaste
1017254721Semastevoid
1018254721SemasteInstructionList::Clear()
1019254721Semaste{
1020254721Semaste  m_instructions.clear();
1021254721Semaste}
1022254721Semaste
1023254721Semastevoid
1024254721SemasteInstructionList::Append (lldb::InstructionSP &inst_sp)
1025254721Semaste{
1026254721Semaste    if (inst_sp)
1027254721Semaste        m_instructions.push_back(inst_sp);
1028254721Semaste}
1029254721Semaste
1030254721Semasteuint32_t
1031254721SemasteInstructionList::GetIndexOfNextBranchInstruction(uint32_t start) const
1032254721Semaste{
1033254721Semaste    size_t num_instructions = m_instructions.size();
1034254721Semaste
1035254721Semaste    uint32_t next_branch = UINT32_MAX;
1036254721Semaste    for (size_t i = start; i < num_instructions; i++)
1037254721Semaste    {
1038254721Semaste        if (m_instructions[i]->DoesBranch())
1039254721Semaste        {
1040254721Semaste            next_branch = i;
1041254721Semaste            break;
1042254721Semaste        }
1043254721Semaste    }
1044254721Semaste    return next_branch;
1045254721Semaste}
1046254721Semaste
1047254721Semasteuint32_t
1048269024SemasteInstructionList::GetIndexOfInstructionAtAddress (const Address &address)
1049254721Semaste{
1050254721Semaste    size_t num_instructions = m_instructions.size();
1051254721Semaste    uint32_t index = UINT32_MAX;
1052254721Semaste    for (size_t i = 0; i < num_instructions; i++)
1053254721Semaste    {
1054254721Semaste        if (m_instructions[i]->GetAddress() == address)
1055254721Semaste        {
1056254721Semaste            index = i;
1057254721Semaste            break;
1058254721Semaste        }
1059254721Semaste    }
1060254721Semaste    return index;
1061254721Semaste}
1062254721Semaste
1063269024Semaste
1064269024Semasteuint32_t
1065269024SemasteInstructionList::GetIndexOfInstructionAtLoadAddress (lldb::addr_t load_addr, Target &target)
1066269024Semaste{
1067269024Semaste    Address address;
1068269024Semaste    address.SetLoadAddress(load_addr, &target);
1069269024Semaste    return GetIndexOfInstructionAtAddress(address);
1070269024Semaste}
1071269024Semaste
1072254721Semastesize_t
1073254721SemasteDisassembler::ParseInstructions (const ExecutionContext *exe_ctx,
1074254721Semaste                                 const AddressRange &range,
1075254721Semaste                                 Stream *error_strm_ptr,
1076254721Semaste                                 bool prefer_file_cache)
1077254721Semaste{
1078254721Semaste    if (exe_ctx)
1079254721Semaste    {
1080254721Semaste        Target *target = exe_ctx->GetTargetPtr();
1081254721Semaste        const addr_t byte_size = range.GetByteSize();
1082254721Semaste        if (target == NULL || byte_size == 0 || !range.GetBaseAddress().IsValid())
1083254721Semaste            return 0;
1084254721Semaste
1085254721Semaste        DataBufferHeap *heap_buffer = new DataBufferHeap (byte_size, '\0');
1086254721Semaste        DataBufferSP data_sp(heap_buffer);
1087254721Semaste
1088254721Semaste        Error error;
1089254721Semaste        lldb::addr_t load_addr = LLDB_INVALID_ADDRESS;
1090254721Semaste        const size_t bytes_read = target->ReadMemory (range.GetBaseAddress(),
1091254721Semaste                                                      prefer_file_cache,
1092254721Semaste                                                      heap_buffer->GetBytes(),
1093254721Semaste                                                      heap_buffer->GetByteSize(),
1094254721Semaste                                                      error,
1095254721Semaste                                                      &load_addr);
1096254721Semaste
1097254721Semaste        if (bytes_read > 0)
1098254721Semaste        {
1099254721Semaste            if (bytes_read != heap_buffer->GetByteSize())
1100254721Semaste                heap_buffer->SetByteSize (bytes_read);
1101254721Semaste            DataExtractor data (data_sp,
1102254721Semaste                                m_arch.GetByteOrder(),
1103254721Semaste                                m_arch.GetAddressByteSize());
1104254721Semaste            const bool data_from_file = load_addr == LLDB_INVALID_ADDRESS;
1105254721Semaste            return DecodeInstructions (range.GetBaseAddress(), data, 0, UINT32_MAX, false, data_from_file);
1106254721Semaste        }
1107254721Semaste        else if (error_strm_ptr)
1108254721Semaste        {
1109254721Semaste            const char *error_cstr = error.AsCString();
1110254721Semaste            if (error_cstr)
1111254721Semaste            {
1112254721Semaste                error_strm_ptr->Printf("error: %s\n", error_cstr);
1113254721Semaste            }
1114254721Semaste        }
1115254721Semaste    }
1116254721Semaste    else if (error_strm_ptr)
1117254721Semaste    {
1118254721Semaste        error_strm_ptr->PutCString("error: invalid execution context\n");
1119254721Semaste    }
1120254721Semaste    return 0;
1121254721Semaste}
1122254721Semaste
1123254721Semastesize_t
1124254721SemasteDisassembler::ParseInstructions (const ExecutionContext *exe_ctx,
1125254721Semaste                                 const Address &start,
1126254721Semaste                                 uint32_t num_instructions,
1127254721Semaste                                 bool prefer_file_cache)
1128254721Semaste{
1129254721Semaste    m_instruction_list.Clear();
1130254721Semaste
1131254721Semaste    if (exe_ctx == NULL || num_instructions == 0 || !start.IsValid())
1132254721Semaste        return 0;
1133254721Semaste
1134254721Semaste    Target *target = exe_ctx->GetTargetPtr();
1135254721Semaste    // Calculate the max buffer size we will need in order to disassemble
1136254721Semaste    const addr_t byte_size = num_instructions * m_arch.GetMaximumOpcodeByteSize();
1137254721Semaste
1138254721Semaste    if (target == NULL || byte_size == 0)
1139254721Semaste        return 0;
1140254721Semaste
1141254721Semaste    DataBufferHeap *heap_buffer = new DataBufferHeap (byte_size, '\0');
1142254721Semaste    DataBufferSP data_sp (heap_buffer);
1143254721Semaste
1144254721Semaste    Error error;
1145254721Semaste    lldb::addr_t load_addr = LLDB_INVALID_ADDRESS;
1146254721Semaste    const size_t bytes_read = target->ReadMemory (start,
1147254721Semaste                                                  prefer_file_cache,
1148254721Semaste                                                  heap_buffer->GetBytes(),
1149254721Semaste                                                  byte_size,
1150254721Semaste                                                  error,
1151254721Semaste                                                  &load_addr);
1152254721Semaste
1153254721Semaste    const bool data_from_file = load_addr == LLDB_INVALID_ADDRESS;
1154254721Semaste
1155254721Semaste    if (bytes_read == 0)
1156254721Semaste        return 0;
1157254721Semaste    DataExtractor data (data_sp,
1158254721Semaste                        m_arch.GetByteOrder(),
1159254721Semaste                        m_arch.GetAddressByteSize());
1160254721Semaste
1161254721Semaste    const bool append_instructions = true;
1162254721Semaste    DecodeInstructions (start,
1163254721Semaste                        data,
1164254721Semaste                        0,
1165254721Semaste                        num_instructions,
1166254721Semaste                        append_instructions,
1167254721Semaste                        data_from_file);
1168254721Semaste
1169254721Semaste    return m_instruction_list.GetSize();
1170254721Semaste}
1171254721Semaste
1172254721Semaste//----------------------------------------------------------------------
1173254721Semaste// Disassembler copy constructor
1174254721Semaste//----------------------------------------------------------------------
1175254721SemasteDisassembler::Disassembler(const ArchSpec& arch, const char *flavor) :
1176254721Semaste    m_arch (arch),
1177254721Semaste    m_instruction_list(),
1178254721Semaste    m_base_addr(LLDB_INVALID_ADDRESS),
1179254721Semaste    m_flavor ()
1180254721Semaste{
1181254721Semaste    if (flavor == NULL)
1182254721Semaste        m_flavor.assign("default");
1183254721Semaste    else
1184254721Semaste        m_flavor.assign(flavor);
1185254721Semaste}
1186254721Semaste
1187254721Semaste//----------------------------------------------------------------------
1188254721Semaste// Destructor
1189254721Semaste//----------------------------------------------------------------------
1190254721SemasteDisassembler::~Disassembler()
1191254721Semaste{
1192254721Semaste}
1193254721Semaste
1194254721SemasteInstructionList &
1195254721SemasteDisassembler::GetInstructionList ()
1196254721Semaste{
1197254721Semaste    return m_instruction_list;
1198254721Semaste}
1199254721Semaste
1200254721Semasteconst InstructionList &
1201254721SemasteDisassembler::GetInstructionList () const
1202254721Semaste{
1203254721Semaste    return m_instruction_list;
1204254721Semaste}
1205254721Semaste
1206254721Semaste//----------------------------------------------------------------------
1207254721Semaste// Class PseudoInstruction
1208254721Semaste//----------------------------------------------------------------------
1209254721SemastePseudoInstruction::PseudoInstruction () :
1210254721Semaste    Instruction (Address(), eAddressClassUnknown),
1211254721Semaste    m_description ()
1212254721Semaste{
1213254721Semaste}
1214254721Semaste
1215254721SemastePseudoInstruction::~PseudoInstruction ()
1216254721Semaste{
1217254721Semaste}
1218254721Semaste
1219254721Semastebool
1220254721SemastePseudoInstruction::DoesBranch ()
1221254721Semaste{
1222254721Semaste    // This is NOT a valid question for a pseudo instruction.
1223254721Semaste    return false;
1224254721Semaste}
1225254721Semaste
1226254721Semastesize_t
1227254721SemastePseudoInstruction::Decode (const lldb_private::Disassembler &disassembler,
1228254721Semaste                           const lldb_private::DataExtractor &data,
1229254721Semaste                           lldb::offset_t data_offset)
1230254721Semaste{
1231254721Semaste    return m_opcode.GetByteSize();
1232254721Semaste}
1233254721Semaste
1234254721Semaste
1235254721Semastevoid
1236254721SemastePseudoInstruction::SetOpcode (size_t opcode_size, void *opcode_data)
1237254721Semaste{
1238254721Semaste    if (!opcode_data)
1239254721Semaste        return;
1240254721Semaste
1241254721Semaste    switch (opcode_size)
1242254721Semaste    {
1243254721Semaste        case 8:
1244254721Semaste        {
1245254721Semaste            uint8_t value8 = *((uint8_t *) opcode_data);
1246269024Semaste            m_opcode.SetOpcode8 (value8, eByteOrderInvalid);
1247254721Semaste            break;
1248254721Semaste         }
1249254721Semaste        case 16:
1250254721Semaste        {
1251254721Semaste            uint16_t value16 = *((uint16_t *) opcode_data);
1252269024Semaste            m_opcode.SetOpcode16 (value16, eByteOrderInvalid);
1253254721Semaste            break;
1254254721Semaste         }
1255254721Semaste        case 32:
1256254721Semaste        {
1257254721Semaste            uint32_t value32 = *((uint32_t *) opcode_data);
1258269024Semaste            m_opcode.SetOpcode32 (value32, eByteOrderInvalid);
1259254721Semaste            break;
1260254721Semaste         }
1261254721Semaste        case 64:
1262254721Semaste        {
1263254721Semaste            uint64_t value64 = *((uint64_t *) opcode_data);
1264269024Semaste            m_opcode.SetOpcode64 (value64, eByteOrderInvalid);
1265254721Semaste            break;
1266254721Semaste         }
1267254721Semaste        default:
1268254721Semaste            break;
1269254721Semaste    }
1270254721Semaste}
1271254721Semaste
1272254721Semastevoid
1273254721SemastePseudoInstruction::SetDescription (const char *description)
1274254721Semaste{
1275254721Semaste    if (description && strlen (description) > 0)
1276254721Semaste        m_description = description;
1277254721Semaste}
1278