When an executable is being generated, unused functions from libqemuutil.a are not linked. This is the linker's convention on archives (libqemuutil.a).
Now that we have dynamically loaded modules, which may reference function from libqemuutil.a but not linked in the executable, because the executable itself didn't reference this symbol. That is a problem for module build. We can't link both executable and the dynamic shared object to libqemuutil.a, because of the risk of inconsistent views of program variables: DSO module sees a copy of some data because it is linked against libqemuutil.a, whereas the executable sees another copy. In other words, they each maintains a copy but with a same name. In this case, it can be very tricky to notice such a duplication, and make a bug hard to reason. So it's good to avoid it from the beginning. This patch solves the above issue by fully linking. Specifically, it fixes block-iscsi.mo: in block/iscsi.c, util/bitmap.c functions are used, but qemu-img doesn't link it. The solution is to link everything in libqemuutil.a. We do this by changing it to qemuutil.o, which includes all the util objects. This is easier and also expected to be more portable than "--whole-archive". Because qemuutil.o is now fully linked and hence make executables references more symbols than before, some test executables now need libqemustub.a, so add them as necessary too. Signed-off-by: Fam Zheng <f...@redhat.com> --- Makefile | 17 +++++++++------- Makefile.objs | 2 +- Makefile.target | 2 +- tests/Makefile | 60 ++++++++++++++++++++++++++++----------------------------- 4 files changed, 42 insertions(+), 39 deletions(-) diff --git a/Makefile b/Makefile index b33aaac..773e5eb 100644 --- a/Makefile +++ b/Makefile @@ -187,7 +187,7 @@ subdir-dtc:dtc/libfdt dtc/tests dtc/%: mkdir -p $@ -$(SUBDIR_RULES): libqemuutil.a libqemustub.a $(common-obj-y) +$(SUBDIR_RULES): qemuutil.o libqemustub.a $(common-obj-y) ROMSUBDIR_RULES=$(patsubst %,romsubdir-%, $(ROMS)) romsubdir-%: @@ -208,7 +208,10 @@ Makefile: $(version-obj-y) $(version-lobj-y) # Build libraries libqemustub.a: $(stub-obj-y) -libqemuutil.a: $(util-obj-y) + +LD_REL := $(CC) -nostdlib -Wl,-r +qemuutil.o: $(util-obj-y) + $(call quiet-command,$(LD_REL) -o $@ $^," LD -r $(TARGET_DIR)$@") block-modules = $(foreach o,$(block-obj-m),"$(basename $(subst /,-,$o))",) NULL util/module.o-cflags = -D'CONFIG_BLOCK_MODULES=$(block-modules)' @@ -217,13 +220,13 @@ util/module.o-cflags = -D'CONFIG_BLOCK_MODULES=$(block-modules)' qemu-img.o: qemu-img-cmds.h -qemu-img$(EXESUF): qemu-img.o $(block-obj-y) libqemuutil.a libqemustub.a -qemu-nbd$(EXESUF): qemu-nbd.o $(block-obj-y) libqemuutil.a libqemustub.a -qemu-io$(EXESUF): qemu-io.o $(block-obj-y) libqemuutil.a libqemustub.a +qemu-img$(EXESUF): qemu-img.o $(block-obj-y) qemuutil.o libqemustub.a +qemu-nbd$(EXESUF): qemu-nbd.o $(block-obj-y) qemuutil.o libqemustub.a +qemu-io$(EXESUF): qemu-io.o $(block-obj-y) qemuutil.o libqemustub.a qemu-bridge-helper$(EXESUF): qemu-bridge-helper.o -fsdev/virtfs-proxy-helper$(EXESUF): fsdev/virtfs-proxy-helper.o fsdev/virtio-9p-marshal.o libqemuutil.a libqemustub.a +fsdev/virtfs-proxy-helper$(EXESUF): fsdev/virtfs-proxy-helper.o fsdev/virtio-9p-marshal.o qemuutil.o libqemustub.a fsdev/virtfs-proxy-helper$(EXESUF): LIBS += -lcap qemu-img-cmds.h: $(SRC_PATH)/qemu-img-cmds.hx @@ -280,7 +283,7 @@ $(qapi-modules) $(SRC_PATH)/scripts/qapi-commands.py $(qapi-py) QGALIB_GEN=$(addprefix qga/qapi-generated/, qga-qapi-types.h qga-qapi-visit.h qga-qmp-commands.h) $(qga-obj-y) qemu-ga.o: $(QGALIB_GEN) -qemu-ga$(EXESUF): $(qga-obj-y) libqemuutil.a libqemustub.a +qemu-ga$(EXESUF): $(qga-obj-y) qemuutil.o libqemustub.a $(call LINK, $^) clean: diff --git a/Makefile.objs b/Makefile.objs index 6445ce9..bbb2ea4 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -109,6 +109,6 @@ target-obj-y += trace/ # guest agent # FIXME: a few definitions from qapi-types.o/qapi-visit.o are needed -# by libqemuutil.a. These should be moved to a separate .json schema. +# by qemuutil.o. These should be moved to a separate .json schema. qga-obj-y = qga/ qga-vss-dll-obj-y = qga/ diff --git a/Makefile.target b/Makefile.target index 1e8d7ab..48a3089 100644 --- a/Makefile.target +++ b/Makefile.target @@ -176,7 +176,7 @@ all-obj-y += $(target-obj-y) all-obj-$(CONFIG_SOFTMMU) += $(block-obj-y) # build either PROG or PROGW -$(QEMU_PROG_BUILD): $(all-obj-y) ../libqemuutil.a ../libqemustub.a +$(QEMU_PROG_BUILD): $(all-obj-y) ../qemuutil.o ../libqemustub.a $(call LINK,$^) gdbstub-xml.c: $(TARGET_XML_FILES) $(SRC_PATH)/scripts/feature_to_c.sh diff --git a/tests/Makefile b/tests/Makefile index 837e9c8..b79a299 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -226,22 +226,22 @@ qom-core-obj = qom/object.o qom/qom-qobject.o qom/container.o tests/test-x86-cpuid.o: QEMU_INCLUDES += -I$(SRC_PATH)/target-i386 -tests/check-qint$(EXESUF): tests/check-qint.o libqemuutil.a -tests/check-qstring$(EXESUF): tests/check-qstring.o libqemuutil.a -tests/check-qdict$(EXESUF): tests/check-qdict.o libqemuutil.a -tests/check-qlist$(EXESUF): tests/check-qlist.o libqemuutil.a -tests/check-qfloat$(EXESUF): tests/check-qfloat.o libqemuutil.a -tests/check-qjson$(EXESUF): tests/check-qjson.o libqemuutil.a libqemustub.a -tests/check-qom-interface$(EXESUF): tests/check-qom-interface.o $(qom-core-obj) libqemuutil.a libqemustub.a -tests/test-coroutine$(EXESUF): tests/test-coroutine.o $(block-obj-y) libqemuutil.a libqemustub.a -tests/test-aio$(EXESUF): tests/test-aio.o $(block-obj-y) libqemuutil.a libqemustub.a -tests/test-rfifolock$(EXESUF): tests/test-rfifolock.o libqemuutil.a libqemustub.a -tests/test-throttle$(EXESUF): tests/test-throttle.o $(block-obj-y) libqemuutil.a libqemustub.a -tests/test-thread-pool$(EXESUF): tests/test-thread-pool.o $(block-obj-y) libqemuutil.a libqemustub.a -tests/test-iov$(EXESUF): tests/test-iov.o libqemuutil.a -tests/test-hbitmap$(EXESUF): tests/test-hbitmap.o libqemuutil.a libqemustub.a +tests/check-qint$(EXESUF): tests/check-qint.o qemuutil.o libqemustub.a +tests/check-qstring$(EXESUF): tests/check-qstring.o qemuutil.o libqemustub.a +tests/check-qdict$(EXESUF): tests/check-qdict.o qemuutil.o libqemustub.a +tests/check-qlist$(EXESUF): tests/check-qlist.o qemuutil.o libqemustub.a +tests/check-qfloat$(EXESUF): tests/check-qfloat.o qemuutil.o libqemustub.a +tests/check-qjson$(EXESUF): tests/check-qjson.o qemuutil.o libqemustub.a +tests/check-qom-interface$(EXESUF): tests/check-qom-interface.o $(qom-core-obj) qemuutil.o libqemustub.a +tests/test-coroutine$(EXESUF): tests/test-coroutine.o $(block-obj-y) qemuutil.o libqemustub.a +tests/test-aio$(EXESUF): tests/test-aio.o $(block-obj-y) qemuutil.o libqemustub.a +tests/test-rfifolock$(EXESUF): tests/test-rfifolock.o qemuutil.o libqemustub.a +tests/test-throttle$(EXESUF): tests/test-throttle.o $(block-obj-y) qemuutil.o libqemustub.a +tests/test-thread-pool$(EXESUF): tests/test-thread-pool.o $(block-obj-y) qemuutil.o libqemustub.a +tests/test-iov$(EXESUF): tests/test-iov.o qemuutil.o libqemustub.a +tests/test-hbitmap$(EXESUF): tests/test-hbitmap.o qemuutil.o libqemustub.a tests/test-x86-cpuid$(EXESUF): tests/test-x86-cpuid.o -tests/test-xbzrle$(EXESUF): tests/test-xbzrle.o xbzrle.o page_cache.o libqemuutil.a +tests/test-xbzrle$(EXESUF): tests/test-xbzrle.o xbzrle.o page_cache.o qemuutil.o libqemustub.a tests/test-cutils$(EXESUF): tests/test-cutils.o util/cutils.o tests/test-int128$(EXESUF): tests/test-int128.o tests/test-qdev-global-props$(EXESUF): tests/test-qdev-global-props.o \ @@ -250,10 +250,10 @@ tests/test-qdev-global-props$(EXESUF): tests/test-qdev-global-props.o \ hw/core/fw-path-provider.o \ $(qom-core-obj) \ $(test-qapi-obj-y) \ - libqemuutil.a libqemustub.a + qemuutil.o libqemustub.a tests/test-vmstate$(EXESUF): tests/test-vmstate.o \ vmstate.o qemu-file.o \ - libqemuutil.a + qemuutil.o libqemustub.a tests/test-qapi-types.c tests/test-qapi-types.h :\ $(SRC_PATH)/tests/qapi-schema/qapi-schema-test.json $(SRC_PATH)/scripts/qapi-types.py @@ -276,18 +276,18 @@ $(SRC_PATH)/tests/qapi-schema/qapi-schema-test.json $(SRC_PATH)/scripts/qapi-eve $(gen-out-type) -o tests -p "test-" -i $<, \ " GEN $@") -tests/test-string-output-visitor$(EXESUF): tests/test-string-output-visitor.o $(test-qapi-obj-y) libqemuutil.a libqemustub.a -tests/test-string-input-visitor$(EXESUF): tests/test-string-input-visitor.o $(test-qapi-obj-y) libqemuutil.a libqemustub.a -tests/test-qmp-event$(EXESUF): tests/test-qmp-event.o $(test-qapi-obj-y) libqemuutil.a libqemustub.a -tests/test-qmp-output-visitor$(EXESUF): tests/test-qmp-output-visitor.o $(test-qapi-obj-y) libqemuutil.a libqemustub.a -tests/test-qmp-input-visitor$(EXESUF): tests/test-qmp-input-visitor.o $(test-qapi-obj-y) libqemuutil.a libqemustub.a -tests/test-qmp-input-strict$(EXESUF): tests/test-qmp-input-strict.o $(test-qapi-obj-y) libqemuutil.a libqemustub.a -tests/test-qmp-commands$(EXESUF): tests/test-qmp-commands.o tests/test-qmp-marshal.o $(test-qapi-obj-y) libqemuutil.a libqemustub.a -tests/test-visitor-serialization$(EXESUF): tests/test-visitor-serialization.o $(test-qapi-obj-y) libqemuutil.a libqemustub.a -tests/test-opts-visitor$(EXESUF): tests/test-opts-visitor.o $(test-qapi-obj-y) libqemuutil.a libqemustub.a +tests/test-string-output-visitor$(EXESUF): tests/test-string-output-visitor.o $(test-qapi-obj-y) qemuutil.o libqemustub.a +tests/test-string-input-visitor$(EXESUF): tests/test-string-input-visitor.o $(test-qapi-obj-y) qemuutil.o libqemustub.a +tests/test-qmp-event$(EXESUF): tests/test-qmp-event.o $(test-qapi-obj-y) qemuutil.o libqemustub.a +tests/test-qmp-output-visitor$(EXESUF): tests/test-qmp-output-visitor.o $(test-qapi-obj-y) qemuutil.o libqemustub.a +tests/test-qmp-input-visitor$(EXESUF): tests/test-qmp-input-visitor.o $(test-qapi-obj-y) qemuutil.o libqemustub.a +tests/test-qmp-input-strict$(EXESUF): tests/test-qmp-input-strict.o $(test-qapi-obj-y) qemuutil.o libqemustub.a +tests/test-qmp-commands$(EXESUF): tests/test-qmp-commands.o tests/test-qmp-marshal.o $(test-qapi-obj-y) qemuutil.o libqemustub.a +tests/test-visitor-serialization$(EXESUF): tests/test-visitor-serialization.o $(test-qapi-obj-y) qemuutil.o libqemustub.a +tests/test-opts-visitor$(EXESUF): tests/test-opts-visitor.o $(test-qapi-obj-y) qemuutil.o libqemustub.a -tests/test-mul64$(EXESUF): tests/test-mul64.o libqemuutil.a -tests/test-bitops$(EXESUF): tests/test-bitops.o libqemuutil.a +tests/test-mul64$(EXESUF): tests/test-mul64.o qemuutil.o libqemustub.a +tests/test-bitops$(EXESUF): tests/test-bitops.o qemuutil.o libqemustub.a libqos-obj-y = tests/libqos/pci.o tests/libqos/fw_cfg.o libqos-obj-y += tests/libqos/i2c.o @@ -338,7 +338,7 @@ tests/ioh3420-test$(EXESUF): tests/ioh3420-test.o tests/usb-hcd-ehci-test$(EXESUF): tests/usb-hcd-ehci-test.o $(libqos-pc-obj-y) tests/vhost-user-test$(EXESUF): tests/vhost-user-test.o qemu-char.o qemu-timer.o $(qtest-obj-y) tests/qemu-iotests/socket_scm_helper$(EXESUF): tests/qemu-iotests/socket_scm_helper.o -tests/test-qemu-opts$(EXESUF): tests/test-qemu-opts.o libqemuutil.a libqemustub.a +tests/test-qemu-opts$(EXESUF): tests/test-qemu-opts.o qemuutil.o libqemustub.a ifeq ($(CONFIG_POSIX),y) LIBS += -lutil @@ -352,7 +352,7 @@ QTEST_TARGETS=$(foreach TARGET,$(TARGETS), $(if $(check-qtest-$(TARGET)-y), $(TA check-qtest-y=$(foreach TARGET,$(TARGETS), $(check-qtest-$(TARGET)-y)) endif -qtest-obj-y = tests/libqtest.o libqemuutil.a libqemustub.a +qtest-obj-y = tests/libqtest.o qemuutil.o libqemustub.a $(check-qtest-y): $(qtest-obj-y) .PHONY: check-help -- 2.0.3