Re: ptrace single-stepping change breaks Wine

Mike Hearn
2004-12-31T13:26:08Z

On Fri, 2004-12-31 at 14:13 +0100, Thomas Sailer wrote:
> No this doesn't work. The decision which address space layout to use is done
> in arch/i386/mm/mmap.c:arch_pick_mmap_layout, and this function is called by
> the elf loader in fs/binfmt_elf.c:load_elf_binary, i.e. the decision which
> address space layout to use for the current wine process is already done long
> time before your personality syscall takes effect.
>
> I hoped there was some ELF section magic to turn this off (like execshield),
> but there doesn't seem to be.

So it has to be done before an exec then? I had assumed changing the
personality would affect all mmaps from that point onwards, too bad.

We do some execs as part of the Wine startup code so it shouldn't be too
much of an issue. Anyway, all the setarch program does is do this
syscall then exec the program so it shouldn't be too hard to do the
equivalent in Wine.

What about this patch?

--- libs/wine/config.c (revision 14)
+++ libs/wine/config.c (local)
@@ -35,6 +35,10 @@
#endif
#include "wine/library.h"

+#ifdef HAVE_SYSCALL_H
+#include <syscall.h>
+#endif
+
static const char server_config_dir[] = "/.wine"; /* config dir relative to $HOME */
static const char server_root_prefix[] = "/tmp/.wine-"; /* prefix for server root dir */
static const char server_dir_prefix[] = "/server-"; /* prefix for server dir */
@@ -289,8 +293,13 @@ static void preloader_exec( char **argv,
new_argv = xmalloc( (last_arg - argv + 2) * sizeof(*argv) );
memcpy( new_argv + 1, argv, (last_arg - argv + 1) * sizeof(*argv) );
new_argv[0] = full_name;
+
+ /* set the abi personality */
+ syscall(136, 0x8 /* PER_LINUX32 */ | 0x0200000 /* ADDR_COMPAT_LAYOUT */);
+
if (envp) execve( full_name, new_argv, envp );
else execv( full_name, new_argv );
+
free( new_argv );
free( full_name );
return;