On Thu, Dec 19, 2019 at 02:54:16PM +0100, Pino Toscano wrote:
Move the interal static libraries as the last items in the list of
libraries of guestfsd, to make sure their symbols are used for all the
other libraries. This is because GCC resolves the symbols looking at
the arguments from the beginning to the end of the command line.
This currently does not cause failures, however it "just works" because
of the tricky situation set up.
The situation is the following:
1) common/utils contains few utility sources: one of them is utils.c,
which contains various functions -- for example
guestfs_int_free_string_list and guestfs_int_drive_name --, it is built
as utils.o, and bundled in the static library libutils.a
2) common/mlutils builds a OCaml library with bindings for some utility
functions in libutils.a, in particular guestfs_int_drive_name (but not
guestfs_int_free_string_list); there are two versions of this library,
one OCaml library (dllmlcutils.so) that links with libutils.a, and one
static library (libmlcutils.a), which cannot specify the libraries it
links to (as it is static)
3) when the daemon is linked, the command line was the following
(simplified):
$ gcc [...] -o guestfsd guestfsd-9p.o other_daemon_object.o [...] \
../common/utils/.libs/libutils.a [...] -lmlcutils [...]
Some of the objects of the daemon itself use
guestfs_int_free_string_list, and thus the compiler opens libutils.a
(it is after the objects in the command line) and picks utils.o, which
contains also guestfs_int_drive_name (not used directly in the daemon);
when linking later on with libmlcutils.a, the symbols for this static
library (like guestfs_int_drive_name) are already resolved, and thus
all the symbols are resolved, and the linking succeeds
This fragile situation can be easily broken by moving e.g.
guestfs_int_drive_name out of common/utils/utils.c to a new source (say
utils2.c) still built as part of libutils.a: since nothing before
-lmlcutils actually needs to pick utils2.o from libutils.a for symbols,
then GCC will not be able to resolve all the symbols in libmlcutils.a.
As solution, move libutils.a (and other internal static libraries) as
last libraries to link guestfsd to: this way, GCC knows where to find
all the symbols needed by all the objects and libraries specified in
the command line.
---
daemon/Makefile.am | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/daemon/Makefile.am b/daemon/Makefile.am
index ab3019cc1..25948dbe9 100644
--- a/daemon/Makefile.am
+++ b/daemon/Makefile.am
@@ -217,9 +217,6 @@ guestfsd_LDFLAGS = \
-L../bundled/ocaml-augeas \
-L../common/mlpcre
guestfsd_LDADD = \
- ../common/errnostring/liberrnostring.la \
- ../common/protocol/libprotocol.la \
- ../common/utils/libutils.la \
camldaemon.o \
$(ACL_LIBS) \
$(CAP_LIBS) \
@@ -236,7 +233,10 @@ guestfsd_LDADD = \
$(TSK_LIBS) \
$(RPC_LIBS) \
$(YARA_LIBS) \
- $(OCAML_LIBS)
+ $(OCAML_LIBS) \
+ ../common/errnostring/liberrnostring.la \
+ ../common/protocol/libprotocol.la \
+ ../common/utils/libutils.la
Good find, ACK.
Rich.
--
Richard Jones, Virtualization Group, Red Hat
http://people.redhat.com/~rjones
Read my programming and virtualization blog:
http://rwmj.wordpress.com
libguestfs lets you edit virtual machines. Supports shell scripting,
bindings from many languages.
http://libguestfs.org