/* Wine internal debugger
 * Interface to Windows debugger API
 * Copyright 2000-2004 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 <stdio.h>
#include <string.h>
#include "debugger.h"

#include "winternl.h"
#include "wine/exception.h"
#include "wine/library.h"

#include "wine/debug.h"

/* TODO list:
 *
 * - minidump
 *      + ensure that all commands work as expected in minidump reload function
 *        (and reenable parser usager)
 * - CPU adherence
 *      + we always assume the stack grows as on i386 (ie downwards)
 * - UI
 *      + enable back the limited output (depth of structure printing and number of 
 *        lines)
 *      + make the output as close as possible to what gdb does
 * - symbol management:
 *      + symbol table loading is broken
 *      + in symbol_get_lvalue, we don't do any scoping (as C does) between local and
 *        global vars (we may need this to force some display for example). A solution
 *        would be always to return arrays with: local vars, global vars, thunks
 * - type management:
 *      + some bits of internal types are missing (like type casts and the address
 *        operator)
 *      + the type for an enum's value is always inferred as int (winedbg & dbghelp)
 *      + most of the code implies that sizeof(void*) = sizeof(int)
 *      + all computations should be made on long long
 *              o expr computations are in int:s
 *              o bitfield size is on a 4-bytes
 * - execution:
 *      + set a better fix for gdb (proxy mode) than the step-mode hack
 *      + implement function call in debuggee
 *      + trampoline management is broken when getting 16 <=> 32 thunk destination
 *        address
 *      + thunking of delayed imports doesn't work as expected (ie, when stepping,
 *        it currently stops at first insn with line number during the library 
 *        loading). We should identify this (__wine_delay_import) and set a
 *        breakpoint instead of single stepping the library loading.
 *      + it's wrong to copy thread->step_over_bp into process->bp[0] (when 
 *        we have a multi-thread debuggee). complete fix must include storing all
 *        thread's step-over bp in process-wide bp array, and not to handle bp
 *        when we have the wrong thread running into that bp
 *      + code in CREATE_PROCESS debug event doesn't work on Windows, as we cannot
 *        get the name of the main module this way. We should rewrite all this code
 *        and store in struct dbg_process as early as possible (before process
 *        creation or attachment), the name of the main module
 * - global:
 *      + define a better way to enable the wine extensions (either DBG SDK function
 *        in dbghelp, or TLS variable, or environment variable or ...)
 *      + audit all files to ensure that we check all potential return values from
 *        every function call to catch the errors
 *      + BTW check also whether the exception mechanism is the best way to return
 *        errors (or find a proper fix for MinGW port)
 */

WINE_DEFAULT_DEBUG_CHANNEL(winedbg);

struct dbg_process*	dbg_curr_process = NULL;
struct dbg_thread*	dbg_curr_thread = NULL;
DWORD_PTR	        dbg_curr_tid = 0;
DWORD_PTR	        dbg_curr_pid = 0;
CONTEXT                 dbg_context;
BOOL    	        dbg_interactiveP = FALSE;

static struct list      dbg_process_list = LIST_INIT(dbg_process_list);

struct dbg_internal_var         dbg_internal_vars[DBG_IV_LAST];
static HANDLE                   dbg_houtput;

static void dbg_outputA(const char* buffer, int len)
{
    static char line_buff[4096];
    static unsigned int line_pos;

    DWORD w, i;

    while (len > 0)
    {
        unsigned int count = min( len, sizeof(line_buff) - line_pos );
        memcpy( line_buff + line_pos, buffer, count );
        buffer += count;
        len -= count;
        line_pos += count;
        for (i = line_pos; i > 0; i--) if (line_buff[i-1] == '\n') break;
        if (!i)  /* no newline found */
        {
            if (len > 0) i = line_pos;  /* buffer is full, flush anyway */
            else break;
        }
        WriteFile(dbg_houtput, line_buff, i, &w, NULL);
        memmove( line_buff, line_buff + i, line_pos - i );
        line_pos -= i;
    }
}

const char* dbg_W2A(const WCHAR* buffer, unsigned len)
{
    static unsigned ansilen;
    static char* ansi;
    unsigned newlen;

    newlen = WideCharToMultiByte(CP_ACP, 0, buffer, len, NULL, 0, NULL, NULL);
    if (newlen > ansilen)
    {
        static char* newansi;
        if (ansi)
            newansi = HeapReAlloc(GetProcessHeap(), 0, ansi, newlen);
        else
            newansi = HeapAlloc(GetProcessHeap(), 0, newlen);
        if (!newansi) return NULL;
        ansilen = newlen;
        ansi = newansi;
    }
    WideCharToMultiByte(CP_ACP, 0, buffer, len, ansi, newlen, NULL, NULL);
    return ansi;
}

void	dbg_outputW(const WCHAR* buffer, int len)
{
    const char* ansi = dbg_W2A(buffer, len);
    if (ansi) dbg_outputA(ansi, strlen(ansi));
    /* FIXME: should CP_ACP be GetConsoleCP()? */
}

int	dbg_printf(const char* format, ...)
{
    static    char	buf[4*1024];
    va_list 	valist;
    int		len;

    va_start(valist, format);
    len = vsnprintf(buf, sizeof(buf), format, valist);
    va_end(valist);

    if (len <= -1 || len >= sizeof(buf)) 
    {
	len = sizeof(buf) - 1;
	buf[len] = 0;
	buf[len - 1] = buf[len - 2] = buf[len - 3] = '.';
    }
    dbg_outputA(buf, len);
    return len;
}

static	unsigned dbg_load_internal_vars(void)
{
    HKEY	                hkey;
    DWORD 	                type = REG_DWORD;
    DWORD	                val;
    DWORD 	                count = sizeof(val);
    int		                i;
    struct dbg_internal_var*    div = dbg_internal_vars;

/* initializes internal vars table */
#define  INTERNAL_VAR(_var,_val,_ref,_tid) 			\
        div->val = _val; div->name = #_var; div->pval = _ref;	\
        div->typeid = _tid; div++;
#include "intvar.h"
#undef   INTERNAL_VAR

    /* @@ Wine registry key: HKCU\Software\Wine\WineDbg */
    if (RegCreateKeyA(HKEY_CURRENT_USER, "Software\\Wine\\WineDbg", &hkey)) 
    {
	WINE_ERR("Cannot create WineDbg key in registry\n");
	return FALSE;
    }

    for (i = 0; i < DBG_IV_LAST; i++) 
    {
        if (!dbg_internal_vars[i].pval) 
        {
            if (!RegQueryValueExA(hkey, dbg_internal_vars[i].name, 0,
                                  &type, (LPBYTE)&val, &count))
                dbg_internal_vars[i].val = val;
            dbg_internal_vars[i].pval = &dbg_internal_vars[i].val;
        }
    }
    RegCloseKey(hkey);

    return TRUE;
}

static	unsigned dbg_save_internal_vars(void)
{
    HKEY	                hkey;
    int		                i;

    /* @@ Wine registry key: HKCU\Software\Wine\WineDbg */
    if (RegCreateKeyA(HKEY_CURRENT_USER, "Software\\Wine\\WineDbg", &hkey)) 
    {
	WINE_ERR("Cannot create WineDbg key in registry\n");
	return FALSE;
    }

    for (i = 0; i < DBG_IV_LAST; i++) 
    {
        /* FIXME: type should be inferred from basic type -if any- of intvar */
        if (dbg_internal_vars[i].pval == &dbg_internal_vars[i].val)
        {
            DWORD val = dbg_internal_vars[i].val;
            RegSetValueExA(hkey, dbg_internal_vars[i].name, 0, REG_DWORD, (BYTE *)&val, sizeof(val));
        }
    }
    RegCloseKey(hkey);
    return TRUE;
}

const struct dbg_internal_var* dbg_get_internal_var(const char* name)
{
    const struct dbg_internal_var*      div;

    for (div = &dbg_internal_vars[DBG_IV_LAST - 1]; div >= dbg_internal_vars; div--)
    {
	if (!strcmp(div->name, name)) return div;
    }
    for (div = be_cpu->context_vars; div->name; div++)
    {
	if (!strcasecmp(div->name, name))
        {
            struct dbg_internal_var*    ret = (void*)lexeme_alloc_size(sizeof(*ret));
            /* relocate register's field against current context */
            *ret = *div;
            ret->pval = (DWORD_PTR*)((char*)&dbg_context + (DWORD_PTR)div->pval);
            return ret;
        }
    }

    return NULL;
}

unsigned         dbg_num_processes(void)
{
    return list_count(&dbg_process_list);
}

struct dbg_process*     dbg_get_process(DWORD pid)
{
    struct dbg_process*	p;

    LIST_FOR_EACH_ENTRY(p, &dbg_process_list, struct dbg_process, entry)
	if (p->pid == pid) return p;
    return NULL;
}

struct dbg_process*     dbg_get_process_h(HANDLE h)
{
    struct dbg_process*	p;

    LIST_FOR_EACH_ENTRY(p, &dbg_process_list, struct dbg_process, entry)
	if (p->handle == h) return p;
    return NULL;
}

struct dbg_process*	dbg_add_process(const struct be_process_io* pio, DWORD pid, HANDLE h)
{
    struct dbg_process*	p;

    if ((p = dbg_get_process(pid)))
    {
        if (p->handle != 0)
        {
            WINE_ERR("Process (%04x) is already defined\n", pid);
        }
        else
        {
            p->handle = h;
            p->process_io = pio;
            p->imageName = NULL;
        }
        return p;
    }

    if (!(p = HeapAlloc(GetProcessHeap(), 0, sizeof(struct dbg_process)))) return NULL;
    p->handle = h;
    p->pid = pid;
    p->process_io = pio;
    p->pio_data = NULL;
    p->imageName = NULL;
    list_init(&p->threads);
    p->continue_on_first_exception = FALSE;
    p->active_debuggee = FALSE;
    p->next_bp = 1;  /* breakpoint 0 is reserved for step-over */
    memset(p->bp, 0, sizeof(p->bp));
    p->delayed_bp = NULL;
    p->num_delayed_bp = 0;
    p->source_ofiles = NULL;
    p->search_path = NULL;
    p->source_current_file[0] = '\0';
    p->source_start_line = -1;
    p->source_end_line = -1;

    list_add_head(&dbg_process_list, &p->entry);
    return p;
}

void dbg_set_process_name(struct dbg_process* p, const WCHAR* imageName)
{
    assert(p->imageName == NULL);
    if (imageName)
    {
        WCHAR* tmp = HeapAlloc(GetProcessHeap(), 0, (lstrlenW(imageName) + 1) * sizeof(WCHAR));
        if (tmp) p->imageName = lstrcpyW(tmp, imageName);
    }
}

void dbg_del_process(struct dbg_process* p)
{
    struct dbg_thread*  t;
    struct dbg_thread*  t2;
    int	i;

    LIST_FOR_EACH_ENTRY_SAFE(t, t2, &p->threads, struct dbg_thread, entry)
        dbg_del_thread(t);

    for (i = 0; i < p->num_delayed_bp; i++)
        if (p->delayed_bp[i].is_symbol)
            HeapFree(GetProcessHeap(), 0, p->delayed_bp[i].u.symbol.name);

    HeapFree(GetProcessHeap(), 0, p->delayed_bp);
    source_nuke_path(p);
    source_free_files(p);
    list_remove(&p->entry);
    if (p == dbg_curr_process) dbg_curr_process = NULL;
    HeapFree(GetProcessHeap(), 0, (char*)p->imageName);
    HeapFree(GetProcessHeap(), 0, p);
}

/******************************************************************
 *		dbg_init
 *
 * Initializes the dbghelp library, and also sets the application directory
 * as a place holder for symbol searches.
 */
BOOL dbg_init(HANDLE hProc, const WCHAR* in, BOOL invade)
{
    BOOL        ret;

    ret = SymInitialize(hProc, NULL, invade);
    if (ret && in)
    {
        const WCHAR*    last;

        for (last = in + lstrlenW(in) - 1; last >= in; last--)
        {
            if (*last == '/' || *last == '\\')
            {
                WCHAR*  tmp;
                tmp = HeapAlloc(GetProcessHeap(), 0, (1024 + 1 + (last - in) + 1) * sizeof(WCHAR));
                if (tmp && SymGetSearchPathW(hProc, tmp, 1024))
                {
                    WCHAR*      x = tmp + lstrlenW(tmp);

                    *x++ = ';';
                    memcpy(x, in, (last - in) * sizeof(WCHAR));
                    x[last - in] = '\0';
                    ret = SymSetSearchPathW(hProc, tmp);
                }
                else ret = FALSE;
                HeapFree(GetProcessHeap(), 0, tmp);
                break;
            }
        }
    }
    return ret;
}

struct mod_loader_info
{
    HANDLE              handle;
    IMAGEHLP_MODULE64*  imh_mod;
};

static BOOL CALLBACK mod_loader_cb(PCSTR mod_name, DWORD64 base, PVOID ctx)
{
    struct mod_loader_info*     mli = ctx;

    if (!strcmp(mod_name, "<wine-loader>"))
    {
        if (SymGetModuleInfo64(mli->handle, base, mli->imh_mod))
            return FALSE; /* stop enum */
    }
    return TRUE;
}

BOOL dbg_get_debuggee_info(HANDLE hProcess, IMAGEHLP_MODULE64* imh_mod)
{
    struct mod_loader_info  mli;
    DWORD                   opt;

    /* this will resynchronize builtin dbghelp's internal ELF module list */
    SymLoadModule(hProcess, 0, 0, 0, 0, 0);
    mli.handle  = hProcess;
    mli.imh_mod = imh_mod;
    imh_mod->SizeOfStruct = sizeof(*imh_mod);
    imh_mod->BaseOfImage = 0;
    /* this is a wine specific options to return also ELF modules in the
     * enumeration
     */
    SymSetOptions((opt = SymGetOptions()) | 0x40000000);
    SymEnumerateModules64(hProcess, mod_loader_cb, (void*)&mli);
    SymSetOptions(opt);

    return imh_mod->BaseOfImage != 0;
}

BOOL dbg_load_module(HANDLE hProc, HANDLE hFile, const WCHAR* name, DWORD_PTR base, DWORD size)
{
    BOOL ret = SymLoadModuleExW(hProc, NULL, name, NULL, base, size, NULL, 0);
    if (ret)
    {
        IMAGEHLP_MODULEW64      ihm;
        ihm.SizeOfStruct = sizeof(ihm);
        if (SymGetModuleInfoW64(hProc, base, &ihm) && (ihm.PdbUnmatched || ihm.DbgUnmatched))
            dbg_printf("Loaded unmatched debug information for %s\n", wine_dbgstr_w(name));
    }
    return ret;
}

struct dbg_thread* dbg_get_thread(struct dbg_process* p, DWORD tid)
{
    struct dbg_thread*	t;

    if (!p) return NULL;
    LIST_FOR_EACH_ENTRY(t, &p->threads, struct dbg_thread, entry)
	if (t->tid == tid) return t;
    return NULL;
}

struct dbg_thread* dbg_add_thread(struct dbg_process* p, DWORD tid,
                                  HANDLE h, void* teb)
{
    struct dbg_thread*	t = HeapAlloc(GetProcessHeap(), 0, sizeof(struct dbg_thread));

    if (!t)
	return NULL;

    t->handle = h;
    t->tid = tid;
    t->teb = teb;
    t->process = p;
    t->exec_mode = dbg_exec_cont;
    t->exec_count = 0;
    t->step_over_bp.enabled = FALSE;
    t->step_over_bp.refcount = 0;
    t->stopped_xpoint = -1;
    t->in_exception = FALSE;
    t->frames = NULL;
    t->num_frames = 0;
    t->curr_frame = -1;
    t->addr_mode = AddrModeFlat;

    snprintf(t->name, sizeof(t->name), "%04x", tid);

    list_add_head(&p->threads, &t->entry);

    return t;
}

void dbg_del_thread(struct dbg_thread* t)
{
    HeapFree(GetProcessHeap(), 0, t->frames);
    list_remove(&t->entry);
    if (t == dbg_curr_thread) dbg_curr_thread = NULL;
    HeapFree(GetProcessHeap(), 0, t);
}

void dbg_set_option(const char* option, const char* val)
{
    if (!strcasecmp(option, "module_load_mismatched"))
    {
        DWORD   opt = SymGetOptions();
        if (!val)
            dbg_printf("Option: module_load_mismatched %s\n", opt & SYMOPT_LOAD_ANYTHING ? "true" : "false");
        else if (!strcasecmp(val, "true"))      opt |= SYMOPT_LOAD_ANYTHING;
        else if (!strcasecmp(val, "false"))     opt &= ~SYMOPT_LOAD_ANYTHING;
        else
        {
            dbg_printf("Syntax: module_load_mismatched [true|false]\n");
            return;
        }
        SymSetOptions(opt);
    }
    else if (!strcasecmp(option, "symbol_picker"))
    {
        if (!val)
            dbg_printf("Option: symbol_picker %s\n",
                       symbol_current_picker == symbol_picker_interactive ? "interactive" : "scoped");
        else if (!strcasecmp(val, "interactive"))
            symbol_current_picker = symbol_picker_interactive;
        else if (!strcasecmp(val, "scoped"))
            symbol_current_picker = symbol_picker_scoped;
        else
        {
            dbg_printf("Syntax: symbol_picker [interactive|scoped]\n");
            return;
        }
    }
    else dbg_printf("Unknown option '%s'\n", option);
}

BOOL dbg_interrupt_debuggee(void)
{
    struct dbg_process* p;
    if (list_empty(&dbg_process_list)) return FALSE;
    /* FIXME: since we likely have a single process, signal the first process
     * in list
     */
    p = LIST_ENTRY(list_head(&dbg_process_list), struct dbg_process, entry);
    if (list_next(&dbg_process_list, &p->entry)) dbg_printf("Ctrl-C: only stopping the first process\n");
    else dbg_printf("Ctrl-C: stopping debuggee\n");
    p->continue_on_first_exception = FALSE;
    return DebugBreakProcess(p->handle);
}

static BOOL WINAPI ctrl_c_handler(DWORD dwCtrlType)
{
    if (dwCtrlType == CTRL_C_EVENT)
    {
        return dbg_interrupt_debuggee();
    }
    return FALSE;
}

void dbg_init_console(void)
{
    /* set the output handle */
    dbg_houtput = GetStdHandle(STD_OUTPUT_HANDLE);

    /* set our control-C handler */
    SetConsoleCtrlHandler(ctrl_c_handler, TRUE);

    /* set our own title */
    SetConsoleTitleA("Wine Debugger");
}

static int dbg_winedbg_usage(BOOL advanced)
{
    if (advanced)
    {
    dbg_printf("Usage:\n"
               "   winedbg cmdline         launch process 'cmdline' (as if you were starting\n"
               "                           it with wine) and run WineDbg on it\n"
               "   winedbg <num>           attach to running process of pid <num> and run\n"
               "                           WineDbg on it\n"
               "   winedbg --gdb cmdline   launch process 'cmdline' (as if you were starting\n"
               "                           wine) and run gdb (proxied) on it\n"
               "   winedbg --gdb <num>     attach to running process of pid <num> and run\n"
               "                           gdb (proxied) on it\n"
               "   winedbg file.mdmp       reload the minidump file.mdmp into memory and run\n"
               "                           WineDbg on it\n"
               "   winedbg --help          prints advanced options\n");
    }
    else
        dbg_printf("Usage:\n\twinedbg [ [ --gdb ] [ prog-name [ prog-args ] | <num> | file.mdmp | --help ]\n");
    return 0;
}

void dbg_start_interactive(HANDLE hFile)
{
    struct dbg_process* p;
    struct dbg_process* p2;

    if (dbg_curr_process)
    {
        dbg_printf("WineDbg starting on pid %04lx\n", dbg_curr_pid);
        if (dbg_curr_process->active_debuggee) dbg_active_wait_for_first_exception();
    }

    dbg_interactiveP = TRUE;
    parser_handle(hFile);

    LIST_FOR_EACH_ENTRY_SAFE(p, p2, &dbg_process_list, struct dbg_process, entry)
        p->process_io->close_process(p, FALSE);

    dbg_save_internal_vars();
}

static LONG CALLBACK top_filter( EXCEPTION_POINTERS *ptr )
{
    dbg_printf( "winedbg: Internal crash at %p\n", ptr->ExceptionRecord->ExceptionAddress );
    return EXCEPTION_EXECUTE_HANDLER;
}

struct backend_cpu* be_cpu;
#ifdef __i386__
extern struct backend_cpu be_i386;
#elif defined(__powerpc__)
extern struct backend_cpu be_ppc;
#elif defined(__ALPHA__)
extern struct backend_cpu be_alpha;
#elif defined(__x86_64__)
extern struct backend_cpu be_x86_64;
#else
# error CPU unknown
#endif

int main(int argc, char** argv)
{
    int 	        retv = 0;
    HANDLE              hFile = INVALID_HANDLE_VALUE;
    enum dbg_start      ds;

#ifdef __i386__
    be_cpu = &be_i386;
#elif defined(__powerpc__)
    be_cpu = &be_ppc;
#elif defined(__ALPHA__)
    be_cpu = &be_alpha;
#elif defined(__x86_64__)
    be_cpu = &be_x86_64;
#else
# error CPU unknown
#endif
    /* Initialize the output */
    dbg_houtput = GetStdHandle(STD_OUTPUT_HANDLE);

    SetUnhandledExceptionFilter( top_filter );

    /* Initialize internal vars */
    if (!dbg_load_internal_vars()) return -1;

    /* as we don't care about exec name */
    argc--; argv++;

    if (argc && !strcmp(argv[0], "--help"))
        return dbg_winedbg_usage(TRUE);

    if (argc && !strcmp(argv[0], "--gdb"))
    {
        retv = gdb_main(argc, argv);
        if (retv == -1) dbg_winedbg_usage(FALSE);
        return retv;
    }
    dbg_init_console();

    SymSetOptions((SymGetOptions() & ~(SYMOPT_UNDNAME)) |
                  SYMOPT_LOAD_LINES | SYMOPT_DEFERRED_LOADS | SYMOPT_AUTO_PUBLICS);

    if (argc && (!strcmp(argv[0], "--auto") || !strcmp(argv[0], "--minidump")))
    {
        /* force some internal variables */
        DBG_IVAR(BreakOnDllLoad) = 0;
        dbg_houtput = GetStdHandle(STD_ERROR_HANDLE);
        switch (dbg_active_auto(argc, argv))
        {
        case start_ok:          return 0;
        case start_error_parse: return dbg_winedbg_usage(FALSE);
        case start_error_init:  return -1;
        }
    }
    /* parse options */
    while (argc > 0 && argv[0][0] == '-')
    {
        if (!strcmp(argv[0], "--command"))
        {
            argc--; argv++;
            hFile = parser_generate_command_file(argv[0], NULL);
            if (hFile == INVALID_HANDLE_VALUE)
            {
                dbg_printf("Couldn't open temp file (%u)\n", GetLastError());
                return 1;
            }
            argc--; argv++;
            continue;
        }
        if (!strcmp(argv[0], "--file"))
        {
            argc--; argv++;
            hFile = CreateFileA(argv[0], GENERIC_READ|DELETE, 0, 
                                NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
            if (hFile == INVALID_HANDLE_VALUE)
            {
                dbg_printf("Couldn't open file %s (%u)\n", argv[0], GetLastError());
                return 1;
            }
            argc--; argv++;
            continue;
        }
        if (!strcmp(argv[0], "--"))
        {
            argc--; argv++;
            break;
        }
        return dbg_winedbg_usage(FALSE);
    }
    if (!argc) ds = start_ok;
    else if ((ds = dbg_active_attach(argc, argv)) == start_error_parse &&
             (ds = minidump_reload(argc, argv)) == start_error_parse)
        ds = dbg_active_launch(argc, argv);
    switch (ds)
    {
    case start_ok:              break;
    case start_error_parse:     return dbg_winedbg_usage(FALSE);
    case start_error_init:      return -1;
    }

    dbg_start_interactive(hFile);

    return 0;
}
