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, ...).
This commit is contained in:
parent
2393231e9a
commit
d6454414fd
|
@ -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 @@ SRCS+= linksyms_sun.c
|
|||
.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
|
||||
|
|
|
@ -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 @@ effect: Iff defined, export normal system call symbols from libc.
|
|||
|
||||
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))
|
||||
|
|
|
@ -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_lwpexit(void);
|
|||
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 @@ rump_daemonize_done(int error)
|
|||
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 @@ RUMP_COMPONENT(RUMP_COMPONENT_POSTINIT)
|
|||
asm("" :: "r"(__start_link_set_rump_components));
|
||||
asm("" :: "r"(__stop_link_set_rump_components));
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
rump_init(void)
|
||||
|
@ -694,9 +695,23 @@ static int compinited[RUMP_COMPONENT_MAX];
|
|||
*/
|
||||
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_addlocal(void)
|
|||
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 @@ rump_component_count(enum rump_component_type type)
|
|||
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 @@ rump_component_init(enum rump_component_type type)
|
|||
/*
|
||||
* 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)
|
||||
|
|
|
@ -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 @@ struct rump_component {
|
|||
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 @@ extern unsigned long rump_physmemlimit;
|
|||
|
||||
#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);
|
||||
|
||||
|
|
|
@ -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 @@ typedef struct module {
|
|||
* 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 @@ static const modinfo_t name##_modinfo = { \
|
|||
.mi_name = #name, \
|
||||
.mi_required = (required) \
|
||||
}; \
|
||||
__link_set_add_rodata(modules, name##_modinfo);
|
||||
_MODULE_REGISTER(name)
|
||||
|
||||
TAILQ_HEAD(modlist, module);
|
||||
|
||||
|
|
Loading…
Reference in New Issue