This patch allows to tell Wine to use a privately bundled ld-linux.so.2 (and related glibc and other libraries) instead of looking for them in the host system.
This greatly simplifies packaging Wine as a self-standing bundle for Linux (e.g., AppDir, AppImage), making it possible to run Wine without installation, even on 64-bit systems on which 32-bit compatibility libraries are not installed.
The problem statement has been described in more detail by me in https://www.winehq.org/pipermail/wine-devel/2017-November/119906.html
The approach was suggested by Alexandre Julliard in https://www.winehq.org/pipermail/wine-devel/2017-November/119944.html
All credit for this patch goes to Hackerl, on whose behalf I am posting.
Source: https://github.com/Hackerl/wine/commit/4f7f784.patch Discussion: https://github.com/Hackerl/Wine_Appimage/issues/11
From: Hackerl 490021209@qq.com
Signed-off-by: Hackerl 490021209@qq.com --- libs/wine/config.c | 21 ++++++++++++++++++++- loader/preloader.c | 10 +++++++--- 2 files changed, 27 insertions(+), 4 deletions(-)
diff --git a/libs/wine/config.c b/libs/wine/config.c index 083e263ee3d..e89c2c63a95 100644 --- a/libs/wine/config.c +++ b/libs/wine/config.c @@ -562,7 +562,26 @@ static void preloader_exec( char **argv, int use_preloader ) free( new_argv ); free( full_name ); } - execv( argv[0], argv ); + else + { + char * wineloader = getenv("WINELDLIBRARY"); + + if (wineloader == NULL) + execv( argv[0], argv ); + + char **last_arg = argv; + + while (*last_arg) last_arg++; + + char ** new_argv = xmalloc( (last_arg - argv + 2) * sizeof(*argv) ); + memcpy( new_argv + 1, argv, (last_arg - argv + 1) * sizeof(*argv) ); + + new_argv[0] = wineloader; + + execv(wineloader, new_argv); + + free( new_argv ); + } }
/* exec a wine internal binary (either the wine loader or the wine server) */ diff --git a/loader/preloader.c b/loader/preloader.c index 13a6ad86b20..55af8383773 100644 --- a/loader/preloader.c +++ b/loader/preloader.c @@ -1255,7 +1255,7 @@ void* wld_start( void **stack ) { long i, *pargc; char **argv, **p; - char *interp, *reserve = NULL; + char *interp = NULL, *reserve = NULL; struct wld_auxv new_av[8], delete_av[3], *av; struct wld_link_map main_binary_map, ld_so_map; struct wine_preload_info **wine_main_preload_info; @@ -1270,8 +1270,11 @@ void* wld_start( void **stack ) /* skip over the environment */ while (*p) { - static const char res[] = "WINEPRELOADRESERVE="; + static const char res[] = "WINEPRELOADRESERVE=", loader[] = "WINELDLIBRARY="; + if (!wld_strncmp( *p, res, sizeof(res)-1 )) reserve = *p + sizeof(res) - 1; + if (!wld_strncmp( *p, loader, sizeof(loader)-1 )) interp = *p + sizeof(loader) - 1; + p++; }
@@ -1323,7 +1326,8 @@ void* wld_start( void **stack ) map_so_lib( argv[1], &main_binary_map );
/* load the ELF interpreter */ - interp = (char *)main_binary_map.l_addr + main_binary_map.l_interp; + if (interp == NULL) + interp = (char *)main_binary_map.l_addr + main_binary_map.l_interp; map_so_lib( interp, &ld_so_map );
/* store pointer to the preload info into the appropriate main binary variable */
Hi,
While running your changed tests on Windows, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=45641
Your paranoid android.
=== debian9 (build log) ===
error: corrupt patch at line 34 Task: Patch failed to apply
=== debian9 (build log) ===
error: corrupt patch at line 34 Task: Patch failed to apply