Commit 0c392850 authored by Alexandre Julliard's avatar Alexandre Julliard

winebuild: Use RVAs instead of absolute addresses in the delay import descriptors.

parent 29060f3d
......@@ -24,49 +24,37 @@
#include "delayloadhandler.h"
WINBASEAPI void *WINAPI DelayLoadFailureHook( LPCSTR name, LPCSTR function );
#ifdef __WINE_PE_BUILD
extern IMAGE_DOS_HEADER __ImageBase;
WINBASEAPI void *WINAPI ResolveDelayLoadedAPI( void* base, const IMAGE_DELAYLOAD_DESCRIPTOR* desc,
PDELAYLOAD_FAILURE_DLL_CALLBACK dllhook,
PDELAYLOAD_FAILURE_SYSTEM_ROUTINE syshook,
IMAGE_THUNK_DATA* addr, ULONG flags );
FARPROC WINAPI __delayLoadHelper2( const IMAGE_DELAYLOAD_DESCRIPTOR *descr, IMAGE_THUNK_DATA *addr )
static inline void *image_base(void)
{
return ResolveDelayLoadedAPI( &__ImageBase, descr, NULL, DelayLoadFailureHook, addr, 0 );
#ifdef __WINE_PE_BUILD
extern IMAGE_DOS_HEADER __ImageBase;
return (void *)&__ImageBase;
#else
extern IMAGE_NT_HEADERS __wine_spec_nt_header;
return (void *)((__wine_spec_nt_header.OptionalHeader.ImageBase + 0xffff) & ~0xffff);
#endif
}
#else /* __WINE_PE_BUILD */
struct ImgDelayDescr
FARPROC WINAPI __delayLoadHelper2( const IMAGE_DELAYLOAD_DESCRIPTOR *descr, IMAGE_THUNK_DATA *addr )
{
DWORD_PTR grAttrs;
LPCSTR szName;
HMODULE *phmod;
IMAGE_THUNK_DATA *pIAT;
const IMAGE_THUNK_DATA *pINT;
const IMAGE_THUNK_DATA *pBoundIAT;
const IMAGE_THUNK_DATA *pUnloadIAT;
DWORD_PTR dwTimeStamp;
};
return ResolveDelayLoadedAPI( image_base(), descr, NULL, DelayLoadFailureHook, addr, 0 );
}
#ifndef __WINE_PE_BUILD
extern struct ImgDelayDescr __wine_spec_delay_imports[];
extern IMAGE_DELAYLOAD_DESCRIPTOR __wine_spec_delay_imports[];
FARPROC WINAPI DECLSPEC_HIDDEN __wine_spec_delay_load( unsigned int id )
{
struct ImgDelayDescr *descr = __wine_spec_delay_imports + HIWORD(id);
WORD func = LOWORD(id);
FARPROC proc;
const IMAGE_DELAYLOAD_DESCRIPTOR *descr = __wine_spec_delay_imports + HIWORD(id);
IMAGE_THUNK_DATA *thunk = (IMAGE_THUNK_DATA *)((char *)image_base() + descr->ImportAddressTableRVA);
if (!*descr->phmod) *descr->phmod = LoadLibraryA( descr->szName );
if (!*descr->phmod ||
!(proc = GetProcAddress( *descr->phmod, (LPCSTR)descr->pINT[func].u1.Function )))
proc = DelayLoadFailureHook( descr->szName, (LPCSTR)descr->pINT[func].u1.Function );
descr->pIAT[func].u1.Function = (ULONG_PTR)proc;
return proc;
return __delayLoadHelper2( descr, thunk + LOWORD(id) );
}
#endif /* __WINE_PE_BUILD */
......@@ -303,6 +303,7 @@ extern void read_undef_symbols( DLLSPEC *spec, struct strarray files );
extern void resolve_imports( DLLSPEC *spec );
extern int is_undefined( const char *name );
extern int has_imports(void);
extern int has_delay_imports(void);
extern void output_get_pc_thunk(void);
extern void output_module( DLLSPEC *spec );
extern void output_stubs( DLLSPEC *spec );
......
......@@ -821,6 +821,12 @@ int has_imports(void)
return !list_empty( &dll_imports );
}
/* check if we need a delayed import directory */
int has_delay_imports(void)
{
return !list_empty( &dll_delayed );
}
/* output the import table of a Win32 module */
static void output_immediate_imports(void)
{
......@@ -928,7 +934,7 @@ static void output_immediate_import_thunks(void)
/* output the delayed import table of a Win32 module */
static void output_delayed_imports( const DLLSPEC *spec )
{
int j, mod;
int j, iat_pos, int_pos, mod_pos;
struct import *import;
if (list_empty( &dll_delayed )) return;
......@@ -936,36 +942,28 @@ static void output_delayed_imports( const DLLSPEC *spec )
output( "\n/* delayed imports */\n\n" );
output( "\t.data\n" );
output( "\t.align %d\n", get_alignment(get_ptr_size()) );
output( ".L__wine_spec_delay_imports:\n" );
output( "%s\n", asm_globl("__wine_spec_delay_imports") );
/* list of dlls */
j = mod = 0;
iat_pos = int_pos = mod_pos = 0;
LIST_FOR_EACH_ENTRY( import, &dll_delayed, struct import, entry )
{
output( "\t%s 0\n", get_asm_ptr_keyword() ); /* grAttrs */
output( "\t%s .L__wine_delay_name_%s\n", /* szName */
get_asm_ptr_keyword(), import->c_name );
output( "\t%s .L__wine_delay_modules+%d\n", /* phmod */
get_asm_ptr_keyword(), mod * get_ptr_size() );
output( "\t%s .L__wine_delay_IAT+%d\n", /* pIAT */
get_asm_ptr_keyword(), j * get_ptr_size() );
output( "\t%s .L__wine_delay_INT+%d\n", /* pINT */
get_asm_ptr_keyword(), j * get_ptr_size() );
output( "\t%s 0\n", get_asm_ptr_keyword() ); /* pBoundIAT */
output( "\t%s 0\n", get_asm_ptr_keyword() ); /* pUnloadIAT */
output( "\t%s 0\n", get_asm_ptr_keyword() ); /* dwTimeStamp */
j += import->nb_imports;
mod++;
}
output( "\t%s 0\n", get_asm_ptr_keyword() ); /* grAttrs */
output( "\t%s 0\n", get_asm_ptr_keyword() ); /* szName */
output( "\t%s 0\n", get_asm_ptr_keyword() ); /* phmod */
output( "\t%s 0\n", get_asm_ptr_keyword() ); /* pIAT */
output( "\t%s 0\n", get_asm_ptr_keyword() ); /* pINT */
output( "\t%s 0\n", get_asm_ptr_keyword() ); /* pBoundIAT */
output( "\t%s 0\n", get_asm_ptr_keyword() ); /* pUnloadIAT */
output( "\t%s 0\n", get_asm_ptr_keyword() ); /* dwTimeStamp */
output( "\t.long 1\n" ); /* Attributes */
output_rva( ".L__wine_delay_name_%s", import->c_name ); /* DllNameRVA */
output_rva( ".L__wine_delay_modules+%d", mod_pos ); /* ModuleHandleRVA */
output_rva( ".L__wine_delay_IAT+%d", iat_pos ); /* ImportAddressTableRVA */
output_rva( ".L__wine_delay_INT+%d", int_pos ); /* ImportNameTableRVA */
output( "\t.long 0\n" ); /* BoundImportAddressTableRVA */
output( "\t.long 0\n" ); /* UnloadInformationTableRVA */
output( "\t.long 0\n" ); /* TimeDateStamp */
iat_pos += import->nb_imports * get_ptr_size();
int_pos += (import->nb_imports + 1) * get_ptr_size();
mod_pos += get_ptr_size();
}
output( "\t.long 0,0,0,0,0,0,0,0\n" );
output( ".L__wine_spec_delay_imports_end:\n" );
output( "\n.L__wine_delay_IAT:\n" );
LIST_FOR_EACH_ENTRY( import, &dll_delayed, struct import, entry )
......@@ -986,12 +984,10 @@ static void output_delayed_imports( const DLLSPEC *spec )
for (j = 0; j < import->nb_imports; j++)
{
struct import_func *func = &import->imports[j];
if (!func->name)
output( "\t%s %d\n", get_asm_ptr_keyword(), func->ordinal );
else
output( "\t%s .L__wine_delay_data_%s_%s\n",
get_asm_ptr_keyword(), import->c_name, func->name );
output_thunk_rva( func->name ? -1 : func->ordinal,
".L__wine_delay_data_%s_%s", import->c_name, func->name );
}
output( "\t%s 0\n", get_asm_ptr_keyword() );
}
output( "\n.L__wine_delay_modules:\n" );
......@@ -1012,7 +1008,9 @@ static void output_delayed_imports( const DLLSPEC *spec )
{
struct import_func *func = &import->imports[j];
if (!func->name) continue;
output( "\t.align %d\n", get_alignment(2) );
output( ".L__wine_delay_data_%s_%s:\n", import->c_name, func->name );
output( "\t.short %d\n", func->hint );
output( "\t%s \"%s\"\n", get_asm_string_keyword(), func->name );
}
}
......
......@@ -735,6 +735,8 @@ void output_module( DLLSPEC *spec )
data_dirs[1] = ".L__wine_spec_imports"; /* DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT] */
if (spec->nb_resources)
data_dirs[2] = ".L__wine_spec_resources"; /* DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE] */
if (has_delay_imports())
data_dirs[13] = ".L__wine_spec_delay_imports"; /* DataDirectory[IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT] */
output_data_directories( data_dirs );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment