Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys Add a RUMP_USE_CTOR compile-time switch. If defined, use



details:   https://anonhg.NetBSD.org/src/rev/5f9b580ef71d
branches:  trunk
changeset: 795670:5f9b580ef71d
user:      pooka <pooka%NetBSD.org@localhost>
date:      Wed Apr 23 23:25:45 2014 +0000

description:
Add a RUMP_USE_CTOR compile-time switch.  If defined, use
__attribute__((constructor)) to determine which rump kernel components
and kernel modules are linked into the rump kernel.  If not defined
(default), use the regular approach with link sets.

This option is aimed to fix problems with toolchains where using link
sets is not possible because the linker does not generate the requisite
__start/__stop symbols for the link set sections (e.g. GNU gold, OS X, ...).

diffstat:

 sys/rump/Makefile.rump                   |   4 ++-
 sys/rump/README.compileopts              |  12 +++++---
 sys/rump/librump/rumpkern/rump.c         |  42 ++++++++++++++++++++++++-------
 sys/rump/librump/rumpkern/rump_private.h |  27 +++++++++++++++++++-
 sys/sys/module.h                         |  32 ++++++++++++++++++++++-
 5 files changed, 97 insertions(+), 20 deletions(-)

diffs (262 lines):

diff -r e74bea7b0ce1 -r 5f9b580ef71d sys/rump/Makefile.rump
--- a/sys/rump/Makefile.rump    Wed Apr 23 23:17:22 2014 +0000
+++ b/sys/rump/Makefile.rump    Wed Apr 23 23:25:45 2014 +0000
@@ -1,4 +1,4 @@
-#      $NetBSD: Makefile.rump,v 1.95 2014/04/15 13:41:46 pooka Exp $
+#      $NetBSD: Makefile.rump,v 1.96 2014/04/23 23:25:45 pooka Exp $
 #
 
 .if !defined(_RUMP_MK)
@@ -51,6 +51,8 @@
 .PATH:         ${RUMPTOP}
 .elif ${RUMP_LDSCRIPT} == "GNU"
 LDFLAGS+=      -Wl,-T,${RUMPTOP}/ldscript.rump
+.elif ${RUMP_LDSCRIPT} == "ctor"
+CPPFLAGS+=     -DRUMP_USE_CTOR
 .else
 .error Unknown ldscript ${RUMP_LDSCRIPT}
 .endif
diff -r e74bea7b0ce1 -r 5f9b580ef71d sys/rump/README.compileopts
--- a/sys/rump/README.compileopts       Wed Apr 23 23:17:22 2014 +0000
+++ b/sys/rump/README.compileopts       Wed Apr 23 23:25:45 2014 +0000
@@ -1,4 +1,4 @@
-       $NetBSD: README.compileopts,v 1.3 2014/03/16 15:31:03 pooka Exp $
+       $NetBSD: README.compileopts,v 1.4 2014/04/23 23:25:45 pooka Exp $
 
 This file describes compile-time options for rump kernels.  Additionally,
 NetBSD build options will have an effect.  See src/share/mk/bsd.README
@@ -94,10 +94,12 @@
 
     RUMP_LDSCRIPT
 
-values: no/GNU/sun
+values: no/GNU/sun/ctor
 defval: GNU
 effect: Select the linker script to be used for linking rump kernel shared
        library components.
-       no  - do not use a linker script
-       GNU - use a linker script for GNU ld 2.18 and later
-       sun - use a linker script for the Solaris linker
+       no      - do not use a linker script
+       GNU     - use a linker script for GNU ld 2.18 and later
+       sun     - use a linker script for the Solaris linker
+       ctor    - do not use a linker script, make the code
+                 generate __attribute__((constructor))
diff -r e74bea7b0ce1 -r 5f9b580ef71d sys/rump/librump/rumpkern/rump.c
--- a/sys/rump/librump/rumpkern/rump.c  Wed Apr 23 23:17:22 2014 +0000
+++ b/sys/rump/librump/rumpkern/rump.c  Wed Apr 23 23:25:45 2014 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: rump.c,v 1.295 2014/04/23 16:17:55 pooka Exp $ */
+/*     $NetBSD: rump.c,v 1.296 2014/04/23 23:25:45 pooka Exp $ */
 
 /*
  * Copyright (c) 2007-2011 Antti Kantee.  All Rights Reserved.
@@ -26,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rump.c,v 1.295 2014/04/23 16:17:55 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rump.c,v 1.296 2014/04/23 23:25:45 pooka Exp $");
 
 #include <sys/systm.h>
 #define ELFSIZE ARCH_ELFSIZE
@@ -107,7 +107,6 @@
 static void rump_hyp_execnotify(const char *);
 
 static void rump_component_addlocal(void);
-static void rump_component_load(const struct rump_component *);
 static struct lwp *bootlwp;
 
 static char rump_msgbuf[16*1024]; /* 16k should be enough for std rump needs */
@@ -217,6 +216,7 @@
        return rumpuser_daemonize_done(error);
 }
 
+#ifndef RUMP_USE_CTOR
 RUMP_COMPONENT(RUMP_COMPONENT_POSTINIT)
 {
        __link_set_decl(rump_components, struct rump_component);
@@ -228,6 +228,7 @@
        asm("" :: "r"(__start_link_set_rump_components));
        asm("" :: "r"(__stop_link_set_rump_components));
 }
+#endif
 
 int
 rump_init(void)
@@ -694,9 +695,23 @@
  */
 static LIST_HEAD(, rump_component) rchead = LIST_HEAD_INITIALIZER(rchead);
 
-/*
- * add components which are visible from the current object.
- */
+#ifdef RUMP_USE_CTOR
+struct modinfo_boot_chain modinfo_boot_chain \
+    = LIST_HEAD_INITIALIZER(modinfo_boot_chain);
+
+static void
+rump_component_addlocal(void)
+{
+       struct modinfo_chain *mc;
+       
+       while ((mc = LIST_FIRST(&modinfo_boot_chain)) != NULL) {
+               LIST_REMOVE(mc, mc_entries);
+               module_builtin_add(&mc->mc_info, 1, false);
+       }
+}
+
+#else /* RUMP_USE_CTOR */
+
 static void
 rump_component_addlocal(void)
 {
@@ -707,8 +722,9 @@
                rump_component_load(*rc);
        }
 }
+#endif /* RUMP_USE_CTOR */
 
-static void
+void
 rump_component_load(const struct rump_component *rc_const)
 {
        struct rump_component *rc, *rc_iter;
@@ -746,13 +762,15 @@
 void
 rump_component_init(enum rump_component_type type)
 {
-       const struct rump_component *rc;
+       const struct rump_component *rc, *rc_safe;
 
        KASSERT(curlwp == bootlwp);
        KASSERT(!compinited[type]);
-       LIST_FOREACH(rc, &rchead, rc_entries) {
-               if (rc->rc_type == type)
+       LIST_FOREACH_SAFE(rc, &rchead, rc_entries, rc_safe) {
+               if (rc->rc_type == type) {
                        rc->rc_init();
+                       LIST_REMOVE(rc, rc_entries);
+               }
        }
        compinited[type] = 1;
 }
@@ -760,6 +778,10 @@
 /*
  * Initialize a module which has already been loaded and linked
  * with dlopen(). This is fundamentally the same as a builtin module.
+ *
+ * XXX: this interface does not really work in the RUMP_USE_CTOR case,
+ * but I'm not sure it's anything to cry about.  In feeling blue,
+ * things could somehow be handled via modinfo_boot_chain.
  */
 int
 rump_module_init(const struct modinfo * const *mip, size_t nmodinfo)
diff -r e74bea7b0ce1 -r 5f9b580ef71d sys/rump/librump/rumpkern/rump_private.h
--- a/sys/rump/librump/rumpkern/rump_private.h  Wed Apr 23 23:17:22 2014 +0000
+++ b/sys/rump/librump/rumpkern/rump_private.h  Wed Apr 23 23:25:45 2014 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: rump_private.h,v 1.82 2014/04/23 16:17:55 pooka Exp $  */
+/*     $NetBSD: rump_private.h,v 1.83 2014/04/23 23:25:45 pooka Exp $  */
 
 /*
  * Copyright (c) 2007-2011 Antti Kantee.  All Rights Reserved.
@@ -75,13 +75,35 @@
        void (*rc_init)(void);
        LIST_ENTRY(rump_component) rc_entries;
 };
+
+/*
+ * If RUMP_USE_CTOR is defined, we use __attribute__((constructor)) to
+ * determine which components are present when rump_init() is called.
+ * Otherwise, we use link sets and the __start/__stop symbols generated
+ * by the toolchain.
+ */
+
+#ifdef RUMP_USE_CTOR
+#define _RUMP_COMPONENT_REGISTER(type)                                 \
+static void rumpcomp_ctor##type(void) __attribute__((constructor));    \
+static void rumpcomp_ctor##type(void)                                  \
+{                                                                      \
+       rump_component_load(&rumpcomp##type);                           \
+}
+
+#else /* RUMP_USE_CTOR */
+
+#define _RUMP_COMPONENT_REGISTER(type)                                 \
+__link_set_add_rodata(rump_components, rumpcomp##type);
+#endif /* RUMP_USE_CTOR */
+
 #define RUMP_COMPONENT(type)                           \
 static void rumpcompinit##type(void);                  \
 static struct rump_component rumpcomp##type = {        \
        .rc_type = type,                                \
        .rc_init = rumpcompinit##type,                  \
 };                                                     \
-__link_set_add_rodata(rump_components, rumpcomp##type);        \
+_RUMP_COMPONENT_REGISTER(type)                         \
 static void rumpcompinit##type(void)
 
 #define FLAWLESSCALL(call)                                             \
@@ -96,6 +118,7 @@
 
 #define RUMP_LOCALPROC_P(p) (p->p_vmspace == vmspace_kernel())
 
+void           rump_component_load(const struct rump_component *);
 void           rump_component_init(enum rump_component_type);
 int            rump_component_count(enum rump_component_type);
 
diff -r e74bea7b0ce1 -r 5f9b580ef71d sys/sys/module.h
--- a/sys/sys/module.h  Wed Apr 23 23:17:22 2014 +0000
+++ b/sys/sys/module.h  Wed Apr 23 23:25:45 2014 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: module.h,v 1.34 2013/10/23 18:57:40 mbalmer Exp $      */
+/*     $NetBSD: module.h,v 1.35 2014/04/23 23:25:45 pooka Exp $        */
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -101,7 +101,35 @@
  * containing only one entry, pointing to the module's modinfo_t record.
  * For the kernel, `link_set_modules' can contain multiple entries and
  * records all modules built into the kernel at link time.
+ *
+ * Alternatively, in some environments rump kernels use
+ * __attribute__((constructor)) due to link sets being
+ * difficult (impossible?) to implement (e.g. GNU gold, OS X, etc.)
  */
+
+#ifdef RUMP_USE_CTOR
+struct modinfo_chain {
+       const struct modinfo    *mc_info;
+       LIST_ENTRY(modinfo_chain) mc_entries;
+};
+LIST_HEAD(modinfo_boot_chain, modinfo_chain);
+#define _MODULE_REGISTER(name)                                         \
+static void modctor_##name(void) __attribute__((constructor));         \
+static void modctor_##name(void)                                       \
+{                                                                      \
+       static struct modinfo_chain mc = {                              \
+               .mc_info = &name##_modinfo,                             \
+       };                                                              \
+       extern struct modinfo_boot_chain modinfo_boot_chain;            \
+       LIST_INSERT_HEAD(&modinfo_boot_chain, &mc, mc_entries);         \
+}
+
+#else /* RUMP_USE_CTOR */
+
+#define _MODULE_REGISTER(name) __link_set_add_rodata(modules, name##_modinfo);
+
+#endif /* RUMP_USE_CTOR */
+
 #define        MODULE(class, name, required)                           \
 static int name##_modcmd(modcmd_t, void *);                    \
 static const modinfo_t name##_modinfo = {                      \
@@ -111,7 +139,7 @@
        .mi_name = #name,                                       \
        .mi_required = (required)                               \
 };                                                             \
-__link_set_add_rodata(modules, name##_modinfo);
+_MODULE_REGISTER(name)
 
 TAILQ_HEAD(modlist, module);
 



Home | Main Index | Thread Index | Old Index