summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorpeter <peter@FreeBSD.org>2001-06-13 10:58:39 +0000
committerpeter <peter@FreeBSD.org>2001-06-13 10:58:39 +0000
commitf10fa038c14063eaf2da32ed734e644e5f569694 (patch)
tree88aef8097c80f09c2f725d61b6da4d433a595a61 /sys
parent2514663dd721b9ac234d35a4dac65dfc457ff6bc (diff)
downloadFreeBSD-src-f10fa038c14063eaf2da32ed734e644e5f569694.zip
FreeBSD-src-f10fa038c14063eaf2da32ed734e644e5f569694.tar.gz
With this commit, I hereby pronounce gensetdefs past its use-by date.
Replace the a.out emulation of 'struct linker_set' with something a little more flexible. <sys/linker_set.h> now provides macros for accessing elements and completely hides the implementation. The linker_set.h macros have been on the back burner in various forms since 1998 and has ideas and code from Mike Smith (SET_FOREACH()), John Polstra (ELF clue) and myself (cleaned up API and the conversion of the rest of the kernel to use it). The macros declare a strongly typed set. They return elements with the type that you declare the set with, rather than a generic void *. For ELF, we use the magic ld symbols (__start_<setname> and __stop_<setname>). Thanks to Richard Henderson <rth@redhat.com> for the trick about how to force ld to provide them for kld's. For a.out, we use the old linker_set struct. NOTE: the item lists are no longer null terminated. This is why the code impact is high in certain areas. The runtime linker has a new method to find the linker set boundaries depending on which backend format is in use. linker sets are still module/kld unfriendly and should never be used for anything that may be modular one day. Reviewed by: eivind
Diffstat (limited to 'sys')
-rw-r--r--sys/alpha/linux/linux.h3
-rw-r--r--sys/alpha/linux/linux_sysvec.c11
-rw-r--r--sys/compat/linux/linux_ioctl.c34
-rw-r--r--sys/conf/Makefile.alpha18
-rw-r--r--sys/conf/Makefile.i38618
-rw-r--r--sys/conf/Makefile.ia6419
-rw-r--r--sys/conf/Makefile.pc9818
-rw-r--r--sys/conf/Makefile.powerpc18
-rw-r--r--sys/conf/kmod.mk7
-rw-r--r--sys/ddb/db_command.c36
-rw-r--r--sys/dev/fb/fb.c15
-rw-r--r--sys/dev/fb/fbreg.h1
-rw-r--r--sys/dev/kbd/kbd.c14
-rw-r--r--sys/dev/kbd/kbdreg.h1
-rw-r--r--sys/dev/syscons/scgfbrndr.c2
-rw-r--r--sys/dev/syscons/scterm.c6
-rw-r--r--sys/dev/syscons/scvgarndr.c2
-rw-r--r--sys/dev/syscons/scvidctl.c6
-rw-r--r--sys/dev/syscons/syscons.h16
-rw-r--r--sys/fs/nwfs/nwfs_io.c2
-rw-r--r--sys/fs/nwfs/nwfs_node.c2
-rw-r--r--sys/fs/smbfs/smbfs_io.c2
-rw-r--r--sys/fs/smbfs/smbfs_node.c1
-rw-r--r--sys/i386/linux/linux.h3
-rw-r--r--sys/i386/linux/linux_sysvec.c11
-rw-r--r--sys/kern/init_main.c44
-rw-r--r--sys/kern/kern_ktr.c1
-rw-r--r--sys/kern/kern_linker.c190
-rw-r--r--sys/kern/kern_sysctl.c27
-rw-r--r--sys/kern/link_aout.c39
-rw-r--r--sys/kern/link_elf.c61
-rw-r--r--sys/kern/link_elf_obj.c61
-rw-r--r--sys/kern/linker_if.m14
-rw-r--r--sys/kern/tty_cons.c5
-rw-r--r--sys/netncp/ncp_conn.c2
-rw-r--r--sys/netsmb/smb_conn.c2
-rw-r--r--sys/pc98/cbus/scgdcrndr.c2
-rw-r--r--sys/pc98/pc98/scgdcrndr.c2
-rw-r--r--sys/sys/cons.h1
-rw-r--r--sys/sys/kernel.h2
-rw-r--r--sys/sys/linker.h8
-rw-r--r--sys/sys/linker_set.h124
-rw-r--r--sys/sys/sysctl.h6
43 files changed, 470 insertions, 387 deletions
diff --git a/sys/alpha/linux/linux.h b/sys/alpha/linux/linux.h
index a11baaa..af3f3ac 100644
--- a/sys/alpha/linux/linux.h
+++ b/sys/alpha/linux/linux.h
@@ -238,7 +238,6 @@ struct linux_sigframe {
/*
* Pluggable ioctl handlers
*/
-struct linker_set;
struct linux_ioctl_args;
struct proc;
@@ -250,9 +249,7 @@ struct linux_ioctl_handler {
};
int linux_ioctl_register_handler(struct linux_ioctl_handler *h);
-int linux_ioctl_register_handlers(struct linker_set *s);
int linux_ioctl_unregister_handler(struct linux_ioctl_handler *h);
-int linux_ioctl_unregister_handlers(struct linker_set *s);
/*
* open/fcntl flags
diff --git a/sys/alpha/linux/linux_sysvec.c b/sys/alpha/linux/linux_sysvec.c
index f0b1249..6f93dc8 100644
--- a/sys/alpha/linux/linux_sysvec.c
+++ b/sys/alpha/linux/linux_sysvec.c
@@ -77,7 +77,7 @@ MALLOC_DEFINE(M_LINUX, "linux", "Linux mode structures");
#define SHELLMAGIC 0x2321
#endif
-extern struct linker_set linux_ioctl_handler_set;
+SET_DECLARE(linux_ioctl_handler_set, struct linux_ioctl_handler);
void osendsig(sig_t catcher, int sig, sigset_t *mask, u_long code);
@@ -221,6 +221,7 @@ linux_elf_modevent(module_t mod, int type, void *data)
{
Elf64_Brandinfo **brandinfo;
int error;
+ struct linux_ioctl_handler **lihp;
error = 0;
@@ -231,8 +232,8 @@ linux_elf_modevent(module_t mod, int type, void *data)
if (elf_insert_brand_entry(*brandinfo) < 0)
error = EINVAL;
if (error == 0) {
- linux_ioctl_register_handlers(
- &linux_ioctl_handler_set);
+ SET_FOREACH(lihp, linux_ioctl_handler_set)
+ linux_ioctl_register_handler(*lihp);
if (bootverbose)
printf("Linux ELF exec handler installed\n");
} else
@@ -250,8 +251,8 @@ linux_elf_modevent(module_t mod, int type, void *data)
error = EINVAL;
}
if (error == 0) {
- linux_ioctl_unregister_handlers(
- &linux_ioctl_handler_set);
+ SET_FOREACH(lihp, linux_ioctl_handler_set)
+ linux_ioctl_unregister_handler(*lihp);
if (bootverbose)
printf("Linux ELF exec handler removed\n");
} else
diff --git a/sys/compat/linux/linux_ioctl.c b/sys/compat/linux/linux_ioctl.c
index 1cf76cf..3b14eb2 100644
--- a/sys/compat/linux/linux_ioctl.c
+++ b/sys/compat/linux/linux_ioctl.c
@@ -1516,37 +1516,3 @@ linux_ioctl_unregister_handler(struct linux_ioctl_handler *h)
return (EINVAL);
}
-
-int
-linux_ioctl_register_handlers(struct linker_set *s)
-{
- int error, i;
-
- if (s == NULL)
- return (EINVAL);
-
- for (i = 0; i < s->ls_length; i++) {
- error = linux_ioctl_register_handler(s->ls_items[i]);
- if (error)
- return (error);
- }
-
- return (0);
-}
-
-int
-linux_ioctl_unregister_handlers(struct linker_set *s)
-{
- int error, i;
-
- if (s == NULL)
- return (EINVAL);
-
- for (i = 0; i < s->ls_length; i++) {
- error = linux_ioctl_unregister_handler(s->ls_items[i]);
- if (error)
- return (error);
- }
-
- return (0);
-}
diff --git a/sys/conf/Makefile.alpha b/sys/conf/Makefile.alpha
index eb79ab7..5f02ae8 100644
--- a/sys/conf/Makefile.alpha
+++ b/sys/conf/Makefile.alpha
@@ -88,15 +88,10 @@ NORMAL_M= perl5 $S/kern/makeobjops.pl -c $<; \
${CC} -c ${CFLAGS} ${PROF} ${.PREFIX}.c
GEN_CFILES= $S/$M/$M/genassym.c
-# setdef0.c and setdef1.c are intentionally
-# omitted from SYSTEM_CFILES. They include setdefs.h, a header which
-# is generated from all of ${OBJS}. We don't want to have to compile
-# everything just to do a make depend.
SYSTEM_CFILES= param.c vnode_if.c hints.c config.c
SYSTEM_SFILES= $S/$M/$M/locore.s
SYSTEM_DEP= Makefile ${SYSTEM_OBJS}
-SYSTEM_OBJS= locore.o setdef0.o vnode_if.o ${OBJS} param.o hints.o config.o \
- setdef1.o hack.So
+SYSTEM_OBJS= locore.o vnode_if.o ${OBJS} param.o hints.o config.o hack.So
SYSTEM_LD= @${LD} ${FMT} -Bdynamic -T $S/conf/ldscript.$M \
-e locorestart \
-export-dynamic -dynamic-linker /red/herring \
@@ -181,17 +176,6 @@ hack.So: Makefile
${CC} ${FMT} -shared -nostdlib hack.c -o hack.So
rm -f hack.c
-.ORDER: setdefs.h setdef0.c setdef1.c
-
-setdef0.o: setdef0.c setdefs.h
- ${NORMAL_C}
-
-setdef1.o: setdef1.c setdefs.h
- ${NORMAL_C}
-
-setdef0.c setdef1.c setdefs.h: Makefile ${OBJS}
- @perl5 $S/kern/gensetdefs.pl ${OBJS}
-
# this rule stops ./assym.s in .depend from causing problems
./assym.s: assym.s
diff --git a/sys/conf/Makefile.i386 b/sys/conf/Makefile.i386
index ec4b719..7e70fd1 100644
--- a/sys/conf/Makefile.i386
+++ b/sys/conf/Makefile.i386
@@ -91,15 +91,10 @@ NORMAL_M= perl5 $S/kern/makeobjops.pl -c $<; \
${CC} -c ${CFLAGS} ${PROF} ${.PREFIX}.c
GEN_CFILES= $S/$M/$M/genassym.c
-# setdef0.c and setdef1.c are intentionally
-# omitted from SYSTEM_CFILES. They include setdefs.h, a header which
-# is generated from all of ${OBJS}. We don't want to have to compile
-# everything just to do a make depend.
SYSTEM_CFILES= param.c vnode_if.c hints.c config.c
SYSTEM_SFILES= $S/$M/$M/locore.s
SYSTEM_DEP= Makefile ${SYSTEM_OBJS}
-SYSTEM_OBJS= locore.o setdef0.o vnode_if.o ${OBJS} param.o hints.o config.o \
- setdef1.o hack.So
+SYSTEM_OBJS= locore.o vnode_if.o ${OBJS} param.o hints.o config.o hack.So
SYSTEM_LD= @${LD} ${FMT} -Bdynamic -T $S/conf/ldscript.$M \
-export-dynamic -dynamic-linker /red/herring \
-o ${.TARGET} -X ${SYSTEM_OBJS} vers.o
@@ -184,17 +179,6 @@ hack.So: Makefile
${CC} ${FMT} -shared -nostdlib hack.c -o hack.So
rm -f hack.c
-.ORDER: setdefs.h setdef0.c setdef1.c
-
-setdef0.o: setdef0.c setdefs.h
- ${NORMAL_C}
-
-setdef1.o: setdef1.c setdefs.h
- ${NORMAL_C}
-
-setdef0.c setdef1.c setdefs.h: Makefile ${OBJS}
- @perl5 $S/kern/gensetdefs.pl ${OBJS}
-
# this rule stops ./assym.s in .depend from causing problems
./assym.s: assym.s
diff --git a/sys/conf/Makefile.ia64 b/sys/conf/Makefile.ia64
index 174c727..e52be5d 100644
--- a/sys/conf/Makefile.ia64
+++ b/sys/conf/Makefile.ia64
@@ -101,15 +101,11 @@ NORMAL_M= perl5 $S/kern/makeobjops.pl -c $<; \
${CC} -c ${CFLAGS} ${PROF} ${.PREFIX}.c
GEN_CFILES= $S/$M/$M/genassym.c
-# setdef0.c and setdef1.c are intentionally
-# omitted from SYSTEM_CFILES. They include setdefs.h, a header which
-# is generated from all of ${OBJS}. We don't want to have to compile
-# everything just to do a make depend.
SYSTEM_CFILES= param.c vnode_if.c hints.c config.c
SYSTEM_SFILES= $S/$M/$M/locore.s
SYSTEM_DEP= Makefile ${SYSTEM_OBJS}
-SYSTEM_OBJS= locore.o setdef0.o vnode_if.o ${OBJS} param.o hints.o config.o \
- setdef1.o # hack.So ski can't cope with dynamic relocs
+SYSTEM_OBJS= locore.o vnode_if.o ${OBJS} param.o hints.o config.o \
+ # hack.So ski can't cope with dynamic relocs
SYSTEM_LD= @${LD} ${FMT} -Bdynamic -T $S/conf/ldscript.$M \
-e locorestart \
-export-dynamic -dynamic-linker /red/herring \
@@ -188,17 +184,6 @@ hack.So: Makefile
${CC} ${FMT} -shared -nostdlib hack.c -o hack.So
rm -f hack.c
-.ORDER: setdefs.h setdef0.c setdef1.c
-
-setdef0.o: setdef0.c setdefs.h
- ${NORMAL_C}
-
-setdef1.o: setdef1.c setdefs.h
- ${NORMAL_C}
-
-setdef0.c setdef1.c setdefs.h: Makefile ${OBJS}
- @OBJDUMP=${OBJDUMP} perl5 $S/kern/gensetdefs.pl ${OBJS}
-
# this rule stops ./assym.s in .depend from causing problems
./assym.s: assym.s
diff --git a/sys/conf/Makefile.pc98 b/sys/conf/Makefile.pc98
index f194f87..a3a9f56 100644
--- a/sys/conf/Makefile.pc98
+++ b/sys/conf/Makefile.pc98
@@ -93,15 +93,10 @@ NORMAL_M= perl5 $S/kern/makeobjops.pl -c $<; \
${CC} -c ${CFLAGS} ${PROF} ${.PREFIX}.c
GEN_CFILES= $S/$M/$M/genassym.c
-# setdef0.c and setdef1.c are intentionally
-# omitted from SYSTEM_CFILES. They include setdefs.h, a header which
-# is generated from all of ${OBJS}. We don't want to have to compile
-# everything just to do a make depend.
SYSTEM_CFILES= param.c vnode_if.c hints.c config.c
SYSTEM_SFILES= $S/$M/$M/locore.s
SYSTEM_DEP= Makefile ${SYSTEM_OBJS}
-SYSTEM_OBJS= locore.o setdef0.o vnode_if.o ${OBJS} param.o hints.o config.o \
- setdef1.o hack.So
+SYSTEM_OBJS= locore.o vnode_if.o ${OBJS} param.o hints.o config.o hack.So
SYSTEM_LD= @${LD} ${FMT} -Bdynamic -T $S/conf/ldscript.$M \
-export-dynamic -dynamic-linker /red/herring \
-o ${.TARGET} -X ${SYSTEM_OBJS} vers.o
@@ -186,17 +181,6 @@ hack.So: Makefile
${CC} ${FMT} -shared -nostdlib hack.c -o hack.So
rm -f hack.c
-.ORDER: setdefs.h setdef0.c setdef1.c
-
-setdef0.o: setdef0.c setdefs.h
- ${NORMAL_C}
-
-setdef1.o: setdef1.c setdefs.h
- ${NORMAL_C}
-
-setdef0.c setdef1.c setdefs.h: Makefile ${OBJS}
- @perl5 $S/kern/gensetdefs.pl ${OBJS}
-
# this rule stops ./assym.s in .depend from causing problems
./assym.s: assym.s
diff --git a/sys/conf/Makefile.powerpc b/sys/conf/Makefile.powerpc
index ec4b719..7e70fd1 100644
--- a/sys/conf/Makefile.powerpc
+++ b/sys/conf/Makefile.powerpc
@@ -91,15 +91,10 @@ NORMAL_M= perl5 $S/kern/makeobjops.pl -c $<; \
${CC} -c ${CFLAGS} ${PROF} ${.PREFIX}.c
GEN_CFILES= $S/$M/$M/genassym.c
-# setdef0.c and setdef1.c are intentionally
-# omitted from SYSTEM_CFILES. They include setdefs.h, a header which
-# is generated from all of ${OBJS}. We don't want to have to compile
-# everything just to do a make depend.
SYSTEM_CFILES= param.c vnode_if.c hints.c config.c
SYSTEM_SFILES= $S/$M/$M/locore.s
SYSTEM_DEP= Makefile ${SYSTEM_OBJS}
-SYSTEM_OBJS= locore.o setdef0.o vnode_if.o ${OBJS} param.o hints.o config.o \
- setdef1.o hack.So
+SYSTEM_OBJS= locore.o vnode_if.o ${OBJS} param.o hints.o config.o hack.So
SYSTEM_LD= @${LD} ${FMT} -Bdynamic -T $S/conf/ldscript.$M \
-export-dynamic -dynamic-linker /red/herring \
-o ${.TARGET} -X ${SYSTEM_OBJS} vers.o
@@ -184,17 +179,6 @@ hack.So: Makefile
${CC} ${FMT} -shared -nostdlib hack.c -o hack.So
rm -f hack.c
-.ORDER: setdefs.h setdef0.c setdef1.c
-
-setdef0.o: setdef0.c setdefs.h
- ${NORMAL_C}
-
-setdef1.o: setdef1.c setdefs.h
- ${NORMAL_C}
-
-setdef0.c setdef1.c setdefs.h: Makefile ${OBJS}
- @perl5 $S/kern/gensetdefs.pl ${OBJS}
-
# this rule stops ./assym.s in .depend from causing problems
./assym.s: assym.s
diff --git a/sys/conf/kmod.mk b/sys/conf/kmod.mk
index 7b1f7c8..54f5bff 100644
--- a/sys/conf/kmod.mk
+++ b/sys/conf/kmod.mk
@@ -132,14 +132,7 @@ PROG= ${KMOD}.ko
.endif
${PROG}: ${KMOD}.kld
-.if ${OBJFORMAT} == elf
- perl5 @/kern/gensetdefs.pl ${KMOD}.kld
- ${CC} ${CFLAGS} -c setdef0.c
- ${CC} ${CFLAGS} -c setdef1.c
- ${LD} -Bshareable ${LDFLAGS} -o ${.TARGET} setdef0.o ${KMOD}.kld setdef1.o
-.else
${LD} -Bshareable ${LDFLAGS} -o ${.TARGET} ${KMOD}.kld
-.endif
${KMOD}.kld: ${OBJS}
${LD} ${LDFLAGS} -r -o ${.TARGET} ${OBJS}
diff --git a/sys/ddb/db_command.c b/sys/ddb/db_command.c
index 201d1f1..39378e9 100644
--- a/sys/ddb/db_command.c
+++ b/sys/ddb/db_command.c
@@ -51,13 +51,14 @@
* Exported global variables
*/
boolean_t db_cmd_loop_done;
-extern struct linker_set db_cmd_set;
db_addr_t db_dot;
jmp_buf db_jmpbuf;
db_addr_t db_last_addr;
db_addr_t db_prev;
db_addr_t db_next;
-extern struct linker_set db_show_cmd_set;
+
+SET_DECLARE(db_cmd_set, struct command);
+SET_DECLARE(db_show_cmd_set, struct command);
static db_cmdfcn_t db_fncall;
static db_cmdfcn_t db_gdb;
@@ -94,22 +95,26 @@ db_skip_to_eol()
#define CMD_HELP 4
static void db_cmd_list __P((struct command *table,
- struct command **aux_tablep));
+ struct command **aux_tablep,
+ struct command **aux_tablep_end));
static int db_cmd_search __P((char *name, struct command *table,
struct command **aux_tablep,
+ struct command **aux_tablep_end,
struct command **cmdp));
static void db_command __P((struct command **last_cmdp,
struct command *cmd_table,
- struct command **aux_cmd_tablep));
+ struct command **aux_cmd_tablep,
+ struct command **aux_cmd_tablep_end));
/*
* Search for command prefix.
*/
static int
-db_cmd_search(name, table, aux_tablep, cmdp)
+db_cmd_search(name, table, aux_tablep, aux_tablep_end, cmdp)
char * name;
struct command *table;
struct command **aux_tablep;
+ struct command **aux_tablep_end;
struct command **cmdp; /* out */
{
struct command *cmd;
@@ -148,7 +153,7 @@ db_cmd_search(name, table, aux_tablep, cmdp)
}
if (result == CMD_NONE && aux_tablep != 0)
/* XXX repeat too much code. */
- for (aux_cmdp = aux_tablep; *aux_cmdp != 0; aux_cmdp++) {
+ for (aux_cmdp = aux_tablep; aux_cmdp < aux_tablep_end; aux_cmdp++) {
register char *lp;
register char *rp;
register int c;
@@ -188,9 +193,10 @@ db_cmd_search(name, table, aux_tablep, cmdp)
}
static void
-db_cmd_list(table, aux_tablep)
+db_cmd_list(table, aux_tablep, aux_tablep_end)
struct command *table;
struct command **aux_tablep;
+ struct command **aux_tablep_end;
{
register struct command *cmd;
register struct command **aux_cmdp;
@@ -201,17 +207,18 @@ db_cmd_list(table, aux_tablep)
}
if (aux_tablep == 0)
return;
- for (aux_cmdp = aux_tablep; *aux_cmdp != 0; aux_cmdp++) {
+ for (aux_cmdp = aux_tablep; aux_cmdp < aux_tablep_end; aux_cmdp++) {
db_printf("%-12s", (*aux_cmdp)->name);
db_end_line();
}
}
static void
-db_command(last_cmdp, cmd_table, aux_cmd_tablep)
+db_command(last_cmdp, cmd_table, aux_cmd_tablep, aux_cmd_tablep_end)
struct command **last_cmdp; /* IN_OUT */
struct command *cmd_table;
struct command **aux_cmd_tablep;
+ struct command **aux_cmd_tablep_end;
{
struct command *cmd;
int t;
@@ -246,6 +253,7 @@ db_command(last_cmdp, cmd_table, aux_cmd_tablep)
result = db_cmd_search(db_tok_string,
cmd_table,
aux_cmd_tablep,
+ aux_cmd_tablep_end,
&cmd);
switch (result) {
case CMD_NONE:
@@ -257,7 +265,7 @@ db_command(last_cmdp, cmd_table, aux_cmd_tablep)
db_flush_lex();
return;
case CMD_HELP:
- db_cmd_list(cmd_table, aux_cmd_tablep);
+ db_cmd_list(cmd_table, aux_cmd_tablep, aux_cmd_tablep_end);
db_flush_lex();
return;
default:
@@ -267,12 +275,12 @@ db_command(last_cmdp, cmd_table, aux_cmd_tablep)
/* XXX usually no more aux's. */
aux_cmd_tablep = 0;
if (cmd_table == db_show_cmds)
- aux_cmd_tablep =
- (struct command **)&db_show_cmd_set.ls_items[0];
+ aux_cmd_tablep = SET_BEGIN(db_show_cmd_set);
+ aux_cmd_tablep_end = SET_LIMIT(db_show_cmd_set);
t = db_read_token();
if (t != tIDENT) {
- db_cmd_list(cmd_table, aux_cmd_tablep);
+ db_cmd_list(cmd_table, aux_cmd_tablep, aux_cmd_tablep_end);
db_flush_lex();
return;
}
@@ -453,7 +461,7 @@ db_command_loop()
(void) db_read_line();
db_command(&db_last_command, db_command_table,
- (struct command **)&db_cmd_set.ls_items[0]);
+ SET_BEGIN(db_cmd_set), SET_LIMIT(db_cmd_set));
}
}
diff --git a/sys/dev/fb/fb.c b/sys/dev/fb/fb.c
index 3d92761..056988d 100644
--- a/sys/dev/fb/fb.c
+++ b/sys/dev/fb/fb.c
@@ -39,12 +39,15 @@
#include <sys/module.h>
#include <sys/uio.h>
#include <sys/fbio.h>
+#include <sys/linker_set.h>
#include <vm/vm.h>
#include <vm/pmap.h>
#include <dev/fb/fbreg.h>
+SET_DECLARE(videodriver_set, const video_driver_t);
+
/* local arrays */
/*
@@ -160,8 +163,8 @@ vid_register(video_adapter_t *adp)
adp->va_index = index;
adp->va_token = NULL;
- list = (const video_driver_t **)videodriver_set.ls_items;
- while ((p = *list++) != NULL) {
+ SET_FOREACH(list, videodriver_set) {
+ p = *list;
if (strcmp(p->name, adp->va_name) == 0) {
adapter[index] = adp;
vidsw[index] = p->vidsw;
@@ -192,8 +195,8 @@ video_switch_t
const video_driver_t **list;
const video_driver_t *p;
- list = (const video_driver_t **)videodriver_set.ls_items;
- while ((p = *list++) != NULL) {
+ SET_FOREACH(list, videodriver_set) {
+ p = *list;
if (strcmp(p->name, name) == 0)
return p->vidsw;
}
@@ -281,8 +284,8 @@ vid_configure(int flags)
const video_driver_t **list;
const video_driver_t *p;
- list = (const video_driver_t **)videodriver_set.ls_items;
- while ((p = *list++) != NULL) {
+ SET_FOREACH(list, videodriver_set) {
+ p = *list;
if (p->configure != NULL)
(*p->configure)(flags);
}
diff --git a/sys/dev/fb/fbreg.h b/sys/dev/fb/fbreg.h
index 7070f19..ba6c0e1 100644
--- a/sys/dev/fb/fbreg.h
+++ b/sys/dev/fb/fbreg.h
@@ -148,7 +148,6 @@ typedef struct video_driver {
/* global variables */
extern struct video_switch **vidsw;
-extern struct linker_set videodriver_set;
/* functions for the video card driver */
int vid_register(video_adapter_t *adp);
diff --git a/sys/dev/kbd/kbd.c b/sys/dev/kbd/kbd.c
index 8ebba7e..ce55b65 100644
--- a/sys/dev/kbd/kbd.c
+++ b/sys/dev/kbd/kbd.c
@@ -54,6 +54,8 @@ typedef struct genkbd_softc {
static SLIST_HEAD(, keyboard_driver) keyboard_drivers =
SLIST_HEAD_INITIALIZER(keyboard_drivers);
+SET_DECLARE(kbddriver_set, const keyboard_driver_t);
+
/* local arrays */
/*
@@ -199,8 +201,8 @@ kbd_register(keyboard_t *kbd)
return index;
}
}
- list = (const keyboard_driver_t **)kbddriver_set.ls_items;
- while ((p = *list++) != NULL) {
+ SET_FOREACH(list, kbddriver_set) {
+ p = *list;
if (strcmp(p->name, kbd->kb_name) == 0) {
keyboard[index] = kbd;
kbdsw[index] = p->kbdsw;
@@ -254,8 +256,8 @@ keyboard_switch_t
if (strcmp(p->name, driver) == 0)
return p->kbdsw;
}
- list = (const keyboard_driver_t **)kbddriver_set.ls_items;
- while ((p = *list++) != NULL) {
+ SET_FOREACH(list, kbddriver_set) {
+ p = *list;
if (strcmp(p->name, driver) == 0)
return p->kbdsw;
}
@@ -393,8 +395,8 @@ kbd_configure(int flags)
if (p->configure != NULL)
(*p->configure)(flags);
}
- list = (const keyboard_driver_t **)kbddriver_set.ls_items;
- while ((p = *list++) != NULL) {
+ SET_FOREACH(list, kbddriver_set) {
+ p = *list;
if (p->configure != NULL)
(*p->configure)(flags);
}
diff --git a/sys/dev/kbd/kbdreg.h b/sys/dev/kbd/kbdreg.h
index de7d941..55e0cef 100644
--- a/sys/dev/kbd/kbdreg.h
+++ b/sys/dev/kbd/kbdreg.h
@@ -173,7 +173,6 @@ typedef struct keyboard_driver {
/* global variables */
extern keyboard_switch_t **kbdsw;
-extern struct linker_set kbddriver_set;
/* functions for the keyboard driver */
int kbd_add_driver(keyboard_driver_t *driver);
diff --git a/sys/dev/syscons/scgfbrndr.c b/sys/dev/syscons/scgfbrndr.c
index 85c4418..6767610 100644
--- a/sys/dev/syscons/scgfbrndr.c
+++ b/sys/dev/syscons/scgfbrndr.c
@@ -80,8 +80,6 @@ static vr_draw_border_t vga_grborder;
static void vga_nop(scr_stat *scp, ...);
-static struct linker_set vga_set;
-
static sc_rndr_sw_t txtrndrsw = {
vga_txtclear,
vga_txtborder,
diff --git a/sys/dev/syscons/scterm.c b/sys/dev/syscons/scterm.c
index 99fad98..5b9c2f4 100644
--- a/sys/dev/syscons/scterm.c
+++ b/sys/dev/syscons/scterm.c
@@ -36,6 +36,8 @@
#include <dev/syscons/syscons.h>
#include <dev/syscons/sctermvar.h>
+SET_DECLARE(scterm_set, sc_term_sw_t);
+
/* exported subroutines */
void
@@ -95,8 +97,8 @@ sc_term_sw_t
}
}
} else {
- list = (sc_term_sw_t **)scterm_set.ls_items;
- while ((p = *list++) != NULL) {
+ SET_FOREACH(list, scterm_set) {
+ p = *list;
if ((strcmp(name, p->te_name) == 0)
|| (strcmp(name, "*") == 0)) {
return p;
diff --git a/sys/dev/syscons/scvgarndr.c b/sys/dev/syscons/scvgarndr.c
index 85c4418..6767610 100644
--- a/sys/dev/syscons/scvgarndr.c
+++ b/sys/dev/syscons/scvgarndr.c
@@ -80,8 +80,6 @@ static vr_draw_border_t vga_grborder;
static void vga_nop(scr_stat *scp, ...);
-static struct linker_set vga_set;
-
static sc_rndr_sw_t txtrndrsw = {
vga_txtclear,
vga_txtborder,
diff --git a/sys/dev/syscons/scvidctl.c b/sys/dev/syscons/scvidctl.c
index be9d1e6..72dc7db 100644
--- a/sys/dev/syscons/scvidctl.c
+++ b/sys/dev/syscons/scvidctl.c
@@ -40,6 +40,8 @@
#include <dev/fb/fbreg.h>
#include <dev/syscons/syscons.h>
+SET_DECLARE(scrndr_set, const sc_renderer_t);
+
/* for compatibility with previous versions */
/* 3.0-RELEASE used the following structure */
typedef struct old_video_adapter {
@@ -803,8 +805,8 @@ sc_rndr_sw_t
}
}
} else {
- list = (const sc_renderer_t **)scrndr_set.ls_items;
- while ((p = *list++) != NULL) {
+ SET_FOREACH(list, scrndr_set) {
+ p = *list;
if ((strcmp(p->name, name) == 0)
&& (mode == p->mode)) {
scp->status &=
diff --git a/sys/dev/syscons/syscons.h b/sys/dev/syscons/syscons.h
index d2d605d..ef10f4d 100644
--- a/sys/dev/syscons/syscons.h
+++ b/sys/dev/syscons/syscons.h
@@ -342,8 +342,6 @@ typedef struct sc_term_sw {
sc_term_input_t *te_input;
} sc_term_sw_t;
-extern struct linker_set scterm_set;
-
#define SCTERM_MODULE(name, sw) \
DATA_SET(scterm_set, sw); \
static int \
@@ -398,8 +396,6 @@ typedef struct sc_renderer {
LIST_ENTRY(sc_renderer) link;
} sc_renderer_t;
-extern struct linker_set scrndr_set;
-
#define RENDERER(name, mode, sw, set) \
static struct sc_renderer scrndr_##name##_##mode## = { \
#name, mode, &sw \
@@ -408,25 +404,23 @@ extern struct linker_set scrndr_set;
DATA_SET(set, scrndr_##name##_##mode##)
#define RENDERER_MODULE(name, set) \
+ SET_DECLARE(set, sc_renderer_t); \
static int \
scrndr_##name##_event(module_t mod, int type, void *data) \
{ \
sc_renderer_t **list; \
- sc_renderer_t *p; \
int error = 0; \
switch (type) { \
case MOD_LOAD: \
- list = (sc_renderer_t **)set.ls_items; \
- while ((p = *list++) != NULL) { \
- error = sc_render_add(p); \
+ SET_FOREACH(list, set) { \
+ error = sc_render_add(*list); \
if (error) \
break; \
} \
break; \
case MOD_UNLOAD: \
- list = (sc_renderer_t **)set.ls_items; \
- while ((p = *list++) != NULL) { \
- error = sc_render_remove(p); \
+ SET_FOREACH(list, set) { \
+ error = sc_render_remove(*list);\
if (error) \
break; \
} \
diff --git a/sys/fs/nwfs/nwfs_io.c b/sys/fs/nwfs/nwfs_io.c
index 8e73cf0..0529158 100644
--- a/sys/fs/nwfs/nwfs_io.c
+++ b/sys/fs/nwfs/nwfs_io.c
@@ -64,8 +64,6 @@
static int nwfs_fastlookup = 1;
-extern struct linker_set sysctl_vfs_nwfs;
-
SYSCTL_DECL(_vfs_nwfs);
SYSCTL_INT(_vfs_nwfs, OID_AUTO, fastlookup, CTLFLAG_RW, &nwfs_fastlookup, 0, "");
diff --git a/sys/fs/nwfs/nwfs_node.c b/sys/fs/nwfs/nwfs_node.c
index 0700b76..c708e1d 100644
--- a/sys/fs/nwfs/nwfs_node.c
+++ b/sys/fs/nwfs/nwfs_node.c
@@ -71,8 +71,6 @@ MALLOC_DEFINE(M_NWFSHASH, "NWFS hash", "NWFS has table");
static int nwfs_sysctl_vnprint(SYSCTL_HANDLER_ARGS);
-extern struct linker_set sysctl_vfs_nwfs;
-
SYSCTL_DECL(_vfs_nwfs);
SYSCTL_PROC(_vfs_nwfs, OID_AUTO, vnprint, CTLFLAG_WR|CTLTYPE_OPAQUE,
diff --git a/sys/fs/smbfs/smbfs_io.c b/sys/fs/smbfs/smbfs_io.c
index 3913f1a..1033e8e 100644
--- a/sys/fs/smbfs/smbfs_io.c
+++ b/sys/fs/smbfs/smbfs_io.c
@@ -73,8 +73,6 @@ extern int smbfs_pbuf_freecnt;
static int smbfs_fastlookup = 1;
-extern struct linker_set sysctl_vfs_smbfs;
-
SYSCTL_DECL(_vfs_smbfs);
SYSCTL_INT(_vfs_smbfs, OID_AUTO, fastlookup, CTLFLAG_RW, &smbfs_fastlookup, 0, "");
diff --git a/sys/fs/smbfs/smbfs_node.c b/sys/fs/smbfs/smbfs_node.c
index 35be6a3..cd8ffe9 100644
--- a/sys/fs/smbfs/smbfs_node.c
+++ b/sys/fs/smbfs/smbfs_node.c
@@ -69,7 +69,6 @@ static MALLOC_DEFINE(M_SMBNODENAME, "SMBFS nname", "SMBFS node name");
int smbfs_hashprint(struct mount *mp);
#if 0
-extern struct linker_set sysctl_vfs_smbfs;
#ifdef SYSCTL_DECL
SYSCTL_DECL(_vfs_smbfs);
#endif
diff --git a/sys/i386/linux/linux.h b/sys/i386/linux/linux.h
index fab3e29..b4eec098 100644
--- a/sys/i386/linux/linux.h
+++ b/sys/i386/linux/linux.h
@@ -366,7 +366,6 @@ extern struct sysentvec elf_linux_sysvec;
/*
* Pluggable ioctl handlers
*/
-struct linker_set;
struct linux_ioctl_args;
struct proc;
@@ -378,9 +377,7 @@ struct linux_ioctl_handler {
};
int linux_ioctl_register_handler(struct linux_ioctl_handler *h);
-int linux_ioctl_register_handlers(struct linker_set *s);
int linux_ioctl_unregister_handler(struct linux_ioctl_handler *h);
-int linux_ioctl_unregister_handlers(struct linker_set *s);
/*
* open/fcntl flags
diff --git a/sys/i386/linux/linux_sysvec.c b/sys/i386/linux/linux_sysvec.c
index de82774..4dd664b 100644
--- a/sys/i386/linux/linux_sysvec.c
+++ b/sys/i386/linux/linux_sysvec.c
@@ -81,7 +81,7 @@ extern int linux_szsigcode;
extern struct sysent linux_sysent[LINUX_SYS_MAXSYSCALL];
-extern struct linker_set linux_ioctl_handler_set;
+SET_DECLARE(linux_ioctl_handler_set, struct linux_ioctl_handler);
static int linux_fixup __P((register_t **stack_base,
struct image_params *iparams));
@@ -809,6 +809,7 @@ linux_elf_modevent(module_t mod, int type, void *data)
{
Elf32_Brandinfo **brandinfo;
int error;
+ struct linux_ioctl_handler **lihp;
error = 0;
@@ -819,8 +820,8 @@ linux_elf_modevent(module_t mod, int type, void *data)
if (elf_insert_brand_entry(*brandinfo) < 0)
error = EINVAL;
if (error == 0) {
- linux_ioctl_register_handlers(
- &linux_ioctl_handler_set);
+ SET_FOREACH(lihp, linux_ioctl_handler_set)
+ linux_ioctl_register_handler(*lihp);
if (bootverbose)
printf("Linux ELF exec handler installed\n");
} else
@@ -838,8 +839,8 @@ linux_elf_modevent(module_t mod, int type, void *data)
error = EINVAL;
}
if (error == 0) {
- linux_ioctl_unregister_handlers(
- &linux_ioctl_handler_set);
+ SET_FOREACH(lihp, linux_ioctl_handler_set)
+ linux_ioctl_unregister_handler(*lihp);
if (bootverbose)
printf("Linux ELF exec handler removed\n");
} else
diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c
index 9698983..aa1fa74 100644
--- a/sys/kern/init_main.c
+++ b/sys/kern/init_main.c
@@ -77,8 +77,6 @@
#include <sys/user.h>
#include <sys/copyright.h>
-extern struct linker_set sysinit_set; /* XXX */
-
void mi_startup(void); /* Should be elsewhere */
/* Components of the first process -- never freed. */
@@ -112,46 +110,43 @@ SYSINIT(placeholder, SI_SUB_DUMMY, SI_ORDER_ANY, NULL, NULL)
* The sysinit table itself. Items are checked off as the are run.
* If we want to register new sysinit types, add them to newsysinit.
*/
-struct sysinit **sysinit = (struct sysinit **)sysinit_set.ls_items;
-struct sysinit **newsysinit;
+SET_DECLARE(sysinit_set, struct sysinit);
+struct sysinit **sysinit, **sysinit_end;
+struct sysinit **newsysinit, **newsysinit_end;
/*
* Merge a new sysinit set into the current set, reallocating it if
* necessary. This can only be called after malloc is running.
*/
void
-sysinit_add(struct sysinit **set)
+sysinit_add(struct sysinit **set, struct sysinit **set_end)
{
struct sysinit **newset;
struct sysinit **sipp;
struct sysinit **xipp;
- int count = 0;
+ int count;
+ count = set_end - set;
if (newsysinit)
- for (sipp = newsysinit; *sipp; sipp++)
- count++;
+ count += newsysinit_end - newsysinit;
else
- for (sipp = sysinit; *sipp; sipp++)
- count++;
- for (sipp = set; *sipp; sipp++)
- count++;
- count++; /* Trailing NULL */
+ count += sysinit_end - sysinit;
newset = malloc(count * sizeof(*sipp), M_TEMP, M_NOWAIT);
if (newset == NULL)
panic("cannot malloc for sysinit");
xipp = newset;
if (newsysinit)
- for (sipp = newsysinit; *sipp; sipp++)
+ for (sipp = newsysinit; sipp < newsysinit_end; sipp++)
*xipp++ = *sipp;
else
- for (sipp = sysinit; *sipp; sipp++)
+ for (sipp = sysinit; sipp < sysinit_end; sipp++)
*xipp++ = *sipp;
- for (sipp = set; *sipp; sipp++)
+ for (sipp = set; sipp < set_end; sipp++)
*xipp++ = *sipp;
- *xipp = NULL;
if (newsysinit)
free(newsysinit, M_TEMP);
newsysinit = newset;
+ newsysinit_end = newset + count;
}
/*
@@ -173,13 +168,18 @@ mi_startup(void)
register struct sysinit **xipp; /* interior loop of sort*/
register struct sysinit *save; /* bubble*/
+ if (sysinit == NULL) {
+ sysinit = SET_BEGIN(sysinit_set);
+ sysinit_end = SET_LIMIT(sysinit_set);
+ }
+
restart:
/*
* Perform a bubble sort of the system initialization objects by
* their subsystem (primary key) and order (secondary key).
*/
- for (sipp = sysinit; *sipp; sipp++) {
- for (xipp = sipp + 1; *xipp; xipp++) {
+ for (sipp = sysinit; sipp < sysinit_end; sipp++) {
+ for (xipp = sipp + 1; xipp < sysinit_end; xipp++) {
if ((*sipp)->subsystem < (*xipp)->subsystem ||
((*sipp)->subsystem == (*xipp)->subsystem &&
(*sipp)->order <= (*xipp)->order))
@@ -197,7 +197,7 @@ restart:
* The last item on the list is expected to be the scheduler,
* which will not return.
*/
- for (sipp = sysinit; *sipp; sipp++) {
+ for (sipp = sysinit; sipp < sysinit_end; sipp++) {
if ((*sipp)->subsystem == SI_SUB_DUMMY)
continue; /* skip dummy task(s)*/
@@ -213,10 +213,12 @@ restart:
/* Check if we've installed more sysinit items via KLD */
if (newsysinit != NULL) {
- if (sysinit != (struct sysinit **)sysinit_set.ls_items)
+ if (sysinit != SET_BEGIN(sysinit_set))
free(sysinit, M_TEMP);
sysinit = newsysinit;
+ sysinit_end = newsysinit_end;
newsysinit = NULL;
+ newsysinit_end = NULL;
goto restart;
}
}
diff --git a/sys/kern/kern_ktr.c b/sys/kern/kern_ktr.c
index 80af2ab..8902ca5 100644
--- a/sys/kern/kern_ktr.c
+++ b/sys/kern/kern_ktr.c
@@ -44,7 +44,6 @@
#include <sys/kernel.h>
#include <sys/ktr.h>
#include <sys/libkern.h>
-#include <sys/linker_set.h>
#include <sys/sysctl.h>
#include <sys/systm.h>
#include <machine/globals.h>
diff --git a/sys/kern/kern_linker.c b/sys/kern/kern_linker.c
index affc1dc..abd7fdd 100644
--- a/sys/kern/kern_linker.c
+++ b/sys/kern/kern_linker.c
@@ -54,6 +54,9 @@ int kld_debug = 0;
static char *linker_search_path(const char *name);
static const char *linker_basename(const char* path);
+/* Metadata from the static kernel */
+SET_DECLARE(modmetadata_set, struct mod_metadata);
+
MALLOC_DEFINE(M_LINKER, "linker", "kernel linker");
linker_file_t linker_kernel_file;
@@ -105,7 +108,7 @@ linker_add_class(linker_class_t lc)
static void
linker_file_sysinit(linker_file_t lf)
{
- struct linker_set* sysinits;
+ struct sysinit** start, ** stop;
struct sysinit** sipp;
struct sysinit** xipp;
struct sysinit* save;
@@ -113,11 +116,7 @@ linker_file_sysinit(linker_file_t lf)
KLD_DPF(FILE, ("linker_file_sysinit: calling SYSINITs for %s\n",
lf->filename));
- sysinits = (struct linker_set*)
- linker_file_lookup_symbol(lf, "sysinit_set", 0);
-
- KLD_DPF(FILE, ("linker_file_sysinit: SYSINITs %p\n", sysinits));
- if (!sysinits)
+ if (linker_file_lookup_set(lf, "sysinit_set", &start, &stop, NULL) != 0)
return;
/*
* Perform a bubble sort of the system initialization objects by
@@ -126,8 +125,8 @@ linker_file_sysinit(linker_file_t lf)
* Since some things care about execution order, this is the
* operation which ensures continued function.
*/
- for (sipp = (struct sysinit **)sysinits->ls_items; *sipp; sipp++) {
- for (xipp = sipp + 1; *xipp; xipp++) {
+ for (sipp = start; sipp < stop; sipp++) {
+ for (xipp = sipp + 1; xipp < stop; xipp++) {
if ((*sipp)->subsystem < (*xipp)->subsystem ||
((*sipp)->subsystem == (*xipp)->subsystem &&
(*sipp)->order <= (*xipp)->order))
@@ -143,7 +142,7 @@ linker_file_sysinit(linker_file_t lf)
* Traverse the (now) ordered list of system initialization tasks.
* Perform each task, and continue on to the next task.
*/
- for (sipp = (struct sysinit **)sysinits->ls_items; *sipp; sipp++) {
+ for (sipp = start; sipp < stop; sipp++) {
if ((*sipp)->subsystem == SI_SUB_DUMMY)
continue; /* skip dummy task(s)*/
@@ -155,7 +154,7 @@ linker_file_sysinit(linker_file_t lf)
static void
linker_file_sysuninit(linker_file_t lf)
{
- struct linker_set* sysuninits;
+ struct sysinit** start, ** stop;
struct sysinit** sipp;
struct sysinit** xipp;
struct sysinit* save;
@@ -163,11 +162,7 @@ linker_file_sysuninit(linker_file_t lf)
KLD_DPF(FILE, ("linker_file_sysuninit: calling SYSUNINITs for %s\n",
lf->filename));
- sysuninits = (struct linker_set*)
- linker_file_lookup_symbol(lf, "sysuninit_set", 0);
-
- KLD_DPF(FILE, ("linker_file_sysuninit: SYSUNINITs %p\n", sysuninits));
- if (!sysuninits)
+ if (linker_file_lookup_set(lf, "sysuninit_set", &start, &stop, NULL) != 0)
return;
/*
@@ -177,8 +172,8 @@ linker_file_sysuninit(linker_file_t lf)
* Since some things care about execution order, this is the
* operation which ensures continued function.
*/
- for (sipp = (struct sysinit **)sysuninits->ls_items; *sipp; sipp++) {
- for (xipp = sipp + 1; *xipp; xipp++) {
+ for (sipp = start; sipp < stop; sipp++) {
+ for (xipp = sipp + 1; xipp < stop; xipp++) {
if ((*sipp)->subsystem > (*xipp)->subsystem ||
((*sipp)->subsystem == (*xipp)->subsystem &&
(*sipp)->order >= (*xipp)->order))
@@ -193,7 +188,7 @@ linker_file_sysuninit(linker_file_t lf)
* Traverse the (now) ordered list of system initialization tasks.
* Perform each task, and continue on to the next task.
*/
- for (sipp = (struct sysinit **)sysuninits->ls_items; *sipp; sipp++) {
+ for (sipp = start; sipp < stop; sipp++) {
if ((*sipp)->subsystem == SI_SUB_DUMMY)
continue; /* skip dummy task(s)*/
@@ -205,64 +200,61 @@ linker_file_sysuninit(linker_file_t lf)
static void
linker_file_register_sysctls(linker_file_t lf)
{
- struct linker_set* sysctls;
+ struct sysctl_oid **start, **stop, **oidp;
KLD_DPF(FILE, ("linker_file_register_sysctls: registering SYSCTLs for %s\n",
lf->filename));
- sysctls = (struct linker_set*)
- linker_file_lookup_symbol(lf, "sysctl_set", 0);
-
- KLD_DPF(FILE, ("linker_file_register_sysctls: SYSCTLs %p\n", sysctls));
- if (!sysctls)
+ if (linker_file_lookup_set(lf, "sysctl_set", &start, &stop, NULL) != 0)
return;
- sysctl_register_set(sysctls);
+ for (oidp = start; oidp < stop; oidp++)
+ sysctl_register_oid(*oidp);
}
static void
linker_file_unregister_sysctls(linker_file_t lf)
{
- struct linker_set* sysctls;
+ struct sysctl_oid **start, **stop, **oidp;
KLD_DPF(FILE, ("linker_file_unregister_sysctls: registering SYSCTLs for %s\n",
lf->filename));
- sysctls = (struct linker_set*)
- linker_file_lookup_symbol(lf, "sysctl_set", 0);
-
- KLD_DPF(FILE, ("linker_file_unregister_sysctls: SYSCTLs %p\n", sysctls));
- if (!sysctls)
+ if (linker_file_lookup_set(lf, "sysctl_set", &start, &stop, NULL) != 0)
return;
- sysctl_unregister_set(sysctls);
+ for (oidp = start; oidp < stop; oidp++)
+ sysctl_unregister_oid(*oidp);
}
-extern struct linker_set modmetadata_set;
-
static int
linker_file_register_modules(linker_file_t lf)
{
int error;
- struct linker_set *modules;
- struct mod_metadata **mdpp;
+ struct mod_metadata **start, **stop;
+ struct mod_metadata **mdp;
const moduledata_t *moddata;
KLD_DPF(FILE, ("linker_file_register_modules: registering modules in %s\n",
lf->filename));
- modules = (struct linker_set*)
- linker_file_lookup_symbol(lf, "modmetadata_set", 0);
-
- if (!modules && lf == linker_kernel_file)
- modules = &modmetadata_set;
-
- if (modules == NULL)
- return 0;
- for (mdpp = (struct mod_metadata**)modules->ls_items; *mdpp; mdpp++) {
- if ((*mdpp)->md_type != MDT_MODULE)
+ if (linker_file_lookup_set(lf, "modmetadata_set", &start, &stop, 0) != 0) {
+ /*
+ * This fallback should be unnecessary, but if we get booted from
+ * boot2 instead of loader and we are missing our metadata then
+ * we have to try the best we can.
+ */
+ if (lf == linker_kernel_file) {
+ start = SET_BEGIN(modmetadata_set);
+ stop = SET_LIMIT(modmetadata_set);
+ } else {
+ return 0;
+ }
+ }
+ for (mdp = start; mdp < stop; mdp++) {
+ if ((*mdp)->md_type != MDT_MODULE)
continue;
- moddata = (*mdpp)->md_data;
+ moddata = (*mdp)->md_data;
KLD_DPF(FILE, ("Registering module %s in %s\n",
moddata->name, lf->filename));
if (module_lookupbyname(moddata->name) != NULL) {
@@ -514,6 +506,19 @@ linker_file_add_dependancy(linker_file_t file, linker_file_t dep)
return 0;
}
+/*
+ * Locate a linker set and its contents.
+ * This is a helper function to avoid linker_if.h exposure elsewhere.
+ * Note: firstp and lastp are really void ***
+ */
+int
+linker_file_lookup_set(linker_file_t file, const char *name,
+ void *firstp, void *lastp, int *countp)
+{
+
+ return LINKER_LOOKUP_SET(file, name, firstp, lastp, countp);
+}
+
caddr_t
linker_file_lookup_symbol(linker_file_t file, const char* name, int deps)
{
@@ -986,17 +991,18 @@ linker_mdt_depend(linker_file_t lf, struct mod_metadata *mp,
}
static void
-linker_addmodules(linker_file_t lf, struct linker_set *deps, int preload)
+linker_addmodules(linker_file_t lf, struct mod_metadata **start,
+ struct mod_metadata **stop, int preload)
{
- struct mod_metadata *mp;
+ struct mod_metadata *mp, **mdp;
char *modname;
- int i, ver;
+ int ver;
- for (i = 0; i < deps->ls_length; i++) {
+ for (mdp = start; mdp < stop; mdp++) {
if (preload)
- mp = deps->ls_items[i];
+ mp = *mdp;
else
- mp = linker_reloc_ptr(lf, deps->ls_items[i]);
+ mp = linker_reloc_ptr(lf, *mdp);
if (mp->md_type != MDT_VERSION)
continue;
if (preload) {
@@ -1022,15 +1028,15 @@ linker_preload(void* arg)
linker_file_t lf;
linker_class_t lc;
int error;
- struct linker_set *sysinits;
linker_file_list_t loaded_files;
linker_file_list_t depended_files;
- struct linker_set *deps;
struct mod_metadata *mp, *nmp;
+ struct mod_metadata **start, **stop, **mdp, **nmdp;
struct mod_depend *verinfo;
- int i, j, nver;
+ int nver;
int resolves;
modlist_t mod;
+ struct sysinit **si_start, **si_stop;
TAILQ_INIT(&loaded_files);
TAILQ_INIT(&depended_files);
@@ -1065,10 +1071,9 @@ linker_preload(void* arg)
/*
* First get a list of stuff in the kernel.
*/
- deps = (struct linker_set*)
- linker_file_lookup_symbol(linker_kernel_file, MDT_SETNAME, 0);
- if (deps)
- linker_addmodules(linker_kernel_file, deps, 1);
+ if (linker_file_lookup_set(linker_kernel_file, MDT_SETNAME, &start, &stop,
+ NULL) == 0)
+ linker_addmodules(linker_kernel_file, start, stop, 1);
/*
* this is a once-off kinky bubble sort
@@ -1076,20 +1081,19 @@ linker_preload(void* arg)
*/
restart:
TAILQ_FOREACH(lf, &loaded_files, loaded) {
- deps = (struct linker_set*)
- linker_file_lookup_symbol(lf, MDT_SETNAME, 0);
+ error = linker_file_lookup_set(lf, MDT_SETNAME, &start, &stop, NULL);
/*
* First, look to see if we would successfully link with this stuff.
*/
resolves = 1; /* unless we know otherwise */
- if (deps) {
- for (i = 0; i < deps->ls_length; i++) {
- mp = linker_reloc_ptr(lf, deps->ls_items[i]);
+ if (!error) {
+ for (mdp = start; mdp < stop; mdp++) {
+ mp = linker_reloc_ptr(lf, *mdp);
if (mp->md_type != MDT_DEPEND)
continue;
linker_mdt_depend(lf, mp, &modname, &verinfo);
- for (j = 0; j < deps->ls_length; j++) {
- nmp = linker_reloc_ptr(lf, deps->ls_items[j]);
+ for (nmdp = start; nmdp < stop; nmdp++) {
+ nmp = linker_reloc_ptr(lf, *nmdp);
if (nmp->md_type != MDT_VERSION)
continue;
linker_mdt_version(lf, nmp, &nmodname, NULL);
@@ -1097,7 +1101,7 @@ restart:
if (strcmp(modname, nmodname) == 0)
break;
}
- if (j < deps->ls_length) /* it's a self reference */
+ if (nmdp < stop) /* it's a self reference */
continue;
if (modlist_lookup(modname, 0) == NULL) {
/* ok, the module isn't here yet, we are not finished */
@@ -1110,9 +1114,9 @@ restart:
* modules inside and add it to the end of the link order list.
*/
if (resolves) {
- if (deps) {
- for (i = 0; i < deps->ls_length; i++) {
- mp = linker_reloc_ptr(lf, deps->ls_items[i]);
+ if (!error) {
+ for (mdp = start; mdp < stop; mdp++) {
+ mp = linker_reloc_ptr(lf, *mdp);
if (mp->md_type != MDT_VERSION)
continue;
linker_mdt_version(lf, mp, &modname, &nver);
@@ -1156,11 +1160,10 @@ restart:
panic("cannot add dependency");
}
lf->userrefs++; /* so we can (try to) kldunload it */
- deps = (struct linker_set*)
- linker_file_lookup_symbol(lf, MDT_SETNAME, 0);
- if (deps) {
- for (i = 0; i < deps->ls_length; i++) {
- mp = linker_reloc_ptr(lf, deps->ls_items[i]);
+ error = linker_file_lookup_set(lf, MDT_SETNAME, &start, &stop, NULL);
+ if (!error) {
+ for (mdp = start; mdp < stop; mdp++) {
+ mp = linker_reloc_ptr(lf, *mdp);
if (mp->md_type != MDT_DEPEND)
continue;
linker_mdt_depend(lf, mp, &modname, &verinfo);
@@ -1172,7 +1175,10 @@ restart:
}
}
- /* Now do relocation etc using the symbol search paths established by the dependencies */
+ /*
+ * Now do relocation etc using the symbol search paths established by
+ * the dependencies
+ */
error = LINKER_LINK_PRELOAD_FINISH(lf);
if (error) {
printf("KLD file %s - could not finalize loading\n", lf->filename);
@@ -1181,10 +1187,8 @@ restart:
}
linker_file_register_modules(lf);
- sysinits = (struct linker_set*)
- linker_file_lookup_symbol(lf, "sysinit_set", 0);
- if (sysinits)
- sysinit_add((struct sysinit **)sysinits->ls_items);
+ if (linker_file_lookup_set(lf, "sysinit_set", &si_start, &si_stop, NULL) == 0)
+ sysinit_add(si_start, si_stop);
linker_file_register_sysctls(lf);
lf->flags |= LINKER_FILE_LINKED;
}
@@ -1348,11 +1352,11 @@ int
linker_load_dependancies(linker_file_t lf)
{
linker_file_t lfdep;
- struct linker_set *deps;
+ struct mod_metadata **start, **stop, **mdp, **nmdp;
struct mod_metadata *mp, *nmp;
modlist_t mod;
char *modname, *nmodname;
- int i, j, ver, error = 0;
+ int ver, error = 0, count;
/*
* All files are dependant on /kernel.
@@ -1364,12 +1368,10 @@ linker_load_dependancies(linker_file_t lf)
return error;
}
- deps = (struct linker_set*)
- linker_file_lookup_symbol(lf, MDT_SETNAME, 0);
- if (deps == NULL)
+ if (linker_file_lookup_set(lf, MDT_SETNAME, &start, &stop, &count) != 0)
return 0;
- for (i = 0; i < deps->ls_length; i++) {
- mp = linker_reloc_ptr(lf, deps->ls_items[i]);
+ for (mdp = start; mdp < stop; mdp++) {
+ mp = linker_reloc_ptr(lf, *mdp);
if (mp->md_type != MDT_VERSION)
continue;
linker_mdt_version(lf, mp, &modname, &ver);
@@ -1381,21 +1383,21 @@ linker_load_dependancies(linker_file_t lf)
}
}
- for (i = 0; i < deps->ls_length; i++) {
- mp = linker_reloc_ptr(lf, deps->ls_items[i]);
+ for (mdp = start; mdp < stop; mdp++) {
+ mp = linker_reloc_ptr(lf, *mdp);
if (mp->md_type != MDT_DEPEND)
continue;
modname = linker_reloc_ptr(lf, mp->md_cval);
nmodname = NULL;
- for (j = 0; j < deps->ls_length; j++) {
- nmp = linker_reloc_ptr(lf, deps->ls_items[j]);
+ for (nmdp = start; nmdp < stop; nmdp++) {
+ nmp = linker_reloc_ptr(lf, *nmdp);
if (nmp->md_type != MDT_VERSION)
continue;
nmodname = linker_reloc_ptr(lf, nmp->md_cval);
if (strcmp(modname, nmodname) == 0)
break;
}
- if (j < deps->ls_length) /* early exit, it's a self reference */
+ if (nmdp < stop) /* early exit, it's a self reference */
continue;
mod = modlist_lookup(modname, 0);
if (mod) { /* woohoo, it's loaded already */
@@ -1416,6 +1418,6 @@ linker_load_dependancies(linker_file_t lf)
if (error)
return error;
- linker_addmodules(lf, deps, 0);
+ linker_addmodules(lf, start, stop, 0);
return error;
}
diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c
index b3bf555..3256cfd 100644
--- a/sys/kern/kern_sysctl.c
+++ b/sys/kern/kern_sysctl.c
@@ -367,34 +367,17 @@ sysctl_add_oid(struct sysctl_ctx_list *clist, struct sysctl_oid_list *parent,
}
/*
- * Bulk-register all the oids in a linker_set.
- */
-void sysctl_register_set(struct linker_set *lsp)
-{
- int count = lsp->ls_length;
- int i;
- for (i = 0; i < count; i++)
- sysctl_register_oid((struct sysctl_oid *) lsp->ls_items[i]);
-}
-
-void sysctl_unregister_set(struct linker_set *lsp)
-{
- int count = lsp->ls_length;
- int i;
- for (i = 0; i < count; i++)
- sysctl_unregister_oid((struct sysctl_oid *) lsp->ls_items[i]);
-}
-
-/*
* Register the kernel's oids on startup.
*/
-extern struct linker_set sysctl_set;
+SET_DECLARE(sysctl_set, struct sysctl_oid);
static void sysctl_register_all(void *arg)
{
- sysctl_register_set(&sysctl_set);
-}
+ struct sysctl_oid **oidp;
+ SET_FOREACH(oidp, sysctl_set)
+ sysctl_register_oid(*oidp);
+}
SYSINIT(sysctl, SI_SUB_KMEM, SI_ORDER_ANY, sysctl_register_all, 0);
/*
diff --git a/sys/kern/link_aout.c b/sys/kern/link_aout.c
index f9e45d7..1218e22 100644
--- a/sys/kern/link_aout.c
+++ b/sys/kern/link_aout.c
@@ -72,6 +72,8 @@ static int link_aout_search_symbol(linker_file_t lf, caddr_t value,
c_linker_sym_t* sym, long* diffp);
static void link_aout_unload_file(linker_file_t);
static void link_aout_unload_preload(linker_file_t);
+static int link_aout_lookup_set(linker_file_t, const char*,
+ void ***, void ***, int*);
static kobj_method_t link_aout_methods[] = {
KOBJMETHOD(linker_lookup_symbol, link_aout_lookup_symbol),
@@ -81,6 +83,7 @@ static kobj_method_t link_aout_methods[] = {
KOBJMETHOD(linker_load_file, link_aout_load_file),
KOBJMETHOD(linker_link_preload, link_aout_link_preload),
KOBJMETHOD(linker_link_preload_finish, link_aout_link_preload_finish),
+ KOBJMETHOD(linker_lookup_set, link_aout_lookup_set),
{ 0, 0 }
};
@@ -548,4 +551,40 @@ link_aout_search_symbol(linker_file_t lf, caddr_t value,
return 0;
}
+/*
+ * Look up a linker set on an a.out + gnu LD system.
+ */
+struct generic_linker_set {
+ int ls_length;
+ void *ls_items[1];
+};
+static int
+link_aout_lookup_set(linker_file_t lf, const char *name,
+ void ***startp, void ***stopp, int *countp)
+{
+ c_linker_sym_t sym;
+ linker_symval_t symval;
+ void **start, **stop;
+ int error, count;
+ struct generic_linker_set *setp;
+
+ error = link_aout_lookup_symbol(lf, name, &sym);
+ if (error)
+ return error;
+ link_aout_symbol_values(lf, sym, &symval);
+ if (symval.value == 0)
+ return ESRCH;
+ setp = (struct generic_linker_set *)symval.value;
+ count = setp->ls_length;
+ start = &setp->ls_items[0];
+ stop = &setp->ls_items[count];
+ if (startp)
+ *startp = start;
+ if (stopp)
+ *stopp = stop;
+ if (countp)
+ *countp = count;
+ return 0;
+}
+
#endif /* !__alpha__ */
diff --git a/sys/kern/link_elf.c b/sys/kern/link_elf.c
index 32f45ce..da7462a 100644
--- a/sys/kern/link_elf.c
+++ b/sys/kern/link_elf.c
@@ -108,6 +108,8 @@ static int link_elf_search_symbol(linker_file_t, caddr_t value,
static void link_elf_unload_file(linker_file_t);
static void link_elf_unload_preload(linker_file_t);
+static int link_elf_lookup_set(linker_file_t, const char *,
+ void ***, void ***, int *);
static kobj_method_t link_elf_methods[] = {
KOBJMETHOD(linker_lookup_symbol, link_elf_lookup_symbol),
@@ -117,6 +119,7 @@ static kobj_method_t link_elf_methods[] = {
KOBJMETHOD(linker_load_file, link_elf_load_file),
KOBJMETHOD(linker_link_preload, link_elf_link_preload),
KOBJMETHOD(linker_link_preload_finish, link_elf_link_preload_finish),
+ KOBJMETHOD(linker_lookup_set, link_elf_lookup_set),
{ 0, 0 }
};
@@ -1075,3 +1078,61 @@ link_elf_search_symbol(linker_file_t lf, caddr_t value,
return 0;
}
+
+/*
+ * Look up a linker set on an ELF system.
+ */
+static int
+link_elf_lookup_set(linker_file_t lf, const char *name,
+ void ***startp, void ***stopp, int *countp)
+{
+ c_linker_sym_t sym;
+ linker_symval_t symval;
+ char *setsym;
+ void **start, **stop;
+ int len, error = 0, count;
+
+ len = strlen(name) + sizeof("__start_set_"); /* sizeof includes \0 */
+ setsym = malloc(len, M_LINKER, M_WAITOK);
+ if (setsym == NULL)
+ return ENOMEM;
+
+ /* get address of first entry */
+ snprintf(setsym, len, "%s%s", "__start_set_", name);
+ error = link_elf_lookup_symbol(lf, setsym, &sym);
+ if (error)
+ goto out;
+ link_elf_symbol_values(lf, sym, &symval);
+ if (symval.value == 0) {
+ error = ESRCH;
+ goto out;
+ }
+ start = (void **)symval.value;
+
+ /* get address of last entry */
+ snprintf(setsym, len, "%s%s", "__stop_set_", name);
+ error = link_elf_lookup_symbol(lf, setsym, &sym);
+ if (error)
+ goto out;
+ link_elf_symbol_values(lf, sym, &symval);
+ if (symval.value == 0) {
+ error = ESRCH;
+ goto out;
+ }
+ stop = (void **)symval.value;
+
+ /* and the number of entries */
+ count = stop - start;
+
+ /* and copy out */
+ if (startp)
+ *startp = start;
+ if (stopp)
+ *stopp = stop;
+ if (countp)
+ *countp = count;
+
+out:
+ free(setsym, M_LINKER);
+ return error;
+}
diff --git a/sys/kern/link_elf_obj.c b/sys/kern/link_elf_obj.c
index 32f45ce..da7462a 100644
--- a/sys/kern/link_elf_obj.c
+++ b/sys/kern/link_elf_obj.c
@@ -108,6 +108,8 @@ static int link_elf_search_symbol(linker_file_t, caddr_t value,
static void link_elf_unload_file(linker_file_t);
static void link_elf_unload_preload(linker_file_t);
+static int link_elf_lookup_set(linker_file_t, const char *,
+ void ***, void ***, int *);
static kobj_method_t link_elf_methods[] = {
KOBJMETHOD(linker_lookup_symbol, link_elf_lookup_symbol),
@@ -117,6 +119,7 @@ static kobj_method_t link_elf_methods[] = {
KOBJMETHOD(linker_load_file, link_elf_load_file),
KOBJMETHOD(linker_link_preload, link_elf_link_preload),
KOBJMETHOD(linker_link_preload_finish, link_elf_link_preload_finish),
+ KOBJMETHOD(linker_lookup_set, link_elf_lookup_set),
{ 0, 0 }
};
@@ -1075,3 +1078,61 @@ link_elf_search_symbol(linker_file_t lf, caddr_t value,
return 0;
}
+
+/*
+ * Look up a linker set on an ELF system.
+ */
+static int
+link_elf_lookup_set(linker_file_t lf, const char *name,
+ void ***startp, void ***stopp, int *countp)
+{
+ c_linker_sym_t sym;
+ linker_symval_t symval;
+ char *setsym;
+ void **start, **stop;
+ int len, error = 0, count;
+
+ len = strlen(name) + sizeof("__start_set_"); /* sizeof includes \0 */
+ setsym = malloc(len, M_LINKER, M_WAITOK);
+ if (setsym == NULL)
+ return ENOMEM;
+
+ /* get address of first entry */
+ snprintf(setsym, len, "%s%s", "__start_set_", name);
+ error = link_elf_lookup_symbol(lf, setsym, &sym);
+ if (error)
+ goto out;
+ link_elf_symbol_values(lf, sym, &symval);
+ if (symval.value == 0) {
+ error = ESRCH;
+ goto out;
+ }
+ start = (void **)symval.value;
+
+ /* get address of last entry */
+ snprintf(setsym, len, "%s%s", "__stop_set_", name);
+ error = link_elf_lookup_symbol(lf, setsym, &sym);
+ if (error)
+ goto out;
+ link_elf_symbol_values(lf, sym, &symval);
+ if (symval.value == 0) {
+ error = ESRCH;
+ goto out;
+ }
+ stop = (void **)symval.value;
+
+ /* and the number of entries */
+ count = stop - start;
+
+ /* and copy out */
+ if (startp)
+ *startp = start;
+ if (stopp)
+ *stopp = stop;
+ if (countp)
+ *countp = count;
+
+out:
+ free(setsym, M_LINKER);
+ return error;
+}
diff --git a/sys/kern/linker_if.m b/sys/kern/linker_if.m
index 5f6f239..be84b9e 100644
--- a/sys/kern/linker_if.m
+++ b/sys/kern/linker_if.m
@@ -54,6 +54,20 @@ METHOD int search_symbol {
};
#
+# Search for a linker set in a file. Return a pointer to the first
+# entry (which is itself a pointer), and the number of entries.
+# "stop" points to the entry beyond the last valid entry.
+# If count, start or stop are NULL, they are not returned.
+#
+METHOD int lookup_set {
+ linker_file_t file;
+ const char* name;
+ void*** start;
+ void*** stop;
+ int* count;
+};
+
+#
# Unload a file, releasing dependancies and freeing storage.
#
METHOD void unload {
diff --git a/sys/kern/tty_cons.c b/sys/kern/tty_cons.c
index a40db4b..478c7e9 100644
--- a/sys/kern/tty_cons.c
+++ b/sys/kern/tty_cons.c
@@ -99,6 +99,7 @@ static d_open_t *cn_phys_open; /* physical device open function */
struct consdev *cn_tab; /* physical console device info */
CONS_DRIVER(cons, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+SET_DECLARE(cons_set, struct consdev);
void
cninit()
@@ -109,8 +110,8 @@ cninit()
* Find the first console with the highest priority.
*/
best_cp = NULL;
- list = (struct consdev **)cons_set.ls_items;
- while ((cp = *list++) != NULL) {
+ SET_FOREACH(list, cons_set) {
+ cp = *list;
if (cp->cn_probe == NULL)
continue;
(*cp->cn_probe)(cp);
diff --git a/sys/netncp/ncp_conn.c b/sys/netncp/ncp_conn.c
index f1f6983..dc255f2 100644
--- a/sys/netncp/ncp_conn.c
+++ b/sys/netncp/ncp_conn.c
@@ -64,8 +64,6 @@ static int ncp_sysctl_connstat(SYSCTL_HANDLER_ARGS);
static int ncp_conn_lock_any(struct ncp_conn *conn, struct proc *p,
struct ucred *cred);
-extern struct linker_set sysctl_net_ncp;
-
SYSCTL_DECL(_net_ncp);
SYSCTL_INT (_net_ncp, OID_AUTO, burst_enabled, CTLFLAG_RD, &ncp_burst_enabled, 0, "");
SYSCTL_INT (_net_ncp, OID_AUTO, conn_cnt, CTLFLAG_RD, &ncp_conn_cnt, 0, "");
diff --git a/sys/netsmb/smb_conn.c b/sys/netsmb/smb_conn.c
index 54f5c0b..1d56d85 100644
--- a/sys/netsmb/smb_conn.c
+++ b/sys/netsmb/smb_conn.c
@@ -56,8 +56,6 @@
static struct smb_connobj smb_vclist;
static int smb_vcnext = 1; /* next unique id for VC */
-extern struct linker_set sysctl_net_smb;
-
SYSCTL_NODE(_net, OID_AUTO, smb, CTLFLAG_RW, NULL, "SMB protocol");
MALLOC_DEFINE(M_SMBCONN, "SMB conn", "SMB connection");
diff --git a/sys/pc98/cbus/scgdcrndr.c b/sys/pc98/cbus/scgdcrndr.c
index b37de73..f1dcec5 100644
--- a/sys/pc98/cbus/scgdcrndr.c
+++ b/sys/pc98/cbus/scgdcrndr.c
@@ -58,8 +58,6 @@ static vr_draw_border_t gdc_grborder;
static void gdc_nop(scr_stat *scp, ...);
-static struct linker_set gdc_set;
-
static sc_rndr_sw_t txtrndrsw = {
gdc_txtclear,
gdc_txtborder,
diff --git a/sys/pc98/pc98/scgdcrndr.c b/sys/pc98/pc98/scgdcrndr.c
index b37de73..f1dcec5 100644
--- a/sys/pc98/pc98/scgdcrndr.c
+++ b/sys/pc98/pc98/scgdcrndr.c
@@ -58,8 +58,6 @@ static vr_draw_border_t gdc_grborder;
static void gdc_nop(scr_stat *scp, ...);
-static struct linker_set gdc_set;
-
static sc_rndr_sw_t txtrndrsw = {
gdc_txtclear,
gdc_txtborder,
diff --git a/sys/sys/cons.h b/sys/sys/cons.h
index 48be371..a99c210 100644
--- a/sys/sys/cons.h
+++ b/sys/sys/cons.h
@@ -78,7 +78,6 @@ struct consdev {
#define CN_REMOTE 3 /* serial interface with remote bit set */
#ifdef _KERNEL
-extern struct linker_set cons_set;
extern int cons_unavail;
extern struct consdev *cn_tab;
diff --git a/sys/sys/kernel.h b/sys/sys/kernel.h
index 7e8ea63..79c57e1 100644
--- a/sys/sys/kernel.h
+++ b/sys/sys/kernel.h
@@ -250,7 +250,7 @@ struct sysinit {
C_SYSUNINIT(uniquifier, subsystem, order, \
(sysinit_cfunc_t)(sysinit_nfunc_t)func, (void *)ident)
-void sysinit_add __P((struct sysinit **set));
+void sysinit_add __P((struct sysinit **set, struct sysinit **set_end));
/*
* Infrastructure for tunable 'constants'. Value may be specified at compile
diff --git a/sys/sys/linker.h b/sys/sys/linker.h
index 87a2a83..671bbe8 100644
--- a/sys/sys/linker.h
+++ b/sys/sys/linker.h
@@ -139,6 +139,14 @@ caddr_t linker_file_lookup_symbol(linker_file_t _file, const char* _name,
int _deps);
/*
+ * Lookup a linker set in a file. Return pointers to the first entry,
+ * last + 1, and count of entries. Use: for (p = start; p < stop; p++) {}
+ * void *start is really: "struct yoursetmember ***start;"
+ */
+int linker_file_lookup_set(linker_file_t _file, const char *_name,
+ void *_start, void *_stop, int *_count);
+
+/*
* This routine is responsible for finding dependencies of userland
* initiated kldload(2)'s of files.
*/
diff --git a/sys/sys/linker_set.h b/sys/sys/linker_set.h
index 2bffa9b..0fa115f 100644
--- a/sys/sys/linker_set.h
+++ b/sys/sys/linker_set.h
@@ -1,5 +1,6 @@
/*-
* Copyright (c) 1999 John D. Polstra
+ * Copyright (c) 1999,2001 Peter Wemm <peter@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -31,56 +32,109 @@
/*
* The following macros are used to declare global sets of objects, which
- * are collected by the linker into a `struct linker_set' as defined below.
+ * are collected by the linker into a `linker_set' as defined below.
* For ELF, this is done by constructing a separate segment for each set.
* For a.out, it is done automatically by the linker.
+ */
+
+#if defined(__ELF__)
+/*
+ * Private macros, not to be used outside this header file.
+ */
+/* this bit of h0h0magic brought to you by cpp */
+#define __GLOBL(sym) __GLOBL2(sym)
+#define __GLOBL2(sym) __asm(".globl " #sym)
+
+#define __MAKE_SET(set, sym) \
+ __GLOBL(__CONCAT(__start_set_,set)); \
+ __GLOBL(__CONCAT(__stop_set_,set)); \
+ static void const * const __set_##set##_sym_##sym \
+ __attribute__((__section__("set_" #set),__unused__)) = &sym
+
+/*
+ * Public macros.
+ */
+#define TEXT_SET(set, sym) __MAKE_SET(set, sym)
+#define DATA_SET(set, sym) __MAKE_SET(set, sym)
+#define BSS_SET(set, sym) __MAKE_SET(set, sym)
+#define ABS_SET(set, sym) __MAKE_SET(set, sym)
+#define SET_ENTRY(set, sym) __MAKE_SET(set, sym)
+
+/*
+ * Initialize before referring to a give linker set
+ */
+#define SET_DECLARE(set, ptype) \
+ extern ptype *__CONCAT(__start_set_,set); \
+ extern ptype *__CONCAT(__stop_set_,set)
+
+#define SET_BEGIN(set) \
+ (&__CONCAT(__start_set_,set))
+#define SET_LIMIT(set) \
+ (&__CONCAT(__stop_set_,set))
+
+#else /* __ELF__ */
+
+/*
+ * The old way. This depends on GNU ld extensions that are not widely
+ * available outside of the a.out format.
*
- * In the MAKE_SET macros below, the lines:
+ * NB: the constants defined below must match those defined in
+ * ld/ld.h. Since their calculation requires arithmetic, we
+ * can't name them symbolically (e.g., 23 is N_SETT | N_EXT).
*
+ * In the __MAKE_SET macro below, the line:
* static void const * const __set_##set##_sym_##sym = &sym;
- *
- * are present only to prevent the compiler from producing bogus
+ * is present only to prevent the compiler from producing bogus
* warnings about unused symbols.
*/
-#ifdef __ELF__
-
-#if defined(__alpha__) || defined(__ia64__)
-#define MAKE_SET(set, sym) \
+/* Private macros */
+#ifdef __UNDERSCORES__
+#define __MAKE_SET(set, sym, type) \
static void const * const __set_##set##_sym_##sym = &sym; \
- __asm(".section .set." #set ",\"aw\""); \
- __asm(".p2align 3"); \
- __asm(".quad " #sym); \
- __asm(".previous")
+ __asm(".stabs \"_" #set "\", " #type ", 0, 0, _" #sym)
#else
-#define MAKE_SET(set, sym) \
+#define __MAKE_SET(set, sym, type) \
static void const * const __set_##set##_sym_##sym = &sym; \
- __asm(".section .set." #set ",\"aw\""); \
- __asm(".p2align 2"); \
- __asm(".long " #sym); \
- __asm(".previous")
+ __asm(".stabs \"" #set "\", " #type ", 0, 0, " #sym)
#endif
-#define TEXT_SET(set, sym) MAKE_SET(set, sym)
-#define DATA_SET(set, sym) MAKE_SET(set, sym)
-#else
+/* Public Macros */
+#define TEXT_SET(set, sym) __MAKE_SET(set, sym, 23)
+#define DATA_SET(set, sym) __MAKE_SET(set, sym, 25)
+#define BSS_SET(set, sym) __MAKE_SET(set, sym, 27)
+#define ABS_SET(set, sym) __MAKE_SET(set, sym, 21)
+#define SET_ENTRY(set, sym) error error must provide text/data type
+
+#define SET_DECLARE(set, ptype) \
+ extern struct { \
+ int ls_length; \
+ ptype *ls_items[1]; \
+ } set
+
+#define SET_BEGIN(set) \
+ (&((set).ls_items[0]))
+#define SET_LIMIT(set) \
+ (&((set).ls_items[(set).ls_length]))
+
+#endif /* __ELF__ */
/*
- * NB: the constants defined below must match those defined in
- * ld/ld.h. Since their calculation requires arithmetic, we
- * can't name them symbolically (e.g., 23 is N_SETT | N_EXT).
+ * Iterate over all the elements of a set.
+ *
+ * Sets always contain addresses of things, and "pvar" points to words
+ * containing those addresses. Thus is must be declared as "type **pvar",
+ * and the address of each set item is obtained inside the loop by "*pvar".
*/
-#define MAKE_SET(set, sym, type) \
- static void const * const __set_##set##_sym_##sym = &sym; \
- __asm(".stabs \"" #set "\", " #type ", 0, 0, " #sym)
-#define TEXT_SET(set, sym) MAKE_SET(set, sym, 23)
-#define DATA_SET(set, sym) MAKE_SET(set, sym, 25)
+#define SET_FOREACH(pvar, set) \
+ for (pvar = SET_BEGIN(set); pvar < SET_LIMIT(set); pvar++)
-#endif
+#define SET_ITEM(set, i) \
+ ((SET_BEGIN(set))[i])
-struct linker_set {
- int ls_length;
- void *ls_items[1]; /* really ls_length of them,
- * trailing NULL */
-};
+/*
+ * Provide a count of the items in a set.
+ */
+#define SET_COUNT(set) \
+ (SET_LIMIT(set) - SET_BEGIN(set))
-#endif /* _SYS_LINKER_SET_H_ */
+#endif /* _SYS_LINKER_SET_H_ */
diff --git a/sys/sys/sysctl.h b/sys/sys/sysctl.h
index d43c89f8..1b6657b 100644
--- a/sys/sys/sysctl.h
+++ b/sys/sys/sysctl.h
@@ -557,8 +557,6 @@ extern char machine[];
extern char osrelease[];
extern char ostype[];
-struct linker_set;
-
/* Dynamic oid handling */
struct sysctl_oid *sysctl_add_oid(struct sysctl_ctx_list *clist,
struct sysctl_oid_list *parent, int nbr, const char *name,
@@ -575,10 +573,6 @@ struct sysctl_ctx_entry *sysctl_ctx_entry_find(struct sysctl_ctx_list *clist,
int sysctl_ctx_entry_del(struct sysctl_ctx_list *clist,
struct sysctl_oid *oidp);
-/* Linker set based oid handling */
-void sysctl_register_set(struct linker_set *lsp);
-void sysctl_unregister_set(struct linker_set *lsp);
-
int kernel_sysctl(struct proc *p, int *name, u_int namelen, void *old,
size_t *oldlenp, void *new, size_t newlen,
size_t *retval);
OpenPOWER on IntegriCloud