forked from Mirrors/wine-wine
winebuild: Support relay debugging for PE builtin dlls.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>stable
parent
d38ec9e226
commit
6c41cc6152
|
@ -2190,7 +2190,14 @@ static NTSTATUS load_native_dll( LPCWSTR load_path, const UNICODE_STRING *nt_nam
|
|||
}
|
||||
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 );
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(relay);
|
|||
|
||||
struct relay_descr /* descriptor for a module */
|
||||
{
|
||||
void *magic; /* signature */
|
||||
ULONG_PTR magic; /* signature */
|
||||
void *relay_call; /* functions to call from relay thunks */
|
||||
void *private; /* reserved for the relay code private data */
|
||||
const char *entry_point_base; /* base address of entry point thunks */
|
||||
|
@ -50,7 +50,13 @@ struct relay_descr /* descriptor for a module */
|
|||
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)
|
||||
|
||||
/* private data built at dll load time */
|
||||
|
@ -837,6 +843,26 @@ __ASM_GLOBAL_FUNC( relay_call,
|
|||
#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
|
||||
*
|
||||
|
@ -846,9 +872,9 @@ FARPROC RELAY_GetProcAddress( HMODULE module, const IMAGE_EXPORT_DIRECTORY *expo
|
|||
DWORD exp_size, FARPROC proc, DWORD ordinal, const WCHAR *user )
|
||||
{
|
||||
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 (check_from_module( debug_from_relay_includelist, debug_from_relay_excludelist, user ))
|
||||
return proc; /* we want to relay it */
|
||||
|
@ -866,18 +892,19 @@ void RELAY_SetupDLL( HMODULE module )
|
|||
IMAGE_EXPORT_DIRECTORY *exports;
|
||||
DWORD *funcs;
|
||||
unsigned int i, len;
|
||||
DWORD size, entry_point_rva;
|
||||
DWORD size, entry_point_rva, old_prot;
|
||||
struct relay_descr *descr;
|
||||
struct relay_private_data *data;
|
||||
const WORD *ordptr;
|
||||
void *func_base;
|
||||
SIZE_T func_size;
|
||||
|
||||
RtlRunOnceExecuteOnce( &init_once, init_debug_lists, NULL, NULL );
|
||||
|
||||
exports = RtlImageDirectoryEntryToData( module, TRUE, IMAGE_DIRECTORY_ENTRY_EXPORT, &size );
|
||||
if (!exports) return;
|
||||
|
||||
descr = (struct relay_descr *)((char *)exports + size);
|
||||
if (descr->magic != RELAY_DESCR_MAGIC) return;
|
||||
if (!(descr = get_relay_descr( module, exports, size ))) return;
|
||||
|
||||
if (!(data = RtlAllocateHeap( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*data) +
|
||||
(exports->NumberOfFunctions-1) * sizeof(data->entry_points) )))
|
||||
|
@ -907,6 +934,10 @@ void RELAY_SetupDLL( HMODULE module )
|
|||
|
||||
funcs = (DWORD *)((char *)module + exports->AddressOfFunctions);
|
||||
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++)
|
||||
{
|
||||
if (!descr->entry_point_offsets[i]) continue; /* not a normal function */
|
||||
|
@ -916,6 +947,8 @@ void RELAY_SetupDLL( HMODULE module )
|
|||
data->entry_points[i].orig_func = (char *)module + *funcs;
|
||||
*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__ */
|
||||
|
|
|
@ -379,6 +379,7 @@ static void output_relay_debug( DLLSPEC *spec )
|
|||
void output_exports( DLLSPEC *spec )
|
||||
{
|
||||
int i, fwd_size = 0;
|
||||
int needs_relay = has_relays( spec );
|
||||
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();
|
||||
|
||||
|
@ -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( "\n.L__wine_spec_exp_names:\n" );
|
||||
|
@ -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 */
|
||||
|
||||
if (!has_relays( spec ))
|
||||
if (target_platform == PLATFORM_WINDOWS)
|
||||
{
|
||||
output( "\t%s 0\n", get_asm_ptr_keyword() );
|
||||
return;
|
||||
if (!needs_relay) 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" );
|
||||
|
|
Loading…
Reference in New Issue