/*
 * Debugger memory handling
 *
 * Copyright 1993 Eric Youngdale
 * Copyright 1995 Alexandre Julliard
 * Copyright 2000-2005 Eric Pouech
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include "config.h"
#include "wine/port.h"

#include <stdlib.h>
#include <string.h>
#include <stdio.h>

#include "debugger.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(winedbg);

void* be_cpu_linearize(HANDLE hThread, const ADDRESS64* addr)
{
    assert(addr->Mode == AddrModeFlat);
    return (void*)(DWORD_PTR)addr->Offset;
}

unsigned be_cpu_build_addr(HANDLE hThread, const CONTEXT* ctx, ADDRESS64* addr, 
                           unsigned seg, unsigned long offset)
{
    addr->Mode    = AddrModeFlat;
    addr->Segment = 0; /* don't need segment */
    addr->Offset  = offset;
    return TRUE;
}

void* memory_to_linear_addr(const ADDRESS64* addr)
{
    return be_cpu->linearize(dbg_curr_thread->handle, addr);
}

BOOL memory_get_current_pc(ADDRESS64* addr)
{
    assert(be_cpu->get_addr);
    return be_cpu->get_addr(dbg_curr_thread->handle, &dbg_context, 
                            be_cpu_addr_pc, addr);
}

BOOL memory_get_current_stack(ADDRESS64* addr)
{
    assert(be_cpu->get_addr);
    return be_cpu->get_addr(dbg_curr_thread->handle, &dbg_context, 
                            be_cpu_addr_stack, addr);
}

BOOL memory_get_current_frame(ADDRESS64* addr)
{
    assert(be_cpu->get_addr);
    return be_cpu->get_addr(dbg_curr_thread->handle, &dbg_context, 
                            be_cpu_addr_frame, addr);
}

static void	memory_report_invalid_addr(const void* addr)
{
    ADDRESS64   address;

    address.Mode    = AddrModeFlat;
    address.Segment = 0;
    address.Offset  = (unsigned long)addr;
    dbg_printf("*** Invalid address ");
    print_address(&address, FALSE);
    dbg_printf(" ***\n");
}

/***********************************************************************
 *           memory_read_value
 *
 * Read a memory value.
 */
BOOL memory_read_value(const struct dbg_lvalue* lvalue, DWORD size, void* result)
{
    BOOL ret = FALSE;

    if (lvalue->cookie == DLV_TARGET)
    {
        void*   linear = memory_to_linear_addr(&lvalue->addr);
        if (!(ret = dbg_read_memory(linear, result, size)))
            memory_report_invalid_addr(linear);
    }
    else
    {
        if (lvalue->addr.Offset)
        {
            memcpy(result, (void*)(DWORD_PTR)lvalue->addr.Offset, size);
            ret = TRUE;
        }
    }
    return ret;
}

/***********************************************************************
 *           memory_write_value
 *
 * Store a value in memory.
 */
BOOL memory_write_value(const struct dbg_lvalue* lvalue, DWORD size, void* value)
{
    BOOL        ret = TRUE;
    DWORD64     os;

    os = ~(DWORD64)size;
    types_get_info(&lvalue->type, TI_GET_LENGTH, &os);
    assert(size == os);

    /* FIXME: only works on little endian systems */
    if (lvalue->cookie == DLV_TARGET)
    {
        void*       linear = memory_to_linear_addr(&lvalue->addr);
        if (!(ret = dbg_write_memory(linear, value, size)))
            memory_report_invalid_addr(linear);
    }
    else 
    {
        memcpy((void*)(DWORD_PTR)lvalue->addr.Offset, value, size);
    }
    return ret;
}

/***********************************************************************
 *           memory_examine
 *
 * Implementation of the 'x' command.
 */
void memory_examine(const struct dbg_lvalue *lvalue, int count, char format)
{
    int			i;
    char                buffer[256];
    ADDRESS64           addr;
    void               *linear;

    types_extract_as_address(lvalue, &addr);
    linear = memory_to_linear_addr(&addr);

    if (format != 'i' && count > 1)
    {
        print_address(&addr, FALSE);
        dbg_printf(": ");
    }

    switch (format)
    {
    case 'u':
        if (count == 1) count = 256;
        memory_get_string(dbg_curr_process, linear, 
                          TRUE, TRUE, buffer, min(count, sizeof(buffer)));
        dbg_printf("%s\n", buffer);
        return;
    case 's':
        if (count == 1) count = 256;
        memory_get_string(dbg_curr_process, linear,
                          TRUE, FALSE, buffer, min(count, sizeof(buffer)));
        dbg_printf("%s\n", buffer);
        return;
    case 'i':
        while (count-- && memory_disasm_one_insn(&addr));
        return;
    case 'g':
        while (count--)
        {
            GUID guid;
            if (!dbg_read_memory(linear, &guid, sizeof(guid)))
            {
                memory_report_invalid_addr(linear);
                break;
            }
            dbg_printf("{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}\n",
                       guid.Data1, guid.Data2, guid.Data3,
                       guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3],
                       guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7]);
            linear = (char*)linear + sizeof(guid);
            addr.Offset += sizeof(guid);
            if (count)
            {
                print_address(&addr, FALSE);
                dbg_printf(": ");
            }
        }
        return;

#define DO_DUMP2(_t,_l,_f,_vv) {                                        \
            _t _v;                                                      \
            for (i = 0; i < count; i++) {                               \
                if (!dbg_read_memory(linear, &_v, sizeof(_t)))          \
                { memory_report_invalid_addr(linear); break; }          \
                dbg_printf(_f, (_vv));                                  \
                addr.Offset += sizeof(_t);                              \
                linear = (char*)linear + sizeof(_t);                    \
                if ((i % (_l)) == (_l) - 1 && i != count - 1)           \
                {                                                       \
                    dbg_printf("\n");                                   \
                    print_address(&addr, FALSE);                        \
                    dbg_printf(": ");                                   \
                }                                                       \
            }                                                           \
            dbg_printf("\n");                                           \
        }
#define DO_DUMP(_t,_l,_f) DO_DUMP2(_t,_l,_f,_v)

    case 'x': DO_DUMP(int, 4, " %8.8x"); break;
    case 'd': DO_DUMP(unsigned int, 4, " %4.4d"); break;
    case 'w': DO_DUMP(unsigned short, 8, " %04x"); break;
    case 'a':
        if (sizeof(DWORD_PTR) == 4)
        {
            DO_DUMP(DWORD_PTR, 4, " %8.8lx");
        }
        else
        {
            DO_DUMP(DWORD_PTR, 2, " %16.16lx");
        }
        break;
    case 'c': DO_DUMP2(char, 32, " %c", (_v < 0x20) ? ' ' : _v); break;
    case 'b': DO_DUMP2(char, 16, " %02x", (_v) & 0xff); break;
    }
}

BOOL memory_get_string(struct dbg_process* pcs, void* addr, BOOL in_debuggee,
                       BOOL unicode, char* buffer, int size)
{
    SIZE_T      sz;
    WCHAR*      buffW;

    buffer[0] = 0;
    if (!addr) return FALSE;
    if (in_debuggee)
    {
        BOOL ret;

        if (!unicode) ret = pcs->process_io->read(pcs->handle, addr, buffer, size, &sz);
        else
        {
            buffW = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR));
            ret = pcs->process_io->read(pcs->handle, addr, buffW, size * sizeof(WCHAR), &sz);
            WideCharToMultiByte(CP_ACP, 0, buffW, sz / sizeof(WCHAR), buffer, size,
                                NULL, NULL);
            HeapFree(GetProcessHeap(), 0, buffW);
        }
        if (size) buffer[size-1] = 0;
        return ret;
    }
    else
    {
        lstrcpynA(buffer, addr, size);
    }
    return TRUE;
}

BOOL memory_get_string_indirect(struct dbg_process* pcs, void* addr, BOOL unicode, WCHAR* buffer, int size)
{
    void*       ad;
    SIZE_T	sz;

    buffer[0] = 0;
    if (addr &&
        pcs->process_io->read(pcs->handle, addr, &ad, sizeof(ad), &sz) && sz == sizeof(ad) && ad)
    {
        LPSTR buff;
        BOOL ret;

        if (unicode)
            ret = pcs->process_io->read(pcs->handle, ad, buffer, size * sizeof(WCHAR), &sz) && sz != 0;
        else
        {
            if ((buff = HeapAlloc(GetProcessHeap(), 0, size)))
            {
                ret = pcs->process_io->read(pcs->handle, ad, buff, size, &sz) && sz != 0;
                MultiByteToWideChar(CP_ACP, 0, buff, sz, buffer, size);
                HeapFree(GetProcessHeap(), 0, buff);
            }
            else ret = FALSE;
        }
        if (size) buffer[size-1] = 0;
        return ret;
    }
    return FALSE;
}

/*
 * Convert an address offset to hex string. If mode == 32, treat offset as
 * 32 bits (discard upper 32 bits), if mode == 64 use all 64 bits, if mode == 0
 * treat as either 32 or 64 bits, depending on whether we're running as
 * Wine32 or Wine64.
 */
char* memory_offset_to_string(char *str, DWORD64 offset, unsigned mode)
{
    if (mode != 32 && mode != 64)
    {
#ifdef _WIN64
        mode = 64;
#else
        mode = 32;
#endif
    }

    if (mode == 32)
        sprintf(str, "0x%08x", (unsigned int) offset);
    else
        sprintf(str, "0x%08x%08x", (unsigned int)(offset >> 32),
                (unsigned int)offset);

    return str;
}

static void dbg_print_longlong(LONGLONG sv, BOOL is_signed)
{
    char      tmp[24], *ptr = tmp + sizeof(tmp) - 1;
    ULONGLONG uv, div;
    *ptr = '\0';
    if (is_signed && sv < 0)    uv = -sv;
    else                        { uv = sv; is_signed = FALSE; }
    for (div = 10; uv; div *= 10, uv /= 10)
        *--ptr = '0' + (uv % 10);
    if (ptr == tmp + sizeof(tmp) - 1) *--ptr = '0';
    if (is_signed) *--ptr = '-';
    dbg_printf("%s", ptr);
}

static void dbg_print_hex(ULONGLONG sv)
{
    if (!sv)
    {
        dbg_printf("0");
        return;
    }

    if (sv >> 32)
        dbg_printf("0x%lx%08lx", (unsigned long)(sv >> 32), (unsigned long)sv);
    else
        dbg_printf("0x%04lx", (unsigned long)sv);
}

static void print_typed_basic(const struct dbg_lvalue* lvalue)
{
    LONGLONG            val_int;
    void*               val_ptr;
    long double         val_real;
    DWORD64             size64;
    DWORD               tag, size, count, bt;
    struct dbg_type     type = lvalue->type;
    struct dbg_type     sub_type;
    struct dbg_lvalue   sub_lvalue;

    if (!types_get_real_type(&type, &tag)) return;

    switch (tag)
    {
    case SymTagBaseType:
        if (!types_get_info(&type, TI_GET_LENGTH, &size64) ||
            !types_get_info(&type, TI_GET_BASETYPE, &bt))
        {
            WINE_ERR("Couldn't get information\n");
            RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
        }
        size = (DWORD)size64;
        switch (bt)
        {
        case btInt:
        case btLong:
            if (!be_cpu->fetch_integer(lvalue, size, TRUE, &val_int)) return;
            if (size == 1) goto print_char;
            dbg_print_hex(val_int);
            break;
        case btUInt:
        case btULong:
            if (!be_cpu->fetch_integer(lvalue, size, FALSE, &val_int)) return;
            dbg_print_hex(val_int);
            break;
        case btFloat:
            if (!be_cpu->fetch_float(lvalue, size, &val_real)) return;
            dbg_printf("%Lf", val_real);
            break;
        case btChar:
            if (!be_cpu->fetch_integer(lvalue, size, TRUE, &val_int)) return;
            /* FIXME: should do the same for a Unicode character (size == 2) */
        print_char:
            if (size == 1 && (val_int < 0x20 || val_int > 0x80))
                dbg_printf("%d", (int)val_int);
            else if (size == 2)
            {
                WCHAR   wch = (WCHAR)val_int;
                dbg_outputW(&wch, 1);
            }
            else
                dbg_printf("'%c'", (char)val_int);
            break;
        case btBool:
            if (!be_cpu->fetch_integer(lvalue, size, TRUE, &val_int)) return;
            dbg_printf("%s", val_int ? "true" : "false");
            break;
        default:
            WINE_FIXME("Unsupported basetype %u\n", bt);
            break;
        }
        break;
    case SymTagPointerType:
        if (!types_deref(lvalue, &sub_lvalue))
        {
            dbg_printf("Internal symbol error: unable to access memory location %p",
                       memory_to_linear_addr(&lvalue->addr));
            break;
        }
        val_ptr = memory_to_linear_addr(&sub_lvalue.addr);
        if (types_get_real_type(&sub_lvalue.type, &tag) && tag == SymTagBaseType &&
            types_get_info(&sub_lvalue.type, TI_GET_BASETYPE, &bt) &&
            types_get_info(&sub_lvalue.type, TI_GET_LENGTH, &size64))
        {
            char    buffer[1024];

            if (!val_ptr) dbg_printf("0x0");
            else if (((bt == btChar || bt == btInt) && size64 == 1) || (bt == btUInt && size64 == 2))
            {
                if (memory_get_string(dbg_curr_process, val_ptr, sub_lvalue.cookie == DLV_TARGET,
                                      size64 == 2, buffer, sizeof(buffer)))
                    dbg_printf("\"%s\"", buffer);
                else
                    dbg_printf("*** invalid address %p ***", val_ptr);
                break;
            }
        }
        dbg_printf("%p", val_ptr);
        break;
    case SymTagArrayType:
    case SymTagUDT:
        if (!memory_read_value(lvalue, sizeof(val_ptr), &val_ptr)) return;
        dbg_printf("%p", val_ptr);
        break;
    case SymTagEnum:
        {
            BOOL        ok = FALSE;

            /* FIXME: it depends on underlying type for enums 
             * (not supported yet in dbghelp)
             * Assuming 4 as for an int
             */
            if (!be_cpu->fetch_integer(lvalue, 4, TRUE, &val_int)) return;

            if (types_get_info(&type, TI_GET_CHILDRENCOUNT, &count))
            {
                char                    buffer[sizeof(TI_FINDCHILDREN_PARAMS) + 256 * sizeof(DWORD)];
                TI_FINDCHILDREN_PARAMS* fcp = (TI_FINDCHILDREN_PARAMS*)buffer;
                WCHAR*                  ptr;
                char                    tmp[256];
                VARIANT                 variant;
                int                     i;

                fcp->Start = 0;
                while (count)
                {
                    fcp->Count = min(count, 256);
                    if (types_get_info(&type, TI_FINDCHILDREN, fcp))
                    {
                        sub_type.module = type.module;
                        for (i = 0; i < min(fcp->Count, count); i++)
                        {
                            sub_type.id = fcp->ChildId[i];
                            if (!types_get_info(&sub_type, TI_GET_VALUE, &variant)) 
                                continue;
                            switch (variant.n1.n2.vt)
                            {
                            case VT_I4: ok = (val_int == variant.n1.n2.n3.lVal); break;
                            default: WINE_FIXME("Unsupported variant type (%u)\n", variant.n1.n2.vt);
                            }
                            if (ok)
                            {
                                ptr = NULL;
                                types_get_info(&sub_type, TI_GET_SYMNAME, &ptr);
                                if (!ptr) continue;
                                WideCharToMultiByte(CP_ACP, 0, ptr, -1, tmp, sizeof(tmp), NULL, NULL);
                                HeapFree(GetProcessHeap(), 0, ptr);
                                dbg_printf("%s", tmp);
                                count = 0; /* so that we'll get away from outter loop */
                                break;
                            }
                        }
                    }
                    count -= min(count, 256);
                    fcp->Start += 256;
                }
            }
            if (!ok) dbg_print_longlong(val_int, TRUE);
        }
        break;
    default:
        WINE_FIXME("Unsupported tag %u\n", tag);
        break;
    }
}

/***********************************************************************
 *           print_basic
 *
 * Implementation of the 'print' command.
 */
void print_basic(const struct dbg_lvalue* lvalue, char format)
{
    if (lvalue->type.id == dbg_itype_none)
    {
        dbg_printf("Unable to evaluate expression\n");
        return;
    }

    if (format != 0)
    {
        unsigned size;
        LONGLONG res = types_extract_as_longlong(lvalue, &size);
        DWORD hi;
        WCHAR wch;

        /* FIXME: this implies i386 byte ordering */
        switch (format)
        {
        case 'x':
            hi = (ULONG64)res >> 32;
            if (size == 8 && hi)
                dbg_printf("0x%x%08x", hi, (DWORD)res);
            else
                dbg_printf("0x%x", (DWORD)res);
            return;

        case 'd':
            dbg_print_longlong(res, TRUE);
            dbg_printf("\n");
            return;

        case 'c':
            dbg_printf("%d = '%c'", (char)(res & 0xff), (char)(res & 0xff));
            return;

        case 'u':
            wch = (WCHAR)(res & 0xFFFF);
            dbg_printf("%d = '", wch);
            dbg_outputW(&wch, 1);
            dbg_printf("'");
            return;

        case 'i':
        case 's':
        case 'w':
        case 'b':
            dbg_printf("Format specifier '%c' is meaningless in 'print' command\n", format);
        }
    }
    if (lvalue->type.id == dbg_itype_segptr)
    {
        dbg_print_longlong(types_extract_as_longlong(lvalue, NULL), TRUE);
        dbg_printf("\n");
    }
    else print_typed_basic(lvalue);
}

void print_bare_address(const ADDRESS64* addr)
{
    char hexbuf[MAX_OFFSET_TO_STR_LEN];

    switch (addr->Mode)
    {
    case AddrModeFlat: 
        dbg_printf("%s", memory_offset_to_string(hexbuf, addr->Offset, 0)); 
        break;
    case AddrModeReal:
    case AddrMode1616:
        dbg_printf("0x%04x:0x%04x", addr->Segment, (unsigned) addr->Offset);
        break;
    case AddrMode1632:
        dbg_printf("0x%04x:%s", addr->Segment,
                   memory_offset_to_string(hexbuf, addr->Offset, 32));
        break;
    default:
        dbg_printf("Unknown mode %x\n", addr->Mode);
        break;
    }
}

/***********************************************************************
 *           print_address
 *
 * Print an 16- or 32-bit address, with the nearest symbol if any.
 */
void print_address(const ADDRESS64* addr, BOOLEAN with_line)
{
    char                buffer[sizeof(SYMBOL_INFO) + 256];
    SYMBOL_INFO*        si = (SYMBOL_INFO*)buffer;
    void*               lin = memory_to_linear_addr(addr);
    DWORD64             disp64;
    DWORD               disp;

    print_bare_address(addr);

    si->SizeOfStruct = sizeof(*si);
    si->MaxNameLen   = 256;
    if (!SymFromAddr(dbg_curr_process->handle, (DWORD_PTR)lin, &disp64, si)) return;
    dbg_printf(" %s", si->Name);
    if (disp64) dbg_printf("+0x%lx", (DWORD_PTR)disp64);
    if (with_line)
    {
        IMAGEHLP_LINE64             il;
        IMAGEHLP_MODULE             im;

        il.SizeOfStruct = sizeof(il);
        if (SymGetLineFromAddr64(dbg_curr_process->handle, (DWORD_PTR)lin, &disp, &il))
            dbg_printf(" [%s:%u]", il.FileName, il.LineNumber);
        im.SizeOfStruct = sizeof(im);
        if (SymGetModuleInfo(dbg_curr_process->handle, (DWORD_PTR)lin, &im))
            dbg_printf(" in %s", im.ModuleName);
    }
}

BOOL memory_disasm_one_insn(ADDRESS64* addr)
{
    char        ch;

    print_address(addr, TRUE);
    dbg_printf(": ");
    if (!dbg_read_memory(memory_to_linear_addr(addr), &ch, sizeof(ch)))
    {
        dbg_printf("-- no code accessible --\n");
        return FALSE;
    }
    be_cpu->disasm_one_insn(addr, TRUE);
    dbg_printf("\n");
    return TRUE;
}

void memory_disassemble(const struct dbg_lvalue* xstart, 
                        const struct dbg_lvalue* xend, int instruction_count)
{
    static ADDRESS64 last = {0,0,0};
    int stop = 0;
    int i;

    if (!xstart && !xend) 
    {
        if (!last.Segment && !last.Offset) memory_get_current_pc(&last);
    }
    else
    {
        if (xstart)
            types_extract_as_address(xstart, &last);
        if (xend) 
            stop = types_extract_as_integer(xend);
    }
    for (i = 0; (instruction_count == 0 || i < instruction_count)  &&
                (stop == 0 || last.Offset <= stop); i++)
        memory_disasm_one_insn(&last);
}

BOOL memory_get_register(DWORD regno, DWORD_PTR** value, char* buffer, int len)
{
    const struct dbg_internal_var*  div;

    /* negative register values are wine's dbghelp hacks
     * see dlls/dbghelp/dbghelp_internal.h for the details      
     */
    switch (regno)
    {
    case -1:
        if (buffer) snprintf(buffer, len, "<internal error>");
        return FALSE;
    case -2:
        if (buffer) snprintf(buffer, len, "<couldn't compute location>");
        return FALSE;
    case -3:
        if (buffer) snprintf(buffer, len, "<is not available>");
        return FALSE;
    case -4:
        if (buffer) snprintf(buffer, len, "<couldn't read memory>");
        return FALSE;
    }

    for (div = dbg_context_vars; div->name; div++)
    {
        if (div->val == regno)
        {
            if (dbg_curr_thread->curr_frame != 0)
            {
                if (!stack_get_register_current_frame(regno, value))
                {
                    if (buffer) snprintf(buffer, len, "<register %s not in topmost frame>", div->name);
                    return FALSE;
                }
            }
            else
                *value = div->pval;

            if (buffer) lstrcpynA(buffer, div->name, len);
            return TRUE;
        }
    }
    if (buffer) snprintf(buffer, len, "<unknown register %u>", regno);
    return FALSE;
}
