Implement binary relocatability [2]
Mike Hearn
mike at theoretic.com
Thu Jan 22 14:09:17 CST 2004
Hm, it seems makedep chokes on the examples in the comments. Here's a
patch without the problematic comment.
Index: configure.ac
===================================================================
RCS file: /home/wine/wine/configure.ac,v
retrieving revision 1.232
diff -u -b -w -r1.232 configure.ac
--- configure.ac 20 Jan 2004 00:21:42 -0000 1.232
+++ configure.ac 22 Jan 2004 19:52:13 -0000
@@ -1408,6 +1408,12 @@
*sun*) WINE_CHECK_DEFINE([__sun__]) ;;
esac
+dnl *** check for /proc/self/maps to see if we can do binary relocatability on linux ***
+
+if test -e /proc/self/maps; then
+ AC_DEFINE(ENABLE_BINRELOC, 1, [Use binary relocatability])
+fi
+
dnl **** Generate output files ****
AH_TOP([#define __WINE_CONFIG_H])
Index: server/Makefile.in
===================================================================
RCS file: /home/wine/wine/server/Makefile.in,v
retrieving revision 1.48
diff -u -b -w -r1.48 Makefile.in
--- server/Makefile.in 10 Dec 2003 04:08:06 -0000 1.48
+++ server/Makefile.in 22 Jan 2004 19:52:13 -0000
@@ -48,12 +48,14 @@
PROGRAMS = wineserver
+RPATH = -Wl,-rpath -Wl,'$${ORIGIN}/../lib'
+
all: $(PROGRAMS)
@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 -b -w -r1.14 Makefile.in
--- loader/Makefile.in 22 Nov 2003 00:08:26 -0000 1.14
+++ loader/Makefile.in 22 Jan 2004 19:52:13 -0000
@@ -16,6 +16,8 @@
WINE_BINARIES = @WINE_BINARIES@
MAIN_BINARY = @MAIN_BINARY@
+RPATH = -Wl,-rpath -Wl,'$${ORIGIN}/../lib'
+
all: $(WINE_BINARIES) $(MODULE)
@MAKE_RULES@
@@ -24,13 +26,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)
Index: libs/wine/loader.c
===================================================================
RCS file: /home/wine/wine/libs/wine/loader.c,v
retrieving revision 1.16
diff -u -b -w -r1.16 loader.c
--- libs/wine/loader.c 2 Jan 2004 21:08:05 -0000 1.16
+++ libs/wine/loader.c 22 Jan 2004 19:52:13 -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,6 +82,27 @@
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)
{
@@ -93,7 +118,7 @@
}
}
- dll_paths = malloc( (count+1) * sizeof(*dll_paths) );
+ dll_paths = malloc( (count + (dynamic_dlldir ? 1 : 2)) * sizeof(*dll_paths) );
if (count)
{
@@ -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;
}
}
--- /dev/null 2003-09-15 14:40:47.000000000 +0100
+++ libs/wine/prefix.c 2004-01-22 19:55:39.000000000 +0000
@@ -0,0 +1,108 @@
+/*
+ * 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 <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