Weak symbols that aren't

Joseph Parmelee jparmele at wildbear.com
Sun Aug 13 13:14:15 PDT 2006

On Fri, 11 Aug 2006, Joseph Parmelee wrote:

> I can submit my patch to fix up the build of libXfont, but it will
> be minimal just to get my system running.  The libXfont in 6.9.0
> has version 1.5.  Unless I hear otherwise, I will submit the patch
> against libXfont-1.2.0 to change its shared library version to
> 1.5.1, and to remove all the debugging stub files from the link.

Attached is the patch.  It changes two Makefile.am's and also
includes the changes to the associated Makefile.in's, so you don't
have to run automake, though doing so with a compatible version
does no harm.  If your automake is old, I advise you not to run it;
simply use the Makefile.in's produced by the patch.

The symbols defined weak previously will now be undefined in the
resulting libXfont.so.1.5.1.  All are being resolved at runtime
from definitions in the Xserver or other X utilities which link
using -lXfont.  This is admittedly not a good thing.

My previous post shows that I didn't fully understand the intent of
the weak symbols.  I thought they were solely for testing purposes. 
I now see that the problem is worse than that.

This patch does not claim in any way to be a fix of this issue.  It
is merely a tactical retreat in order to stabilize my system.  The
package developers are quite right to attempt to isolate these
symbols as they pose a remaining problem with the modular
structure.  The question is how to best do it.  Weak symbols don't
work for the reasons given earlier.

But this really is not an immediate problem for X utilities, even
if those utilities don't define these dangling symbols, so long as
they will always be run under the xserver; the necessary symbols
are then already provided for libXfont.  Removing the -no-undefined
linker option from the libXfont build, and if necessary, from X
utility builds that use libXfont, allows this.

However, if a given separately-linked utility which uses libXfont
it intended to also be run outside of X, then it must locally
provide and export these symbols in a form semantically compatible
with the versions in the xserver.  Since the utilities seem to
properly resolve the undefined symbols in libXfont, it is clear
that this has been the previous policy.

Note that when such a utility is run on a system with lazy dynamic
loading which is also running X, even if the utility is not itself
run under X, it will find a version of libXfont already mapped into
memory.  This utility's local versions will be used only if it
needs a symbol which has not been previously loaded by the
in-memory copy, either called explicitly by somebody else, or
loaded incidentally in a block containing some other symbol.

This is at least a testing issue.  You have to kill the xserver on
your system before you can reliably test the local implementations
for such utilities.

A more interesting question is: what happens if you run such a
utility alongside X, and while the utility is still mapped, X
itself needs one of these symbols which has already been loaded
from the local copy.  I think it uses that local copy, with
possibly disastrous consequences.  You just can't have incompatible
multiple definitions of these symbols on a system with lazy loading
because you can't control which one will be used.  Multiple
definitions of a symbol have to be insured semantically equivalent
in order for the system to function in a deterministic manner.

This situation clearly applies at the moment to xfs, which is
usually started before X and continues (we hope) to run throughout
the X session.  If libXfont loads one of the symbols from xfs, it
continues to use the xfs code throughout the entire X session.  In
quickly inspecting the xfs code (and I mean real quick) it looks
like the implementation of at least the error reporting is
adequate, so maybe there is no problem here at the moment.

However, this situation in a utility is unsatisfactory; the complex
interdependencies which it introduces between modules makes the
whole structure fragile, hard to maintain, and a potential source
of hard-to-find bugs.

The right approach to untangle this is probably to simply pull all
the service functions and data that are needed by libXfont and
standalone applications out of the xserver in their present form
into a separate library (not necessarily creating another module;
probably should be part of xorg-server) which can be explicitly
linked by the xserver, libXfont, and anybody else that needs it. 
Maybe libXsvrutils?  Pending further cleanup, this may be a rather
eclectic catch-all mess.  But that is much less ugly than the
present situation in which the runtime semantics are not clearly
defined.  It also relieves utility developers from having to write
and/or maintain xserver compatible versions of these services; they
will be able to link to the xserver version directly.

If you really want libXfont to provide these symbols internally,
you must at least provide complete error reporting, and you must
specifically prevent the linker from exporting them, which
otherwise conflict at runtime with those currently provided by the
xserver and X utilities.  For gnu ld, you do this with the
--exclude-symbols option.

Be advised, however, that at least one of these symbols is a data
item from the xserver (serverGeneration).  I don't know whether
this is a show-stopper for this approach, but it will be if this
data item cannot be locally defined in libXfont in such a way that
conflict with a running xserver is impossible.

To get a list of symbols required by libXfont from the xserver or
other host application, run this from the top-level libXfont build

   ldd -r src/.libs/libXfont.so.1.5.1 2>&1 | \
     awk '/^undefined/ {print $3}'

These are the first guess on candidates for inclusion in
libXsrvutils.  There may be additional inclusions from the
utilities for symbols not related to libXfont.

If I had nothing else to do right now, I would take a cut at
implementing a test version of this.  But I simply do not have any
more time and must now get back to my own problems.  Enough of this
X-style diversion.

Hope this is some help to somebody.  Bye for now.


-------------- next part --------------
--- src/Makefile.am.orig	2006-07-06 13:56:16.000000000 -0600
+++ src/Makefile.am	2006-08-11 20:26:37.000000000 -0600
@@ -76,10 +76,10 @@
 libXfont_la_LIBADD = \
 libXfont_la_SOURCES = dummy.c
-libXfont_la_LDFLAGS = -version-number 1:4:1 -no-undefined
+libXfont_la_LDFLAGS = -version-number 1:5:1
--- src/util/Makefile.am.orig	2006-07-06 13:56:16.000000000 -0600
+++ src/util/Makefile.am	2006-08-11 20:31:15.000000000 -0600
@@ -1,17 +1,14 @@
-	-I${top_srcdir}/include \
-	-I$(top_srcdir)/src/stubs
+	-I${top_srcdir}/include
 noinst_LTLIBRARIES = libutil.la
 libutil_la_SOURCES = 		\
-	atom.c			\
 	fontaccel.c		\
 	fontnames.c		\
 	fontutil.c		\
 	fontxlfd.c		\
 	format.c		\
-	miscutil.c		\
 	patcache.c		\
 	private.c		\
--- ./src/Makefile.in.orig	2006-07-07 18:11:54.000000000 -0600
+++ ./src/Makefile.in	2006-08-12 21:27:36.000000000 -0600
@@ -84,18 +84,16 @@
 @XFONT_BUILTINS_TRUE at am__DEPENDENCIES_4 = builtins/libbuiltins.la
 @XFONT_FC_TRUE at am__DEPENDENCIES_5 = fc/libfc.la
 am__DEPENDENCIES_6 = util/libutil.la
-am__DEPENDENCIES_7 = stubs/libstubs.la
- at XFONT_FONTCACHE_TRUE@am__DEPENDENCIES_8 = fontcache/libfontcache.la
- at XFONT_TYPE1_TRUE@am__DEPENDENCIES_9 = Type1/libtype1.la
- at XFONT_SPEEDO_TRUE@am__DEPENDENCIES_10 = Speedo/libspeedo.la
+ at XFONT_FONTCACHE_TRUE@am__DEPENDENCIES_7 = fontcache/libfontcache.la
+ at XFONT_TYPE1_TRUE@am__DEPENDENCIES_8 = Type1/libtype1.la
+ at XFONT_SPEEDO_TRUE@am__DEPENDENCIES_9 = Speedo/libspeedo.la
 	$(am__DEPENDENCIES_9) $(am__DEPENDENCIES_10) \
-	$(am__DEPENDENCIES_11) $(am__DEPENDENCIES_11) \
-	$(am__DEPENDENCIES_11)
 am_libXfont_la_OBJECTS = dummy.lo
 libXfont_la_OBJECTS = $(am_libXfont_la_OBJECTS)
 DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) -I$(top_builddir)/include/X11/fonts
@@ -284,12 +282,12 @@
 libXfont_la_LIBADD = \
 libXfont_la_SOURCES = dummy.c
-libXfont_la_LDFLAGS = -version-number 1:4:1 -no-undefined
+libXfont_la_LDFLAGS = -version-number 1:5:1
 all: all-recursive
--- ./src/util/Makefile.in.orig	2006-07-07 18:11:56.000000000 -0600
+++ ./src/util/Makefile.in	2006-08-12 21:27:45.000000000 -0600
@@ -48,9 +48,8 @@
 libutil_la_LIBADD =
-am_libutil_la_OBJECTS = atom.lo fontaccel.lo fontnames.lo fontutil.lo \
-	fontxlfd.lo format.lo miscutil.lo patcache.lo private.lo \
-	utilbitmap.lo
+am_libutil_la_OBJECTS = fontaccel.lo fontnames.lo fontutil.lo \
+	fontxlfd.lo format.lo patcache.lo private.lo utilbitmap.lo
 libutil_la_OBJECTS = $(am_libutil_la_OBJECTS)
 DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) -I$(top_builddir)/include/X11/fonts
 depcomp = $(SHELL) $(top_srcdir)/depcomp
@@ -203,18 +202,15 @@
 sysconfdir = @sysconfdir@
 target_alias = @target_alias@
-	-I${top_srcdir}/include \
-	-I$(top_srcdir)/src/stubs
+	-I${top_srcdir}/include
 noinst_LTLIBRARIES = libutil.la
 libutil_la_SOURCES = \
-	atom.c			\
 	fontaccel.c		\
 	fontnames.c		\
 	fontutil.c		\
 	fontxlfd.c		\
 	format.c		\
-	miscutil.c		\
 	patcache.c		\
 	private.c		\
@@ -270,13 +266,11 @@
 	-rm -f *.tab.c
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/atom.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/fontaccel.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/fontnames.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/fontutil.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/fontxlfd.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/format.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/miscutil.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/patcache.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/private.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/utilbitmap.Plo at am__quote@

More information about the xorg mailing list