Merge remote-tracking branch 'remotes/bonzini/configure' into staging
* remotes/bonzini/configure: build: softmmu targets do not have a "main.o" file configure: Disable libtool if -fPIE does not work with it (bug #1257099) block: convert block drivers linked with libs to modules Makefile: introduce common-obj-m and block-obj-m for DSO Makefile: install modules with "make install" module: implement module loading rules.mak: introduce DSO rules darwin: do not use -mdynamic-no-pic block: use per-object cflags and libs rules.mak: allow per object cflags and libs rules.mak: fix $(obj) to a real relative path util: Split out exec_dir from os_find_datadir Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
6dedf0522c
3
.gitignore
vendored
3
.gitignore
vendored
@ -66,6 +66,9 @@ libuser
|
||||
*.cp
|
||||
*.dvi
|
||||
*.exe
|
||||
*.dll
|
||||
*.so
|
||||
*.mo
|
||||
*.fn
|
||||
*.ky
|
||||
*.log
|
||||
|
29
Makefile
29
Makefile
@ -127,13 +127,29 @@ defconfig:
|
||||
|
||||
ifneq ($(wildcard config-host.mak),)
|
||||
include $(SRC_PATH)/Makefile.objs
|
||||
endif
|
||||
|
||||
dummy := $(call unnest-vars,, \
|
||||
stub-obj-y \
|
||||
util-obj-y \
|
||||
qga-obj-y \
|
||||
block-obj-y \
|
||||
block-obj-m \
|
||||
common-obj-y \
|
||||
common-obj-m)
|
||||
|
||||
ifneq ($(wildcard config-host.mak),)
|
||||
include $(SRC_PATH)/tests/Makefile
|
||||
endif
|
||||
ifeq ($(CONFIG_SMARTCARD_NSS),y)
|
||||
include $(SRC_PATH)/libcacard/Makefile
|
||||
endif
|
||||
|
||||
all: $(DOCS) $(TOOLS) $(HELPERS-y) recurse-all
|
||||
all: $(DOCS) $(TOOLS) $(HELPERS-y) recurse-all modules
|
||||
|
||||
vl.o: QEMU_CFLAGS+=$(GPROF_CFLAGS)
|
||||
|
||||
vl.o: QEMU_CFLAGS+=$(SDL_CFLAGS)
|
||||
|
||||
config-host.h: config-host.h-timestamp
|
||||
config-host.h-timestamp: config-host.mak
|
||||
@ -192,6 +208,9 @@ Makefile: $(version-obj-y) $(version-lobj-y)
|
||||
libqemustub.a: $(stub-obj-y)
|
||||
libqemuutil.a: $(util-obj-y) qapi-types.o qapi-visit.o
|
||||
|
||||
block-modules = $(foreach o,$(block-obj-m),"$(basename $(subst /,-,$o))",) NULL
|
||||
util/module.o-cflags = -D'CONFIG_BLOCK_MODULES=$(block-modules)'
|
||||
|
||||
######################################################################
|
||||
|
||||
qemu-img.o: qemu-img-cmds.h
|
||||
@ -247,6 +266,8 @@ clean:
|
||||
rm -f qemu-options.def
|
||||
find . -name '*.[oda]' -type f -exec rm -f {} +
|
||||
find . -name '*.l[oa]' -type f -exec rm -f {} +
|
||||
find . -name '*$(DSOSUF)' -type f -exec rm -f {} +
|
||||
find . -name '*.mo' -type f -exec rm -f {} +
|
||||
rm -f $(filter-out %.tlb,$(TOOLS)) $(HELPERS-y) qemu-ga TAGS cscope.* *.pod *~ */*~
|
||||
rm -f fsdev/*.pod
|
||||
rm -rf .libs */.libs
|
||||
@ -354,6 +375,12 @@ install-datadir install-localstatedir
|
||||
ifneq ($(TOOLS),)
|
||||
$(INSTALL_PROG) $(STRIP_OPT) $(TOOLS) "$(DESTDIR)$(bindir)"
|
||||
endif
|
||||
ifneq ($(CONFIG_MODULES),)
|
||||
$(INSTALL_DIR) "$(DESTDIR)$(qemu_moddir)"
|
||||
for s in $(patsubst %.mo,%$(DSOSUF),$(modules-m)); do \
|
||||
$(INSTALL_PROG) $(STRIP_OPT) $$s "$(DESTDIR)$(qemu_moddir)/$${s//\//-}"; \
|
||||
done
|
||||
endif
|
||||
ifneq ($(HELPERS-y),)
|
||||
$(INSTALL_DIR) "$(DESTDIR)$(libexecdir)"
|
||||
$(INSTALL_PROG) $(STRIP_OPT) $(HELPERS-y) "$(DESTDIR)$(libexecdir)"
|
||||
|
@ -19,6 +19,8 @@ block-obj-y += qemu-coroutine.o qemu-coroutine-lock.o qemu-coroutine-io.o
|
||||
block-obj-y += qemu-coroutine-sleep.o
|
||||
block-obj-y += coroutine-$(CONFIG_COROUTINE_BACKEND).o
|
||||
|
||||
block-obj-m = block/
|
||||
|
||||
ifeq ($(CONFIG_VIRTIO)$(CONFIG_VIRTFS)$(CONFIG_PCI),yyy)
|
||||
# Lots of the fsdev/9pcode is pulled in by vl.c via qemu_fsdev_add.
|
||||
# only pull in the actual virtio-9p device if we also enabled virtio.
|
||||
@ -41,7 +43,7 @@ libcacard-y += libcacard/vcardt.o
|
||||
# single QEMU executable should support all CPUs and machines.
|
||||
|
||||
ifeq ($(CONFIG_SOFTMMU),y)
|
||||
common-obj-y = $(block-obj-y) blockdev.o blockdev-nbd.o block/
|
||||
common-obj-y = blockdev.o blockdev-nbd.o block/
|
||||
common-obj-y += net/
|
||||
common-obj-y += qdev-monitor.o device-hotplug.o
|
||||
common-obj-$(CONFIG_WIN32) += os-win32.o
|
||||
@ -111,18 +113,3 @@ version-lobj-$(CONFIG_WIN32) += $(BUILD_DIR)/version.lo
|
||||
# by libqemuutil.a. These should be moved to a separate .json schema.
|
||||
qga-obj-y = qga/ qapi-types.o qapi-visit.o
|
||||
qga-vss-dll-obj-y = qga/
|
||||
|
||||
vl.o: QEMU_CFLAGS+=$(GPROF_CFLAGS)
|
||||
|
||||
vl.o: QEMU_CFLAGS+=$(SDL_CFLAGS)
|
||||
|
||||
QEMU_CFLAGS+=$(GLIB_CFLAGS)
|
||||
|
||||
nested-vars += \
|
||||
stub-obj-y \
|
||||
util-obj-y \
|
||||
qga-obj-y \
|
||||
qga-vss-dll-obj-y \
|
||||
block-obj-y \
|
||||
common-obj-y
|
||||
dummy := $(call unnest-vars)
|
||||
|
@ -130,8 +130,6 @@ else
|
||||
obj-y += hw/$(TARGET_BASE_ARCH)/
|
||||
endif
|
||||
|
||||
main.o: QEMU_CFLAGS+=$(GPROF_CFLAGS)
|
||||
|
||||
GENERATED_HEADERS += hmp-commands.h qmp-commands-old.h
|
||||
|
||||
endif # CONFIG_SOFTMMU
|
||||
@ -139,13 +137,26 @@ endif # CONFIG_SOFTMMU
|
||||
# Workaround for http://gcc.gnu.org/PR55489, see configure.
|
||||
%/translate.o: QEMU_CFLAGS += $(TRANSLATE_OPT_CFLAGS)
|
||||
|
||||
nested-vars += obj-y
|
||||
dummy := $(call unnest-vars,,obj-y)
|
||||
|
||||
# This resolves all nested paths, so it must come last
|
||||
# we are making another call to unnest-vars with different vars, protect obj-y,
|
||||
# it can be overriden in subdir Makefile.objs
|
||||
obj-y-save := $(obj-y)
|
||||
|
||||
block-obj-y :=
|
||||
common-obj-y :=
|
||||
include $(SRC_PATH)/Makefile.objs
|
||||
dummy := $(call unnest-vars,.., \
|
||||
block-obj-y \
|
||||
block-obj-m \
|
||||
common-obj-y \
|
||||
common-obj-m)
|
||||
|
||||
all-obj-y = $(obj-y)
|
||||
all-obj-y += $(addprefix ../, $(common-obj-y))
|
||||
# Now restore obj-y
|
||||
obj-y := $(obj-y-save)
|
||||
|
||||
all-obj-y = $(obj-y) $(common-obj-y)
|
||||
all-obj-$(CONFIG_SOFTMMU) += $(block-obj-y)
|
||||
|
||||
ifndef CONFIG_HAIKU
|
||||
LIBS+=-lm
|
||||
|
@ -24,4 +24,15 @@ common-obj-y += commit.o
|
||||
common-obj-y += mirror.o
|
||||
common-obj-y += backup.o
|
||||
|
||||
$(obj)/curl.o: QEMU_CFLAGS+=$(CURL_CFLAGS)
|
||||
iscsi.o-cflags := $(LIBISCSI_CFLAGS)
|
||||
iscsi.o-libs := $(LIBISCSI_LIBS)
|
||||
curl.o-cflags := $(CURL_CFLAGS)
|
||||
curl.o-libs := $(CURL_LIBS)
|
||||
rbd.o-cflags := $(RBD_CFLAGS)
|
||||
rbd.o-libs := $(RBD_LIBS)
|
||||
gluster.o-cflags := $(GLUSTERFS_CFLAGS)
|
||||
gluster.o-libs := $(GLUSTERFS_LIBS)
|
||||
ssh.o-cflags := $(LIBSSH2_CFLAGS)
|
||||
ssh.o-libs := $(LIBSSH2_LIBS)
|
||||
qcow.o-libs := -lz
|
||||
linux-aio.o-libs := -laio
|
||||
|
156
configure
vendored
156
configure
vendored
@ -12,7 +12,10 @@ else
|
||||
fi
|
||||
|
||||
TMPC="${TMPDIR1}/qemu-conf-${RANDOM}-$$-${RANDOM}.c"
|
||||
TMPO="${TMPDIR1}/qemu-conf-${RANDOM}-$$-${RANDOM}.o"
|
||||
TMPB="qemu-conf-${RANDOM}-$$-${RANDOM}"
|
||||
TMPO="${TMPDIR1}/${TMPB}.o"
|
||||
TMPL="${TMPDIR1}/${TMPB}.lo"
|
||||
TMPA="${TMPDIR1}/lib${TMPB}.la"
|
||||
TMPE="${TMPDIR1}/qemu-conf-${RANDOM}-$$-${RANDOM}.exe"
|
||||
|
||||
# NB: do not call "exit" in the trap handler; this is buggy with some shells;
|
||||
@ -86,6 +89,38 @@ compile_prog() {
|
||||
do_cc $QEMU_CFLAGS $local_cflags -o $TMPE $TMPC $LDFLAGS $local_ldflags
|
||||
}
|
||||
|
||||
do_libtool() {
|
||||
local mode=$1
|
||||
shift
|
||||
# Run the compiler, capturing its output to the log.
|
||||
echo $libtool $mode --tag=CC $cc "$@" >> config.log
|
||||
$libtool $mode --tag=CC $cc "$@" >> config.log 2>&1 || return $?
|
||||
# Test passed. If this is an --enable-werror build, rerun
|
||||
# the test with -Werror and bail out if it fails. This
|
||||
# makes warning-generating-errors in configure test code
|
||||
# obvious to developers.
|
||||
if test "$werror" != "yes"; then
|
||||
return 0
|
||||
fi
|
||||
# Don't bother rerunning the compile if we were already using -Werror
|
||||
case "$*" in
|
||||
*-Werror*)
|
||||
return 0
|
||||
;;
|
||||
esac
|
||||
echo $libtool $mode --tag=CC $cc -Werror "$@" >> config.log
|
||||
$libtool $mode --tag=CC $cc -Werror "$@" >> config.log 2>&1 && return $?
|
||||
error_exit "configure test passed without -Werror but failed with -Werror." \
|
||||
"This is probably a bug in the configure script. The failing command" \
|
||||
"will be at the bottom of config.log." \
|
||||
"You can run configure with --disable-werror to bypass this check."
|
||||
}
|
||||
|
||||
libtool_prog() {
|
||||
do_libtool --mode=compile $QEMU_CFLAGS -c -fPIE -DPIE -o $TMPO $TMPC || return $?
|
||||
do_libtool --mode=link $LDFLAGS -o $TMPA $TMPL -rpath /usr/local/lib
|
||||
}
|
||||
|
||||
# symbolically link $1 to $2. Portable version of "ln -sf".
|
||||
symlink() {
|
||||
rm -rf "$2"
|
||||
@ -205,6 +240,9 @@ mingw32="no"
|
||||
gcov="no"
|
||||
gcov_tool="gcov"
|
||||
EXESUF=""
|
||||
DSOSUF=".so"
|
||||
LDFLAGS_SHARED="-shared"
|
||||
modules="no"
|
||||
prefix="/usr/local"
|
||||
mandir="\${prefix}/share/man"
|
||||
datadir="\${prefix}/share"
|
||||
@ -515,11 +553,10 @@ OpenBSD)
|
||||
Darwin)
|
||||
bsd="yes"
|
||||
darwin="yes"
|
||||
LDFLAGS_SHARED="-bundle -undefined dynamic_lookup"
|
||||
if [ "$cpu" = "x86_64" ] ; then
|
||||
QEMU_CFLAGS="-arch x86_64 $QEMU_CFLAGS"
|
||||
LDFLAGS="-arch x86_64 $LDFLAGS"
|
||||
else
|
||||
QEMU_CFLAGS="-mdynamic-no-pic $QEMU_CFLAGS"
|
||||
fi
|
||||
cocoa="yes"
|
||||
audio_drv_list="coreaudio"
|
||||
@ -610,6 +647,7 @@ fi
|
||||
|
||||
if test "$mingw32" = "yes" ; then
|
||||
EXESUF=".exe"
|
||||
DSOSUF=".dll"
|
||||
QEMU_CFLAGS="-DWIN32_LEAN_AND_MEAN -DWINVER=0x501 $QEMU_CFLAGS"
|
||||
# enable C99/POSIX format strings (needs mingw32-runtime 3.15 or later)
|
||||
QEMU_CFLAGS="-D__USE_MINGW_ANSI_STDIO=1 $QEMU_CFLAGS"
|
||||
@ -676,6 +714,9 @@ for opt do
|
||||
;;
|
||||
--disable-debug-info)
|
||||
;;
|
||||
--enable-modules)
|
||||
modules="yes"
|
||||
;;
|
||||
--cpu=*)
|
||||
;;
|
||||
--target-list=*) target_list="$optarg"
|
||||
@ -1131,7 +1172,8 @@ Advanced options (experts only):
|
||||
--libdir=PATH install libraries in PATH
|
||||
--sysconfdir=PATH install config in PATH$confsuffix
|
||||
--localstatedir=PATH install local state in PATH (set at runtime on win32)
|
||||
--with-confsuffix=SUFFIX suffix for QEMU data inside datadir and sysconfdir [$confsuffix]
|
||||
--with-confsuffix=SUFFIX suffix for QEMU data inside datadir/libdir/sysconfdir [$confsuffix]
|
||||
--enable-modules enable modules support
|
||||
--enable-debug-tcg enable TCG debugging
|
||||
--disable-debug-tcg disable TCG debugging (default)
|
||||
--enable-debug-info enable debugging information (default)
|
||||
@ -1428,6 +1470,32 @@ EOF
|
||||
fi
|
||||
fi
|
||||
|
||||
# check for broken gcc and libtool in RHEL5
|
||||
if test -n "$libtool" -a "$pie" != "no" ; then
|
||||
cat > $TMPC <<EOF
|
||||
|
||||
void *f(unsigned char *buf, int len);
|
||||
void *g(unsigned char *buf, int len);
|
||||
|
||||
void *
|
||||
f(unsigned char *buf, int len)
|
||||
{
|
||||
return (void*)0L;
|
||||
}
|
||||
|
||||
void *
|
||||
g(unsigned char *buf, int len)
|
||||
{
|
||||
return f(buf, len);
|
||||
}
|
||||
|
||||
EOF
|
||||
if ! libtool_prog; then
|
||||
echo "Disabling libtool due to broken toolchain support"
|
||||
libtool=
|
||||
fi
|
||||
fi
|
||||
|
||||
##########################################
|
||||
# __sync_fetch_and_and requires at least -march=i486. Many toolchains
|
||||
# use i686 as default anyway, but for those that don't, an explicit
|
||||
@ -2347,8 +2415,6 @@ EOF
|
||||
curl_libs=`$curlconfig --libs 2>/dev/null`
|
||||
if compile_prog "$curl_cflags" "$curl_libs" ; then
|
||||
curl=yes
|
||||
libs_tools="$curl_libs $libs_tools"
|
||||
libs_softmmu="$curl_libs $libs_softmmu"
|
||||
else
|
||||
if test "$curl" = "yes" ; then
|
||||
feature_not_found "curl" "Install libcurl devel"
|
||||
@ -2386,13 +2452,32 @@ if test "$mingw32" = yes; then
|
||||
else
|
||||
glib_req_ver=2.12
|
||||
fi
|
||||
if $pkg_config --atleast-version=$glib_req_ver gthread-2.0; then
|
||||
glib_cflags=`$pkg_config --cflags gthread-2.0`
|
||||
glib_libs=`$pkg_config --libs gthread-2.0`
|
||||
LIBS="$glib_libs $LIBS"
|
||||
libs_qga="$glib_libs $libs_qga"
|
||||
else
|
||||
error_exit "glib-$glib_req_ver required to compile QEMU"
|
||||
|
||||
for i in gthread-2.0 gmodule-2.0; do
|
||||
if $pkg_config --atleast-version=$glib_req_ver $i; then
|
||||
glib_cflags=`$pkg_config --cflags $i`
|
||||
glib_libs=`$pkg_config --libs $i`
|
||||
CFLAGS="$glib_cflags $CFLAGS"
|
||||
LIBS="$glib_libs $LIBS"
|
||||
libs_qga="$glib_libs $libs_qga"
|
||||
else
|
||||
error_exit "glib-$glib_req_ver $i is required to compile QEMU"
|
||||
fi
|
||||
done
|
||||
|
||||
##########################################
|
||||
# SHA command probe for modules
|
||||
if test "$modules" = yes; then
|
||||
shacmd_probe="sha1sum sha1 shasum"
|
||||
for c in $shacmd_probe; do
|
||||
if which $c &>/dev/null; then
|
||||
shacmd="$c"
|
||||
break
|
||||
fi
|
||||
done
|
||||
if test "$shacmd" = ""; then
|
||||
error_exit "one of the checksum commands is required to enable modules: $shacmd_probe"
|
||||
fi
|
||||
fi
|
||||
|
||||
##########################################
|
||||
@ -2503,8 +2588,6 @@ EOF
|
||||
rbd_libs="-lrbd -lrados"
|
||||
if compile_prog "" "$rbd_libs" ; then
|
||||
rbd=yes
|
||||
libs_tools="$rbd_libs $libs_tools"
|
||||
libs_softmmu="$rbd_libs $libs_softmmu"
|
||||
else
|
||||
if test "$rbd" = "yes" ; then
|
||||
feature_not_found "rados block device" "Install librbd/ceph devel"
|
||||
@ -2521,9 +2604,6 @@ if test "$libssh2" != "no" ; then
|
||||
libssh2_cflags=`$pkg_config libssh2 --cflags`
|
||||
libssh2_libs=`$pkg_config libssh2 --libs`
|
||||
libssh2=yes
|
||||
libs_tools="$libssh2_libs $libs_tools"
|
||||
libs_softmmu="$libssh2_libs $libs_softmmu"
|
||||
QEMU_CFLAGS="$QEMU_CFLAGS $libssh2_cflags"
|
||||
else
|
||||
if test "$libssh2" = "yes" ; then
|
||||
error_exit "libssh2 >= $min_libssh2_version required for --enable-libssh2"
|
||||
@ -2569,8 +2649,6 @@ int main(void) { io_setup(0, NULL); io_set_eventfd(NULL, 0); eventfd(0, 0); retu
|
||||
EOF
|
||||
if compile_prog "" "-laio" ; then
|
||||
linux_aio=yes
|
||||
libs_softmmu="$libs_softmmu -laio"
|
||||
libs_tools="$libs_tools -laio"
|
||||
else
|
||||
if test "$linux_aio" = "yes" ; then
|
||||
feature_not_found "linux AIO" "Install libaio devel"
|
||||
@ -2739,9 +2817,6 @@ if test "$glusterfs" != "no" ; then
|
||||
glusterfs="yes"
|
||||
glusterfs_cflags=`$pkg_config --cflags glusterfs-api`
|
||||
glusterfs_libs=`$pkg_config --libs glusterfs-api`
|
||||
CFLAGS="$CFLAGS $glusterfs_cflags"
|
||||
libs_tools="$glusterfs_libs $libs_tools"
|
||||
libs_softmmu="$glusterfs_libs $libs_softmmu"
|
||||
if $pkg_config --atleast-version=5 glusterfs-api; then
|
||||
glusterfs_discard="yes"
|
||||
fi
|
||||
@ -3112,11 +3187,9 @@ EOF
|
||||
libiscsi="yes"
|
||||
libiscsi_cflags=$($pkg_config --cflags libiscsi)
|
||||
libiscsi_libs=$($pkg_config --libs libiscsi)
|
||||
CFLAGS="$CFLAGS $libiscsi_cflags"
|
||||
LIBS="$LIBS $libiscsi_libs"
|
||||
elif compile_prog "" "-liscsi" ; then
|
||||
libiscsi="yes"
|
||||
LIBS="$LIBS -liscsi"
|
||||
libiscsi_libs="-liscsi"
|
||||
else
|
||||
if test "$libiscsi" = "yes" ; then
|
||||
feature_not_found "libiscsi" "Install libiscsi devel"
|
||||
@ -3717,6 +3790,7 @@ if test "$mingw32" = "yes" ; then
|
||||
fi
|
||||
|
||||
qemu_confdir=$sysconfdir$confsuffix
|
||||
qemu_moddir=$libdir$confsuffix
|
||||
qemu_datadir=$datadir$confsuffix
|
||||
qemu_localedir="$datadir/locale"
|
||||
|
||||
@ -3807,6 +3881,7 @@ echo "Install prefix $prefix"
|
||||
echo "BIOS directory `eval echo $qemu_datadir`"
|
||||
echo "binary directory `eval echo $bindir`"
|
||||
echo "library directory `eval echo $libdir`"
|
||||
echo "module directory `eval echo $qemu_moddir`"
|
||||
echo "libexec directory `eval echo $libexecdir`"
|
||||
echo "include directory `eval echo $includedir`"
|
||||
echo "config directory `eval echo $sysconfdir`"
|
||||
@ -3833,6 +3908,7 @@ echo "python $python"
|
||||
if test "$slirp" = "yes" ; then
|
||||
echo "smbd $smbd"
|
||||
fi
|
||||
echo "module support $modules"
|
||||
echo "host CPU $cpu"
|
||||
echo "host big endian $bigendian"
|
||||
echo "target list $target_list"
|
||||
@ -3945,6 +4021,7 @@ echo "sysconfdir=$sysconfdir" >> $config_host_mak
|
||||
echo "qemu_confdir=$qemu_confdir" >> $config_host_mak
|
||||
echo "qemu_datadir=$qemu_datadir" >> $config_host_mak
|
||||
echo "qemu_docdir=$qemu_docdir" >> $config_host_mak
|
||||
echo "qemu_moddir=$qemu_moddir" >> $config_host_mak
|
||||
if test "$mingw32" = "no" ; then
|
||||
echo "qemu_localstatedir=$local_statedir" >> $config_host_mak
|
||||
fi
|
||||
@ -4077,6 +4154,12 @@ echo "TARGET_DIRS=$target_list" >> $config_host_mak
|
||||
if [ "$docs" = "yes" ] ; then
|
||||
echo "BUILD_DOCS=yes" >> $config_host_mak
|
||||
fi
|
||||
if test "$modules" = "yes"; then
|
||||
# $shacmd can generate a hash started with digit, which the compiler doesn't
|
||||
# like as an symbol. So prefix it with an underscore
|
||||
echo "CONFIG_STAMP=_`(echo $qemu_version; echo $pkgversion; cat $0) | $shacmd - | cut -f1 -d\ `" >> $config_host_mak
|
||||
echo "CONFIG_MODULES=y" >> $config_host_mak
|
||||
fi
|
||||
if test "$sdl" = "yes" ; then
|
||||
echo "CONFIG_SDL=y" >> $config_host_mak
|
||||
echo "SDL_CFLAGS=$sdl_cflags" >> $config_host_mak
|
||||
@ -4148,8 +4231,9 @@ if test "$bswap_h" = "yes" ; then
|
||||
echo "CONFIG_MACHINE_BSWAP_H=y" >> $config_host_mak
|
||||
fi
|
||||
if test "$curl" = "yes" ; then
|
||||
echo "CONFIG_CURL=y" >> $config_host_mak
|
||||
echo "CONFIG_CURL=m" >> $config_host_mak
|
||||
echo "CURL_CFLAGS=$curl_cflags" >> $config_host_mak
|
||||
echo "CURL_LIBS=$curl_libs" >> $config_host_mak
|
||||
fi
|
||||
if test "$brlapi" = "yes" ; then
|
||||
echo "CONFIG_BRLAPI=y" >> $config_host_mak
|
||||
@ -4238,10 +4322,12 @@ if test "$glx" = "yes" ; then
|
||||
fi
|
||||
|
||||
if test "$libiscsi" = "yes" ; then
|
||||
echo "CONFIG_LIBISCSI=y" >> $config_host_mak
|
||||
echo "CONFIG_LIBISCSI=m" >> $config_host_mak
|
||||
if test "$libiscsi_version" = "1.4.0"; then
|
||||
echo "CONFIG_LIBISCSI_1_4=y" >> $config_host_mak
|
||||
fi
|
||||
echo "LIBISCSI_CFLAGS=$libiscsi_cflags" >> $config_host_mak
|
||||
echo "LIBISCSI_LIBS=$libiscsi_libs" >> $config_host_mak
|
||||
fi
|
||||
|
||||
if test "$libnfs" = "yes" ; then
|
||||
@ -4266,7 +4352,9 @@ if test "$qom_cast_debug" = "yes" ; then
|
||||
echo "CONFIG_QOM_CAST_DEBUG=y" >> $config_host_mak
|
||||
fi
|
||||
if test "$rbd" = "yes" ; then
|
||||
echo "CONFIG_RBD=y" >> $config_host_mak
|
||||
echo "CONFIG_RBD=m" >> $config_host_mak
|
||||
echo "RBD_CFLAGS=$rbd_cflags" >> $config_host_mak
|
||||
echo "RBD_LIBS=$rbd_libs" >> $config_host_mak
|
||||
fi
|
||||
|
||||
echo "CONFIG_COROUTINE_BACKEND=$coroutine" >> $config_host_mak
|
||||
@ -4309,7 +4397,9 @@ if test "$getauxval" = "yes" ; then
|
||||
fi
|
||||
|
||||
if test "$glusterfs" = "yes" ; then
|
||||
echo "CONFIG_GLUSTERFS=y" >> $config_host_mak
|
||||
echo "CONFIG_GLUSTERFS=m" >> $config_host_mak
|
||||
echo "GLUSTERFS_CFLAGS=$glusterfs_cflags" >> $config_host_mak
|
||||
echo "GLUSTERFS_LIBS=$glusterfs_libs" >> $config_host_mak
|
||||
fi
|
||||
|
||||
if test "$glusterfs_discard" = "yes" ; then
|
||||
@ -4321,7 +4411,9 @@ if test "$glusterfs_zerofill" = "yes" ; then
|
||||
fi
|
||||
|
||||
if test "$libssh2" = "yes" ; then
|
||||
echo "CONFIG_LIBSSH2=y" >> $config_host_mak
|
||||
echo "CONFIG_LIBSSH2=m" >> $config_host_mak
|
||||
echo "LIBSSH2_CFLAGS=$libssh2_cflags" >> $config_host_mak
|
||||
echo "LIBSSH2_LIBS=$libssh2_libs" >> $config_host_mak
|
||||
fi
|
||||
|
||||
if test "$virtio_blk_data_plane" = "yes" ; then
|
||||
@ -4452,6 +4544,8 @@ echo "LIBTOOLFLAGS=$LIBTOOLFLAGS" >> $config_host_mak
|
||||
echo "LIBS+=$LIBS" >> $config_host_mak
|
||||
echo "LIBS_TOOLS+=$libs_tools" >> $config_host_mak
|
||||
echo "EXESUF=$EXESUF" >> $config_host_mak
|
||||
echo "DSOSUF=$DSOSUF" >> $config_host_mak
|
||||
echo "LDFLAGS_SHARED=$LDFLAGS_SHARED" >> $config_host_mak
|
||||
echo "LIBS_QGA+=$libs_qga" >> $config_host_mak
|
||||
echo "POD2MAN=$POD2MAN" >> $config_host_mak
|
||||
echo "TRANSLATE_OPT_CFLAGS=$TRANSLATE_OPT_CFLAGS" >> $config_host_mak
|
||||
|
@ -352,7 +352,7 @@ char *qemu_find_file(int type, const char *name);
|
||||
|
||||
/* OS specific functions */
|
||||
void os_setup_early_signal_handling(void);
|
||||
char *os_find_datadir(const char *argv0);
|
||||
char *os_find_datadir(void);
|
||||
void os_parse_cmd_args(int index, const char *optarg);
|
||||
void os_pidfile_error(void);
|
||||
|
||||
|
@ -14,11 +14,31 @@
|
||||
#ifndef QEMU_MODULE_H
|
||||
#define QEMU_MODULE_H
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
|
||||
#define DSO_STAMP_FUN glue(qemu_stamp, CONFIG_STAMP)
|
||||
#define DSO_STAMP_FUN_STR stringify(DSO_STAMP_FUN)
|
||||
|
||||
#ifdef BUILD_DSO
|
||||
void DSO_STAMP_FUN(void);
|
||||
/* This is a dummy symbol to identify a loaded DSO as a QEMU module, so we can
|
||||
* distinguish "version mismatch" from "not a QEMU module", when the stamp
|
||||
* check fails during module loading */
|
||||
void qemu_module_dummy(void);
|
||||
|
||||
#define module_init(function, type) \
|
||||
static void __attribute__((constructor)) do_qemu_init_ ## function(void) \
|
||||
{ \
|
||||
register_dso_module_init(function, type); \
|
||||
}
|
||||
#else
|
||||
/* This should not be used directly. Use block_init etc. instead. */
|
||||
#define module_init(function, type) \
|
||||
static void __attribute__((constructor)) do_qemu_init_ ## function(void) { \
|
||||
static void __attribute__((constructor)) do_qemu_init_ ## function(void) \
|
||||
{ \
|
||||
register_module_init(function, type); \
|
||||
}
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
MODULE_INIT_BLOCK,
|
||||
@ -34,6 +54,7 @@ typedef enum {
|
||||
#define type_init(function) module_init(function, MODULE_INIT_QOM)
|
||||
|
||||
void register_module_init(void (*fn)(void), module_init_type type);
|
||||
void register_dso_module_init(void (*fn)(void), module_init_type type);
|
||||
|
||||
void module_call_init(module_init_type type);
|
||||
|
||||
|
@ -215,6 +215,15 @@ bool fips_get_state(void);
|
||||
*/
|
||||
char *qemu_get_local_state_pathname(const char *relative_pathname);
|
||||
|
||||
/* Find program directory, and save it for later usage with
|
||||
* qemu_get_exec_dir().
|
||||
* Try OS specific API first, if not working, parse from argv0. */
|
||||
void qemu_init_exec_dir(const char *argv0);
|
||||
|
||||
/* Get the saved exec dir.
|
||||
* Caller needs to release the returned string by g_free() */
|
||||
char *qemu_get_exec_dir(void);
|
||||
|
||||
/**
|
||||
* qemu_getauxval:
|
||||
* @type: the auxiliary vector key to lookup
|
||||
|
10
module-common.c
Normal file
10
module-common.c
Normal file
@ -0,0 +1,10 @@
|
||||
#include "config-host.h"
|
||||
#include "qemu/module.h"
|
||||
|
||||
void qemu_module_dummy(void)
|
||||
{
|
||||
}
|
||||
|
||||
void DSO_STAMP_FUN(void)
|
||||
{
|
||||
}
|
42
os-posix.c
42
os-posix.c
@ -84,46 +84,17 @@ void os_setup_signal_handling(void)
|
||||
running from the build tree this will be "$bindir/../pc-bios". */
|
||||
#define SHARE_SUFFIX "/share/qemu"
|
||||
#define BUILD_SUFFIX "/pc-bios"
|
||||
char *os_find_datadir(const char *argv0)
|
||||
char *os_find_datadir(void)
|
||||
{
|
||||
char *dir;
|
||||
char *p = NULL;
|
||||
char *dir, *exec_dir;
|
||||
char *res;
|
||||
char buf[PATH_MAX];
|
||||
size_t max_len;
|
||||
|
||||
#if defined(__linux__)
|
||||
{
|
||||
int len;
|
||||
len = readlink("/proc/self/exe", buf, sizeof(buf) - 1);
|
||||
if (len > 0) {
|
||||
buf[len] = 0;
|
||||
p = buf;
|
||||
}
|
||||
exec_dir = qemu_get_exec_dir();
|
||||
if (exec_dir == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
#elif defined(__FreeBSD__)
|
||||
{
|
||||
static int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1};
|
||||
size_t len = sizeof(buf) - 1;
|
||||
|
||||
*buf = '\0';
|
||||
if (!sysctl(mib, ARRAY_SIZE(mib), buf, &len, NULL, 0) &&
|
||||
*buf) {
|
||||
buf[sizeof(buf) - 1] = '\0';
|
||||
p = buf;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/* If we don't have any way of figuring out the actual executable
|
||||
location then try argv[0]. */
|
||||
if (!p) {
|
||||
p = realpath(argv0, buf);
|
||||
if (!p) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
dir = dirname(p);
|
||||
dir = dirname(dir);
|
||||
dir = dirname(exec_dir);
|
||||
|
||||
max_len = strlen(dir) +
|
||||
MAX(strlen(SHARE_SUFFIX), strlen(BUILD_SUFFIX)) + 1;
|
||||
@ -137,6 +108,7 @@ char *os_find_datadir(const char *argv0)
|
||||
}
|
||||
}
|
||||
|
||||
g_free(exec_dir);
|
||||
return res;
|
||||
}
|
||||
#undef SHARE_SUFFIX
|
||||
|
21
os-win32.c
21
os-win32.c
@ -84,26 +84,9 @@ void os_setup_early_signal_handling(void)
|
||||
}
|
||||
|
||||
/* Look for support files in the same directory as the executable. */
|
||||
char *os_find_datadir(const char *argv0)
|
||||
char *os_find_datadir(void)
|
||||
{
|
||||
char *p;
|
||||
char buf[MAX_PATH];
|
||||
DWORD len;
|
||||
|
||||
len = GetModuleFileName(NULL, buf, sizeof(buf) - 1);
|
||||
if (len == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
buf[len] = 0;
|
||||
p = buf + len - 1;
|
||||
while (p != buf && *p != '\\')
|
||||
p--;
|
||||
*p = 0;
|
||||
if (access(buf, R_OK) == 0) {
|
||||
return g_strdup(buf);
|
||||
}
|
||||
return NULL;
|
||||
return qemu_get_exec_dir();
|
||||
}
|
||||
|
||||
void os_set_line_buffering(void)
|
||||
|
@ -2719,6 +2719,7 @@ int main(int argc, char **argv)
|
||||
#endif
|
||||
|
||||
error_set_progname(argv[0]);
|
||||
qemu_init_exec_dir(argv[0]);
|
||||
|
||||
qemu_init_main_loop();
|
||||
bdrv_init();
|
||||
|
@ -381,6 +381,7 @@ int main(int argc, char **argv)
|
||||
#endif
|
||||
|
||||
progname = basename(argv[0]);
|
||||
qemu_init_exec_dir(argv[0]);
|
||||
|
||||
while ((c = getopt_long(argc, argv, sopt, lopt, &opt_index)) != -1) {
|
||||
switch (c) {
|
||||
|
@ -376,6 +376,7 @@ int main(int argc, char **argv)
|
||||
memset(&sa_sigterm, 0, sizeof(sa_sigterm));
|
||||
sa_sigterm.sa_handler = termsig_handler;
|
||||
sigaction(SIGTERM, &sa_sigterm, NULL);
|
||||
qemu_init_exec_dir(argv[0]);
|
||||
|
||||
while ((ch = getopt_long(argc, argv, sopt, lopt, &opt_ind)) != -1) {
|
||||
switch (ch) {
|
||||
|
80
rules.mak
80
rules.mak
@ -22,8 +22,15 @@ QEMU_DGFLAGS += -MMD -MP -MT $@ -MF $(*D)/$(*F).d
|
||||
# Same as -I$(SRC_PATH) -I., but for the nested source/object directories
|
||||
QEMU_INCLUDES += -I$(<D) -I$(@D)
|
||||
|
||||
maybe-add = $(filter-out $1, $2) $1
|
||||
extract-libs = $(strip $(sort $(foreach o,$1,$($o-libs)) \
|
||||
$(foreach o,$(call expand-objs,$1),$($o-libs))))
|
||||
expand-objs = $(strip $(sort $(filter %.o,$1)) \
|
||||
$(foreach o,$(filter %.mo,$1),$($o-objs)) \
|
||||
$(filter-out %.o %.mo,$1))
|
||||
|
||||
%.o: %.c
|
||||
$(call quiet-command,$(CC) $(QEMU_INCLUDES) $(QEMU_CFLAGS) $(QEMU_DGFLAGS) $(CFLAGS) -c -o $@ $<," CC $(TARGET_DIR)$@")
|
||||
$(call quiet-command,$(CC) $(QEMU_INCLUDES) $(QEMU_CFLAGS) $(QEMU_DGFLAGS) $(CFLAGS) $($@-cflags) -c -o $@ $<," CC $(TARGET_DIR)$@")
|
||||
%.o: %.rc
|
||||
$(call quiet-command,$(WINDRES) -I. -o $@ $<," RC $(TARGET_DIR)$@")
|
||||
|
||||
@ -33,8 +40,8 @@ LINKPROG = $(or $(CXX),$(CC))
|
||||
|
||||
ifeq ($(LIBTOOL),)
|
||||
LINK = $(call quiet-command,$(LINKPROG) $(QEMU_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ \
|
||||
$(sort $(filter %.o, $1)) $(filter-out %.o, $1) $(version-obj-y) \
|
||||
$(LIBS)," LINK $(TARGET_DIR)$@")
|
||||
$(call expand-objs,$1) $(version-obj-y) \
|
||||
$(call extract-libs,$1) $(LIBS)," LINK $(TARGET_DIR)$@")
|
||||
else
|
||||
LIBTOOL += $(if $(V),,--quiet)
|
||||
%.lo: %.c
|
||||
@ -45,12 +52,12 @@ LIBTOOL += $(if $(V),,--quiet)
|
||||
$(call quiet-command,$(LIBTOOL) --mode=compile --tag=CC dtrace -o $@ -G -s $<, " lt GEN $(TARGET_DIR)$@")
|
||||
|
||||
LINK = $(call quiet-command,\
|
||||
$(if $(filter %.lo %.la,$^),$(LIBTOOL) --mode=link --tag=CC \
|
||||
$(if $(filter %.lo %.la,$1),$(LIBTOOL) --mode=link --tag=CC \
|
||||
)$(LINKPROG) $(QEMU_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ \
|
||||
$(sort $(filter %.o, $1)) $(filter-out %.o, $1) \
|
||||
$(if $(filter %.lo %.la,$^),$(version-lobj-y),$(version-obj-y)) \
|
||||
$(if $(filter %.lo %.la,$^),$(LIBTOOLFLAGS)) \
|
||||
$(LIBS),$(if $(filter %.lo %.la,$^),"lt LINK ", " LINK ")"$(TARGET_DIR)$@")
|
||||
$(call expand-objs,$1) \
|
||||
$(if $(filter %.lo %.la,$1),$(version-lobj-y),$(version-obj-y)) \
|
||||
$(if $(filter %.lo %.la,$1),$(LIBTOOLFLAGS)) \
|
||||
$(call extract-libs,$1) $(LIBS),$(if $(filter %.lo %.la,$1),"lt LINK ", " LINK ")"$(TARGET_DIR)$@")
|
||||
endif
|
||||
|
||||
%.asm: %.S
|
||||
@ -71,6 +78,16 @@ endif
|
||||
%.o: %.dtrace
|
||||
$(call quiet-command,dtrace -o $@ -G -s $<, " GEN $(TARGET_DIR)$@")
|
||||
|
||||
DSO_CFLAGS := -fPIC -DBUILD_DSO
|
||||
%$(DSOSUF): LDFLAGS += $(LDFLAGS_SHARED)
|
||||
%$(DSOSUF): %.mo libqemustub.a
|
||||
$(call LINK,$^)
|
||||
@# Copy to build root so modules can be loaded when program started without install
|
||||
$(if $(findstring /,$@),$(call quiet-command,cp $@ $(subst /,-,$@), " CP $(subst /,-,$@)"))
|
||||
|
||||
.PHONY: modules
|
||||
modules:
|
||||
|
||||
%$(EXESUF): %.o
|
||||
$(call LINK,$^)
|
||||
|
||||
@ -146,9 +163,6 @@ clean: clean-timestamp
|
||||
|
||||
# magic to descend into other directories
|
||||
|
||||
obj := .
|
||||
old-nested-dirs :=
|
||||
|
||||
define push-var
|
||||
$(eval save-$2-$1 = $(value $1))
|
||||
$(eval $1 :=)
|
||||
@ -160,11 +174,27 @@ $(eval $1 = $(value save-$2-$1) $$(subdir-$2-$1))
|
||||
$(eval save-$2-$1 :=)
|
||||
endef
|
||||
|
||||
define fix-obj-vars
|
||||
$(foreach v,$($1), \
|
||||
$(if $($v-cflags), \
|
||||
$(eval $2$v-cflags := $($v-cflags)) \
|
||||
$(eval $v-cflags := )) \
|
||||
$(if $($v-libs), \
|
||||
$(eval $2$v-libs := $($v-libs)) \
|
||||
$(eval $v-libs := )) \
|
||||
$(if $($v-objs), \
|
||||
$(eval $2$v-objs := $(addprefix $2,$($v-objs))) \
|
||||
$(eval $v-objs := )))
|
||||
endef
|
||||
|
||||
define unnest-dir
|
||||
$(foreach var,$(nested-vars),$(call push-var,$(var),$1/))
|
||||
$(eval obj := $(obj)/$1)
|
||||
$(eval obj-parent-$1 := $(obj))
|
||||
$(eval obj := $(if $(obj),$(obj)/$1,$1))
|
||||
$(eval include $(SRC_PATH)/$1/Makefile.objs)
|
||||
$(eval obj := $(patsubst %/$1,%,$(obj)))
|
||||
$(foreach v,$(nested-vars),$(call fix-obj-vars,$v,$(if $(obj),$(obj)/)))
|
||||
$(eval obj := $(obj-parent-$1))
|
||||
$(eval obj-parent-$1 := )
|
||||
$(foreach var,$(nested-vars),$(call pop-var,$(var),$1/))
|
||||
endef
|
||||
|
||||
@ -178,10 +208,34 @@ $(if $(nested-dirs),
|
||||
$(call unnest-vars-1))
|
||||
endef
|
||||
|
||||
define process-modules
|
||||
$(foreach o,$(filter %.o,$($1)),
|
||||
$(eval $(patsubst %.o,%.mo,$o): $o) \
|
||||
$(eval $(patsubst %.o,%.mo,$o)-objs := $o))
|
||||
$(foreach o,$(filter-out $(modules-m), $(patsubst %.o,%.mo,$($1))), \
|
||||
$(eval $o-objs += module-common.o)
|
||||
$(eval $o: $($o-objs))
|
||||
$(eval modules-objs-m += $($o-objs))
|
||||
$(eval modules-m += $o)
|
||||
$(eval $o:; $$(call quiet-command,touch $$@," GEN $$(TARGET_DIR)$$@"))
|
||||
$(if $(CONFIG_MODULES),$(eval modules: $(patsubst %.mo,%$(DSOSUF),$o)))) \
|
||||
$(eval modules-objs-m := $(sort $(modules-objs-m)))
|
||||
$(foreach o,$(modules-objs-m), \
|
||||
$(if $(CONFIG_MODULES),$(eval $o-cflags := $(call maybe-add, $(DSO_CFLAGS), $($o-cflags)))))
|
||||
$(eval $(patsubst %-m,%-$(call lnot,$(CONFIG_MODULES)),$1) += $($1))
|
||||
endef
|
||||
|
||||
define unnest-vars
|
||||
$(eval obj := $1)
|
||||
$(eval nested-vars := $2)
|
||||
$(eval old-nested-dirs := )
|
||||
$(call unnest-vars-1)
|
||||
$(if $1,$(foreach v,$(nested-vars),$(eval \
|
||||
$v := $(addprefix $1/,$($v)))))
|
||||
$(foreach var,$(nested-vars),$(eval $(var) := $(filter-out %/, $($(var)))))
|
||||
$(shell mkdir -p $(sort $(foreach var,$(nested-vars),$(dir $($(var))))))
|
||||
$(foreach var,$(nested-vars), $(eval \
|
||||
-include $(addsuffix *.d, $(sort $(dir $($(var)))))))
|
||||
$(foreach v,$(filter %-m,$(nested-vars)), \
|
||||
$(call process-modules,$v))
|
||||
endef
|
||||
|
@ -108,6 +108,9 @@ case $line in
|
||||
value=${line#*=}
|
||||
echo "#define $name $value"
|
||||
;;
|
||||
DSOSUF=*)
|
||||
echo "#define HOST_DSOSUF \"${line#*=}\""
|
||||
;;
|
||||
esac
|
||||
|
||||
done # read
|
||||
|
145
util/module.c
145
util/module.c
@ -13,6 +13,8 @@
|
||||
* GNU GPL, version 2 or (at your option) any later version.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <gmodule.h>
|
||||
#include "qemu-common.h"
|
||||
#include "qemu/queue.h"
|
||||
#include "qemu/module.h"
|
||||
@ -21,13 +23,16 @@ typedef struct ModuleEntry
|
||||
{
|
||||
void (*init)(void);
|
||||
QTAILQ_ENTRY(ModuleEntry) node;
|
||||
module_init_type type;
|
||||
} ModuleEntry;
|
||||
|
||||
typedef QTAILQ_HEAD(, ModuleEntry) ModuleTypeList;
|
||||
|
||||
static ModuleTypeList init_type_list[MODULE_INIT_MAX];
|
||||
|
||||
static void init_types(void)
|
||||
static ModuleTypeList dso_init_list;
|
||||
|
||||
static void init_lists(void)
|
||||
{
|
||||
static int inited;
|
||||
int i;
|
||||
@ -40,6 +45,8 @@ static void init_types(void)
|
||||
QTAILQ_INIT(&init_type_list[i]);
|
||||
}
|
||||
|
||||
QTAILQ_INIT(&dso_init_list);
|
||||
|
||||
inited = 1;
|
||||
}
|
||||
|
||||
@ -48,7 +55,7 @@ static ModuleTypeList *find_type(module_init_type type)
|
||||
{
|
||||
ModuleTypeList *l;
|
||||
|
||||
init_types();
|
||||
init_lists();
|
||||
|
||||
l = &init_type_list[type];
|
||||
|
||||
@ -62,20 +69,154 @@ void register_module_init(void (*fn)(void), module_init_type type)
|
||||
|
||||
e = g_malloc0(sizeof(*e));
|
||||
e->init = fn;
|
||||
e->type = type;
|
||||
|
||||
l = find_type(type);
|
||||
|
||||
QTAILQ_INSERT_TAIL(l, e, node);
|
||||
}
|
||||
|
||||
void register_dso_module_init(void (*fn)(void), module_init_type type)
|
||||
{
|
||||
ModuleEntry *e;
|
||||
|
||||
init_lists();
|
||||
|
||||
e = g_malloc0(sizeof(*e));
|
||||
e->init = fn;
|
||||
e->type = type;
|
||||
|
||||
QTAILQ_INSERT_TAIL(&dso_init_list, e, node);
|
||||
}
|
||||
|
||||
static void module_load(module_init_type type);
|
||||
|
||||
void module_call_init(module_init_type type)
|
||||
{
|
||||
ModuleTypeList *l;
|
||||
ModuleEntry *e;
|
||||
|
||||
module_load(type);
|
||||
l = find_type(type);
|
||||
|
||||
QTAILQ_FOREACH(e, l, node) {
|
||||
e->init();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MODULES
|
||||
static int module_load_file(const char *fname)
|
||||
{
|
||||
GModule *g_module;
|
||||
void (*sym)(void);
|
||||
const char *dsosuf = HOST_DSOSUF;
|
||||
int len = strlen(fname);
|
||||
int suf_len = strlen(dsosuf);
|
||||
ModuleEntry *e, *next;
|
||||
int ret;
|
||||
|
||||
if (len <= suf_len || strcmp(&fname[len - suf_len], dsosuf)) {
|
||||
/* wrong suffix */
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
if (access(fname, F_OK)) {
|
||||
ret = -ENOENT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
assert(QTAILQ_EMPTY(&dso_init_list));
|
||||
|
||||
g_module = g_module_open(fname, G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL);
|
||||
if (!g_module) {
|
||||
fprintf(stderr, "Failed to open module: %s\n",
|
||||
g_module_error());
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
if (!g_module_symbol(g_module, DSO_STAMP_FUN_STR, (gpointer *)&sym)) {
|
||||
fprintf(stderr, "Failed to initialize module: %s\n",
|
||||
fname);
|
||||
/* Print some info if this is a QEMU module (but from different build),
|
||||
* this will make debugging user problems easier. */
|
||||
if (g_module_symbol(g_module, "qemu_module_dummy", (gpointer *)&sym)) {
|
||||
fprintf(stderr,
|
||||
"Note: only modules from the same build can be loaded.\n");
|
||||
}
|
||||
g_module_close(g_module);
|
||||
ret = -EINVAL;
|
||||
} else {
|
||||
QTAILQ_FOREACH(e, &dso_init_list, node) {
|
||||
register_module_init(e->init, e->type);
|
||||
}
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
QTAILQ_FOREACH_SAFE(e, &dso_init_list, node, next) {
|
||||
QTAILQ_REMOVE(&dso_init_list, e, node);
|
||||
g_free(e);
|
||||
}
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
void module_load(module_init_type type)
|
||||
{
|
||||
#ifdef CONFIG_MODULES
|
||||
char *fname = NULL;
|
||||
const char **mp;
|
||||
static const char *block_modules[] = {
|
||||
CONFIG_BLOCK_MODULES
|
||||
};
|
||||
char *exec_dir;
|
||||
char *dirs[3];
|
||||
int i = 0;
|
||||
int ret;
|
||||
|
||||
if (!g_module_supported()) {
|
||||
fprintf(stderr, "Module is not supported by system.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case MODULE_INIT_BLOCK:
|
||||
mp = block_modules;
|
||||
break;
|
||||
default:
|
||||
/* no other types have dynamic modules for now*/
|
||||
return;
|
||||
}
|
||||
|
||||
exec_dir = qemu_get_exec_dir();
|
||||
dirs[i++] = g_strdup_printf("%s", CONFIG_QEMU_MODDIR);
|
||||
dirs[i++] = g_strdup_printf("%s/..", exec_dir ? : "");
|
||||
dirs[i++] = g_strdup_printf("%s", exec_dir ? : "");
|
||||
assert(i == ARRAY_SIZE(dirs));
|
||||
g_free(exec_dir);
|
||||
exec_dir = NULL;
|
||||
|
||||
for ( ; *mp; mp++) {
|
||||
for (i = 0; i < ARRAY_SIZE(dirs); i++) {
|
||||
fname = g_strdup_printf("%s/%s%s", dirs[i], *mp, HOST_DSOSUF);
|
||||
ret = module_load_file(fname);
|
||||
/* Try loading until loaded a module file */
|
||||
if (!ret) {
|
||||
break;
|
||||
}
|
||||
g_free(fname);
|
||||
fname = NULL;
|
||||
}
|
||||
if (ret == -ENOENT) {
|
||||
fprintf(stderr, "Can't find module: %s\n", *mp);
|
||||
}
|
||||
|
||||
g_free(fname);
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(dirs); i++) {
|
||||
g_free(dirs[i]);
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
@ -57,6 +57,7 @@ extern int daemon(int, int);
|
||||
#include "trace.h"
|
||||
#include "qemu/sockets.h"
|
||||
#include <sys/mman.h>
|
||||
#include <libgen.h>
|
||||
|
||||
#ifdef CONFIG_LINUX
|
||||
#include <sys/syscall.h>
|
||||
@ -274,3 +275,56 @@ void qemu_set_tty_echo(int fd, bool echo)
|
||||
|
||||
tcsetattr(fd, TCSANOW, &tty);
|
||||
}
|
||||
|
||||
static char exec_dir[PATH_MAX];
|
||||
|
||||
void qemu_init_exec_dir(const char *argv0)
|
||||
{
|
||||
char *dir;
|
||||
char *p = NULL;
|
||||
char buf[PATH_MAX];
|
||||
|
||||
assert(!exec_dir[0]);
|
||||
|
||||
#if defined(__linux__)
|
||||
{
|
||||
int len;
|
||||
len = readlink("/proc/self/exe", buf, sizeof(buf) - 1);
|
||||
if (len > 0) {
|
||||
buf[len] = 0;
|
||||
p = buf;
|
||||
}
|
||||
}
|
||||
#elif defined(__FreeBSD__)
|
||||
{
|
||||
static int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1};
|
||||
size_t len = sizeof(buf) - 1;
|
||||
|
||||
*buf = '\0';
|
||||
if (!sysctl(mib, ARRAY_SIZE(mib), buf, &len, NULL, 0) &&
|
||||
*buf) {
|
||||
buf[sizeof(buf) - 1] = '\0';
|
||||
p = buf;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/* If we don't have any way of figuring out the actual executable
|
||||
location then try argv[0]. */
|
||||
if (!p) {
|
||||
if (!argv0) {
|
||||
return;
|
||||
}
|
||||
p = realpath(argv0, buf);
|
||||
if (!p) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
dir = dirname(p);
|
||||
|
||||
pstrcpy(exec_dir, sizeof(exec_dir), dir);
|
||||
}
|
||||
|
||||
char *qemu_get_exec_dir(void)
|
||||
{
|
||||
return g_strdup(exec_dir);
|
||||
}
|
||||
|
@ -208,3 +208,33 @@ void qemu_set_tty_echo(int fd, bool echo)
|
||||
dwMode & ~(ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT));
|
||||
}
|
||||
}
|
||||
|
||||
static char exec_dir[PATH_MAX];
|
||||
|
||||
void qemu_init_exec_dir(const char *argv0)
|
||||
{
|
||||
|
||||
char *p;
|
||||
char buf[MAX_PATH];
|
||||
DWORD len;
|
||||
|
||||
len = GetModuleFileName(NULL, buf, sizeof(buf) - 1);
|
||||
if (len == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
buf[len] = 0;
|
||||
p = buf + len - 1;
|
||||
while (p != buf && *p != '\\') {
|
||||
p--;
|
||||
}
|
||||
*p = 0;
|
||||
if (access(buf, R_OK) == 0) {
|
||||
pstrcpy(exec_dir, sizeof(exec_dir), buf);
|
||||
}
|
||||
}
|
||||
|
||||
char *qemu_get_exec_dir(void)
|
||||
{
|
||||
return g_strdup(exec_dir);
|
||||
}
|
||||
|
3
vl.c
3
vl.c
@ -2827,6 +2827,7 @@ int main(int argc, char **argv, char **envp)
|
||||
|
||||
atexit(qemu_run_exit_notifiers);
|
||||
error_set_progname(argv[0]);
|
||||
qemu_init_exec_dir(argv[0]);
|
||||
|
||||
g_mem_set_vtable(&mem_trace);
|
||||
if (!g_thread_supported()) {
|
||||
@ -3865,7 +3866,7 @@ int main(int argc, char **argv, char **envp)
|
||||
/* If no data_dir is specified then try to find it relative to the
|
||||
executable path. */
|
||||
if (data_dir_idx < ARRAY_SIZE(data_dir)) {
|
||||
data_dir[data_dir_idx] = os_find_datadir(argv[0]);
|
||||
data_dir[data_dir_idx] = os_find_datadir();
|
||||
if (data_dir[data_dir_idx] != NULL) {
|
||||
data_dir_idx++;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user