/* -*- tab-width: 8; c-basic-offset: 4 -*- */
/*
 * File module.c - module handling for the wine debugger
 *
 * Copyright (C) 1993, Eric Youngdale.
 * 		 2000, Eric Pouech
 */
#include "config.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "neexe.h"
#include "file.h"
#include "debugger.h"
#include "toolhelp.h"
#include "wingdi.h"
#include "winuser.h"

/***********************************************************************
 * Creates and links a new module to the current process 
 *
 */
DBG_MODULE*	DEBUG_AddModule(const char* name, int type, 
				void* mod_addr, HMODULE hmodule)
{
    DBG_MODULE*	wmod;

    if (!(wmod = (DBG_MODULE*)DBG_alloc(sizeof(*wmod))))
	return NULL;

    memset(wmod, 0, sizeof(*wmod));

    wmod->next = DEBUG_CurrProcess->modules;
    wmod->status = DM_STATUS_NEW;
    wmod->type = type;
    wmod->load_addr = mod_addr;
    wmod->handle = hmodule;
    wmod->dbg_index = DEBUG_CurrProcess->next_index;
    wmod->module_name = DBG_strdup(name);
    DEBUG_CurrProcess->modules = wmod;

    return wmod;
}

/***********************************************************************
 *	DEBUG_FindModuleByName
 *
 */
DBG_MODULE*	DEBUG_FindModuleByName(const char* name, int type)
{
    DBG_MODULE*	wmod;
    
    for (wmod = DEBUG_CurrProcess->modules; wmod; wmod = wmod->next) {
	if ((type == DM_TYPE_UNKNOWN || type == wmod->type) &&
	    !strcasecmp(name, wmod->module_name)) break;
    }
    return wmod;
}

/***********************************************************************
 *	DEBUG_FindModuleByAddr
 *
 * either the addr where module is loaded, or any address inside the 
 * module
 */
DBG_MODULE*	DEBUG_FindModuleByAddr(void* addr, int type)
{
    DBG_MODULE*	wmod;
    DBG_MODULE*	res = NULL;
    
    for (wmod = DEBUG_CurrProcess->modules; wmod; wmod = wmod->next) {
	if ((type == DM_TYPE_UNKNOWN || type == wmod->type) &&
	    (u_long)addr >= (u_long)wmod->load_addr &&
	    (!res || res->load_addr < wmod->load_addr))
	    res = wmod;
    }
    return res;
}

/***********************************************************************
 *		DEBUG_FindModuleByHandle
 */
DBG_MODULE*	DEBUG_FindModuleByHandle(HANDLE handle, int type)
{
    DBG_MODULE*	wmod;
    
    for (wmod = DEBUG_CurrProcess->modules; wmod; wmod = wmod->next) {
	if ((type == DM_TYPE_UNKNOWN || type == wmod->type) && handle == wmod->handle) break;
    }
    return wmod;
}

/***********************************************************************
 *		DEBUG_GetProcessMainModule
 */
DBG_MODULE*	DEBUG_GetProcessMainModule(DBG_PROCESS* process)
{
    DBG_MODULE*	wmod;

    if (!process) return NULL;

    /* main module is the first to be loaded on a given process, so it's the last on
     * the list */
    for (wmod = process->modules; wmod && wmod->next; wmod = wmod->next);
    return wmod;
}

/***********************************************************************
 *			DEBUG_RegisterELFModule
 *
 * ELF modules are also entered into the list - this is so that we
 * can make 'info shared' types of displays possible.
 */
DBG_MODULE* DEBUG_RegisterELFModule(u_long load_addr, const char* name)
{
    DBG_MODULE*	wmod = DEBUG_AddModule(name, DM_TYPE_ELF, (void*)load_addr, 0);

    if (!wmod) return NULL;

    wmod->status = DM_STATUS_LOADED;
    DEBUG_CurrProcess->next_index++;

    return wmod;
}

/***********************************************************************
 *			DEBUG_RegisterPEModule
 *
 */
DBG_MODULE* DEBUG_RegisterPEModule(HMODULE hModule, u_long load_addr, const char *module_name)
{
    DBG_MODULE*	wmod = DEBUG_AddModule(module_name, DM_TYPE_PE, (void*)load_addr, hModule);

    if (!wmod) return NULL;

    DEBUG_CurrProcess->next_index++;

    return wmod;
}

/***********************************************************************
 *			DEBUG_RegisterNEModule
 *
 */
DBG_MODULE* DEBUG_RegisterNEModule(HMODULE hModule, void* load_addr, const char *module_name)
{
    DBG_MODULE*	wmod = DEBUG_AddModule(module_name, DM_TYPE_NE, load_addr, hModule);

    if (!wmod) return NULL;

    wmod->status = DM_STATUS_LOADED;
    DEBUG_CurrProcess->next_index++;
    return wmod;
}

#if 0
/***********************************************************************
 *           DEBUG_GetEP16
 *
 * Helper function fo DEBUG_LoadModuleEPs16:
 *	finds the address of a given entry point from a given module
 */
static BOOL DEBUG_GetEP16(char* moduleAddr, const NE_MODULE* module, 
			  WORD ordinal, DBG_ADDR* addr)
{
    void*		idx;
    ET_ENTRY		entry;
    ET_BUNDLE		bundle;
    SEGTABLEENTRY	ste;

    bundle.next = module->entry_table;
    do {
	if (!bundle.next)
	    return FALSE;
	idx = moduleAddr + bundle.next;
	if (!DEBUG_READ_MEM_VERBOSE(idx, &bundle, sizeof(bundle)))
	    return FALSE;
    } while ((ordinal < bundle.first + 1) || (ordinal > bundle.last));
    
    if (!DEBUG_READ_MEM_VERBOSE((char*)idx + sizeof(ET_BUNDLE) + 
				(ordinal - bundle.first - 1) * sizeof(ET_ENTRY), 
				&entry, sizeof(ET_ENTRY)))
	return FALSE;
    
    addr->seg = entry.segnum;
    addr->off = entry.offs;
    
    if (addr->seg == 0xfe) addr->seg = 0xffff;  /* constant entry */
    else {
	if (!DEBUG_READ_MEM_VERBOSE(moduleAddr + module->seg_table + 
				    sizeof(ste) * (addr->seg - 1),
				    &ste, sizeof(ste)))
	    return FALSE;
	addr->seg = GlobalHandleToSel16(ste.hSeg);
    }
    return TRUE;
}

/***********************************************************************
 *           DEBUG_LoadModule16
 *
 * Load the entry points of a Win16 module into the hash table.
 */
static void DEBUG_LoadModule16(HMODULE hModule, NE_MODULE* module, char* moduleAddr, const char* name)
{
    DBG_VALUE	value;
    BYTE	buf[1 + 256 + 2];
    char 	epname[512];
    char*	cpnt;
    DBG_MODULE*	wmod;

    wmod = DEBUG_RegisterNEModule(hModule, moduleAddr, name);

    value.type = NULL;
    value.cookie = DV_TARGET;
    value.addr.seg = 0;
    value.addr.off = 0;
    
    cpnt = moduleAddr + module->name_table;
    
    /* First search the resident names */
    
    /* skip module name */
    if (!DEBUG_READ_MEM_VERBOSE(cpnt, buf, sizeof(buf)) || !buf[0])
	return;
    cpnt += 1 + buf[0] + sizeof(WORD);
    
    while (DEBUG_READ_MEM_VERBOSE(cpnt, buf, sizeof(buf)) && buf[0]) {
	sprintf(epname, "%s.%.*s", name, buf[0], &buf[1]);
	if (DEBUG_GetEP16(moduleAddr, module, *(WORD*)&buf[1 + buf[0]], &value.addr)) {
	    DEBUG_AddSymbol(epname, &value, NULL, SYM_WIN32 | SYM_FUNC);
	}
	cpnt += buf[0] + 1 + sizeof(WORD);
    }
    
    /* Now search the non-resident names table */
    if (!module->nrname_handle) return;  /* No non-resident table */
    cpnt = (char *)GlobalLock16(module->nrname_handle);
    while (DEBUG_READ_MEM_VERBOSE(cpnt, buf, sizeof(buf)) && buf[0]) {
	sprintf(epname, "%s.%.*s", name, buf[0], &buf[1]);
	if (DEBUG_GetEP16(moduleAddr, module, *(WORD*)&buf[1 + buf[0]], &value.addr)) {
	    DEBUG_AddSymbol(epname, &value, NULL, SYM_WIN32 | SYM_FUNC);
	}
	cpnt += buf[0] + 1 + sizeof(WORD);
    }
    GlobalUnlock16(module->nrname_handle);
}
#endif

/***********************************************************************
 *			DEBUG_LoadModule32
 */
void	DEBUG_LoadModule32(const char* name, HANDLE hFile, DWORD base)
{
    DBG_VALUE			value;
    char			buffer[512];
    char			bufstr[256];
    int 			i;
    IMAGE_NT_HEADERS		pe_header;
    DWORD			pe_header_ofs;
    IMAGE_SECTION_HEADER 	pe_seg;
    DWORD			pe_seg_ofs;
    IMAGE_DATA_DIRECTORY 	dir;
    DWORD			dir_ofs;
    DBG_MODULE*			wmod;
    const char *prefix;

    /* FIXME: we make the assumption that hModule == base */
    wmod = DEBUG_RegisterPEModule((HMODULE)base, base, name);

    DEBUG_Printf(DBG_CHN_TRACE, "Registring 32bit DLL '%s' at %08lx\n", name, base);
    
    value.type = NULL;
    value.cookie = DV_TARGET;
    value.addr.seg = 0;
    value.addr.off = 0;
    
    /* grab PE Header */
    if (!DEBUG_READ_MEM_VERBOSE((void*)(base + OFFSET_OF(IMAGE_DOS_HEADER, e_lfanew)),
				&pe_header_ofs, sizeof(pe_header_ofs)) ||
	!DEBUG_READ_MEM_VERBOSE((void*)(base + pe_header_ofs), 
				&pe_header, sizeof(pe_header)))
	return;
    
    if (wmod) {
	DEBUG_RegisterStabsDebugInfo(wmod, hFile, &pe_header, pe_header_ofs);
	DEBUG_RegisterMSCDebugInfo(wmod, hFile, &pe_header, pe_header_ofs);	
    }

    /* Add start of DLL */
    value.addr.off = base;
    if ((prefix = strrchr( name, '\\' ))) prefix++;
    else prefix = name;

    DEBUG_AddSymbol(prefix, &value, NULL, SYM_WIN32 | SYM_FUNC);
    
    /* Add entry point */
    wsnprintf(buffer, sizeof(buffer), "%s.EntryPoint", prefix);
    value.addr.off = base + pe_header.OptionalHeader.AddressOfEntryPoint;
    DEBUG_AddSymbol(buffer, &value, NULL, SYM_WIN32 | SYM_FUNC);

    /* Add start of sections */
    pe_seg_ofs = pe_header_ofs + OFFSET_OF(IMAGE_NT_HEADERS, OptionalHeader) +
	pe_header.FileHeader.SizeOfOptionalHeader;
    
    for (i = 0; i < pe_header.FileHeader.NumberOfSections; i++, pe_seg_ofs += sizeof(pe_seg)) {
	if (!DEBUG_READ_MEM_VERBOSE((void*)(base + pe_seg_ofs), &pe_seg, sizeof(pe_seg)))
	    continue;
	wsnprintf(buffer, sizeof(buffer), "%s.%s", prefix, pe_seg.Name);
	value.addr.off = base + pe_seg.VirtualAddress;
	DEBUG_AddSymbol(buffer, &value, NULL, SYM_WIN32 | SYM_FUNC);
    }
    
    /* Add exported functions */
    dir_ofs = pe_header_ofs + 
	OFFSET_OF(IMAGE_NT_HEADERS, 
		  OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]);
    if (DEBUG_READ_MEM_VERBOSE((void*)(base + dir_ofs), &dir, sizeof(dir)) && dir.Size) {
	IMAGE_EXPORT_DIRECTORY 	exports;
	WORD*			ordinals = NULL;
	void**			functions = NULL;
	DWORD*			names = NULL;
	int			j;
	
	if (DEBUG_READ_MEM_VERBOSE((void*)(base + dir.VirtualAddress), 
				   &exports, sizeof(exports)) &&
	    
	    ((functions = DBG_alloc(sizeof(functions[0]) * exports.NumberOfFunctions))) &&
	    DEBUG_READ_MEM_VERBOSE((void*)(base + (DWORD)exports.AddressOfFunctions),
				   functions, sizeof(functions[0]) * exports.NumberOfFunctions) &&
	    
	    ((ordinals = DBG_alloc(sizeof(ordinals[0]) * exports.NumberOfNames))) &&
	    DEBUG_READ_MEM_VERBOSE((void*)(base + (DWORD)exports.AddressOfNameOrdinals),
				   ordinals, sizeof(ordinals[0]) * exports.NumberOfNames) &&
	    
	    ((names = DBG_alloc(sizeof(names[0]) * exports.NumberOfNames))) &&
	    DEBUG_READ_MEM_VERBOSE((void*)(base + (DWORD)exports.AddressOfNames),
				   names, sizeof(names[0]) * exports.NumberOfNames)) {
	    
	    for (i = 0; i < exports.NumberOfNames; i++) {
		if (!names[i] ||
		    !DEBUG_READ_MEM_VERBOSE((void*)(base + names[i]), bufstr, sizeof(bufstr)))
		    continue;
		bufstr[sizeof(bufstr) - 1] = 0;
		wsnprintf(buffer, sizeof(buffer), "%s.%s", prefix, bufstr);
		value.addr.off = base + (DWORD)functions[ordinals[i]];
		DEBUG_AddSymbol(buffer, &value, NULL, SYM_WIN32 | SYM_FUNC);
	    }
	    
	    for (i = 0; i < exports.NumberOfFunctions; i++) {
		if (!functions[i]) continue;
		/* Check if we already added it with a name */
		for (j = 0; j < exports.NumberOfNames; j++)
		    if ((ordinals[j] == i) && names[j]) break;
		if (j < exports.NumberOfNames) continue;
		wsnprintf(buffer, sizeof(buffer), "%s.%ld", prefix, i + exports.Base);
		value.addr.off = base + (DWORD)functions[i];
		DEBUG_AddSymbol(buffer, &value, NULL, SYM_WIN32 | SYM_FUNC);
	    }
	}
	DBG_free(functions);
	DBG_free(ordinals);
	DBG_free(names);
    }
}

/***********************************************************************
 *           	DEBUG_LoadEntryPoints
 *
 * Load the entry points of all the modules into the hash table.
 */
int DEBUG_LoadEntryPoints(const char* pfx)
{
    int		first = 0;
    /* FIXME: with address space separation in space, this is plain wrong
     *	      it requires the 16 bit WOW debugging interface...
     */
#if 0
    MODULEENTRY	entry;
    NE_MODULE	module;
    void*	moduleAddr;
    int		rowcount = 0;
    int		len;

    /* FIXME: we assume that a module is never removed from memory */
    /* FIXME: this is (currently plain wrong when debugger is started by
     *	      attaching to an existing program => the 16 bit modules will
     *        not be shared... not much to do on debugger side... sigh
     */
    if (ModuleFirst16(&entry)) do {
	if (DEBUG_FindModuleByName(entry.szModule, DM_TYPE_UNKNOWN) ||
	    !(moduleAddr = NE_GetPtr(entry.hModule)) ||
	    !DEBUG_READ_MEM_VERBOSE(moduleAddr, &module, sizeof(module)) ||
	    (module.flags & NE_FFLAGS_WIN32) /* NE module */)
	    continue;
	if (!first) {
	    if (pfx) DEBUG_Printf(DBG_CHN_MESG, pfx);
	    DEBUG_Printf(DBG_CHN_MESG, "   ");
	    rowcount = 3 + (pfx ? strlen(pfx) : 0);
	    first = 1;
	}
	
	len = strlen(entry.szModule);
	if ((rowcount + len) > 76) {
	    DEBUG_Printf(DBG_CHN_MESG, "\n   ");
	    rowcount = 3;
	}
	DEBUG_Printf(DBG_CHN_MESG, " %s", entry.szModule);
	rowcount += len + 1;
	
	DEBUG_LoadModule16(entry.hModule, &module, moduleAddr, entry.szModule);
    } while (ModuleNext16(&entry));
#endif
    
    if (first) DEBUG_Printf(DBG_CHN_MESG, "\n"); 
    return first;
}

/***********************************************************************
 *           DEBUG_InfoShare
 *
 * Display shared libarary information.
 */
void DEBUG_InfoShare(void)
{
    DBG_MODULE*	wmod;
    const char*	xtype;

    DEBUG_Printf(DBG_CHN_MESG, "Address\t\tModule\tName\n");

    for (wmod = DEBUG_CurrProcess->modules; wmod; wmod = wmod->next) {
	switch (wmod->type) {
	case DM_TYPE_NE:	xtype = "NE"; break;
	case DM_TYPE_PE:	xtype = "PE"; break;
	case DM_TYPE_ELF:	xtype = "ELF"; break;
	default:		xtype = "???"; break;
	}
	DEBUG_Printf(DBG_CHN_MESG, "0x%8.8x\t(%s)\t%s\n", (unsigned int)wmod->load_addr,
		     xtype, wmod->module_name);
    }
}

static const char*	DEBUG_GetModuleType(int type)
{
    switch (type) {
    case DM_TYPE_NE:	return "NE";
    case DM_TYPE_PE:	return "PE";
    case DM_TYPE_ELF:	return "ELF";
    default:		return "???";;
    }
}

static const char*	DEBUG_GetModuleStatus(int status)
{
    switch (status) {
    case DM_STATUS_NEW:		return "deferred"; 
    case DM_STATUS_LOADED:	return "ok"; 
    case DM_STATUS_ERROR:	return "error"; 
    default:			return "???"; 
    }
}

/***********************************************************************
 *           DEBUG_
 * Display information about a given module (DLL or EXE)
 */
void DEBUG_DumpModule(DWORD mod)
{
    DBG_MODULE*	wmod;

    if (!(wmod = DEBUG_FindModuleByHandle(mod, DM_TYPE_UNKNOWN)) &&
	!(wmod = DEBUG_FindModuleByAddr((void*)mod, DM_TYPE_UNKNOWN))) {
	DEBUG_Printf(DBG_CHN_MESG, "'0x%08lx' is not a valid module handle or address\n", mod);
	return;
    }

    DEBUG_Printf(DBG_CHN_MESG, "Module '%s' (handle=0x%08x) at 0x%8.8x (%s/%s)\n",
		 wmod->module_name, wmod->handle, (unsigned int)wmod->load_addr,
		 DEBUG_GetModuleType(wmod->type), DEBUG_GetModuleStatus(wmod->status));
}

/***********************************************************************
 *           DEBUG_WalkModules
 *
 * Display information about all modules (DLLs and EXEs)
 */
void DEBUG_WalkModules(void)
{
    DBG_MODULE*	wmod;
    const char*	xtype;

    DEBUG_Printf(DBG_CHN_MESG, "Address\t\tModule\tName\n");

    for (wmod = DEBUG_CurrProcess->modules; wmod; wmod = wmod->next) {
	switch (wmod->type) {
	case DM_TYPE_NE:	xtype = "NE"; break;
	case DM_TYPE_PE:	xtype = "PE"; break;
	case DM_TYPE_ELF:	continue;
	default:		xtype = "???"; break;
	}
	
	DEBUG_Printf(DBG_CHN_MESG, "0x%8.8x\t(%s)\t%s\n", 
		     (unsigned int)wmod->load_addr, DEBUG_GetModuleType(wmod->type), 
		     wmod->module_name);
    }
}

