when: - Wine is installed in a (configure:d) directory - running wine directly from <confdir>/bin/wine(64) (without setting any WINE specific env variables) - dbghelp cannot find back the loader/wine(64) file
consequences: - dbghelp cannot get back to the ELF information, hence (on a live target) doesn't report the already loaded ELF modules (only the PE ones are listed)
dbghelp searches: - WINELOADER env var (but it isn't set in that case) - LD_LIBRARY_PATH (isn't changed, and even if it would, it would point to <confdir>/lib directory) - WINEDLLDIR<NN>, but again could point to <confdir>/lib directory, not the bin one
wine-staging has a solution by forcing dbghelp to search @bindir@ as well
this patch proposes an alternate approach: the wine loader sets WINELOADER if it isn't already set by the calling environment
Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- loader/main.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-)
diff --git a/loader/main.c b/loader/main.c index 242ff15accd..c5e0fdf68b2 100644 --- a/loader/main.c +++ b/loader/main.c @@ -41,18 +41,12 @@ extern char **environ; /* the preloader will set this variable */ const struct wine_preload_info *wine_main_preload_info = NULL;
-/* canonicalize path and return its directory name */ -static char *realpath_dirname( const char *name ) +/* remove filename from an (absolute) path */ +static void remove_filename( char *fullpath ) { - char *p, *fullpath = realpath( name, NULL ); - - if (fullpath) - { - p = strrchr( fullpath, '/' ); - if (p == fullpath) p++; - if (p) *p = 0; - } - return fullpath; + char *p = strrchr( fullpath, '/' ); + if (p == fullpath) p++; + if (p) *p = 0; }
/* if string ends with tail, remove it */ @@ -141,8 +135,10 @@ static void *load_ntdll( char *argv0 ) char *path, *p; void *handle = NULL;
- if (self && ((path = realpath_dirname( self )))) + if (self && (path = realpath( self, NULL ))) { + setenv( "WINELOADER", path, 0 ); + remove_filename( path ); if ((p = remove_tail( path, "/loader" ))) { handle = try_dlopen( p, "dlls/ntdll/ntdll.so" );
Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- dlls/dbghelp/path.c | 38 +++++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 13 deletions(-)
diff --git a/dlls/dbghelp/path.c b/dlls/dbghelp/path.c index f99129eac49..f93276e7b6d 100644 --- a/dlls/dbghelp/path.c +++ b/dlls/dbghelp/path.c @@ -32,20 +32,30 @@ WINE_DEFAULT_DEBUG_CHANNEL(dbghelp);
#ifdef __i386__ -static const WCHAR pe_dir[] = L"\i386-windows"; -static const WCHAR so_dir[] = L"\i386-unix"; +static const WCHAR pe_dir[] = L"\i386-windows"; +static const WCHAR so_dir[] = L"\i386-unix"; +static const WCHAR pe_wow_dir[] = L""; +static const WCHAR so_wow_dir[] = L""; #elif defined __x86_64__ -static const WCHAR pe_dir[] = L"\x86_64-windows"; -static const WCHAR so_dir[] = L"\x86_64-unix"; +static const WCHAR pe_dir[] = L"\x86_64-windows"; +static const WCHAR so_dir[] = L"\x86_64-unix"; +static const WCHAR pe_wow_dir[] = L"\i386-windows"; +static const WCHAR so_wow_dir[] = L"\i386-unix"; #elif defined __arm__ -static const WCHAR pe_dir[] = L"\arm-windows"; -static const WCHAR so_dir[] = L"\arm-unix"; +static const WCHAR pe_dir[] = L"\arm-windows"; +static const WCHAR so_dir[] = L"\arm-unix"; +static const WCHAR pe_wow_dir[] = L""; +static const WCHAR so_wow_dir[] = L""; #elif defined __aarch64__ -static const WCHAR pe_dir[] = L"\aarch64-windows"; -static const WCHAR so_dir[] = L"\aarch64-unix"; +static const WCHAR pe_dir[] = L"\aarch64-windows"; +static const WCHAR so_dir[] = L"\aarch64-unix"; +static const WCHAR pe_wow_dir[] = L""; +static const WCHAR so_wow_dir[] = L""; #else -static const WCHAR pe_dir[] = L""; -static const WCHAR so_dir[] = L""; +static const WCHAR pe_dir[] = L""; +static const WCHAR so_dir[] = L""; +static const WCHAR pe_wow_dir[] = L""; +static const WCHAR so_wow_dir[] = L""; #endif
static inline BOOL is_sepA(char ch) {return ch == '/' || ch == '\';} @@ -763,14 +773,16 @@ BOOL search_dll_path(const struct process *process, const WCHAR *name, BOOL (*ma for (i = 0;; i++) { WCHAR env_name[64]; + const WCHAR* pcspe_dir = (sizeof(void*) == 4 || process->is_64bit) ? pe_dir : pe_wow_dir; + const WCHAR* pcsso_dir = (sizeof(void*) == 4 || process->is_64bit) ? so_dir : so_wow_dir; swprintf(env_name, ARRAY_SIZE(env_name), L"WINEDLLDIR%u", i); if (!(env = process_getenv(process, env_name))) return FALSE; - len = wcslen(env) + wcslen(pe_dir) + wcslen(name) + 2; + len = wcslen(env) + wcslen(pcspe_dir) + wcslen(name) + 2; if (!(buf = heap_alloc(len * sizeof(WCHAR)))) return FALSE; if ((p = wcsrchr(name, '.')) && !lstrcmpW(p, L".so")) - swprintf(buf, len, L"%s%s\%s", env, so_dir, name); + swprintf(buf, len, L"%s%s\%s", env, pcsso_dir, name); else - swprintf(buf, len, L"%s%s\%s", env, pe_dir, name); + swprintf(buf, len, L"%s%s\%s", env, pcspe_dir, name); file = CreateFileW(buf, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (file != INVALID_HANDLE_VALUE) {