//===-- CommandObjectDisassemble.cpp ----------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "lldb/lldb-python.h"

#include "CommandObjectDisassemble.h"

// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
#include "lldb/Core/AddressRange.h"
#include "lldb/Core/Disassembler.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/SourceManager.h"
#include "lldb/Interpreter/Args.h"
#include "lldb/Interpreter/CommandCompletions.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Interpreter/Options.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/Symbol.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/StackFrame.h"
#include "lldb/Target/Target.h"

#define DEFAULT_DISASM_BYTE_SIZE 32
#define DEFAULT_DISASM_NUM_INS  4

using namespace lldb;
using namespace lldb_private;

CommandObjectDisassemble::CommandOptions::CommandOptions (CommandInterpreter &interpreter) :
    Options(interpreter),
    num_lines_context(0),
    num_instructions (0),
    func_name(),
    current_function (false),
    start_addr(),
    end_addr (),
    at_pc (false),
    frame_line (false),
    plugin_name (),
    flavor_string(),
    arch(),
    some_location_specified (false),
    symbol_containing_addr () 
{
    OptionParsingStarting();
}

CommandObjectDisassemble::CommandOptions::~CommandOptions ()
{
}

Error
CommandObjectDisassemble::CommandOptions::SetOptionValue (uint32_t option_idx, const char *option_arg)
{
    Error error;

    const int short_option = m_getopt_table[option_idx].val;

    bool success;
    
    switch (short_option)
    {
    case 'm':
        show_mixed = true;
        break;

    case 'C':
        num_lines_context = Args::StringToUInt32(option_arg, 0, 0, &success);
        if (!success)
            error.SetErrorStringWithFormat ("invalid num context lines string: \"%s\"", option_arg);
        break;

    case 'c':
        num_instructions = Args::StringToUInt32(option_arg, 0, 0, &success);
        if (!success)
            error.SetErrorStringWithFormat ("invalid num of instructions string: \"%s\"", option_arg);
        break;

    case 'b':
        show_bytes = true;
        break;

    case 's':
        {
            ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
            start_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error);
            if (start_addr != LLDB_INVALID_ADDRESS)
                some_location_specified = true;
        }
        break;
    case 'e':
        {
            ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
            end_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error);
            if (end_addr != LLDB_INVALID_ADDRESS)
                some_location_specified = true;
        }
        break;
    case 'n':
        func_name.assign (option_arg);
        some_location_specified = true;
        break;

    case 'p':
        at_pc = true;
        some_location_specified = true;
        break;

    case 'l':
        frame_line = true;
        // Disassemble the current source line kind of implies showing mixed
        // source code context. 
        show_mixed = true;
        some_location_specified = true;
        break;

    case 'P':
        plugin_name.assign (option_arg);
        break;

    case 'F':
        {
            Target *target = m_interpreter.GetExecutionContext().GetTargetPtr();
            if (target->GetArchitecture().GetTriple().getArch() == llvm::Triple::x86
                || target->GetArchitecture().GetTriple().getArch() == llvm::Triple::x86_64)
            {
                flavor_string.assign (option_arg);
            }
            else
                error.SetErrorStringWithFormat("Disassembler flavors are currently only supported for x86 and x86_64 targets.");
            break;
        }
    case 'r':
        raw = true;
        break;

    case 'f':
        current_function = true;
        some_location_specified = true;
        break;

    case 'A':
        if (!arch.SetTriple (option_arg, m_interpreter.GetPlatform (true).get()))
            arch.SetTriple (option_arg);
        break;

    case 'a':
        {
            ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
            symbol_containing_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error);
            if (symbol_containing_addr != LLDB_INVALID_ADDRESS)
            {
                some_location_specified = true;
            }
        }
        break;

    default:
        error.SetErrorStringWithFormat("unrecognized short option '%c'", short_option);
        break;
    }

    return error;
}

void
CommandObjectDisassemble::CommandOptions::OptionParsingStarting ()
{
    show_mixed = false;
    show_bytes = false;
    num_lines_context = 0;
    num_instructions = 0;
    func_name.clear();
    current_function = false;
    at_pc = false;
    frame_line = false;
    start_addr = LLDB_INVALID_ADDRESS;
    end_addr = LLDB_INVALID_ADDRESS;
    symbol_containing_addr = LLDB_INVALID_ADDRESS;
    raw = false;
    plugin_name.clear();
    
    Target *target = m_interpreter.GetExecutionContext().GetTargetPtr();
    
    // This is a hack till we get the ability to specify features based on architecture.  For now GetDisassemblyFlavor
    // is really only valid for x86 (and for the llvm assembler plugin, but I'm papering over that since that is the
    // only disassembler plugin we have...
    if (target)
    {
        if (target->GetArchitecture().GetTriple().getArch() == llvm::Triple::x86
            || target->GetArchitecture().GetTriple().getArch() == llvm::Triple::x86_64)
        {
            flavor_string.assign(target->GetDisassemblyFlavor());
        }
        else
            flavor_string.assign ("default");
        
    }
    else
        flavor_string.assign("default");
    
    arch.Clear();
    some_location_specified = false;
}

Error
CommandObjectDisassemble::CommandOptions::OptionParsingFinished ()
{
    if (!some_location_specified)
        current_function = true;
    return Error();
    
}

const OptionDefinition*
CommandObjectDisassemble::CommandOptions::GetDefinitions ()
{
    return g_option_table;
}

OptionDefinition
CommandObjectDisassemble::CommandOptions::g_option_table[] =
{
{ LLDB_OPT_SET_ALL, false, "bytes"        , 'b', no_argument        , NULL, 0, eArgTypeNone,        "Show opcode bytes when disassembling."},
{ LLDB_OPT_SET_ALL, false, "context"      , 'C', required_argument  , NULL, 0, eArgTypeNumLines,    "Number of context lines of source to show."},
{ LLDB_OPT_SET_ALL, false, "mixed"        , 'm', no_argument        , NULL, 0, eArgTypeNone,        "Enable mixed source and assembly display."},
{ LLDB_OPT_SET_ALL, false, "raw"          , 'r', no_argument        , NULL, 0, eArgTypeNone,        "Print raw disassembly with no symbol information."},
{ LLDB_OPT_SET_ALL, false, "plugin"       , 'P', required_argument  , NULL, 0, eArgTypePlugin,      "Name of the disassembler plugin you want to use."},
{ LLDB_OPT_SET_ALL, false, "flavor"       , 'F', required_argument  , NULL, 0, eArgTypeDisassemblyFlavor,        "Name of the disassembly flavor you want to use.  "
                                                                                                    "Currently the only valid options are default, and for Intel"
                                                                                                    " architectures, att and intel."},
{ LLDB_OPT_SET_ALL, false, "arch"         , 'A', required_argument  , NULL, 0, eArgTypeArchitecture,"Specify the architecture to use from cross disassembly."},
{ LLDB_OPT_SET_1  |
  LLDB_OPT_SET_2  , true , "start-address", 's', required_argument  , NULL, 0, eArgTypeAddressOrExpression,"Address at which to start disassembling."},
{ LLDB_OPT_SET_1  , false, "end-address"  , 'e', required_argument  , NULL, 0, eArgTypeAddressOrExpression,  "Address at which to end disassembling."},
{ LLDB_OPT_SET_2  |
  LLDB_OPT_SET_3  |
  LLDB_OPT_SET_4  |
  LLDB_OPT_SET_5  , false, "count"        , 'c', required_argument  , NULL, 0, eArgTypeNumLines,    "Number of instructions to display."},
{ LLDB_OPT_SET_3  , false, "name"         , 'n', required_argument  , NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
                                                                                                    "Disassemble entire contents of the given function name."},
{ LLDB_OPT_SET_4  , false, "frame"        , 'f', no_argument        , NULL, 0, eArgTypeNone,        "Disassemble from the start of the current frame's function."},
{ LLDB_OPT_SET_5  , false, "pc"           , 'p', no_argument        , NULL, 0, eArgTypeNone,        "Disassemble around the current pc."},
{ LLDB_OPT_SET_6  , false, "line"         , 'l', no_argument        , NULL, 0, eArgTypeNone,        "Disassemble the current frame's current source line instructions if there debug line table information, else disasemble around the pc."},
{ LLDB_OPT_SET_7  , false, "address"      , 'a', required_argument  , NULL, 0, eArgTypeAddressOrExpression, "Disassemble function containing this address."},
{ 0               , false, NULL           ,   0, 0                  , NULL, 0, eArgTypeNone,        NULL }
};



//-------------------------------------------------------------------------
// CommandObjectDisassemble
//-------------------------------------------------------------------------

CommandObjectDisassemble::CommandObjectDisassemble (CommandInterpreter &interpreter) :
    CommandObjectParsed (interpreter,
                         "disassemble",
                         "Disassemble bytes in the current function, or elsewhere in the executable program as specified by the user.",
                         "disassemble [<cmd-options>]"),
    m_options (interpreter)
{
}

CommandObjectDisassemble::~CommandObjectDisassemble()
{
}

bool
CommandObjectDisassemble::DoExecute (Args& command, CommandReturnObject &result)
{
    Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
    if (target == NULL)
    {
        result.AppendError ("invalid target, create a debug target using the 'target create' command");
        result.SetStatus (eReturnStatusFailed);
        return false;
    }
    if (!m_options.arch.IsValid())
        m_options.arch = target->GetArchitecture();

    if (!m_options.arch.IsValid())
    {
        result.AppendError ("use the --arch option or set the target architecure to disassemble");
        result.SetStatus (eReturnStatusFailed);
        return false;
    }

    const char *plugin_name = m_options.GetPluginName ();
    const char *flavor_string = m_options.GetFlavorString();

    DisassemblerSP disassembler = Disassembler::FindPlugin(m_options.arch, flavor_string, plugin_name);

    if (!disassembler)
    {
        if (plugin_name)
        {
            result.AppendErrorWithFormat ("Unable to find Disassembler plug-in named '%s' that supports the '%s' architecture.\n",
                                          plugin_name,
                                          m_options.arch.GetArchitectureName());
        }
        else
            result.AppendErrorWithFormat ("Unable to find Disassembler plug-in for the '%s' architecture.\n", 
                                          m_options.arch.GetArchitectureName());
        result.SetStatus (eReturnStatusFailed);
        return false;
    }
    else if (flavor_string != NULL && !disassembler->FlavorValidForArchSpec(m_options.arch, flavor_string))
        result.AppendWarningWithFormat("invalid disassembler flavor \"%s\", using default.\n", flavor_string);

    result.SetStatus (eReturnStatusSuccessFinishResult);

    if (command.GetArgumentCount() != 0)
    {
        result.AppendErrorWithFormat ("\"disassemble\" arguments are specified as options.\n");
        GetOptions()->GenerateOptionUsage (result.GetErrorStream(), this);
        result.SetStatus (eReturnStatusFailed);
        return false;
    }
    
    if (m_options.show_mixed && m_options.num_lines_context == 0)
        m_options.num_lines_context = 1;

    // Always show the PC in the disassembly
    uint32_t options = Disassembler::eOptionMarkPCAddress;

    // Mark the source line for the current PC only if we are doing mixed source and assembly
    if (m_options.show_mixed)
        options |= Disassembler::eOptionMarkPCSourceLine;

    if (m_options.show_bytes)
        options |= Disassembler::eOptionShowBytes;

    if (m_options.raw)
        options |= Disassembler::eOptionRawOuput;

    if (!m_options.func_name.empty())
    {
        ConstString name(m_options.func_name.c_str());
        
        if (Disassembler::Disassemble (m_interpreter.GetDebugger(), 
                                       m_options.arch,
                                       plugin_name,
                                       flavor_string,
                                       m_exe_ctx,
                                       name,
                                       NULL,    // Module *
                                       m_options.num_instructions,
                                       m_options.show_mixed ? m_options.num_lines_context : 0,
                                       options,
                                       result.GetOutputStream()))
        {
            result.SetStatus (eReturnStatusSuccessFinishResult);
        }
        else
        {
            result.AppendErrorWithFormat ("Unable to find symbol with name '%s'.\n", name.GetCString());
            result.SetStatus (eReturnStatusFailed);
        }
    } 
    else
    {
        AddressRange range;
        StackFrame *frame = m_exe_ctx.GetFramePtr();
        if (m_options.frame_line)
        {
            if (frame == NULL)
            {
                result.AppendError ("Cannot disassemble around the current line without a selected frame.\n");
                result.SetStatus (eReturnStatusFailed);
                return false;
            }
            LineEntry pc_line_entry (frame->GetSymbolContext(eSymbolContextLineEntry).line_entry);
            if (pc_line_entry.IsValid())
            {
                range = pc_line_entry.range;
            }
            else
            {
                m_options.at_pc = true; // No line entry, so just disassemble around the current pc
                m_options.show_mixed = false;
            }
        }
        else if (m_options.current_function)
        {
            if (frame == NULL)
            {
                result.AppendError ("Cannot disassemble around the current function without a selected frame.\n");
                result.SetStatus (eReturnStatusFailed);
                return false;
            }
            Symbol *symbol = frame->GetSymbolContext(eSymbolContextSymbol).symbol;
            if (symbol)
            {
                range.GetBaseAddress() = symbol->GetAddress();
                range.SetByteSize(symbol->GetByteSize());
            }
        }

        // Did the "m_options.frame_line" find a valid range already? If so
        // skip the rest...
        if (range.GetByteSize() == 0)
        {
            if (m_options.at_pc)
            {
                if (frame == NULL)
                {
                    result.AppendError ("Cannot disassemble around the current PC without a selected frame.\n");
                    result.SetStatus (eReturnStatusFailed);
                    return false;
                }
                range.GetBaseAddress() = frame->GetFrameCodeAddress();
                if (m_options.num_instructions == 0)
                {
                    // Disassembling at the PC always disassembles some number of instructions (not the whole function).
                    m_options.num_instructions = DEFAULT_DISASM_NUM_INS;
                }
            }
            else
            {
                range.GetBaseAddress().SetOffset (m_options.start_addr);
                if (range.GetBaseAddress().IsValid())
                {
                    if (m_options.end_addr != LLDB_INVALID_ADDRESS)
                    {
                        if (m_options.end_addr <= m_options.start_addr)
                        {
                            result.AppendErrorWithFormat ("End address before start address.\n");
                            result.SetStatus (eReturnStatusFailed);
                            return false;            
                        }
                        range.SetByteSize (m_options.end_addr - m_options.start_addr);
                    }
                }
                else
                {
                    if (m_options.symbol_containing_addr != LLDB_INVALID_ADDRESS 
                        && target 
                        && !target->GetSectionLoadList().IsEmpty())
                    {
                        bool failed = false;
                        Address symbol_containing_address;
                        if (target->GetSectionLoadList().ResolveLoadAddress (m_options.symbol_containing_addr, symbol_containing_address))
                        {
                            ModuleSP module_sp (symbol_containing_address.GetModule());
                            SymbolContext sc;
                            module_sp->ResolveSymbolContextForAddress (symbol_containing_address, eSymbolContextEverything, sc);
                            if (sc.function || sc.symbol)
                            {
                                sc.GetAddressRange (eSymbolContextFunction | eSymbolContextSymbol, 0, false, range);
                            }
                            else
                            {
                                failed = true;
                            }
                        }
                        else
                        {
                            failed = true;
                        }
                        if (failed)
                        {
                            result.AppendErrorWithFormat ("Could not find function bounds for address 0x%" PRIx64 "\n", m_options.symbol_containing_addr);
                            result.SetStatus (eReturnStatusFailed);
                            return false;
                        }
                    }
                }
            }
        }

        if (m_options.num_instructions != 0)
        {
            if (!range.GetBaseAddress().IsValid())
            {
                // The default action is to disassemble the current frame function.
                if (frame)
                {
                    SymbolContext sc(frame->GetSymbolContext(eSymbolContextFunction | eSymbolContextSymbol));
                    if (sc.function)
                        range.GetBaseAddress() = sc.function->GetAddressRange().GetBaseAddress();
                    else if (sc.symbol && sc.symbol->ValueIsAddress())
                        range.GetBaseAddress() = sc.symbol->GetAddress();
                    else
                        range.GetBaseAddress() = frame->GetFrameCodeAddress();
                }
                
                if (!range.GetBaseAddress().IsValid())
                {
                    result.AppendError ("invalid frame");
                    result.SetStatus (eReturnStatusFailed);
                    return false;
                }
            }

            if (Disassembler::Disassemble (m_interpreter.GetDebugger(), 
                                           m_options.arch,
                                           plugin_name,
                                           flavor_string,
                                           m_exe_ctx,
                                           range.GetBaseAddress(),
                                           m_options.num_instructions,
                                           m_options.show_mixed ? m_options.num_lines_context : 0,
                                           options,
                                           result.GetOutputStream()))
            {
                result.SetStatus (eReturnStatusSuccessFinishResult);
            }
            else
            {
                result.AppendErrorWithFormat ("Failed to disassemble memory at 0x%8.8" PRIx64 ".\n", m_options.start_addr);
                result.SetStatus (eReturnStatusFailed);            
            }
        }
        else
        {
            if (!range.GetBaseAddress().IsValid())
            {
                // The default action is to disassemble the current frame function.
                if (frame)
                {
                    SymbolContext sc(frame->GetSymbolContext(eSymbolContextFunction | eSymbolContextSymbol));
                    if (sc.function)
                        range = sc.function->GetAddressRange();
                    else if (sc.symbol && sc.symbol->ValueIsAddress())
                    {
                        range.GetBaseAddress() = sc.symbol->GetAddress();
                        range.SetByteSize (sc.symbol->GetByteSize());
                    }
                    else
                        range.GetBaseAddress() = frame->GetFrameCodeAddress();
                }
                else
                {
                    result.AppendError ("invalid frame");
                    result.SetStatus (eReturnStatusFailed);
                    return false;
                }
            }
            if (range.GetByteSize() == 0)
                range.SetByteSize(DEFAULT_DISASM_BYTE_SIZE);

            if (Disassembler::Disassemble (m_interpreter.GetDebugger(), 
                                           m_options.arch,
                                           plugin_name,
                                           flavor_string,
                                           m_exe_ctx,
                                           range,
                                           m_options.num_instructions,
                                           m_options.show_mixed ? m_options.num_lines_context : 0,
                                           options,
                                           result.GetOutputStream()))
            {
                result.SetStatus (eReturnStatusSuccessFinishResult);
            }
            else
            {
                result.AppendErrorWithFormat ("Failed to disassemble memory at 0x%8.8" PRIx64 ".\n", m_options.start_addr);
                result.SetStatus (eReturnStatusFailed);            
            }
        }
    }

    return result.Succeeded();
}
