1*30fdc8d8SChris Lattner //===-- CommandObjectDisassemble.cpp ----------------------------*- C++ -*-===//
2*30fdc8d8SChris Lattner //
3*30fdc8d8SChris Lattner //                     The LLVM Compiler Infrastructure
4*30fdc8d8SChris Lattner //
5*30fdc8d8SChris Lattner // This file is distributed under the University of Illinois Open Source
6*30fdc8d8SChris Lattner // License. See LICENSE.TXT for details.
7*30fdc8d8SChris Lattner //
8*30fdc8d8SChris Lattner //===----------------------------------------------------------------------===//
9*30fdc8d8SChris Lattner 
10*30fdc8d8SChris Lattner #include "CommandObjectDisassemble.h"
11*30fdc8d8SChris Lattner 
12*30fdc8d8SChris Lattner // C Includes
13*30fdc8d8SChris Lattner // C++ Includes
14*30fdc8d8SChris Lattner // Other libraries and framework includes
15*30fdc8d8SChris Lattner // Project includes
16*30fdc8d8SChris Lattner #include "lldb/Core/AddressRange.h"
17*30fdc8d8SChris Lattner #include "lldb/Core/Args.h"
18*30fdc8d8SChris Lattner #include "lldb/Interpreter/CommandCompletions.h"
19*30fdc8d8SChris Lattner #include "lldb/Interpreter/CommandInterpreter.h"
20*30fdc8d8SChris Lattner #include "lldb/Interpreter/CommandReturnObject.h"
21*30fdc8d8SChris Lattner #include "lldb/Core/Disassembler.h"
22*30fdc8d8SChris Lattner #include "lldb/Core/Options.h"
23*30fdc8d8SChris Lattner #include "lldb/Core/SourceManager.h"
24*30fdc8d8SChris Lattner #include "lldb/Target/StackFrame.h"
25*30fdc8d8SChris Lattner #include "lldb/Symbol/Symbol.h"
26*30fdc8d8SChris Lattner #include "lldb/Target/Process.h"
27*30fdc8d8SChris Lattner #include "lldb/Target/Target.h"
28*30fdc8d8SChris Lattner 
29*30fdc8d8SChris Lattner #define DEFAULT_DISASM_BYTE_SIZE 32
30*30fdc8d8SChris Lattner 
31*30fdc8d8SChris Lattner using namespace lldb;
32*30fdc8d8SChris Lattner using namespace lldb_private;
33*30fdc8d8SChris Lattner 
34*30fdc8d8SChris Lattner CommandObjectDisassemble::CommandOptions::CommandOptions () :
35*30fdc8d8SChris Lattner     Options(),
36*30fdc8d8SChris Lattner     m_func_name(),
37*30fdc8d8SChris Lattner     m_load_addr()
38*30fdc8d8SChris Lattner {
39*30fdc8d8SChris Lattner     ResetOptionValues();
40*30fdc8d8SChris Lattner }
41*30fdc8d8SChris Lattner 
42*30fdc8d8SChris Lattner CommandObjectDisassemble::CommandOptions::~CommandOptions ()
43*30fdc8d8SChris Lattner {
44*30fdc8d8SChris Lattner }
45*30fdc8d8SChris Lattner 
46*30fdc8d8SChris Lattner Error
47*30fdc8d8SChris Lattner CommandObjectDisassemble::CommandOptions::SetOptionValue (int option_idx, const char *option_arg)
48*30fdc8d8SChris Lattner {
49*30fdc8d8SChris Lattner     Error error;
50*30fdc8d8SChris Lattner 
51*30fdc8d8SChris Lattner     char short_option = (char) m_getopt_table[option_idx].val;
52*30fdc8d8SChris Lattner 
53*30fdc8d8SChris Lattner     switch (short_option)
54*30fdc8d8SChris Lattner     {
55*30fdc8d8SChris Lattner     case 'm':
56*30fdc8d8SChris Lattner         show_mixed = true;
57*30fdc8d8SChris Lattner         break;
58*30fdc8d8SChris Lattner 
59*30fdc8d8SChris Lattner     case 'c':
60*30fdc8d8SChris Lattner         num_lines_context = Args::StringToUInt32(option_arg, 0, 0);
61*30fdc8d8SChris Lattner         break;
62*30fdc8d8SChris Lattner 
63*30fdc8d8SChris Lattner     case 'b':
64*30fdc8d8SChris Lattner         show_bytes = true;
65*30fdc8d8SChris Lattner         break;
66*30fdc8d8SChris Lattner 
67*30fdc8d8SChris Lattner     case 'a':
68*30fdc8d8SChris Lattner         m_load_addr = Args::StringToUInt64(optarg, LLDB_INVALID_ADDRESS, 0);
69*30fdc8d8SChris Lattner         if (m_load_addr == LLDB_INVALID_ADDRESS)
70*30fdc8d8SChris Lattner             m_load_addr = Args::StringToUInt64(optarg, LLDB_INVALID_ADDRESS, 16);
71*30fdc8d8SChris Lattner 
72*30fdc8d8SChris Lattner         if (m_load_addr == LLDB_INVALID_ADDRESS)
73*30fdc8d8SChris Lattner             error.SetErrorStringWithFormat ("Invalid address string '%s'.\n", optarg);
74*30fdc8d8SChris Lattner         break;
75*30fdc8d8SChris Lattner 
76*30fdc8d8SChris Lattner     case 'n':
77*30fdc8d8SChris Lattner         m_func_name = option_arg;
78*30fdc8d8SChris Lattner         break;
79*30fdc8d8SChris Lattner 
80*30fdc8d8SChris Lattner     case 'r':
81*30fdc8d8SChris Lattner         raw = true;
82*30fdc8d8SChris Lattner         break;
83*30fdc8d8SChris Lattner 
84*30fdc8d8SChris Lattner     default:
85*30fdc8d8SChris Lattner         error.SetErrorStringWithFormat("Unrecognized short option '%c'.\n", short_option);
86*30fdc8d8SChris Lattner         break;
87*30fdc8d8SChris Lattner     }
88*30fdc8d8SChris Lattner 
89*30fdc8d8SChris Lattner     return error;
90*30fdc8d8SChris Lattner }
91*30fdc8d8SChris Lattner 
92*30fdc8d8SChris Lattner void
93*30fdc8d8SChris Lattner CommandObjectDisassemble::CommandOptions::ResetOptionValues ()
94*30fdc8d8SChris Lattner {
95*30fdc8d8SChris Lattner     Options::ResetOptionValues();
96*30fdc8d8SChris Lattner     show_mixed = false;
97*30fdc8d8SChris Lattner     show_bytes = false;
98*30fdc8d8SChris Lattner     num_lines_context = 0;
99*30fdc8d8SChris Lattner     m_func_name.clear();
100*30fdc8d8SChris Lattner     m_load_addr = LLDB_INVALID_ADDRESS;
101*30fdc8d8SChris Lattner }
102*30fdc8d8SChris Lattner 
103*30fdc8d8SChris Lattner const lldb::OptionDefinition*
104*30fdc8d8SChris Lattner CommandObjectDisassemble::CommandOptions::GetDefinitions ()
105*30fdc8d8SChris Lattner {
106*30fdc8d8SChris Lattner     return g_option_table;
107*30fdc8d8SChris Lattner }
108*30fdc8d8SChris Lattner 
109*30fdc8d8SChris Lattner lldb::OptionDefinition
110*30fdc8d8SChris Lattner CommandObjectDisassemble::CommandOptions::g_option_table[] =
111*30fdc8d8SChris Lattner {
112*30fdc8d8SChris Lattner { 0, false, "bytes",    'b', no_argument,       NULL, 0, NULL,             "Show opcode bytes when disassembling."},
113*30fdc8d8SChris Lattner { 0, false, "context",  'c', required_argument, NULL, 0, "<num-lines>",    "Number of context lines of source to show."},
114*30fdc8d8SChris Lattner { 0, false, "mixed",    'm', no_argument,       NULL, 0, NULL,             "Enable mixed source and assembly display."},
115*30fdc8d8SChris Lattner { 0, false, "raw",      'r', no_argument,       NULL, 0, NULL,             "Print raw disassembly with no symbol information."},
116*30fdc8d8SChris Lattner 
117*30fdc8d8SChris Lattner { 1, false, "address",  'a', required_argument, NULL, 0, "<address>",      "Address to start disassembling."},
118*30fdc8d8SChris Lattner { 1, false, "bytes",    'b', no_argument,       NULL, 0, NULL,             "Show opcode bytes when disassembling."},
119*30fdc8d8SChris Lattner { 1, false, "context",  'c', required_argument, NULL, 0, "<num-lines>",    "Number of context lines of source to show."},
120*30fdc8d8SChris Lattner { 1, false, "mixed",    'm', no_argument,       NULL, 0, NULL,             "Enable mixed source and assembly display."},
121*30fdc8d8SChris Lattner { 1, false, "raw",      'r', no_argument,       NULL, 0, NULL,             "Print raw disassembly with no symbol information."},
122*30fdc8d8SChris Lattner 
123*30fdc8d8SChris Lattner { 2, false, "name",     'n', required_argument, NULL, CommandCompletions::eSymbolCompletion, "<function-name>",             "Disassemble entire contents of the given function name."},
124*30fdc8d8SChris Lattner { 2, false, "bytes",    'b', no_argument,       NULL, 0, NULL,             "Show opcode bytes when disassembling."},
125*30fdc8d8SChris Lattner { 2, false, "context",  'c', required_argument, NULL, 0, "<num-lines>",    "Number of context lines of source to show."},
126*30fdc8d8SChris Lattner { 2, false, "mixed",    'm', no_argument,       NULL, 0, NULL,             "Enable mixed source and assembly display."},
127*30fdc8d8SChris Lattner { 2, false, "raw",      'r', no_argument,       NULL, 0, NULL,             "Print raw disassembly with no symbol information."},
128*30fdc8d8SChris Lattner 
129*30fdc8d8SChris Lattner { 0, false, NULL, 0, 0, NULL, 0, NULL, NULL }
130*30fdc8d8SChris Lattner };
131*30fdc8d8SChris Lattner 
132*30fdc8d8SChris Lattner 
133*30fdc8d8SChris Lattner 
134*30fdc8d8SChris Lattner //-------------------------------------------------------------------------
135*30fdc8d8SChris Lattner // CommandObjectDisassemble
136*30fdc8d8SChris Lattner //-------------------------------------------------------------------------
137*30fdc8d8SChris Lattner 
138*30fdc8d8SChris Lattner CommandObjectDisassemble::CommandObjectDisassemble () :
139*30fdc8d8SChris Lattner     CommandObject ("disassemble",
140*30fdc8d8SChris Lattner                      "Disassemble bytes in the current function or anywhere in the inferior program.",
141*30fdc8d8SChris Lattner                      "disassemble [[<start-addr> [<end-addr>]] | <function-name>] [<cmd-options>]")
142*30fdc8d8SChris Lattner {
143*30fdc8d8SChris Lattner }
144*30fdc8d8SChris Lattner 
145*30fdc8d8SChris Lattner CommandObjectDisassemble::~CommandObjectDisassemble()
146*30fdc8d8SChris Lattner {
147*30fdc8d8SChris Lattner }
148*30fdc8d8SChris Lattner 
149*30fdc8d8SChris Lattner void
150*30fdc8d8SChris Lattner CommandObjectDisassemble::Disassemble
151*30fdc8d8SChris Lattner (
152*30fdc8d8SChris Lattner     CommandContext *context,
153*30fdc8d8SChris Lattner     CommandInterpreter *interpreter,
154*30fdc8d8SChris Lattner     CommandReturnObject &result,
155*30fdc8d8SChris Lattner     Disassembler *disassembler,
156*30fdc8d8SChris Lattner     const SymbolContextList &sc_list
157*30fdc8d8SChris Lattner )
158*30fdc8d8SChris Lattner {
159*30fdc8d8SChris Lattner     const size_t count = sc_list.GetSize();
160*30fdc8d8SChris Lattner     SymbolContext sc;
161*30fdc8d8SChris Lattner     AddressRange range;
162*30fdc8d8SChris Lattner     for (size_t i=0; i<count; ++i)
163*30fdc8d8SChris Lattner     {
164*30fdc8d8SChris Lattner         if (sc_list.GetContextAtIndex(i, sc) == false)
165*30fdc8d8SChris Lattner             break;
166*30fdc8d8SChris Lattner         if (sc.GetAddressRange(eSymbolContextFunction | eSymbolContextSymbol, range))
167*30fdc8d8SChris Lattner         {
168*30fdc8d8SChris Lattner             lldb::addr_t addr = range.GetBaseAddress().GetLoadAddress(context->GetExecutionContext().process);
169*30fdc8d8SChris Lattner             if (addr != LLDB_INVALID_ADDRESS)
170*30fdc8d8SChris Lattner             {
171*30fdc8d8SChris Lattner                 lldb::addr_t end_addr = addr + range.GetByteSize();
172*30fdc8d8SChris Lattner                 Disassemble (context, interpreter, result, disassembler, addr, end_addr);
173*30fdc8d8SChris Lattner             }
174*30fdc8d8SChris Lattner         }
175*30fdc8d8SChris Lattner     }
176*30fdc8d8SChris Lattner }
177*30fdc8d8SChris Lattner 
178*30fdc8d8SChris Lattner void
179*30fdc8d8SChris Lattner CommandObjectDisassemble::Disassemble
180*30fdc8d8SChris Lattner (
181*30fdc8d8SChris Lattner     CommandContext *context,
182*30fdc8d8SChris Lattner     CommandInterpreter *interpreter,
183*30fdc8d8SChris Lattner     CommandReturnObject &result,
184*30fdc8d8SChris Lattner     Disassembler *disassembler,
185*30fdc8d8SChris Lattner     lldb::addr_t addr,
186*30fdc8d8SChris Lattner     lldb::addr_t end_addr
187*30fdc8d8SChris Lattner )
188*30fdc8d8SChris Lattner {
189*30fdc8d8SChris Lattner     if (addr == LLDB_INVALID_ADDRESS)
190*30fdc8d8SChris Lattner         return;
191*30fdc8d8SChris Lattner 
192*30fdc8d8SChris Lattner     if (end_addr == LLDB_INVALID_ADDRESS || addr >= end_addr)
193*30fdc8d8SChris Lattner         end_addr = addr + DEFAULT_DISASM_BYTE_SIZE;
194*30fdc8d8SChris Lattner 
195*30fdc8d8SChris Lattner     ExecutionContext exe_ctx (context->GetExecutionContext());
196*30fdc8d8SChris Lattner     DataExtractor data;
197*30fdc8d8SChris Lattner     size_t bytes_disassembled = disassembler->ParseInstructions (&exe_ctx, eAddressTypeLoad, addr, end_addr - addr, data);
198*30fdc8d8SChris Lattner     if (bytes_disassembled == 0)
199*30fdc8d8SChris Lattner     {
200*30fdc8d8SChris Lattner         // Nothing got disassembled...
201*30fdc8d8SChris Lattner     }
202*30fdc8d8SChris Lattner     else
203*30fdc8d8SChris Lattner     {
204*30fdc8d8SChris Lattner         // We got some things disassembled...
205*30fdc8d8SChris Lattner         size_t num_instructions = disassembler->GetInstructionList().GetSize();
206*30fdc8d8SChris Lattner         uint32_t offset = 0;
207*30fdc8d8SChris Lattner         Stream &output_stream = result.GetOutputStream();
208*30fdc8d8SChris Lattner         SymbolContext sc;
209*30fdc8d8SChris Lattner         SymbolContext prev_sc;
210*30fdc8d8SChris Lattner         AddressRange sc_range;
211*30fdc8d8SChris Lattner         if (m_options.show_mixed)
212*30fdc8d8SChris Lattner             output_stream.IndentMore ();
213*30fdc8d8SChris Lattner 
214*30fdc8d8SChris Lattner         for (size_t i=0; i<num_instructions; ++i)
215*30fdc8d8SChris Lattner         {
216*30fdc8d8SChris Lattner             Disassembler::Instruction *inst = disassembler->GetInstructionList().GetInstructionAtIndex (i);
217*30fdc8d8SChris Lattner             if (inst)
218*30fdc8d8SChris Lattner             {
219*30fdc8d8SChris Lattner                 lldb::addr_t curr_addr = addr + offset;
220*30fdc8d8SChris Lattner                 if (m_options.show_mixed)
221*30fdc8d8SChris Lattner                 {
222*30fdc8d8SChris Lattner                     Process *process = context->GetExecutionContext().process;
223*30fdc8d8SChris Lattner                     if (!sc_range.ContainsLoadAddress (curr_addr, process))
224*30fdc8d8SChris Lattner                     {
225*30fdc8d8SChris Lattner                         prev_sc = sc;
226*30fdc8d8SChris Lattner                         Address curr_so_addr;
227*30fdc8d8SChris Lattner                         if (process && process->ResolveLoadAddress (curr_addr, curr_so_addr))
228*30fdc8d8SChris Lattner                         {
229*30fdc8d8SChris Lattner                             if (curr_so_addr.GetSection())
230*30fdc8d8SChris Lattner                             {
231*30fdc8d8SChris Lattner                                 Module *module = curr_so_addr.GetSection()->GetModule();
232*30fdc8d8SChris Lattner                                 uint32_t resolved_mask = module->ResolveSymbolContextForAddress(curr_so_addr, eSymbolContextEverything, sc);
233*30fdc8d8SChris Lattner                                 if (resolved_mask)
234*30fdc8d8SChris Lattner                                 {
235*30fdc8d8SChris Lattner                                     sc.GetAddressRange (eSymbolContextEverything, sc_range);
236*30fdc8d8SChris Lattner                                     if (sc != prev_sc)
237*30fdc8d8SChris Lattner                                     {
238*30fdc8d8SChris Lattner                                         if (offset != 0)
239*30fdc8d8SChris Lattner                                             output_stream.EOL();
240*30fdc8d8SChris Lattner 
241*30fdc8d8SChris Lattner                                         sc.DumpStopContext(&output_stream, process, curr_so_addr);
242*30fdc8d8SChris Lattner                                         output_stream.EOL();
243*30fdc8d8SChris Lattner                                         if (sc.comp_unit && sc.line_entry.IsValid())
244*30fdc8d8SChris Lattner                                         {
245*30fdc8d8SChris Lattner                                             interpreter->GetSourceManager().DisplaySourceLinesWithLineNumbers (
246*30fdc8d8SChris Lattner                                                     sc.line_entry.file,
247*30fdc8d8SChris Lattner                                                     sc.line_entry.line,
248*30fdc8d8SChris Lattner                                                     m_options.num_lines_context,
249*30fdc8d8SChris Lattner                                                     m_options.num_lines_context,
250*30fdc8d8SChris Lattner                                                     m_options.num_lines_context ? "->" : "",
251*30fdc8d8SChris Lattner                                                     &output_stream);
252*30fdc8d8SChris Lattner                                         }
253*30fdc8d8SChris Lattner                                     }
254*30fdc8d8SChris Lattner                                 }
255*30fdc8d8SChris Lattner                             }
256*30fdc8d8SChris Lattner                         }
257*30fdc8d8SChris Lattner                     }
258*30fdc8d8SChris Lattner                 }
259*30fdc8d8SChris Lattner                 if (m_options.show_mixed)
260*30fdc8d8SChris Lattner                     output_stream.IndentMore ();
261*30fdc8d8SChris Lattner                 output_stream.Indent();
262*30fdc8d8SChris Lattner                 size_t inst_byte_size = inst->GetByteSize();
263*30fdc8d8SChris Lattner                 inst->Dump(&output_stream, curr_addr, m_options.show_bytes ? &data : NULL, offset, exe_ctx, m_options.raw);
264*30fdc8d8SChris Lattner                 output_stream.EOL();
265*30fdc8d8SChris Lattner                 offset += inst_byte_size;
266*30fdc8d8SChris Lattner                 if (m_options.show_mixed)
267*30fdc8d8SChris Lattner                     output_stream.IndentLess ();
268*30fdc8d8SChris Lattner             }
269*30fdc8d8SChris Lattner             else
270*30fdc8d8SChris Lattner             {
271*30fdc8d8SChris Lattner                 break;
272*30fdc8d8SChris Lattner             }
273*30fdc8d8SChris Lattner         }
274*30fdc8d8SChris Lattner         if (m_options.show_mixed)
275*30fdc8d8SChris Lattner             output_stream.IndentLess ();
276*30fdc8d8SChris Lattner 
277*30fdc8d8SChris Lattner     }
278*30fdc8d8SChris Lattner }
279*30fdc8d8SChris Lattner 
280*30fdc8d8SChris Lattner bool
281*30fdc8d8SChris Lattner CommandObjectDisassemble::Execute
282*30fdc8d8SChris Lattner (
283*30fdc8d8SChris Lattner     Args& command,
284*30fdc8d8SChris Lattner     CommandContext *context,
285*30fdc8d8SChris Lattner     CommandInterpreter *interpreter,
286*30fdc8d8SChris Lattner     CommandReturnObject &result
287*30fdc8d8SChris Lattner )
288*30fdc8d8SChris Lattner {
289*30fdc8d8SChris Lattner     Target *target = context->GetTarget();
290*30fdc8d8SChris Lattner     if (target == NULL)
291*30fdc8d8SChris Lattner     {
292*30fdc8d8SChris Lattner         result.AppendError ("invalid target, set executable file using 'file' command");
293*30fdc8d8SChris Lattner         result.SetStatus (eReturnStatusFailed);
294*30fdc8d8SChris Lattner         return false;
295*30fdc8d8SChris Lattner     }
296*30fdc8d8SChris Lattner 
297*30fdc8d8SChris Lattner     ArchSpec arch(target->GetArchitecture());
298*30fdc8d8SChris Lattner     if (!arch.IsValid())
299*30fdc8d8SChris Lattner     {
300*30fdc8d8SChris Lattner         result.AppendError ("target needs valid architecure in order to be able to disassemble");
301*30fdc8d8SChris Lattner         result.SetStatus (eReturnStatusFailed);
302*30fdc8d8SChris Lattner         return false;
303*30fdc8d8SChris Lattner     }
304*30fdc8d8SChris Lattner 
305*30fdc8d8SChris Lattner     Disassembler *disassembler = Disassembler::FindPlugin(arch);
306*30fdc8d8SChris Lattner 
307*30fdc8d8SChris Lattner     if (disassembler == NULL)
308*30fdc8d8SChris Lattner     {
309*30fdc8d8SChris Lattner         result.AppendErrorWithFormat ("Unable to find Disassembler plug-in for %s architecture.\n", arch.AsCString());
310*30fdc8d8SChris Lattner         result.SetStatus (eReturnStatusFailed);
311*30fdc8d8SChris Lattner         return false;
312*30fdc8d8SChris Lattner     }
313*30fdc8d8SChris Lattner 
314*30fdc8d8SChris Lattner     result.SetStatus (eReturnStatusSuccessFinishResult);
315*30fdc8d8SChris Lattner 
316*30fdc8d8SChris Lattner     lldb::addr_t addr = LLDB_INVALID_ADDRESS;
317*30fdc8d8SChris Lattner     lldb::addr_t end_addr = LLDB_INVALID_ADDRESS;
318*30fdc8d8SChris Lattner     ConstString name;
319*30fdc8d8SChris Lattner     const size_t argc = command.GetArgumentCount();
320*30fdc8d8SChris Lattner     if (argc == 0 && m_options.m_load_addr != LLDB_INVALID_ADDRESS)
321*30fdc8d8SChris Lattner     {
322*30fdc8d8SChris Lattner         addr = m_options.m_load_addr;
323*30fdc8d8SChris Lattner         end_addr = addr + DEFAULT_DISASM_BYTE_SIZE;
324*30fdc8d8SChris Lattner     } else if (argc == 0 && !m_options.m_func_name.empty())
325*30fdc8d8SChris Lattner     {
326*30fdc8d8SChris Lattner         ConstString tmpname(m_options.m_func_name.c_str());
327*30fdc8d8SChris Lattner         name = tmpname;
328*30fdc8d8SChris Lattner     } else if (argc == 0)
329*30fdc8d8SChris Lattner     {
330*30fdc8d8SChris Lattner         ExecutionContext exe_ctx(context->GetExecutionContext());
331*30fdc8d8SChris Lattner         if (exe_ctx.frame)
332*30fdc8d8SChris Lattner         {
333*30fdc8d8SChris Lattner             SymbolContext sc(exe_ctx.frame->GetSymbolContext(eSymbolContextFunction | eSymbolContextSymbol));
334*30fdc8d8SChris Lattner             if (sc.function)
335*30fdc8d8SChris Lattner             {
336*30fdc8d8SChris Lattner                 addr = sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress(exe_ctx.process);
337*30fdc8d8SChris Lattner                 if (addr != LLDB_INVALID_ADDRESS)
338*30fdc8d8SChris Lattner                     end_addr = addr + sc.function->GetAddressRange().GetByteSize();
339*30fdc8d8SChris Lattner             }
340*30fdc8d8SChris Lattner             else if (sc.symbol && sc.symbol->GetAddressRangePtr())
341*30fdc8d8SChris Lattner             {
342*30fdc8d8SChris Lattner                 addr = sc.symbol->GetAddressRangePtr()->GetBaseAddress().GetLoadAddress(exe_ctx.process);
343*30fdc8d8SChris Lattner                 if (addr != LLDB_INVALID_ADDRESS)
344*30fdc8d8SChris Lattner                 {
345*30fdc8d8SChris Lattner                     end_addr = addr + sc.symbol->GetAddressRangePtr()->GetByteSize();
346*30fdc8d8SChris Lattner                     if (addr == end_addr)
347*30fdc8d8SChris Lattner                         end_addr += DEFAULT_DISASM_BYTE_SIZE;
348*30fdc8d8SChris Lattner                 }
349*30fdc8d8SChris Lattner             }
350*30fdc8d8SChris Lattner             else
351*30fdc8d8SChris Lattner             {
352*30fdc8d8SChris Lattner                 addr = exe_ctx.frame->GetPC().GetLoadAddress(exe_ctx.process);
353*30fdc8d8SChris Lattner                 if (addr != LLDB_INVALID_ADDRESS)
354*30fdc8d8SChris Lattner                     end_addr = addr + DEFAULT_DISASM_BYTE_SIZE;
355*30fdc8d8SChris Lattner             }
356*30fdc8d8SChris Lattner         }
357*30fdc8d8SChris Lattner         else
358*30fdc8d8SChris Lattner         {
359*30fdc8d8SChris Lattner             result.AppendError ("invalid frame");
360*30fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
361*30fdc8d8SChris Lattner             return false;
362*30fdc8d8SChris Lattner         }
363*30fdc8d8SChris Lattner     }
364*30fdc8d8SChris Lattner     else if (argc == 1)
365*30fdc8d8SChris Lattner     {
366*30fdc8d8SChris Lattner         const char *arg = command.GetArgumentAtIndex(0);
367*30fdc8d8SChris Lattner         addr = Args::StringToAddress (arg);
368*30fdc8d8SChris Lattner         if (addr == LLDB_INVALID_ADDRESS)
369*30fdc8d8SChris Lattner         {
370*30fdc8d8SChris Lattner             // Lookup function or symbol name?
371*30fdc8d8SChris Lattner             ConstString tmpname(arg);
372*30fdc8d8SChris Lattner             name = tmpname;
373*30fdc8d8SChris Lattner         }
374*30fdc8d8SChris Lattner         else
375*30fdc8d8SChris Lattner         {
376*30fdc8d8SChris Lattner             end_addr = addr + DEFAULT_DISASM_BYTE_SIZE;
377*30fdc8d8SChris Lattner         }
378*30fdc8d8SChris Lattner     }
379*30fdc8d8SChris Lattner     else if (argc >= 1 && argc <= 2)
380*30fdc8d8SChris Lattner     {
381*30fdc8d8SChris Lattner         addr = Args::StringToAddress (command.GetArgumentAtIndex(0));
382*30fdc8d8SChris Lattner         if (addr == LLDB_INVALID_ADDRESS)
383*30fdc8d8SChris Lattner         {
384*30fdc8d8SChris Lattner             result.AppendErrorWithFormat ("Unable to parse address '%s'.\n", command.GetArgumentAtIndex(0));
385*30fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
386*30fdc8d8SChris Lattner             return false;
387*30fdc8d8SChris Lattner         }
388*30fdc8d8SChris Lattner         end_addr = Args::StringToAddress (command.GetArgumentAtIndex(1), addr);
389*30fdc8d8SChris Lattner         if (end_addr == LLDB_INVALID_ADDRESS)
390*30fdc8d8SChris Lattner         {
391*30fdc8d8SChris Lattner             result.AppendErrorWithFormat ("Unable to parse address '%s'.\n", command.GetArgumentAtIndex(1));
392*30fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
393*30fdc8d8SChris Lattner             return false;
394*30fdc8d8SChris Lattner         }
395*30fdc8d8SChris Lattner     }
396*30fdc8d8SChris Lattner 
397*30fdc8d8SChris Lattner     if (!name.IsEmpty())
398*30fdc8d8SChris Lattner     {
399*30fdc8d8SChris Lattner         SymbolContextList sc_list;
400*30fdc8d8SChris Lattner 
401*30fdc8d8SChris Lattner         if (target->GetImages().FindFunctions(name, sc_list))
402*30fdc8d8SChris Lattner         {
403*30fdc8d8SChris Lattner             Disassemble (context, interpreter, result, disassembler, sc_list);
404*30fdc8d8SChris Lattner         }
405*30fdc8d8SChris Lattner         else if (target->GetImages().FindSymbolsWithNameAndType(name, eSymbolTypeCode, sc_list))
406*30fdc8d8SChris Lattner         {
407*30fdc8d8SChris Lattner             Disassemble (context, interpreter, result, disassembler, sc_list);
408*30fdc8d8SChris Lattner         }
409*30fdc8d8SChris Lattner         else
410*30fdc8d8SChris Lattner         {
411*30fdc8d8SChris Lattner             result.AppendErrorWithFormat ("Unable to find symbol with name '%s'.\n", name.GetCString());
412*30fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
413*30fdc8d8SChris Lattner             return false;
414*30fdc8d8SChris Lattner         }
415*30fdc8d8SChris Lattner     }
416*30fdc8d8SChris Lattner 
417*30fdc8d8SChris Lattner     if (addr < end_addr)
418*30fdc8d8SChris Lattner     {
419*30fdc8d8SChris Lattner         Disassemble (context, interpreter, result, disassembler, addr, end_addr);
420*30fdc8d8SChris Lattner     }
421*30fdc8d8SChris Lattner 
422*30fdc8d8SChris Lattner     if (addr == LLDB_INVALID_ADDRESS && name.IsEmpty())
423*30fdc8d8SChris Lattner     {
424*30fdc8d8SChris Lattner         result.AppendError ("No recognizable address of function name provided");
425*30fdc8d8SChris Lattner         result.SetStatus (eReturnStatusFailed);
426*30fdc8d8SChris Lattner         return false;
427*30fdc8d8SChris Lattner     }
428*30fdc8d8SChris Lattner     {
429*30fdc8d8SChris Lattner         return result.Succeeded();
430*30fdc8d8SChris Lattner     }
431*30fdc8d8SChris Lattner }
432