Commit 6c41cc61 authored by Alexandre Julliard's avatar Alexandre Julliard

winebuild: Support relay debugging for PE builtin dlls.

parent d38ec9e2
...@@ -2190,7 +2190,14 @@ static NTSTATUS load_native_dll( LPCWSTR load_path, const UNICODE_STRING *nt_nam ...@@ -2190,7 +2190,14 @@ static NTSTATUS load_native_dll( LPCWSTR load_path, const UNICODE_STRING *nt_nam
} }
SERVER_END_REQ; SERVER_END_REQ;
if ((wm->ldr.Flags & LDR_IMAGE_IS_DLL) && TRACE_ON(snoop)) SNOOP_SetupDLL( module ); if (image_info->image_flags & IMAGE_FLAGS_WineBuiltin)
{
if (TRACE_ON(relay)) RELAY_SetupDLL( module );
}
else
{
if ((wm->ldr.Flags & LDR_IMAGE_IS_DLL) && TRACE_ON(snoop)) SNOOP_SetupDLL( module );
}
TRACE_(loaddll)( "Loaded %s at %p: %s\n", debugstr_w(wm->ldr.FullDllName.Buffer), module, dll_type ); TRACE_(loaddll)( "Loaded %s at %p: %s\n", debugstr_w(wm->ldr.FullDllName.Buffer), module, dll_type );
......
...@@ -42,7 +42,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(relay); ...@@ -42,7 +42,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(relay);
struct relay_descr /* descriptor for a module */ struct relay_descr /* descriptor for a module */
{ {
void *magic; /* signature */ ULONG_PTR magic; /* signature */
void *relay_call; /* functions to call from relay thunks */ void *relay_call; /* functions to call from relay thunks */
void *private; /* reserved for the relay code private data */ void *private; /* reserved for the relay code private data */
const char *entry_point_base; /* base address of entry point thunks */ const char *entry_point_base; /* base address of entry point thunks */
...@@ -50,7 +50,13 @@ struct relay_descr /* descriptor for a module */ ...@@ -50,7 +50,13 @@ struct relay_descr /* descriptor for a module */
const char *args_string; /* string describing the arguments */ const char *args_string; /* string describing the arguments */
}; };
#define RELAY_DESCR_MAGIC ((void *)0xdeb90002) struct relay_descr_rva /* RVA to the descriptor for PE dlls */
{
DWORD magic;
DWORD descr;
};
#define RELAY_DESCR_MAGIC 0xdeb90002
#define IS_INTARG(x) (((ULONG_PTR)(x) >> 16) == 0) #define IS_INTARG(x) (((ULONG_PTR)(x) >> 16) == 0)
/* private data built at dll load time */ /* private data built at dll load time */
...@@ -837,6 +843,26 @@ __ASM_GLOBAL_FUNC( relay_call, ...@@ -837,6 +843,26 @@ __ASM_GLOBAL_FUNC( relay_call,
#endif #endif
static struct relay_descr *get_relay_descr( HMODULE module, const IMAGE_EXPORT_DIRECTORY *exports,
DWORD exp_size )
{
struct relay_descr *descr;
struct relay_descr_rva *rva;
ULONG_PTR ptr = (ULONG_PTR)module + exports->Name;
/* sanity checks */
if (ptr <= (ULONG_PTR)(exports + 1)) return NULL;
if (ptr > (ULONG_PTR)exports + exp_size) return NULL;
if (ptr % sizeof(DWORD)) return NULL;
rva = (struct relay_descr_rva *)ptr - 1;
if (rva->magic != RELAY_DESCR_MAGIC) return NULL;
if (rva->descr) descr = (struct relay_descr *)((char *)module + rva->descr);
else descr = (struct relay_descr *)((const char *)exports + exp_size);
if (descr->magic != RELAY_DESCR_MAGIC) return NULL;
return descr;
}
/*********************************************************************** /***********************************************************************
* RELAY_GetProcAddress * RELAY_GetProcAddress
* *
...@@ -846,9 +872,9 @@ FARPROC RELAY_GetProcAddress( HMODULE module, const IMAGE_EXPORT_DIRECTORY *expo ...@@ -846,9 +872,9 @@ FARPROC RELAY_GetProcAddress( HMODULE module, const IMAGE_EXPORT_DIRECTORY *expo
DWORD exp_size, FARPROC proc, DWORD ordinal, const WCHAR *user ) DWORD exp_size, FARPROC proc, DWORD ordinal, const WCHAR *user )
{ {
struct relay_private_data *data; struct relay_private_data *data;
const struct relay_descr *descr = (const struct relay_descr *)((const char *)exports + exp_size); const struct relay_descr *descr = get_relay_descr( module, exports, exp_size );
if (descr->magic != RELAY_DESCR_MAGIC || !(data = descr->private)) return proc; /* no relay data */ if (!descr || !(data = descr->private)) return proc; /* no relay data */
if (!data->entry_points[ordinal].orig_func) return proc; /* not a relayed function */ if (!data->entry_points[ordinal].orig_func) return proc; /* not a relayed function */
if (check_from_module( debug_from_relay_includelist, debug_from_relay_excludelist, user )) if (check_from_module( debug_from_relay_includelist, debug_from_relay_excludelist, user ))
return proc; /* we want to relay it */ return proc; /* we want to relay it */
...@@ -866,18 +892,19 @@ void RELAY_SetupDLL( HMODULE module ) ...@@ -866,18 +892,19 @@ void RELAY_SetupDLL( HMODULE module )
IMAGE_EXPORT_DIRECTORY *exports; IMAGE_EXPORT_DIRECTORY *exports;
DWORD *funcs; DWORD *funcs;
unsigned int i, len; unsigned int i, len;
DWORD size, entry_point_rva; DWORD size, entry_point_rva, old_prot;
struct relay_descr *descr; struct relay_descr *descr;
struct relay_private_data *data; struct relay_private_data *data;
const WORD *ordptr; const WORD *ordptr;
void *func_base;
SIZE_T func_size;
RtlRunOnceExecuteOnce( &init_once, init_debug_lists, NULL, NULL ); RtlRunOnceExecuteOnce( &init_once, init_debug_lists, NULL, NULL );
exports = RtlImageDirectoryEntryToData( module, TRUE, IMAGE_DIRECTORY_ENTRY_EXPORT, &size ); exports = RtlImageDirectoryEntryToData( module, TRUE, IMAGE_DIRECTORY_ENTRY_EXPORT, &size );
if (!exports) return; if (!exports) return;
descr = (struct relay_descr *)((char *)exports + size); if (!(descr = get_relay_descr( module, exports, size ))) return;
if (descr->magic != RELAY_DESCR_MAGIC) return;
if (!(data = RtlAllocateHeap( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*data) + if (!(data = RtlAllocateHeap( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*data) +
(exports->NumberOfFunctions-1) * sizeof(data->entry_points) ))) (exports->NumberOfFunctions-1) * sizeof(data->entry_points) )))
...@@ -907,6 +934,10 @@ void RELAY_SetupDLL( HMODULE module ) ...@@ -907,6 +934,10 @@ void RELAY_SetupDLL( HMODULE module )
funcs = (DWORD *)((char *)module + exports->AddressOfFunctions); funcs = (DWORD *)((char *)module + exports->AddressOfFunctions);
entry_point_rva = descr->entry_point_base - (const char *)module; entry_point_rva = descr->entry_point_base - (const char *)module;
func_base = funcs;
func_size = exports->NumberOfFunctions * sizeof(*funcs);
NtProtectVirtualMemory( NtCurrentProcess(), &func_base, &func_size, PAGE_READWRITE, &old_prot );
for (i = 0; i < exports->NumberOfFunctions; i++, funcs++) for (i = 0; i < exports->NumberOfFunctions; i++, funcs++)
{ {
if (!descr->entry_point_offsets[i]) continue; /* not a normal function */ if (!descr->entry_point_offsets[i]) continue; /* not a normal function */
...@@ -916,6 +947,8 @@ void RELAY_SetupDLL( HMODULE module ) ...@@ -916,6 +947,8 @@ void RELAY_SetupDLL( HMODULE module )
data->entry_points[i].orig_func = (char *)module + *funcs; data->entry_points[i].orig_func = (char *)module + *funcs;
*funcs = entry_point_rva + descr->entry_point_offsets[i]; *funcs = entry_point_rva + descr->entry_point_offsets[i];
} }
if (old_prot != PAGE_READWRITE)
NtProtectVirtualMemory( NtCurrentProcess(), &func_base, &func_size, old_prot, &old_prot );
} }
#else /* __i386__ || __x86_64__ || __arm__ || __aarch64__ */ #else /* __i386__ || __x86_64__ || __arm__ || __aarch64__ */
......
...@@ -379,6 +379,7 @@ static void output_relay_debug( DLLSPEC *spec ) ...@@ -379,6 +379,7 @@ static void output_relay_debug( DLLSPEC *spec )
void output_exports( DLLSPEC *spec ) void output_exports( DLLSPEC *spec )
{ {
int i, fwd_size = 0; int i, fwd_size = 0;
int needs_relay = has_relays( spec );
int nr_exports = spec->base <= spec->limit ? spec->limit - spec->base + 1 : 0; int nr_exports = spec->base <= spec->limit ? spec->limit - spec->base + 1 : 0;
const char *func_ptr = (target_platform == PLATFORM_WINDOWS) ? ".rva" : get_asm_ptr_keyword(); const char *func_ptr = (target_platform == PLATFORM_WINDOWS) ? ".rva" : get_asm_ptr_keyword();
...@@ -472,6 +473,13 @@ void output_exports( DLLSPEC *spec ) ...@@ -472,6 +473,13 @@ void output_exports( DLLSPEC *spec )
} }
} }
if (needs_relay)
{
output( "\t.long 0xdeb90002\n" ); /* magic */
if (target_platform == PLATFORM_WINDOWS) output_rva( ".L__wine_spec_relay_descr" );
else output( "\t.long 0\n" );
}
/* output the export name strings */ /* output the export name strings */
output( "\n.L__wine_spec_exp_names:\n" ); output( "\n.L__wine_spec_exp_names:\n" );
...@@ -493,17 +501,23 @@ void output_exports( DLLSPEC *spec ) ...@@ -493,17 +501,23 @@ void output_exports( DLLSPEC *spec )
} }
} }
if (target_platform == PLATFORM_WINDOWS) return;
output( "\t.align %d\n", get_alignment(get_ptr_size()) );
output( ".L__wine_spec_exports_end:\n" );
/* output relays */ /* output relays */
if (!has_relays( spec )) if (target_platform == PLATFORM_WINDOWS)
{ {
output( "\t%s 0\n", get_asm_ptr_keyword() ); if (!needs_relay) return;
return; output( "\t.data\n" );
output( "\t.align %d\n", get_alignment(get_ptr_size()) );
}
else
{
output( "\t.align %d\n", get_alignment(get_ptr_size()) );
output( ".L__wine_spec_exports_end:\n" );
if (!needs_relay)
{
output( "\t%s 0\n", get_asm_ptr_keyword() );
return;
}
} }
output( ".L__wine_spec_relay_descr:\n" ); output( ".L__wine_spec_relay_descr:\n" );
......
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