summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYaakov Selkowitz <yselkowitz@users.sourceforge.net>2014-04-06 14:18:32 -0500
committerYaakov Selkowitz <yselkowitz@users.sourceforge.net>2014-06-27 18:31:56 -0500
commit0dcdd82059c69ec417bb094f4da2afef7cc1426a (patch)
tree2c6fb577baf6d252e728864d75b1be486e1bb364
parent783a406d6258509abfbdc54c0b32366dcaf13044 (diff)
Make shared library work on Cygwin/MinGW
Weak symbols on PE platforms do not work the same way as on ELF platforms, hence we have been unable to have a fully functional shared libXfont until now. This patch works around these issues so that we can fix that. In summary, only when compiling shared libraries on NO_WEAK_SYMBOLS platforms, when the first stub is called, the invoking program is first checked to determine if it exports the stubbed functions. Then, for every stub call, if the function is exported by the loader, it is called instead of the stub code. serverClient and serverGeneration are data pointers, and therefore are replaced by getter functions. ErrorF is variadic, so the override is routed through VErrorF instead. FatalError has no va_list equivalent, but it is not actually used in libXfont and therefore should be safe to remove. This requires all X servers to export their symbols, which requires forthcoming patches for hw/xwin and xfs; the other xservers (including tigervnc) already do this via LD_EXPORT_SYMBOLS_FLAG. Signed-off-by: Yaakov Selkowitz <yselkowitz@users.sourceforge.net> Reviewed-by: Colin Harrison <colin.harrison@virgin.net> Acked-by: Alan Coopersmith <alan.coopersmith@oracle.com> Tested-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com>
-rw-r--r--src/Makefile.am2
-rw-r--r--src/bitmap/bitscale.c6
-rw-r--r--src/fc/fserve.c8
-rw-r--r--src/fontfile/renderers.c6
-rw-r--r--src/stubs/Makefile.am2
-rw-r--r--src/stubs/cauthgen.c1
-rw-r--r--src/stubs/csignal.c1
-rw-r--r--src/stubs/delfntcid.c1
-rw-r--r--src/stubs/errorf.c1
-rw-r--r--src/stubs/fatalerror.c13
-rw-r--r--src/stubs/findoldfnt.c1
-rw-r--r--src/stubs/getcres.c1
-rw-r--r--src/stubs/getdefptsize.c1
-rw-r--r--src/stubs/getnewfntcid.c1
-rw-r--r--src/stubs/gettime.c1
-rw-r--r--src/stubs/initfshdl.c1
-rw-r--r--src/stubs/regfpefunc.c4
-rw-r--r--src/stubs/rmfshdl.c1
-rw-r--r--src/stubs/servclient.c9
-rw-r--r--src/stubs/setfntauth.c1
-rw-r--r--src/stubs/stfntcfnt.c1
-rw-r--r--src/stubs/stubs.h49
-rw-r--r--src/stubs/stubsinit.c82
-rw-r--r--src/util/atom.c4
-rw-r--r--src/util/miscutil.c12
25 files changed, 182 insertions, 28 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index cd09ab9..33fd135 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -65,4 +65,4 @@ libXfont_la_LIBADD = \
libXfont_la_SOURCES = dummy.c
-libXfont_la_LDFLAGS = -version-number 1:4:1
+libXfont_la_LDFLAGS = -version-number 1:4:1 -no-undefined
diff --git a/src/bitmap/bitscale.c b/src/bitmap/bitscale.c
index b32639f..c9af4c0 100644
--- a/src/bitmap/bitscale.c
+++ b/src/bitmap/bitscale.c
@@ -44,7 +44,7 @@ from The Open Group.
#endif
/* Should get this from elsewhere */
-extern unsigned long serverGeneration;
+extern unsigned long __GetServerGeneration(void);
static void bitmapUnloadScalable (FontPtr pFont);
static void ScaleBitmap ( FontPtr pFont, CharInfoPtr opci,
@@ -581,9 +581,9 @@ ComputeScaledProperties(FontInfoPtr sourceFontInfo, /* the font to be scaled */
char *isStringProp;
int nProps;
- if (bitscaleGeneration != serverGeneration) {
+ if (bitscaleGeneration != __GetServerGeneration()) {
initFontPropTable();
- bitscaleGeneration = serverGeneration;
+ bitscaleGeneration = __GetServerGeneration();
}
nProps = NPROPS + 1 + sizeof(fontPropTable) / sizeof(fontProp) +
sizeof(rawFontPropTable) / sizeof(fontProp);
diff --git a/src/fc/fserve.c b/src/fc/fserve.c
index c1cf9d6..92b0d53 100644
--- a/src/fc/fserve.c
+++ b/src/fc/fserve.c
@@ -2161,7 +2161,7 @@ fs_send_load_glyphs(pointer client, FontPtr pfont,
}
-extern pointer serverClient; /* This could be any number that
+extern pointer __GetServerClient(void); /* This could be any number that
doesn't conflict with existing
client values. */
@@ -2333,17 +2333,17 @@ fs_load_all_glyphs(FontPtr pfont)
* perform an unpleasant job that, we hope, will never be required.
*/
- while ((err = _fs_load_glyphs(serverClient, pfont, TRUE, 0, 0, NULL)) ==
+ while ((err = _fs_load_glyphs(__GetServerClient(), pfont, TRUE, 0, 0, NULL)) ==
Suspended)
{
if (fs_await_reply (conn) != FSIO_READY)
{
/* Get rid of blockrec */
- fs_client_died(serverClient, pfont->fpe);
+ fs_client_died(__GetServerClient(), pfont->fpe);
err = BadCharRange;
break;
}
- fs_read_reply (pfont->fpe, serverClient);
+ fs_read_reply (pfont->fpe, __GetServerClient());
}
return err;
}
diff --git a/src/fontfile/renderers.c b/src/fontfile/renderers.c
index 5091922..bbcd466 100644
--- a/src/fontfile/renderers.c
+++ b/src/fontfile/renderers.c
@@ -40,7 +40,7 @@ static FontRenderersRec renderers;
* XXX Maybe should allow unregistering renders. For now, just clear the
* list at each new generation.
*/
-extern unsigned long serverGeneration;
+extern unsigned long __GetServerGeneration(void);
static unsigned long rendererGeneration = 0;
Bool
@@ -55,8 +55,8 @@ FontFilePriorityRegisterRenderer (FontRendererPtr renderer, int priority)
int i;
struct _FontRenderersElement *new;
- if (rendererGeneration != serverGeneration) {
- rendererGeneration = serverGeneration;
+ if (rendererGeneration != __GetServerGeneration()) {
+ rendererGeneration = __GetServerGeneration();
renderers.number = 0;
if (renderers.renderers)
free(renderers.renderers);
diff --git a/src/stubs/Makefile.am b/src/stubs/Makefile.am
index 23e3bd1..7eb16d4 100644
--- a/src/stubs/Makefile.am
+++ b/src/stubs/Makefile.am
@@ -10,7 +10,6 @@ libstubs_la_SOURCES = \
csignal.c \
delfntcid.c \
errorf.c \
- fatalerror.c \
findoldfnt.c \
getcres.c \
getdefptsize.c \
@@ -22,4 +21,5 @@ libstubs_la_SOURCES = \
servclient.c \
setfntauth.c \
stfntcfnt.c \
+ stubsinit.c \
stubs.h
diff --git a/src/stubs/cauthgen.c b/src/stubs/cauthgen.c
index 026c52d..10086e4 100644
--- a/src/stubs/cauthgen.c
+++ b/src/stubs/cauthgen.c
@@ -10,5 +10,6 @@
weak int
client_auth_generation(ClientPtr client)
{
+ OVERRIDE_SYMBOL(client_auth_generation, client);
return 0;
}
diff --git a/src/stubs/csignal.c b/src/stubs/csignal.c
index e6fdeae..dd88b3d 100644
--- a/src/stubs/csignal.c
+++ b/src/stubs/csignal.c
@@ -10,5 +10,6 @@
weak Bool
ClientSignal(ClientPtr client)
{
+ OVERRIDE_SYMBOL(ClientSignal,client);
return True;
}
diff --git a/src/stubs/delfntcid.c b/src/stubs/delfntcid.c
index ca71328..8113b9f 100644
--- a/src/stubs/delfntcid.c
+++ b/src/stubs/delfntcid.c
@@ -10,4 +10,5 @@
weak void
DeleteFontClientID(Font id)
{
+ OVERRIDE_SYMBOL(DeleteFontClientID, id);
}
diff --git a/src/stubs/errorf.c b/src/stubs/errorf.c
index fd32965..d2de6c6 100644
--- a/src/stubs/errorf.c
+++ b/src/stubs/errorf.c
@@ -10,4 +10,5 @@
weak void
ErrorF(const char *f, ...)
{
+ OVERRIDE_VA_SYMBOL(VErrorF, f);
}
diff --git a/src/stubs/fatalerror.c b/src/stubs/fatalerror.c
deleted file mode 100644
index 1549ad3..0000000
--- a/src/stubs/fatalerror.c
+++ /dev/null
@@ -1,13 +0,0 @@
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-#include "stubs.h"
-
-#ifdef __SUNPRO_C
-#pragma weak FatalError
-#endif
-
-weak void
-FatalError(const char *f, ...)
-{
-}
diff --git a/src/stubs/findoldfnt.c b/src/stubs/findoldfnt.c
index 7a00084..c73279e 100644
--- a/src/stubs/findoldfnt.c
+++ b/src/stubs/findoldfnt.c
@@ -10,5 +10,6 @@
weak FontPtr
find_old_font(FSID id)
{
+ OVERRIDE_SYMBOL(find_old_font, id);
return (FontPtr)NULL;
}
diff --git a/src/stubs/getcres.c b/src/stubs/getcres.c
index 0b98f46..27a9180 100644
--- a/src/stubs/getcres.c
+++ b/src/stubs/getcres.c
@@ -10,5 +10,6 @@
weak FontResolutionPtr
GetClientResolutions(int *num)
{
+ OVERRIDE_SYMBOL(GetClientResolutions, num);
return (FontResolutionPtr) 0;
}
diff --git a/src/stubs/getdefptsize.c b/src/stubs/getdefptsize.c
index 0b9e409..50c1b18 100644
--- a/src/stubs/getdefptsize.c
+++ b/src/stubs/getdefptsize.c
@@ -10,5 +10,6 @@
weak int
GetDefaultPointSize(void)
{
+ OVERRIDE_SYMBOL(GetDefaultPointSize);
return 0;
}
diff --git a/src/stubs/getnewfntcid.c b/src/stubs/getnewfntcid.c
index e2fe8bb..d31ccf1 100644
--- a/src/stubs/getnewfntcid.c
+++ b/src/stubs/getnewfntcid.c
@@ -10,5 +10,6 @@
weak Font
GetNewFontClientID(void)
{
+ OVERRIDE_SYMBOL(GetNewFontClientID);
return (Font)0;
}
diff --git a/src/stubs/gettime.c b/src/stubs/gettime.c
index 7b2d3b3..1b20f62 100644
--- a/src/stubs/gettime.c
+++ b/src/stubs/gettime.c
@@ -10,5 +10,6 @@
weak unsigned long
GetTimeInMillis (void)
{
+ OVERRIDE_SYMBOL(GetTimeInMillis);
return 0;
}
diff --git a/src/stubs/initfshdl.c b/src/stubs/initfshdl.c
index a14daff..e1c0b24 100644
--- a/src/stubs/initfshdl.c
+++ b/src/stubs/initfshdl.c
@@ -11,5 +11,6 @@ weak int
init_fs_handlers(FontPathElementPtr fpe,
BlockHandlerProcPtr block_handler)
{
+ OVERRIDE_SYMBOL(init_fs_handlers, fpe, block_handler);
return Successful;
}
diff --git a/src/stubs/regfpefunc.c b/src/stubs/regfpefunc.c
index fdf22cd..ae12a01 100644
--- a/src/stubs/regfpefunc.c
+++ b/src/stubs/regfpefunc.c
@@ -24,5 +24,9 @@ RegisterFPEFunctions(NameCheckFunc name_func,
NextLaFunc next_list_alias_func,
SetPathFunc set_path_func)
{
+ OVERRIDE_SYMBOL(RegisterFPEFunctions, name_func, init_func, free_func,
+ reset_func, open_func, close_func, list_func, start_lfwi_func,
+ next_lfwi_func, wakeup_func, client_died, load_glyphs,
+ start_list_alias_func, next_list_alias_func, set_path_func);
return 0;
}
diff --git a/src/stubs/rmfshdl.c b/src/stubs/rmfshdl.c
index b495661..22a3091 100644
--- a/src/stubs/rmfshdl.c
+++ b/src/stubs/rmfshdl.c
@@ -12,4 +12,5 @@ remove_fs_handlers(FontPathElementPtr fpe,
BlockHandlerProcPtr blockHandler,
Bool all)
{
+ OVERRIDE_SYMBOL(remove_fs_handlers, fpe, blockHandler, all);
}
diff --git a/src/stubs/servclient.c b/src/stubs/servclient.c
index 9b6cebb..f85e08e 100644
--- a/src/stubs/servclient.c
+++ b/src/stubs/servclient.c
@@ -8,3 +8,12 @@
#endif
weak void *serverClient = 0;
+
+void *__GetServerClient(void);
+
+void *
+__GetServerClient(void)
+{
+ OVERRIDE_DATA(serverClient);
+ return serverClient;
+}
diff --git a/src/stubs/setfntauth.c b/src/stubs/setfntauth.c
index 0c7eccc..371807e 100644
--- a/src/stubs/setfntauth.c
+++ b/src/stubs/setfntauth.c
@@ -10,5 +10,6 @@
weak int
set_font_authorizations(char **authorizations, int *authlen, ClientPtr client)
{
+ OVERRIDE_SYMBOL(set_font_authorizations, authorizations, authlen, client);
return 0;
}
diff --git a/src/stubs/stfntcfnt.c b/src/stubs/stfntcfnt.c
index 5fc1745..d490988 100644
--- a/src/stubs/stfntcfnt.c
+++ b/src/stubs/stfntcfnt.c
@@ -10,5 +10,6 @@
weak int
StoreFontClientFont(FontPtr pfont, Font id)
{
+ OVERRIDE_SYMBOL(StoreFontClientFont, pfont, id);
return 0;
}
diff --git a/src/stubs/stubs.h b/src/stubs/stubs.h
index fa634e9..7d499d5 100644
--- a/src/stubs/stubs.h
+++ b/src/stubs/stubs.h
@@ -19,6 +19,54 @@
#endif
#endif
+#if defined(NO_WEAK_SYMBOLS) && defined(PIC)
+#include <stdarg.h>
+extern int _font_init_stubs(void);
+#define OVERRIDE_DATA(sym) \
+ _font_init_stubs(); \
+ if (__ptr_##sym && __ptr_##sym != &sym) \
+ sym = *__ptr_##sym
+#define OVERRIDE_SYMBOL(sym,...) \
+ _font_init_stubs(); \
+ if (__##sym && __##sym != sym) \
+ return (*__##sym)(__VA_ARGS__)
+#define OVERRIDE_VA_SYMBOL(sym,f) \
+ va_list _args; \
+ _font_init_stubs(); \
+ va_start(_args, f); \
+ if (__##sym) \
+ (*__##sym)(f, _args); \
+ va_end(_args)
+
+int (*__client_auth_generation)(ClientPtr);
+Bool (*__ClientSignal)(ClientPtr);
+void (*__DeleteFontClientID)(Font);
+void (*__VErrorF)(const char *, va_list);
+FontPtr (*__find_old_font)(FSID);
+FontResolutionPtr (*__GetClientResolutions)(int *);
+int (*__GetDefaultPointSize)(void);
+Font (*__GetNewFontClientID)(void);
+unsigned long (*__GetTimeInMillis)(void);
+int (*__init_fs_handlers)(FontPathElementPtr, BlockHandlerProcPtr);
+int (*__RegisterFPEFunctions)(NameCheckFunc, InitFpeFunc, FreeFpeFunc,
+ ResetFpeFunc, OpenFontFunc, CloseFontFunc, ListFontsFunc,
+ StartLfwiFunc, NextLfwiFunc, WakeupFpeFunc, ClientDiedFunc,
+ LoadGlyphsFunc, StartLaFunc, NextLaFunc, SetPathFunc);
+void (*__remove_fs_handlers)(FontPathElementPtr, BlockHandlerProcPtr, Bool);
+void **__ptr_serverClient;
+int (*__set_font_authorizations)(char **, int *, ClientPtr);
+int (*__StoreFontClientFont)(FontPtr, Font);
+Atom (*__MakeAtom)(const char *, unsigned, int);
+int (*__ValidAtom)(Atom);
+char *(*__NameForAtom)(Atom);
+unsigned long *__ptr_serverGeneration;
+void (*__register_fpe_functions)(void);
+#else /* NO_WEAK_SYMBOLS && PIC */
+#define OVERRIDE_DATA(sym)
+#define OVERRIDE_SYMBOL(sym,...)
+#define OVERRIDE_VA_SYMBOL(sym,f)
+#endif
+
/* This is really just a hack for now... __APPLE__ really should be using
* the weak symbols route above, but it's causing an as-yet unresolved issue,
* so we're instead building with flat_namespace.
@@ -36,6 +84,5 @@ extern int set_font_authorizations ( char **authorizations,
extern unsigned long GetTimeInMillis (void);
extern void ErrorF(const char *format, ...);
-extern void FatalError(const char *format, ...);
/* end of file */
diff --git a/src/stubs/stubsinit.c b/src/stubs/stubsinit.c
new file mode 100644
index 0000000..fc52332
--- /dev/null
+++ b/src/stubs/stubsinit.c
@@ -0,0 +1,82 @@
+#include "stubs.h"
+
+#if defined(NO_WEAK_SYMBOLS) && defined(PIC)
+
+#ifdef WIN32
+#include <X11/Xwindows.h>
+#define DLOPEN_SELF() GetModuleHandle(NULL)
+#define DLSYM(h,f) GetProcAddress(h,f)
+#else
+#include <dlfcn.h>
+#define DLOPEN_SELF() dlopen(NULL, RTLD_LOCAL)
+#define DLSYM(h,f) dlsym(h, f)
+#endif
+
+int (*__client_auth_generation)(ClientPtr) = NULL;
+Bool (*__ClientSignal)(ClientPtr) = NULL;
+void (*__DeleteFontClientID)(Font) = NULL;
+void (*__VErrorF)(const char *, va_list) = NULL;
+FontPtr (*__find_old_font)(FSID) = NULL;
+FontResolutionPtr (*__GetClientResolutions)(int *) = NULL;
+int (*__GetDefaultPointSize)(void) = NULL;
+Font (*__GetNewFontClientID)(void) = NULL;
+unsigned long (*__GetTimeInMillis)(void) = NULL;
+int (*__init_fs_handlers)(FontPathElementPtr, BlockHandlerProcPtr) = NULL;
+int (*__RegisterFPEFunctions)(NameCheckFunc, InitFpeFunc, FreeFpeFunc,
+ ResetFpeFunc, OpenFontFunc, CloseFontFunc, ListFontsFunc,
+ StartLfwiFunc, NextLfwiFunc, WakeupFpeFunc, ClientDiedFunc,
+ LoadGlyphsFunc, StartLaFunc, NextLaFunc, SetPathFunc) = NULL;
+void (*__remove_fs_handlers)(FontPathElementPtr, BlockHandlerProcPtr, Bool) = NULL;
+void **__ptr_serverClient = NULL;
+int (*__set_font_authorizations)(char **, int *, ClientPtr) = NULL;
+int (*__StoreFontClientFont)(FontPtr, Font) = NULL;
+Atom (*__MakeAtom)(const char *, unsigned, int) = NULL;
+int (*__ValidAtom)(Atom) = NULL;
+char *(*__NameForAtom)(Atom) = NULL;
+unsigned long *__ptr_serverGeneration = NULL;
+void (*__register_fpe_functions)(void) = NULL;
+
+#define INIT_SYMBOL(sym) \
+ if (!__##sym) \
+ __##sym = (typeof(__##sym)) DLSYM(handle, #sym)
+#define INIT_DATA(sym) \
+ if (!__ptr_##sym) \
+ __ptr_##sym = (typeof(__ptr_##sym)) DLSYM(handle, #sym)
+
+int
+_font_init_stubs (void)
+{
+ static int inited = FALSE;
+ static void *handle = NULL;
+
+ if (inited)
+ return inited;
+ if (!handle)
+ handle = DLOPEN_SELF();
+
+ INIT_SYMBOL(client_auth_generation);
+ INIT_SYMBOL(ClientSignal);
+ INIT_SYMBOL(DeleteFontClientID);
+ INIT_SYMBOL(VErrorF);
+ INIT_SYMBOL(find_old_font);
+ INIT_SYMBOL(GetClientResolutions);
+ INIT_SYMBOL(GetDefaultPointSize);
+ INIT_SYMBOL(GetNewFontClientID);
+ INIT_SYMBOL(GetTimeInMillis);
+ INIT_SYMBOL(init_fs_handlers);
+ INIT_SYMBOL(RegisterFPEFunctions);
+ INIT_SYMBOL(remove_fs_handlers);
+ INIT_SYMBOL(set_font_authorizations);
+ INIT_SYMBOL(StoreFontClientFont);
+ INIT_SYMBOL(MakeAtom);
+ INIT_SYMBOL(ValidAtom);
+ INIT_SYMBOL(NameForAtom);
+ INIT_SYMBOL(register_fpe_functions);
+ INIT_DATA(serverClient);
+ INIT_DATA(serverGeneration);
+
+ inited = TRUE;
+ return inited;
+}
+
+#endif /* NO_WEAK_SYMBOLS && PIC */
diff --git a/src/util/atom.c b/src/util/atom.c
index 37811f9..5f7f1c6 100644
--- a/src/util/atom.c
+++ b/src/util/atom.c
@@ -158,6 +158,8 @@ MakeAtom(const char *string, unsigned len, int makeit)
int h = 0;
int r;
+ OVERRIDE_SYMBOL(MakeAtom, string, len, makeit);
+
hash = Hash (string, len);
if (hashTable)
{
@@ -230,6 +232,7 @@ MakeAtom(const char *string, unsigned len, int makeit)
weak int
ValidAtom(Atom atom)
{
+ OVERRIDE_SYMBOL(ValidAtom, atom);
return (atom != None) && (atom <= lastAtom);
}
@@ -240,6 +243,7 @@ ValidAtom(Atom atom)
weak char *
NameForAtom(Atom atom)
{
+ OVERRIDE_SYMBOL(NameForAtom, atom);
if (atom != None && atom <= lastAtom)
return reverseMap[atom]->name;
return NULL;
diff --git a/src/util/miscutil.c b/src/util/miscutil.c
index 3d802d2..61c9d11 100644
--- a/src/util/miscutil.c
+++ b/src/util/miscutil.c
@@ -45,14 +45,22 @@ from The Open Group.
extern void BuiltinRegisterFpeFunctions(void);
-#ifndef NO_WEAK_SYMBOLS
/* make sure everything initializes themselves at least once */
weak unsigned long serverGeneration = 1;
-#endif
+
+unsigned long __GetServerGeneration (void);
+
+unsigned long
+__GetServerGeneration (void)
+{
+ OVERRIDE_DATA(serverGeneration);
+ return serverGeneration;
+}
weak void
register_fpe_functions (void)
{
+ OVERRIDE_SYMBOL(register_fpe_functions);
BuiltinRegisterFpeFunctions();
FontFileRegisterFpeFunctions();
#ifdef XFONT_FC