130fdc8d8SChris Lattner //===-- CommandObjectDisassemble.cpp ----------------------------*- C++ -*-===//
230fdc8d8SChris Lattner //
330fdc8d8SChris Lattner //                     The LLVM Compiler Infrastructure
430fdc8d8SChris Lattner //
530fdc8d8SChris Lattner // This file is distributed under the University of Illinois Open Source
630fdc8d8SChris Lattner // License. See LICENSE.TXT for details.
730fdc8d8SChris Lattner //
830fdc8d8SChris Lattner //===----------------------------------------------------------------------===//
930fdc8d8SChris Lattner 
1030fdc8d8SChris Lattner #include "CommandObjectDisassemble.h"
1130fdc8d8SChris Lattner 
1230fdc8d8SChris Lattner // C Includes
1330fdc8d8SChris Lattner // C++ Includes
1430fdc8d8SChris Lattner // Other libraries and framework includes
1530fdc8d8SChris Lattner // Project includes
1630fdc8d8SChris Lattner #include "lldb/Core/AddressRange.h"
1740af72e1SJim Ingham #include "lldb/Interpreter/Args.h"
1830fdc8d8SChris Lattner #include "lldb/Interpreter/CommandCompletions.h"
1930fdc8d8SChris Lattner #include "lldb/Interpreter/CommandInterpreter.h"
2030fdc8d8SChris Lattner #include "lldb/Interpreter/CommandReturnObject.h"
2130fdc8d8SChris Lattner #include "lldb/Core/Disassembler.h"
2240af72e1SJim Ingham #include "lldb/Interpreter/Options.h"
2330fdc8d8SChris Lattner #include "lldb/Core/SourceManager.h"
2430fdc8d8SChris Lattner #include "lldb/Target/StackFrame.h"
2530fdc8d8SChris Lattner #include "lldb/Symbol/Symbol.h"
2630fdc8d8SChris Lattner #include "lldb/Target/Process.h"
2730fdc8d8SChris Lattner #include "lldb/Target/Target.h"
2830fdc8d8SChris Lattner 
2930fdc8d8SChris Lattner #define DEFAULT_DISASM_BYTE_SIZE 32
3037023b06SJim Ingham #define DEFAULT_DISASM_NUM_INS  4
3130fdc8d8SChris Lattner 
3230fdc8d8SChris Lattner using namespace lldb;
3330fdc8d8SChris Lattner using namespace lldb_private;
3430fdc8d8SChris Lattner 
3530fdc8d8SChris Lattner CommandObjectDisassemble::CommandOptions::CommandOptions () :
3630fdc8d8SChris Lattner     Options(),
3737023b06SJim Ingham     num_lines_context(0),
3837023b06SJim Ingham     num_instructions (0),
3930fdc8d8SChris Lattner     m_func_name(),
408651121cSJim Ingham     m_start_addr(),
4137023b06SJim Ingham     m_end_addr (),
42*1080edbcSGreg Clayton     m_at_pc (false),
43*1080edbcSGreg Clayton     m_plugin_name ()
4430fdc8d8SChris Lattner {
4530fdc8d8SChris Lattner     ResetOptionValues();
4630fdc8d8SChris Lattner }
4730fdc8d8SChris Lattner 
4830fdc8d8SChris Lattner CommandObjectDisassemble::CommandOptions::~CommandOptions ()
4930fdc8d8SChris Lattner {
5030fdc8d8SChris Lattner }
5130fdc8d8SChris Lattner 
5230fdc8d8SChris Lattner Error
5330fdc8d8SChris Lattner CommandObjectDisassemble::CommandOptions::SetOptionValue (int option_idx, const char *option_arg)
5430fdc8d8SChris Lattner {
5530fdc8d8SChris Lattner     Error error;
5630fdc8d8SChris Lattner 
5730fdc8d8SChris Lattner     char short_option = (char) m_getopt_table[option_idx].val;
5830fdc8d8SChris Lattner 
5937023b06SJim Ingham     bool success;
6037023b06SJim Ingham 
6130fdc8d8SChris Lattner     switch (short_option)
6230fdc8d8SChris Lattner     {
6330fdc8d8SChris Lattner     case 'm':
6430fdc8d8SChris Lattner         show_mixed = true;
6530fdc8d8SChris Lattner         break;
6630fdc8d8SChris Lattner 
6737023b06SJim Ingham     case 'x':
6837023b06SJim Ingham         num_lines_context = Args::StringToUInt32(option_arg, 0, 0, &success);
6937023b06SJim Ingham         if (!success)
7037023b06SJim Ingham             error.SetErrorStringWithFormat ("Invalid num context lines string: \"%s\".\n", option_arg);
7137023b06SJim Ingham         break;
7237023b06SJim Ingham 
7330fdc8d8SChris Lattner     case 'c':
7437023b06SJim Ingham         num_instructions = Args::StringToUInt32(option_arg, 0, 0, &success);
7537023b06SJim Ingham         if (!success)
7637023b06SJim Ingham             error.SetErrorStringWithFormat ("Invalid num of instructions string: \"%s\".\n", option_arg);
7730fdc8d8SChris Lattner         break;
7830fdc8d8SChris Lattner 
7930fdc8d8SChris Lattner     case 'b':
8030fdc8d8SChris Lattner         show_bytes = true;
8130fdc8d8SChris Lattner         break;
8230fdc8d8SChris Lattner 
838651121cSJim Ingham     case 's':
8437023b06SJim Ingham         m_start_addr = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS, 0);
858651121cSJim Ingham         if (m_start_addr == LLDB_INVALID_ADDRESS)
8637023b06SJim Ingham             m_start_addr = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS, 16);
8730fdc8d8SChris Lattner 
888651121cSJim Ingham         if (m_start_addr == LLDB_INVALID_ADDRESS)
8937023b06SJim Ingham             error.SetErrorStringWithFormat ("Invalid start address string '%s'.\n", option_arg);
908651121cSJim Ingham         break;
918651121cSJim Ingham     case 'e':
9237023b06SJim Ingham         m_end_addr = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS, 0);
938651121cSJim Ingham         if (m_end_addr == LLDB_INVALID_ADDRESS)
9437023b06SJim Ingham             m_end_addr = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS, 16);
958651121cSJim Ingham 
968651121cSJim Ingham         if (m_end_addr == LLDB_INVALID_ADDRESS)
9737023b06SJim Ingham             error.SetErrorStringWithFormat ("Invalid end address string '%s'.\n", option_arg);
9830fdc8d8SChris Lattner         break;
9930fdc8d8SChris Lattner 
10030fdc8d8SChris Lattner     case 'n':
101*1080edbcSGreg Clayton         m_func_name.assign (option_arg);
10230fdc8d8SChris Lattner         break;
10330fdc8d8SChris Lattner 
10437023b06SJim Ingham     case 'p':
10537023b06SJim Ingham         m_at_pc = true;
10637023b06SJim Ingham         break;
10737023b06SJim Ingham 
108*1080edbcSGreg Clayton     case 'P':
109*1080edbcSGreg Clayton         m_plugin_name.assign (option_arg);
110*1080edbcSGreg Clayton         break;
111*1080edbcSGreg Clayton 
11230fdc8d8SChris Lattner     case 'r':
11330fdc8d8SChris Lattner         raw = true;
11430fdc8d8SChris Lattner         break;
11530fdc8d8SChris Lattner 
1168ceb8ba2SJohnny Chen     case 'f':
1178ceb8ba2SJohnny Chen         // The default action is to disassemble the function for the current frame.
1188ceb8ba2SJohnny Chen         // There's no need to set any flag.
1198ceb8ba2SJohnny Chen         break;
1208ceb8ba2SJohnny Chen 
12130fdc8d8SChris Lattner     default:
12230fdc8d8SChris Lattner         error.SetErrorStringWithFormat("Unrecognized short option '%c'.\n", short_option);
12330fdc8d8SChris Lattner         break;
12430fdc8d8SChris Lattner     }
12530fdc8d8SChris Lattner 
12630fdc8d8SChris Lattner     return error;
12730fdc8d8SChris Lattner }
12830fdc8d8SChris Lattner 
12930fdc8d8SChris Lattner void
13030fdc8d8SChris Lattner CommandObjectDisassemble::CommandOptions::ResetOptionValues ()
13130fdc8d8SChris Lattner {
13230fdc8d8SChris Lattner     Options::ResetOptionValues();
13330fdc8d8SChris Lattner     show_mixed = false;
13430fdc8d8SChris Lattner     show_bytes = false;
13530fdc8d8SChris Lattner     num_lines_context = 0;
13637023b06SJim Ingham     num_instructions = 0;
13730fdc8d8SChris Lattner     m_func_name.clear();
13837023b06SJim Ingham     m_at_pc = false;
1398651121cSJim Ingham     m_start_addr = LLDB_INVALID_ADDRESS;
1408651121cSJim Ingham     m_end_addr = LLDB_INVALID_ADDRESS;
141a68c1a21SSean Callanan     raw = false;
142*1080edbcSGreg Clayton     m_plugin_name.clear();
14330fdc8d8SChris Lattner }
14430fdc8d8SChris Lattner 
145e0d378b3SGreg Clayton const OptionDefinition*
14630fdc8d8SChris Lattner CommandObjectDisassemble::CommandOptions::GetDefinitions ()
14730fdc8d8SChris Lattner {
14830fdc8d8SChris Lattner     return g_option_table;
14930fdc8d8SChris Lattner }
15030fdc8d8SChris Lattner 
151e0d378b3SGreg Clayton OptionDefinition
15230fdc8d8SChris Lattner CommandObjectDisassemble::CommandOptions::g_option_table[] =
15330fdc8d8SChris Lattner {
154deaab222SCaroline Tice { LLDB_OPT_SET_ALL, false, "bytes",    'b', no_argument,       NULL, 0, eArgTypeNone,    "Show opcode bytes when disassembling."},
15537023b06SJim Ingham { LLDB_OPT_SET_ALL, false, "context",  'x', required_argument, NULL, 0, eArgTypeNumLines,"Number of context lines of source to show."},
156deaab222SCaroline Tice { LLDB_OPT_SET_ALL, false, "mixed",    'm', no_argument,       NULL, 0, eArgTypeNone,    "Enable mixed source and assembly display."},
157deaab222SCaroline Tice { LLDB_OPT_SET_ALL, false, "raw",      'r', no_argument,       NULL, 0, eArgTypeNone,    "Print raw disassembly with no symbol information."},
158*1080edbcSGreg Clayton { LLDB_OPT_SET_ALL, false, "plugin",   'P', required_argument, NULL, 0, eArgTypePlugin,  "Name of the disassembler plugin you want to use."},
15930fdc8d8SChris Lattner 
160405fe67fSCaroline Tice { LLDB_OPT_SET_1, true, "start-address",  's', required_argument, NULL, 0, eArgTypeStartAddress,      "Address at which to start disassembling."},
161405fe67fSCaroline Tice { LLDB_OPT_SET_1, false, "end-address",  'e', required_argument, NULL, 0, eArgTypeEndAddress,      "Address at which to end disassembling."},
16230fdc8d8SChris Lattner 
16337023b06SJim Ingham { LLDB_OPT_SET_2, true, "start-address",  's', required_argument, NULL, 0, eArgTypeStartAddress,      "Address at which to start disassembling."},
16437023b06SJim Ingham { LLDB_OPT_SET_2, false, "instruction-count",  'c', required_argument, NULL, 0, eArgTypeNumLines,      "Number of instructions to display."},
1658651121cSJim Ingham 
16637023b06SJim Ingham { LLDB_OPT_SET_3, true, "name",     'n', required_argument, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,             "Disassemble entire contents of the given function name."},
16737023b06SJim Ingham { LLDB_OPT_SET_3, false, "instruction-count",  'c', required_argument, NULL, 0, eArgTypeNumLines,      "Number of instructions to display."},
16837023b06SJim Ingham 
16937023b06SJim Ingham { LLDB_OPT_SET_4, true, "current-frame", 'f',  no_argument, NULL, 0, eArgTypeNone,             "Disassemble from the start of the current frame's function."},
17037023b06SJim Ingham { LLDB_OPT_SET_4, false, "instruction-count",  'c', required_argument, NULL, 0, eArgTypeNumLines,      "Number of instructions to display."},
17137023b06SJim Ingham 
17237023b06SJim Ingham { LLDB_OPT_SET_5, true, "current-pc", 'p',  no_argument, NULL, 0, eArgTypeNone,             "Disassemble from the current pc."},
17337023b06SJim Ingham { LLDB_OPT_SET_5, false, "instruction-count",  'c', required_argument, NULL, 0, eArgTypeNumLines,      "Number of instructions to display."},
17430fdc8d8SChris Lattner 
175deaab222SCaroline Tice { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
17630fdc8d8SChris Lattner };
17730fdc8d8SChris Lattner 
17830fdc8d8SChris Lattner 
17930fdc8d8SChris Lattner 
18030fdc8d8SChris Lattner //-------------------------------------------------------------------------
18130fdc8d8SChris Lattner // CommandObjectDisassemble
18230fdc8d8SChris Lattner //-------------------------------------------------------------------------
18330fdc8d8SChris Lattner 
184a7015092SGreg Clayton CommandObjectDisassemble::CommandObjectDisassemble (CommandInterpreter &interpreter) :
185a7015092SGreg Clayton     CommandObject (interpreter,
186a7015092SGreg Clayton                    "disassemble",
1873f4c09c1SCaroline Tice                    "Disassemble bytes in the current function, or elsewhere in the executable program as specified by the user.",
1888651121cSJim Ingham                    "disassemble [<cmd-options>]")
18930fdc8d8SChris Lattner {
19030fdc8d8SChris Lattner }
19130fdc8d8SChris Lattner 
19230fdc8d8SChris Lattner CommandObjectDisassemble::~CommandObjectDisassemble()
19330fdc8d8SChris Lattner {
19430fdc8d8SChris Lattner }
19530fdc8d8SChris Lattner 
19630fdc8d8SChris Lattner bool
19730fdc8d8SChris Lattner CommandObjectDisassemble::Execute
19830fdc8d8SChris Lattner (
19930fdc8d8SChris Lattner     Args& command,
20030fdc8d8SChris Lattner     CommandReturnObject &result
20130fdc8d8SChris Lattner )
20230fdc8d8SChris Lattner {
203a7015092SGreg Clayton     Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
20430fdc8d8SChris Lattner     if (target == NULL)
20530fdc8d8SChris Lattner     {
20630fdc8d8SChris Lattner         result.AppendError ("invalid target, set executable file using 'file' command");
20730fdc8d8SChris Lattner         result.SetStatus (eReturnStatusFailed);
20830fdc8d8SChris Lattner         return false;
20930fdc8d8SChris Lattner     }
21030fdc8d8SChris Lattner 
21130fdc8d8SChris Lattner     ArchSpec arch(target->GetArchitecture());
21230fdc8d8SChris Lattner     if (!arch.IsValid())
21330fdc8d8SChris Lattner     {
21430fdc8d8SChris Lattner         result.AppendError ("target needs valid architecure in order to be able to disassemble");
21530fdc8d8SChris Lattner         result.SetStatus (eReturnStatusFailed);
21630fdc8d8SChris Lattner         return false;
21730fdc8d8SChris Lattner     }
21830fdc8d8SChris Lattner 
219*1080edbcSGreg Clayton     const char *plugin_name = m_options.GetPluginName ();
220*1080edbcSGreg Clayton     Disassembler *disassembler = Disassembler::FindPlugin(arch, plugin_name);
22130fdc8d8SChris Lattner 
22230fdc8d8SChris Lattner     if (disassembler == NULL)
22330fdc8d8SChris Lattner     {
224*1080edbcSGreg Clayton         if (plugin_name)
225*1080edbcSGreg Clayton             result.AppendErrorWithFormat ("Unable to find Disassembler plug-in for %s architecture named '%s'.\n",
226*1080edbcSGreg Clayton                                           arch.GetArchitectureName(),
227*1080edbcSGreg Clayton                                           plugin_name);
228*1080edbcSGreg Clayton         else
229*1080edbcSGreg Clayton             result.AppendErrorWithFormat ("Unable to find Disassembler plug-in for %s architecture.\n",
230*1080edbcSGreg Clayton                                           arch.GetArchitectureName());
23130fdc8d8SChris Lattner         result.SetStatus (eReturnStatusFailed);
23230fdc8d8SChris Lattner         return false;
23330fdc8d8SChris Lattner     }
23430fdc8d8SChris Lattner 
23530fdc8d8SChris Lattner     result.SetStatus (eReturnStatusSuccessFinishResult);
23630fdc8d8SChris Lattner 
237dda4f7b5SGreg Clayton     if (command.GetArgumentCount() != 0)
23830fdc8d8SChris Lattner     {
239a7015092SGreg Clayton         result.AppendErrorWithFormat ("\"disassemble\" arguments are specified as options.\n");
240a7015092SGreg Clayton         GetOptions()->GenerateOptionUsage (m_interpreter,
241a7015092SGreg Clayton                                            result.GetErrorStream(),
242a7015092SGreg Clayton                                            this);
243a7015092SGreg Clayton 
2448651121cSJim Ingham         result.SetStatus (eReturnStatusFailed);
2458651121cSJim Ingham         return false;
2468651121cSJim Ingham     }
2478651121cSJim Ingham 
248dda4f7b5SGreg Clayton     if (m_options.show_mixed && m_options.num_lines_context == 0)
2496dbd3983SGreg Clayton         m_options.num_lines_context = 1;
250dda4f7b5SGreg Clayton 
25137023b06SJim Ingham     ExecutionContext exe_ctx(m_interpreter.GetDebugger().GetExecutionContext());
25237023b06SJim Ingham 
253dda4f7b5SGreg Clayton     if (!m_options.m_func_name.empty())
254dda4f7b5SGreg Clayton     {
255dda4f7b5SGreg Clayton         ConstString name(m_options.m_func_name.c_str());
256dda4f7b5SGreg Clayton 
257a7015092SGreg Clayton         if (Disassembler::Disassemble (m_interpreter.GetDebugger(),
258dda4f7b5SGreg Clayton                                        arch,
259*1080edbcSGreg Clayton                                        plugin_name,
260dda4f7b5SGreg Clayton                                        exe_ctx,
261dda4f7b5SGreg Clayton                                        name,
262dda4f7b5SGreg Clayton                                        NULL,    // Module *
26337023b06SJim Ingham                                        m_options.num_instructions,
264dda4f7b5SGreg Clayton                                        m_options.show_mixed ? m_options.num_lines_context : 0,
265dda4f7b5SGreg Clayton                                        m_options.show_bytes,
266b3396b22SSean Callanan                                        m_options.raw,
267dda4f7b5SGreg Clayton                                        result.GetOutputStream()))
268dda4f7b5SGreg Clayton         {
269dda4f7b5SGreg Clayton             result.SetStatus (eReturnStatusSuccessFinishResult);
270dda4f7b5SGreg Clayton         }
271dda4f7b5SGreg Clayton         else
272dda4f7b5SGreg Clayton         {
273dda4f7b5SGreg Clayton             result.AppendErrorWithFormat ("Unable to find symbol with name '%s'.\n", name.GetCString());
274dda4f7b5SGreg Clayton             result.SetStatus (eReturnStatusFailed);
275dda4f7b5SGreg Clayton         }
276dda4f7b5SGreg Clayton     }
277dda4f7b5SGreg Clayton     else
278dda4f7b5SGreg Clayton     {
27937023b06SJim Ingham         Address start_addr;
28037023b06SJim Ingham         lldb::addr_t range_byte_size = DEFAULT_DISASM_BYTE_SIZE;
28137023b06SJim Ingham 
28237023b06SJim Ingham         if (m_options.m_at_pc)
2838651121cSJim Ingham         {
28437023b06SJim Ingham             if (exe_ctx.frame == NULL)
28537023b06SJim Ingham             {
28637023b06SJim Ingham                 result.AppendError ("Cannot disassemble around the current PC without a selected frame.\n");
28737023b06SJim Ingham                 result.SetStatus (eReturnStatusFailed);
28837023b06SJim Ingham                 return false;
28937023b06SJim Ingham             }
29037023b06SJim Ingham             start_addr = exe_ctx.frame->GetFrameCodeAddress();
29137023b06SJim Ingham             if (m_options.num_instructions == 0)
29237023b06SJim Ingham             {
29337023b06SJim Ingham                 // Disassembling at the PC always disassembles some number of instructions (not the whole function).
29437023b06SJim Ingham                 m_options.num_instructions = DEFAULT_DISASM_NUM_INS;
29537023b06SJim Ingham             }
29637023b06SJim Ingham         }
29737023b06SJim Ingham         else
29837023b06SJim Ingham         {
29937023b06SJim Ingham             start_addr.SetOffset (m_options.m_start_addr);
30037023b06SJim Ingham             if (start_addr.IsValid())
30137023b06SJim Ingham             {
3028651121cSJim Ingham                 if (m_options.m_end_addr != LLDB_INVALID_ADDRESS)
3038651121cSJim Ingham                 {
304dda4f7b5SGreg Clayton                     if (m_options.m_end_addr < m_options.m_start_addr)
3058651121cSJim Ingham                     {
3068651121cSJim Ingham                         result.AppendErrorWithFormat ("End address before start address.\n");
3078651121cSJim Ingham                         result.SetStatus (eReturnStatusFailed);
3088651121cSJim Ingham                         return false;
3098651121cSJim Ingham                     }
31037023b06SJim Ingham                     range_byte_size = m_options.m_end_addr - m_options.m_start_addr;
31137023b06SJim Ingham                 }
31237023b06SJim Ingham             }
31337023b06SJim Ingham         }
31437023b06SJim Ingham 
31537023b06SJim Ingham         if (m_options.num_instructions != 0)
31637023b06SJim Ingham         {
31737023b06SJim Ingham             if (!start_addr.IsValid())
31837023b06SJim Ingham             {
31937023b06SJim Ingham                 // The default action is to disassemble the current frame function.
32037023b06SJim Ingham                 if (exe_ctx.frame)
32137023b06SJim Ingham                 {
32237023b06SJim Ingham                     SymbolContext sc(exe_ctx.frame->GetSymbolContext(eSymbolContextFunction | eSymbolContextSymbol));
32337023b06SJim Ingham                     if (sc.function)
32437023b06SJim Ingham                         start_addr = sc.function->GetAddressRange().GetBaseAddress();
32537023b06SJim Ingham                     else if (sc.symbol && sc.symbol->GetAddressRangePtr())
32637023b06SJim Ingham                         start_addr = sc.symbol->GetAddressRangePtr()->GetBaseAddress();
32737023b06SJim Ingham                     else
32837023b06SJim Ingham                         start_addr = exe_ctx.frame->GetFrameCodeAddress();
32937023b06SJim Ingham                 }
33037023b06SJim Ingham 
33137023b06SJim Ingham                 if (!start_addr.IsValid())
33237023b06SJim Ingham                 {
33337023b06SJim Ingham                     result.AppendError ("invalid frame");
33437023b06SJim Ingham                     result.SetStatus (eReturnStatusFailed);
33537023b06SJim Ingham                     return false;
33637023b06SJim Ingham                 }
33737023b06SJim Ingham             }
33837023b06SJim Ingham 
33937023b06SJim Ingham             if (Disassembler::Disassemble (m_interpreter.GetDebugger(),
34037023b06SJim Ingham                                            arch,
341*1080edbcSGreg Clayton                                            plugin_name,
34237023b06SJim Ingham                                            exe_ctx,
34337023b06SJim Ingham                                            start_addr,
34437023b06SJim Ingham                                            m_options.num_instructions,
34537023b06SJim Ingham                                            m_options.show_mixed ? m_options.num_lines_context : 0,
34637023b06SJim Ingham                                            m_options.show_bytes,
34737023b06SJim Ingham                                            m_options.raw,
34837023b06SJim Ingham                                            result.GetOutputStream()))
34937023b06SJim Ingham             {
35037023b06SJim Ingham                 result.SetStatus (eReturnStatusSuccessFinishResult);
3518651121cSJim Ingham             }
3528651121cSJim Ingham             else
35337023b06SJim Ingham             {
35437023b06SJim Ingham                 result.AppendErrorWithFormat ("Failed to disassemble memory at 0x%8.8llx.\n", m_options.m_start_addr);
35537023b06SJim Ingham                 result.SetStatus (eReturnStatusFailed);
35637023b06SJim Ingham             }
35737023b06SJim Ingham         }
35837023b06SJim Ingham         else
35937023b06SJim Ingham         {
36037023b06SJim Ingham             AddressRange range;
36137023b06SJim Ingham             if (start_addr.IsValid())
36237023b06SJim Ingham             {
36337023b06SJim Ingham                 range.GetBaseAddress() = start_addr;
36437023b06SJim Ingham                 range.SetByteSize (range_byte_size);
3658651121cSJim Ingham             }
3668651121cSJim Ingham             else
36730fdc8d8SChris Lattner             {
3688ceb8ba2SJohnny Chen                 // The default action is to disassemble the current frame function.
36930fdc8d8SChris Lattner                 if (exe_ctx.frame)
37030fdc8d8SChris Lattner                 {
371dae97b4aSJason Molenda                     SymbolContext sc(exe_ctx.frame->GetSymbolContext(eSymbolContextFunction | eSymbolContextSymbol));
37230fdc8d8SChris Lattner                     if (sc.function)
373dda4f7b5SGreg Clayton                         range = sc.function->GetAddressRange();
37430fdc8d8SChris Lattner                     else if (sc.symbol && sc.symbol->GetAddressRangePtr())
375dda4f7b5SGreg Clayton                         range = *sc.symbol->GetAddressRangePtr();
37630fdc8d8SChris Lattner                     else
3779da7bd07SGreg Clayton                         range.GetBaseAddress() = exe_ctx.frame->GetFrameCodeAddress();
37830fdc8d8SChris Lattner                 }
37930fdc8d8SChris Lattner                 else
38030fdc8d8SChris Lattner                 {
38130fdc8d8SChris Lattner                     result.AppendError ("invalid frame");
38230fdc8d8SChris Lattner                     result.SetStatus (eReturnStatusFailed);
38330fdc8d8SChris Lattner                     return false;
38430fdc8d8SChris Lattner                 }
38530fdc8d8SChris Lattner             }
386dda4f7b5SGreg Clayton             if (range.GetByteSize() == 0)
387dda4f7b5SGreg Clayton                 range.SetByteSize(DEFAULT_DISASM_BYTE_SIZE);
38830fdc8d8SChris Lattner 
389a7015092SGreg Clayton             if (Disassembler::Disassemble (m_interpreter.GetDebugger(),
390dda4f7b5SGreg Clayton                                            arch,
391*1080edbcSGreg Clayton                                            plugin_name,
392dda4f7b5SGreg Clayton                                            exe_ctx,
393dda4f7b5SGreg Clayton                                            range,
39437023b06SJim Ingham                                            m_options.num_instructions,
395dda4f7b5SGreg Clayton                                            m_options.show_mixed ? m_options.num_lines_context : 0,
396dda4f7b5SGreg Clayton                                            m_options.show_bytes,
397b3396b22SSean Callanan                                            m_options.raw,
398dda4f7b5SGreg Clayton                                            result.GetOutputStream()))
39930fdc8d8SChris Lattner             {
400dda4f7b5SGreg Clayton                 result.SetStatus (eReturnStatusSuccessFinishResult);
40130fdc8d8SChris Lattner             }
40230fdc8d8SChris Lattner             else
40330fdc8d8SChris Lattner             {
404dda4f7b5SGreg Clayton                 result.AppendErrorWithFormat ("Failed to disassemble memory at 0x%8.8llx.\n", m_options.m_start_addr);
40530fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusFailed);
40630fdc8d8SChris Lattner             }
40730fdc8d8SChris Lattner         }
40837023b06SJim Ingham     }
40930fdc8d8SChris Lattner 
41030fdc8d8SChris Lattner     return result.Succeeded();
41130fdc8d8SChris Lattner }
412