From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1M3WTE-00011Y-81 for qemu-devel@nongnu.org; Mon, 11 May 2009 10:27:08 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1M3WT9-0000y7-E1 for qemu-devel@nongnu.org; Mon, 11 May 2009 10:27:07 -0400 Received: from [199.232.76.173] (port=59242 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1M3WT9-0000y4-3q for qemu-devel@nongnu.org; Mon, 11 May 2009 10:27:03 -0400 Received: from e34.co.us.ibm.com ([32.97.110.152]:36819) by monty-python.gnu.org with esmtps (TLS-1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1M3WT8-00055B-JX for qemu-devel@nongnu.org; Mon, 11 May 2009 10:27:02 -0400 Received: from d03relay04.boulder.ibm.com (d03relay04.boulder.ibm.com [9.17.195.106]) by e34.co.us.ibm.com (8.13.1/8.13.1) with ESMTP id n4BEONsY031093 for ; Mon, 11 May 2009 08:24:23 -0600 Received: from d03av02.boulder.ibm.com (d03av02.boulder.ibm.com [9.17.195.168]) by d03relay04.boulder.ibm.com (8.13.8/8.13.8/NCO v9.2) with ESMTP id n4BEQqQ5060062 for ; Mon, 11 May 2009 08:26:54 -0600 Received: from d03av02.boulder.ibm.com (loopback [127.0.0.1]) by d03av02.boulder.ibm.com (8.12.11.20060308/8.13.3) with ESMTP id n4BEQpGK008374 for ; Mon, 11 May 2009 08:26:52 -0600 From: Anthony Liguori Date: Mon, 11 May 2009 09:26:46 -0500 Message-Id: <1242052009-27339-2-git-send-email-aliguori@us.ibm.com> In-Reply-To: <1242052009-27339-1-git-send-email-aliguori@us.ibm.com> References: <1242052009-27339-1-git-send-email-aliguori@us.ibm.com> Subject: [Qemu-devel] [PATCH 1/4] Add module infrastructure to QEMU List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Anthony Liguori , Paul Brook Signed-off-by: Anthony Liguori diff --git a/Makefile b/Makefile index 8649938..5c53801 100644 --- a/Makefile +++ b/Makefile @@ -63,7 +63,7 @@ recurse-all: $(SUBDIR_RULES) ####################################################################### # BLOCK_OBJS is code used by both qemu system emulation and qemu-img -BLOCK_OBJS=cutils.o cache-utils.o qemu-malloc.o +BLOCK_OBJS=cutils.o cache-utils.o qemu-malloc.o module.o BLOCK_OBJS+=block-cow.o block-qcow.o aes.o block-vmdk.o block-cloop.o BLOCK_OBJS+=block-dmg.o block-bochs.o block-vpc.o block-vvfat.o BLOCK_OBJS+=block-qcow2.o block-parallels.o block-nbd.o diff --git a/Makefile.target b/Makefile.target index fe83837..c08c6fd 100644 --- a/Makefile.target +++ b/Makefile.target @@ -340,14 +340,13 @@ ifeq ($(TARGET_ARCH), m68k) OBJS+= m68k-sim.o m68k-semi.o endif -OBJS+= libqemu.a - # Note: this is a workaround. The real fix is to avoid compiling # cpu_signal_handler() in cpu-exec.c. signal.o: CFLAGS += $(HELPER_CFLAGS) -$(QEMU_PROG): $(OBJS) ../libqemu_user.a - $(LINK) +$(QEMU_PROG): ARLIBS=../libqemu_user.a libqemu.a +$(QEMU_PROG): $(OBJS) ../libqemu_user.a libqemu.a + $(call LINK,$(OBJS)) ifeq ($(ARCH),alpha) # Mark as 32 bit binary, i. e. it will be mapped into the low 31 bit of # the address space (31 bit so sign extending doesn't matter) @@ -372,14 +371,13 @@ LIBS+=-lmx OBJS= main.o commpage.o machload.o mmap.o signal.o syscall.o thunk.o \ gdbstub.o gdbstub-xml.o -OBJS+= libqemu.a - # Note: this is a workaround. The real fix is to avoid compiling # cpu_signal_handler() in cpu-exec.c. signal.o: CFLAGS += $(HELPER_CFLAGS) -$(QEMU_PROG): $(OBJS) - $(LINK) +$(QEMU_PROG): ARLIBS=libqemu.a +$(QEMU_PROG): $(OBJS) libqemu.a + $(call LINK,$(OBJS)) endif #CONFIG_DARWIN_USER @@ -473,14 +471,13 @@ OBJS= main.o bsdload.o elfload.o mmap.o path.o signal.o strace.o syscall.o \ gdbstub.o gdbstub-xml.o OBJS+= uaccess.o -OBJS+= libqemu.a - # Note: this is a workaround. The real fix is to avoid compiling # cpu_signal_handler() in cpu-exec.c. signal.o: CFLAGS += $(HELPER_CFLAGS) -$(QEMU_PROG): $(OBJS) ../libqemu_user.a - $(LINK) +$(QEMU_PROG): ARLIBS=libqemu.a ../libqemu_user.a +$(QEMU_PROG): $(OBJS) libqemu.a ../libqemu_user.a + $(call LINK,$(OBJS)) endif #CONFIG_BSD_USER @@ -497,14 +494,6 @@ OBJS+=fw_cfg.o ifdef CONFIG_KVM OBJS+=kvm.o kvm-all.o endif -ifdef CONFIG_WIN32 -OBJS+=block-raw-win32.o -else -ifdef CONFIG_AIO -OBJS+=posix-aio-compat.o -endif -OBJS+=block-raw-posix.o -endif LIBS+=-lz ifdef CONFIG_ALSA @@ -724,9 +713,9 @@ endif vl.o: qemu-options.h $(QEMU_PROG): LIBS += $(SDL_LIBS) $(COCOA_LIBS) $(CURSES_LIBS) $(BRLAPI_LIBS) $(VDE_LIBS) - +$(QEMU_PROG): ARLIBS=../libqemu_common.a libqemu.a $(QEMU_PROG): $(OBJS) ../libqemu_common.a libqemu.a - $(LINK) + $(call LINK,$(OBJS)) endif # !CONFIG_USER_ONLY diff --git a/module.c b/module.c new file mode 100644 index 0000000..2db2dad --- /dev/null +++ b/module.c @@ -0,0 +1,137 @@ +/* + * QEMU Module Infrastructure + * + * Copyright IBM, Corp. 2009 + * + * Authors: + * Anthony Liguori + * + * This work is licensed under the terms of the GNU GPL, version 2. See + * the COPYING file in the top-level directory. + * + */ + +#include "qemu-common.h" +#include "sys-queue.h" +#include "module.h" + +typedef struct ModuleEntry +{ + int priority; + int is_init; + union { + int (*init)(void); + void (*exit)(void); + }; + TAILQ_ENTRY(ModuleEntry) node; +} ModuleEntry; + +typedef struct ModulePriorityList +{ + int priority; + TAILQ_HEAD(, ModuleEntry) entry_list; + TAILQ_ENTRY(ModulePriorityList) node; +} ModulePriorityList; + +static TAILQ_HEAD(, ModulePriorityList) priority_list; + +static ModulePriorityList *find_priority_or_alloc(int priority, int alloc) +{ + ModulePriorityList *n; + + TAILQ_FOREACH(n, &priority_list, node) { + if (priority >= n->priority) + break; + } + + if (!n || n->priority != priority) { + ModulePriorityList *o; + + if (!alloc) + return NULL; + + o = qemu_mallocz(sizeof(*o)); + o->priority = priority; + TAILQ_INIT(&o->entry_list); + + if (n) { + TAILQ_INSERT_AFTER(&priority_list, n, o, node); + } else { + TAILQ_INSERT_HEAD(&priority_list, o, node); + } + + n = o; + } + + return n; +} + +void register_module_init(int (*fn)(void), int priority) +{ + ModuleEntry *e; + ModulePriorityList *l; + + e = qemu_mallocz(sizeof(*e)); + e->is_init = 1; + e->init = fn; + + l = find_priority_or_alloc(priority, 1); + + TAILQ_INSERT_TAIL(&l->entry_list, e, node); +} + +void register_module_exit(void (*fn)(void), int priority) +{ + ModuleEntry *e; + ModulePriorityList *l; + + e = qemu_mallocz(sizeof(*e)); + e->is_init = 0; + e->exit = fn; + + l = find_priority_or_alloc(priority, 1); + + TAILQ_INSERT_TAIL(&l->entry_list, e, node); +} + +int module_call_init(int priority) +{ + ModulePriorityList *l; + ModuleEntry *e; + + l = find_priority_or_alloc(priority, 0); + if (!l) { + return 0; + } + + TAILQ_FOREACH(e, &l->entry_list, node) { + int ret; + + if (!e->is_init) { + continue; + } + + ret = e->init(); + if (ret != 0) + return ret; + } + + return 0; +} + +void module_call_exit(int priority) +{ + ModulePriorityList *l; + ModuleEntry *e; + + l = find_priority_or_alloc(priority, 0); + if (!l) { + return; + } + + TAILQ_FOREACH(e, &l->entry_list, node) { + if (!e->is_init) { + e->exit(); + } + } +} diff --git a/module.h b/module.h new file mode 100644 index 0000000..5aa3eaa --- /dev/null +++ b/module.h @@ -0,0 +1,41 @@ +/* + * QEMU Module Infrastructure + * + * Copyright IBM, Corp. 2009 + * + * Authors: + * Anthony Liguori + * + * This work is licensed under the terms of the GNU GPL, version 2. See + * the COPYING file in the top-level directory. + * + */ + +#ifndef QEMU_MODULE_H +#define QEMU_MODULE_H + +#define module_init(function, priority) \ +static void __attribute__((constructor)) qemu_init_ ## function(void) { \ + register_module_init(function, priority); \ +} + +#define module_exit(function, priority) \ +static void __attribute__((constructor)) qemu_exit_ ## function(void) { \ + register_module_exit(function, priority); \ +} + +#define MOD_PRI_HIGHEST 0 +#define MOD_PRI_BLOCK (MOD_PRI_HIGHEST + 1) + +#define block_init(function) module_init(function, MOD_PRI_BLOCK) +#define block_exit(function) module_exit(function, MOD_PRI_BLOCK) + +void register_module_init(int (*fn)(void), int priority); + +void register_module_exit(void (*fn)(void), int priority); + +int module_call_init(int priority); + +void module_call_exit(int priority); + +#endif diff --git a/rules.mak b/rules.mak index a75a93b..8471d40 100644 --- a/rules.mak +++ b/rules.mak @@ -8,10 +8,13 @@ %.o: %.m $(call quiet-command,$(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $<," OBJC $(TARGET_DIR)$@") -LINK = $(call quiet-command,$(CC) $(LDFLAGS) -o $@ $^ $(LIBS)," LINK $(TARGET_DIR)$@") +WAS=-Wl,--whole-archive +WAE=-Wl,--no-whole-archive + +LINK = $(call quiet-command,$(CC) $(LDFLAGS) -o $@ $(1) $(LIBS) $(WAS) $(ARLIBS) $(WAE)," LINK $(TARGET_DIR)$@") %$(EXESUF): %.o - $(LINK) + $(call LINK,$^) %.a: $(call quiet-command,rm -f $@ && $(AR) rcs $@ $^," AR $(TARGET_DIR)$@") -- 1.6.0.6