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:
pooka 2014-04-23 23:25:45 +00:00
parent 2393231e9a
commit d6454414fd
5 changed files with 97 additions and 20 deletions

View File

@ -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

View File

@ -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))

View File

@ -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)

View File

@ -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);

View File

@ -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);