Binary relocatability [4]
Mike Hearn
mike at theoretic.com
Fri Jan 23 04:24:30 CST 2004
Here it is with the ability to switch it off in the configure script.
Mike Hearn <mike at theoretic.com>
Hongli Lai <h.lai at chello.nl>
Implement runtime binary relocatability
Index: configure.ac
===================================================================
RCS file: /home/wine/wine/configure.ac,v
retrieving revision 1.232
diff -u -r1.232 configure.ac
--- configure.ac 20 Jan 2004 00:21:42 -0000 1.232
+++ configure.ac 23 Jan 2004 10:17:36 -0000
@@ -15,6 +15,7 @@
AC_ARG_ENABLE(win16, AC_HELP_STRING([--disable-win16],[do not include Win16 support]))
AC_ARG_ENABLE(debug, AC_HELP_STRING([--disable-debug],[compile out all debugging messages]))
AC_ARG_ENABLE(trace, AC_HELP_STRING([--disable-trace],[compile out TRACE messages]))
+AC_ARG_ENABLE(binreloc, AC_HELP_STRING([--disable-binreloc],[disable binary runtime relocatability]))
AC_ARG_WITH(opengl, AC_HELP_STRING([--without-opengl],[do not use OpenGL]))
AC_ARG_WITH(curses, AC_HELP_STRING([--without-curses],[do not use curses]))
@@ -1407,6 +1408,18 @@
case $host_vendor in
*sun*) WINE_CHECK_DEFINE([__sun__]) ;;
esac
+
+dnl *** check for /proc/self/maps to see if we can do binary relocatability on linux ***
+
+if ! test "x$enable_binreloc" = "xno" -a -e /proc/self/maps; then
+ AC_DEFINE(ENABLE_BINRELOC, 1, [Use binary relocatability])
+ RPATH='-Wl,-rpath -Wl,$${ORIGIN}/../lib'
+else
+ RPATH=''
+fi
+AC_SUBST(RPATH)
+
+
dnl **** Generate output files ****
Index: Make.rules.in
===================================================================
RCS file: /home/wine/wine/Make.rules.in,v
retrieving revision 1.164
diff -u -r1.164 Make.rules.in
--- Make.rules.in 13 Dec 2003 03:19:34 -0000 1.164
+++ Make.rules.in 23 Jan 2004 10:17:36 -0000
@@ -99,6 +99,7 @@
sysconfdir = @sysconfdir@
includedir = @includedir@/wine
dlldir = @libdir@/wine
+RPATH = @RPATH@
prog_manext = 1
api_manext = 3w
conf_manext = 5
Index: libs/wine/loader.c
===================================================================
RCS file: /home/wine/wine/libs/wine/loader.c,v
retrieving revision 1.16
diff -u -r1.16 loader.c
--- libs/wine/loader.c 2 Jan 2004 21:08:05 -0000 1.16
+++ libs/wine/loader.c 23 Jan 2004 10:17:36 -0000
@@ -41,6 +41,10 @@
#include "winbase.h"
#include "wine/library.h"
+#ifdef ENABLE_BINRELOC
+extern char *wine_locate (void *symbol);
+#endif
+
/* argc/argv for the Windows application */
int __wine_main_argc = 0;
char **__wine_main_argv = NULL;
@@ -78,11 +82,32 @@
static const char * const dlldir = DLLDIR;
int len, count = 0;
char *p, *path = getenv( "WINEDLLPATH" );
+ char *dynamic_dlldir = NULL;
+
+#ifdef ENABLE_BINRELOC
+ char *slash;
+ char *relpath = "/wine";
+
+ /* We want to determine the absolute path of this libwine from the linker mappings, then calculate a dlldir from that
+ For now, we'll assume a relative path of ./wine
+ */
+ dynamic_dlldir = wine_locate("");
+ slash = strrchr( dynamic_dlldir, '/' ); /* get to the prefix */
+ if (slash) {
+ *slash = '\0';
+ p = malloc( strlen(dynamic_dlldir) + strlen(relpath) + 1 );
+ strcpy( p, dynamic_dlldir );
+ strcat( p, relpath );
+ dynamic_dlldir = p;
+ } else dynamic_dlldir = NULL;
+
+#endif
+
if (path)
{
/* count how many path elements we need */
- path = strdup(path);
+ path = strdup(path);
p = path;
while (*p)
{
@@ -93,8 +118,8 @@
}
}
- dll_paths = malloc( (count+1) * sizeof(*dll_paths) );
-
+ dll_paths = malloc( (count + (dynamic_dlldir ? 1 : 2)) * sizeof(*dll_paths) );
+
if (count)
{
p = path;
@@ -116,6 +141,11 @@
{
if (len > dll_path_maxlen) dll_path_maxlen = len;
dll_paths[nb_dll_paths++] = dlldir;
+ }
+
+ if (dynamic_dlldir && (len = strlen(dynamic_dlldir))) {
+ if (len > dll_path_maxlen) dll_path_maxlen = len;
+ dll_paths[nb_dll_paths++] = dynamic_dlldir;
}
}
Index: server/Makefile.in
===================================================================
RCS file: /home/wine/wine/server/Makefile.in,v
retrieving revision 1.48
diff -u -r1.48 Makefile.in
--- server/Makefile.in 10 Dec 2003 04:08:06 -0000 1.48
+++ server/Makefile.in 23 Jan 2004 10:17:36 -0000
@@ -53,7 +53,7 @@
@MAKE_RULES@
wineserver: $(OBJS)
- $(CC) -o $(PROGRAMS) $(OBJS) $(LIBWINE) $(LIBUNICODE) $(LIBPORT) $(LDFLAGS) $(LIBS)
+ $(CC) -o $(PROGRAMS) $(OBJS) $(LIBWINE) $(LIBUNICODE) $(LIBPORT) $(LDFLAGS) $(LIBS) $(RPATH)
install:: $(PROGRAMS)
$(MKINSTALLDIRS) $(bindir)
Index: loader/Makefile.in
===================================================================
RCS file: /home/wine/wine/loader/Makefile.in,v
retrieving revision 1.14
diff -u -r1.14 Makefile.in
--- loader/Makefile.in 22 Nov 2003 00:08:26 -0000 1.14
+++ loader/Makefile.in 23 Jan 2004 10:17:36 -0000
@@ -24,13 +24,13 @@
LDEXECFLAGS = @LDEXECFLAGS@
wine-glibc: glibc.o Makefile.in
- $(CC) -o $@ $(LDEXECFLAGS) glibc.o $(LIBWINE) $(LIBPORT) $(LIBPTHREAD) $(EXTRALIBS) $(LDFLAGS)
+ $(CC) -o $@ $(LDEXECFLAGS) glibc.o $(LIBWINE) $(LIBPORT) $(LIBPTHREAD) $(EXTRALIBS) $(LDFLAGS) $(RPATH)
wine-kthread: $(KTHREAD_OBJS) Makefile.in
- $(CC) -o $@ $(LDEXECFLAGS) $(KTHREAD_OBJS) $(LIBWINE) $(LIBPORT) $(EXTRALIBS) $(LDFLAGS)
+ $(CC) -o $@ $(LDEXECFLAGS) $(KTHREAD_OBJS) $(LIBWINE) $(LIBPORT) $(EXTRALIBS) $(LDFLAGS) $(RPATH)
wine-pthread: $(PTHREAD_OBJS) Makefile.in
- $(CC) -o $@ $(LDEXECFLAGS) $(PTHREAD_OBJS) $(LIBWINE) $(LIBPORT) $(LIBPTHREAD) $(EXTRALIBS) $(LDFLAGS)
+ $(CC) -o $@ $(LDEXECFLAGS) $(PTHREAD_OBJS) $(LIBWINE) $(LIBPORT) $(LIBPTHREAD) $(EXTRALIBS) $(LDFLAGS) $(RPATH)
$(MODULE): $(MAIN_BINARY)
$(RM) $(MODULE) && $(LN_S) $(MAIN_BINARY) $(MODULE)
--- /dev/null 2003-09-15 14:40:47.000000000 +0100
+++ libs/wine/prefix.c 2004-01-22 20:18:04.000000000 +0000
@@ -0,0 +1,109 @@
+/*
+ * Dynamic DLL path detection support
+ *
+ * Copyright 2004 Mike Hearn
+ * Copyright 2004 Hongli Lai
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _PREFIX_C_
+#define _PREFIX_C_
+
+#include "config.h"
+
+#define __USE_GNU
+#include <features.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <limits.h>
+
+#ifdef ENABLE_BINRELOC
+#define __USE_GNU
+#include <dlfcn.h>
+#include <link.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/param.h>
+#include <unistd.h>
+
+
+/**
+ * wine_locate:
+ * symbol: A symbol that belongs to the app/library you want to locate.
+ * Returns: A newly allocated string containing the full path of the
+ * app/library that func belongs to, or NULL on error. This
+ * string should be freed when not when no longer needed.
+ *
+ * Finds out to which application or library symbol belongs, then locate
+ * the full path of that application or library.
+ * Note that symbol cannot be a pointer to a function. That will not work.
+ *
+ */
+char *
+wine_locate (void *symbol)
+{
+ Dl_info info;
+ char line[5000];
+ FILE *f;
+ char *path;
+
+ if (symbol == NULL) return NULL;
+ if (!dladdr (symbol, &info)) return NULL;
+
+ f = fopen ("/proc/self/maps", "r");
+ if (f == NULL) return NULL;
+
+ while (fgets (line, sizeof (line), f))
+ {
+ unsigned int start;
+
+ sscanf (line, "%x-", &start);
+
+ if (start == (unsigned int) info.dli_fbase)
+ {
+ char *tmp;
+ size_t len;
+
+ /* Extract the filename; it is always an absolute path */
+ path = strchr (line, '/');
+
+ /* Get rid of the newline */
+ tmp = strrchr (path, '\n');
+ if (tmp) *tmp = 0;
+
+ /* Get rid of "(deleted)" */
+ len = strlen (path);
+ if (len > 10 && strcmp (path + len - 10, " (deleted)") == 0)
+ {
+ tmp = path + len - 10;
+ *tmp = 0;
+ }
+
+ fclose(f);
+ return strdup (path);
+ }
+ }
+
+ fclose (f);
+ /* we should not get here */
+ return NULL;
+}
+
+
+#endif /* ENABLE_BINRELOC */
+
+#endif /* _PREFIX_C */
More information about the wine-patches
mailing list