/* 
 *	UNIX dynamic loader
 * 
 * Currently only supports stuff using the dl* API.
 *
 * Copyright 1998 Marcus Meissner
 *
 * FIXME: 	Small reentrancy problem.
 * IDEA(s):	could be used to split up shell32,comctl32... 
 */

#include "config.h"

#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>

#include "snoop.h"
#include "process.h"
#include "neexe.h"
#include "peexe.h"
#include "heap.h"
#include "module.h"
#include "pe_image.h"
#include "debugtools.h"
#include "winerror.h"
#include "elfdll.h"

DEFAULT_DEBUG_CHANNEL(win32)

#if defined(HAVE_DL_API)

#define UNIX_DLL_ENDING		"so"

#define	STUBSIZE		4095

#include <dlfcn.h>


static WINE_MODREF *ELF_CreateDummyModule( LPCSTR libname, LPCSTR modname )
{
	PIMAGE_DOS_HEADER	dh;
	PIMAGE_NT_HEADERS	nth;
	PIMAGE_SECTION_HEADER	sh;
	WINE_MODREF *wm;
	HMODULE hmod;

	wm=(WINE_MODREF*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*wm) );
	wm->type = MODULE32_ELF;

	/* FIXME: hmm, order? */
	wm->next = PROCESS_Current()->modref_list;
	PROCESS_Current()->modref_list = wm;

	wm->modname = HEAP_strdupA( GetProcessHeap(), 0, modname );
	wm->filename = HEAP_strdupA( GetProcessHeap(), 0, libname );
	wm->short_modname = wm->modname;
	wm->short_filename = wm->filename;

	hmod = (HMODULE)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, 
                                     sizeof(IMAGE_DOS_HEADER) + 
                                     sizeof(IMAGE_NT_HEADERS) +
                                     sizeof(IMAGE_SECTION_HEADER) + 100 );
	dh = (PIMAGE_DOS_HEADER)hmod;
	dh->e_magic = IMAGE_DOS_SIGNATURE;
	dh->e_lfanew = sizeof(IMAGE_DOS_HEADER);
	nth = PE_HEADER(hmod);
	nth->Signature = IMAGE_NT_SIGNATURE; 
	nth->FileHeader.Machine = IMAGE_FILE_MACHINE_I386;
	nth->FileHeader.NumberOfSections = 1;
	nth->FileHeader.SizeOfOptionalHeader = sizeof(IMAGE_OPTIONAL_HEADER);
	nth->FileHeader.Characteristics = 
		IMAGE_FILE_RELOCS_STRIPPED|IMAGE_FILE_LINE_NUMS_STRIPPED|
		IMAGE_FILE_LOCAL_SYMS_STRIPPED|IMAGE_FILE_32BIT_MACHINE|
		IMAGE_FILE_DLL|IMAGE_FILE_DEBUG_STRIPPED;
	nth->OptionalHeader.Magic = IMAGE_NT_OPTIONAL_HDR_MAGIC;
	nth->OptionalHeader.SizeOfCode = 0;
	nth->OptionalHeader.SizeOfInitializedData = 0;
	nth->OptionalHeader.SizeOfUninitializedData = 0;
	nth->OptionalHeader.AddressOfEntryPoint	= 0;
	nth->OptionalHeader.BaseOfCode		= 0;
	nth->OptionalHeader.MajorOperatingSystemVersion = 4;
	nth->OptionalHeader.MajorImageVersion	= 4;
	nth->OptionalHeader.SizeOfImage		= 0;
	nth->OptionalHeader.SizeOfHeaders	= 0;
	nth->OptionalHeader.Subsystem		= IMAGE_SUBSYSTEM_NATIVE;
	nth->OptionalHeader.DllCharacteristics	= 0;
	nth->OptionalHeader.NumberOfRvaAndSizes	= 0;

	/* allocate one code section that crosses the whole process range
	 * (we could find out from internal tables ... hmm )
	 */
	sh=(PIMAGE_SECTION_HEADER)(nth+1);
	strcpy(sh->Name,".text");
	sh->Misc.VirtualSize	= 0x7fffffff;
	sh->VirtualAddress	= 0x42; /* so snoop can use it ... */
	sh->SizeOfRawData	= 0x7fffffff;
	sh->PointerToRawData	= 0;
	sh->Characteristics	= IMAGE_SCN_CNT_CODE|IMAGE_SCN_CNT_INITIALIZED_DATA|IMAGE_SCN_MEM_EXECUTE|IMAGE_SCN_MEM_READ;
	wm->module = hmod;
	return wm;
}

WINE_MODREF *ELF_LoadLibraryExA( LPCSTR libname, DWORD flags, DWORD *err)
{
	WINE_MODREF	*wm;
	char		*modname,*s,*t,*x;
	LPVOID		*dlhandle;

	t = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
                       strlen(libname) + strlen("lib.so") + 1 );
	*t = '\0';
	/* copy path to tempvar ... */
	s=strrchr(libname,'/');
	if (!s)
		s=strrchr(libname,'\\');
	if (s) {
		s++; /* skip / or \ */
		/* copy everything up to s-1 */
		memcpy(t,libname,s-libname);
		t[s-libname]= '\0';
	} else
		s = (LPSTR)libname;
	modname = s;
	/* append "lib" foo ".so" */
	strcat(t,"lib");
	x = t+strlen(t);
	strcat(t,s);
	s = strchr(x,'.');
	if (s) {
            while (s) {
		if (!strcasecmp(s,".dll")) {
                    strcpy(s+1,UNIX_DLL_ENDING);
                    break;
		}
		s=strchr(s+1,'.');
            }
	} else {
	    	strcat(x,"."UNIX_DLL_ENDING);
	}

	/* FIXME: make UNIX filename from DOS fn? */

	/* ... and open it */
	dlhandle = ELFDLL_dlopen(t,RTLD_NOW);
	if (!dlhandle) {
		HeapFree( GetProcessHeap(), 0, t );
		*err = ERROR_FILE_NOT_FOUND;
		return NULL;
	}

	wm = ELF_CreateDummyModule( t, modname );
	wm->binfmt.elf.dlhandle = dlhandle;

	SNOOP_RegisterDLL(wm->module,libname,STUBSIZE/sizeof(ELF_STDCALL_STUB));
	*err = 0;
	return wm;
}

FARPROC ELF_FindExportedFunction( WINE_MODREF *wm, LPCSTR funcName) 
{
	LPVOID			fun;
	int			i,nrofargs = 0;
	ELF_STDCALL_STUB	*stub;

	assert(wm->type == MODULE32_ELF);
	if (!HIWORD(funcName)) {
		ERR("Can't import from UNIX dynamic libs by ordinal, sorry.\n");
		return (FARPROC)0;
	}
	fun = dlsym(wm->binfmt.elf.dlhandle,funcName);
	/* we sometimes have an excess '_' at the beginning of the name */
	if (!fun && (funcName[0]=='_')) {
		funcName++ ;
		fun = dlsym(wm->binfmt.elf.dlhandle,funcName);
	}
	if (!fun) {
		/* Function@nrofargs usually marks a stdcall function 
		 * with nrofargs bytes that are popped at the end
		 */
		if (strchr(funcName,'@')) {
			LPSTR	t,fn = HEAP_strdupA( GetProcessHeap(), 0, funcName );

			t = strchr(fn,'@');
			*t = '\0';
			nrofargs = 0;
			sscanf(t+1,"%d",&nrofargs);
			fun = dlsym(wm->binfmt.elf.dlhandle,fn);
			HeapFree( GetProcessHeap(), 0, fn );
		}
	}
	/* We sometimes have Win32 dlls implemented using stdcall but UNIX 
	 * dlls using cdecl. If we find out the number of args the function
	 * uses, we remove them from the stack using two small stubs.
	 */
	if (!wm->binfmt.elf.stubs) {
		/* one page should suffice */
		wm->binfmt.elf.stubs = VirtualAlloc(NULL,STUBSIZE,MEM_COMMIT|MEM_RESERVE,PAGE_EXECUTE_READWRITE);
		memset(wm->binfmt.elf.stubs,0,STUBSIZE);
	}
	stub = wm->binfmt.elf.stubs;
	for (i=0;i<STUBSIZE/sizeof(ELF_STDCALL_STUB);i++) {
		if (!stub->origfun)
			break;
		if (stub->origfun == (DWORD)fun)
			break;
		stub++;
	}
	if (i==STUBSIZE/sizeof(ELF_STDCALL_STUB)) {
		ERR("please report, that there are not enough slots for stdcall stubs in the ELF loader.\n");
		assert(i<STUBSIZE/sizeof(ELF_STDCALL_STUB));
	}
	if (!stub->origfun)
		stub->origfun=(DWORD)fun; /* just a marker */

	if (fun && nrofargs) { /* we don't need it for 0 args */
		/* Selfmodifying entry/return stub for stdcall -> cdecl 
		 * conversion.
		 *  - Pop returnaddress directly into our return code
		 * 		popl <into code below>
		 *  - Replace it by pointer to start of our returncode
		 * 		push $newret
		 *  - And call the original function
		 * 		jmp $orgfun
		 *  - Remove the arguments no longer needed
		 * newret: 	add esp, <nrofargs>
		 *  - Push the original returnvalue on the stack
		 *		pushl <poppedvalue>
		 *  - And return to it.
		 *		ret
		 */

		/* FIXME: The function stub is not reentrant. */

		((LPBYTE)&(stub->popl))[0]	  = 0x8f;
		((LPBYTE)&(stub->popl))[1]	  = 0x05;
		stub->addr_popped = (DWORD)&(stub->oldret);
		stub->pushl1	  = 0x68;
		stub->newret	  = (DWORD)&(stub->addesp);
		stub->pushl2	  = 0x68;
		stub->origfun	  = (DWORD)fun;
		stub->ret1	  = 0xc3;
		((LPBYTE)&(stub->addesp))[0]=0x83;
		((LPBYTE)&(stub->addesp))[1]=0xc4;
		stub->nrofargs	  = nrofargs;
		stub->pushl3	  = 0x68;
			/* filled out by entrycode */
		stub->oldret	  = 0xdeadbeef;
		stub->ret2	  = 0xc3;
		fun=(FARPROC)stub;
	}
	if (!fun) {
		FIXME("function %s not found: %s\n",funcName,dlerror());
		return fun;
	}
	fun = SNOOP_GetProcAddress(wm->module,funcName,stub-wm->binfmt.elf.stubs,fun);
	return (FARPROC)fun;
}


/***************************************************************************
 *	ELF_UnloadLibrary
 *
 * Unload the elf library and free the modref
 */
void ELF_UnloadLibrary(WINE_MODREF *wm)
{
	/* FIXME: do something here */
}

#else

WINE_MODREF *ELF_LoadLibraryExA( LPCSTR libname, DWORD flags, DWORD *err)
{
	return NULL;
}

void ELF_UnloadLibrary(WINE_MODREF *wm)
{
}

FARPROC ELF_FindExportedFunction( WINE_MODREF *wm, LPCSTR funcName) 
{
	return (FARPROC)0;
}

#endif
