*** *** NOT TESTED!!!! NOT EVEN COMPILED YET!!!! *** diff -ru --exclude=compile ../sys/alpha/linux/linux.h ./alpha/linux/linux.h --- ../sys/alpha/linux/linux.h Fri Feb 16 12:36:20 2001 +++ ./alpha/linux/linux.h Tue Jun 12 23:04:44 2001 @@ -238,7 +238,6 @@ /* * Pluggable ioctl handlers */ -struct linker_set; struct linux_ioctl_args; struct proc; @@ -250,9 +249,7 @@ }; 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 -ru --exclude=compile ../sys/alpha/linux/linux_sysvec.c ./alpha/linux/linux_sysvec.c --- ../sys/alpha/linux/linux_sysvec.c Fri May 25 18:41:04 2001 +++ ./alpha/linux/linux_sysvec.c Tue Jun 12 23:03:37 2001 @@ -77,7 +77,7 @@ #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 @@ { Elf64_Brandinfo **brandinfo; int error; + struct linux_ioctl_handler **lihp; error = 0; @@ -231,8 +232,8 @@ 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 @@ 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 -ru --exclude=compile ../sys/compat/linux/linux_ioctl.c ./compat/linux/linux_ioctl.c --- ../sys/compat/linux/linux_ioctl.c Fri Feb 16 12:36:24 2001 +++ ./compat/linux/linux_ioctl.c Tue Jun 12 23:04:04 2001 @@ -1516,37 +1516,3 @@ 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 -ru --exclude=compile ../sys/dev/fb/fb.c ./dev/fb/fb.c --- ../sys/dev/fb/fb.c Mon Mar 26 06:41:46 2001 +++ ./dev/fb/fb.c Tue Jun 12 23:19:36 2001 @@ -45,6 +45,8 @@ #include +SET_DECLARE(videodriver_set, const videodriver_t); + /* local arrays */ /* @@ -146,7 +148,6 @@ vid_register(video_adapter_t *adp) { const video_driver_t **list; - const video_driver_t *p; int index; for (index = 0; index < adapters; ++index) { @@ -160,11 +161,10 @@ adp->va_index = index; adp->va_token = NULL; - list = (const video_driver_t **)videodriver_set.ls_items; - while ((p = *list++) != NULL) { - if (strcmp(p->name, adp->va_name) == 0) { + SET_FOREACH(list, videodriver_set) { + if (strcmp((*list)->name, adp->va_name) == 0) { adapter[index] = adp; - vidsw[index] = p->vidsw; + vidsw[index] = (*list)->vidsw; return index; } } @@ -190,11 +190,10 @@ *vid_get_switch(char *name) { const video_driver_t **list; - const video_driver_t *p; - list = (const video_driver_t **)videodriver_set.ls_items; - while ((p = *list++) != NULL) { - if (strcmp(p->name, name) == 0) + + SET_FOREACH(list, videodriver_set) { + if (strcmp((*list)->name, name) == 0) return p->vidsw; } @@ -279,12 +278,10 @@ 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) { - if (p->configure != NULL) - (*p->configure)(flags); + SET_FOREACH(list, videodriver_set) { + if ((*list)->configure != NULL) + ((*list)->configure)(flags); } return 0; diff -ru --exclude=compile ../sys/dev/fb/fbreg.h ./dev/fb/fbreg.h --- ../sys/dev/fb/fbreg.h Wed Dec 29 02:57:44 1999 +++ ./dev/fb/fbreg.h Tue Jun 12 23:11:21 2001 @@ -148,7 +148,6 @@ /* 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 -ru --exclude=compile ../sys/dev/kbd/kbd.c ./dev/kbd/kbd.c --- ../sys/dev/kbd/kbd.c Mon Mar 26 06:41:49 2001 +++ ./dev/kbd/kbd.c Tue Jun 12 23:18:49 2001 @@ -54,6 +54,8 @@ static SLIST_HEAD(, keyboard_driver) keyboard_drivers = SLIST_HEAD_INITIALIZER(keyboard_drivers); +SET_DECLARE(kbddriver_set, const keyboard_driver_t); + /* local arrays */ /* @@ -167,12 +169,12 @@ return 0; } + /* register a keyboard and associate it with a function table */ int kbd_register(keyboard_t *kbd) { const keyboard_driver_t **list; - const keyboard_driver_t *p; int index; for (index = 0; index < keyboards; ++index) { @@ -199,11 +201,10 @@ return index; } } - list = (const keyboard_driver_t **)kbddriver_set.ls_items; - while ((p = *list++) != NULL) { - if (strcmp(p->name, kbd->kb_name) == 0) { + SET_FOREACH(list, kbddriver_set) { + if (strcmp((*list)->name, kbd->kb_name) == 0) { keyboard[index] = kbd; - kbdsw[index] = p->kbdsw; + kbdsw[index] = (*list)->kbdsw; return index; } } @@ -248,16 +249,14 @@ *kbd_get_switch(char *driver) { const keyboard_driver_t **list; - const keyboard_driver_t *p; SLIST_FOREACH(p, &keyboard_drivers, link) { if (strcmp(p->name, driver) == 0) return p->kbdsw; } - list = (const keyboard_driver_t **)kbddriver_set.ls_items; - while ((p = *list++) != NULL) { - if (strcmp(p->name, driver) == 0) - return p->kbdsw; + SET_FOREACH(list, kbddriver_set) { + if (strcmp((*list)->name, driver) == 0) + return (*list)->kbdsw; } return NULL; @@ -387,16 +386,14 @@ kbd_configure(int flags) { const keyboard_driver_t **list; - const keyboard_driver_t *p; SLIST_FOREACH(p, &keyboard_drivers, link) { if (p->configure != NULL) (*p->configure)(flags); } - list = (const keyboard_driver_t **)kbddriver_set.ls_items; - while ((p = *list++) != NULL) { - if (p->configure != NULL) - (*p->configure)(flags); + SET_FOREACH(list, kbddriver_set) { + if ((*list)->configure != NULL) + ((*list)->configure)(flags); } return 0; diff -ru --exclude=compile ../sys/dev/kbd/kbdreg.h ./dev/kbd/kbdreg.h --- ../sys/dev/kbd/kbdreg.h Sun Oct 15 01:31:57 2000 +++ ./dev/kbd/kbdreg.h Tue Jun 12 23:15:46 2001 @@ -173,7 +173,6 @@ /* 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 -ru --exclude=compile ../sys/dev/syscons/scterm.c ./dev/syscons/scterm.c --- ../sys/dev/syscons/scterm.c Fri May 26 00:39:41 2000 +++ ./dev/syscons/scterm.c Tue Jun 12 23:23:09 2001 @@ -36,6 +36,8 @@ #include #include +SET_DECLARE(scterm_set, sc_term_sw_t); + /* exported subroutines */ void @@ -85,7 +87,6 @@ *sc_term_match(char *name) { sc_term_sw_t **list; - sc_term_sw_t *p; if (!LIST_EMPTY(&sc_term_list)) { LIST_FOREACH(p, &sc_term_list, link) { @@ -95,11 +96,10 @@ } } } else { - list = (sc_term_sw_t **)scterm_set.ls_items; - while ((p = *list++) != NULL) { - if ((strcmp(name, p->te_name) == 0) + SET_FOREACH(list, scterm_set) { + if ((strcmp(name, (*list)->te_name) == 0) || (strcmp(name, "*") == 0)) { - return p; + return (*list); } } } diff -ru --exclude=compile ../sys/dev/syscons/scvgarndr.c ./dev/syscons/scvgarndr.c --- ../sys/dev/syscons/scvgarndr.c Sun Oct 15 01:31:57 2000 +++ ./dev/syscons/scvgarndr.c Tue Jun 12 23:28:54 2001 @@ -80,7 +80,7 @@ static void vga_nop(scr_stat *scp, ...); -static struct linker_set vga_set; +SET_DECLARE(vga_set, sc_rndr_sw_t); static sc_rndr_sw_t txtrndrsw = { vga_txtclear, diff -ru --exclude=compile ../sys/dev/syscons/scvidctl.c ./dev/syscons/scvidctl.c --- ../sys/dev/syscons/scvidctl.c Sun Oct 15 01:31:57 2000 +++ ./dev/syscons/scvidctl.c Tue Jun 12 23:25:42 2001 @@ -40,6 +40,8 @@ #include #include +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 { @@ -791,7 +793,6 @@ *sc_render_match(scr_stat *scp, char *name, int mode) { const sc_renderer_t **list; - const sc_renderer_t *p; if (!LIST_EMPTY(&sc_rndr_list)) { LIST_FOREACH(p, &sc_rndr_list, link) { @@ -803,13 +804,12 @@ } } } else { - list = (const sc_renderer_t **)scrndr_set.ls_items; - while ((p = *list++) != NULL) { - if ((strcmp(p->name, name) == 0) - && (mode == p->mode)) { + SET_FOREACH(list, scrndr_set) { + if ((strcmp((*list)->name, name) == 0) + && (mode == (*list)->mode)) { scp->status &= ~(VR_CURSOR_ON | VR_CURSOR_BLINK); - return p->rndrsw; + return (*list)->rndrsw; } } } diff -ru --exclude=compile ../sys/dev/syscons/syscons.h ./dev/syscons/syscons.h --- ../sys/dev/syscons/syscons.h Mon May 28 18:49:35 2001 +++ ./dev/syscons/syscons.h Tue Jun 12 23:53:42 2001 @@ -342,8 +342,6 @@ 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 @@ 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 @@ 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 -ru --exclude=compile ../sys/fs/nwfs/nwfs_io.c ./fs/nwfs/nwfs_io.c --- ../sys/fs/nwfs/nwfs_io.c Sat May 26 06:41:04 2001 +++ ./fs/nwfs/nwfs_io.c Tue Jun 12 22:49:06 2001 @@ -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 -ru --exclude=compile ../sys/fs/nwfs/nwfs_node.c ./fs/nwfs/nwfs_node.c --- ../sys/fs/nwfs/nwfs_node.c Sat May 26 06:41:04 2001 +++ ./fs/nwfs/nwfs_node.c Tue Jun 12 22:49:10 2001 @@ -71,8 +71,6 @@ 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 -ru --exclude=compile ../sys/fs/smbfs/smbfs_io.c ./fs/smbfs/smbfs_io.c --- ../sys/fs/smbfs/smbfs_io.c Thu May 3 06:41:52 2001 +++ ./fs/smbfs/smbfs_io.c Tue Jun 12 22:48:27 2001 @@ -73,8 +73,6 @@ 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 -ru --exclude=compile ../sys/fs/smbfs/smbfs_node.c ./fs/smbfs/smbfs_node.c --- ../sys/fs/smbfs/smbfs_node.c Tue May 1 06:41:39 2001 +++ ./fs/smbfs/smbfs_node.c Tue Jun 12 22:48:39 2001 @@ -69,7 +69,6 @@ int smbfs_hashprint(struct mount *mp); #if 0 -extern struct linker_set sysctl_vfs_smbfs; #ifdef SYSCTL_DECL SYSCTL_DECL(_vfs_smbfs); #endif diff -ru --exclude=compile ../sys/i386/linux/linux.h ./i386/linux/linux.h --- ../sys/i386/linux/linux.h Fri Feb 16 12:36:36 2001 +++ ./i386/linux/linux.h Tue Jun 12 23:04:48 2001 @@ -366,7 +366,6 @@ /* * Pluggable ioctl handlers */ -struct linker_set; struct linux_ioctl_args; struct proc; @@ -378,9 +377,7 @@ }; 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 -ru --exclude=compile ../sys/i386/linux/linux_sysvec.c ./i386/linux/linux_sysvec.c --- ../sys/i386/linux/linux_sysvec.c Fri May 25 12:41:48 2001 +++ ./i386/linux/linux_sysvec.c Tue Jun 12 23:02:28 2001 @@ -81,7 +81,7 @@ 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 @@ { Elf32_Brandinfo **brandinfo; int error; + struct linux_ioctl_handler **lihp; error = 0; @@ -819,8 +820,8 @@ 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 @@ 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 -ru --exclude=compile ../sys/kern/init_main.c ./kern/init_main.c --- ../sys/kern/init_main.c Fri May 25 12:42:01 2001 +++ ./kern/init_main.c Tue Jun 12 21:25:44 2001 @@ -77,7 +77,6 @@ #include #include -extern struct linker_set sysinit_set; /* XXX */ void mi_startup(void); /* Should be elsewhere */ @@ -112,46 +111,44 @@ * 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 +170,18 @@ register struct sysinit **xipp; /* interior loop of sort*/ register struct sysinit *save; /* bubble*/ + if (sysinit == NULL) { + sysinit = __SET_BEGIN(sysinit_set); + sysinit_end = __SET_END(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 +199,7 @@ * 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 +215,12 @@ /* 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 -ru --exclude=compile ../sys/kern/kern_ktr.c ./kern/kern_ktr.c --- ../sys/kern/kern_ktr.c Fri Jun 8 01:00:17 2001 +++ ./kern/kern_ktr.c Tue Jun 12 21:44:09 2001 @@ -44,7 +44,6 @@ #include #include #include -#include #include #include #include diff -ru --exclude=compile ../sys/kern/kern_linker.c ./kern/kern_linker.c --- ../sys/kern/kern_linker.c Wed Jun 6 18:59:18 2001 +++ ./kern/kern_linker.c Tue Jun 12 22:43:06 2001 @@ -105,7 +105,7 @@ 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 +113,7 @@ 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 +122,8 @@ * 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 +139,7 @@ * 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 +151,7 @@ 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 +159,7 @@ 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 +169,8 @@ * 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 +185,7 @@ * 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,61 +197,55 @@ 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; +SET_DECLARE(modmetadata_set, struct mod_metadata); static int linker_file_register_modules(linker_file_t lf) { int error; - struct linker_set *modules; + struct mod_metadata **start, **stop; struct mod_metadata **mdpp; 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 (linker_file_lookup_set(lf, "modmetadata_set", &start, &stop, 0) != 0) { + if (lf == linker_kernel_file) { + start = __SET_BEGIN(modmetadata_set); + stop = __SET_END(modmetadata_set); + } else { + return 0; + } + } + for (mdpp = start; mdpp < stop; mdpp++) { if ((*mdpp)->md_type != MDT_MODULE) continue; moddata = (*mdpp)->md_data; @@ -514,6 +500,18 @@ return 0; } +/* + * Locate a linker set and its contents. + * This is a helper function to avoid linker_if.h exposure elsewhere. + */ +int +linker_file_lookup_set(linker_file_t file, const char *name, int *countp, + void ***firstp, void ***lastp) +{ + + return LINKER_LOOKUP_SET(file, name, countp, firstp, lastp); +} + caddr_t linker_file_lookup_symbol(linker_file_t file, const char* name, int deps) { @@ -986,17 +984,18 @@ } 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, **mdpp; char *modname; - int i, ver; + int ver; - for (i = 0; i < deps->ls_length; i++) { + for (mdpp = start; mdpp < stop; mdpp++) { if (preload) - mp = deps->ls_items[i]; + mp = *mdpp; else - mp = linker_reloc_ptr(lf, deps->ls_items[i]); + mp = linker_reloc_ptr(lf, *mdpp); if (mp->md_type != MDT_VERSION) continue; if (preload) { @@ -1022,15 +1021,15 @@ 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, **mdpp, **mdpp2; struct mod_depend *verinfo; int i, j, nver; int resolves; modlist_t mod; + struct sysinit **start, **stop; TAILQ_INIT(&loaded_files); TAILQ_INIT(&depended_files); @@ -1065,10 +1064,9 @@ /* * 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 +1074,19 @@ */ restart: TAILQ_FOREACH(lf, &loaded_files, loaded) { - deps = (struct linker_set*) - linker_file_lookup_symbol(lf, MDT_SETNAME, 0); + error = linker_file_lookup_set(ld, 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 (mdpp = start; mdpp < stop; mdpp++) { + mp = linker_reloc_ptr(lf, *mdpp); 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 (mdpp2 = start; mdpp2 < stop; mdpp2++) { + nmp = linker_reloc_ptr(lf, *mdpp2); if (nmp->md_type != MDT_VERSION) continue; linker_mdt_version(lf, nmp, &nmodname, NULL); @@ -1097,7 +1094,7 @@ if (strcmp(modname, nmodname) == 0) break; } - if (j < deps->ls_length) /* it's a self reference */ + if (mdpp2 < 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 +1107,9 @@ * 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 (mdpp = start; mdpp < stop; mdpp++) { + mp = linker_reloc_ptr(lf, *mdpp); if (mp->md_type != MDT_VERSION) continue; linker_mdt_version(lf, mp, &modname, &nver); @@ -1156,11 +1153,10 @@ 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(ld, MDT_SETNAME, &start, &stop, NULL); + if (!error) { + for (mdpp = start; mdpp < stop; mdpp++) { + mp = linker_reloc_ptr(lf, *mdpp); if (mp->md_type != MDT_DEPEND) continue; linker_mdt_depend(lf, mp, &modname, &verinfo); @@ -1172,7 +1168,10 @@ } } - /* 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 +1180,8 @@ } 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", &start, &stop, NULL) == 0) + sysinit_add(start, stop); linker_file_register_sysctls(lf); lf->flags |= LINKER_FILE_LINKED; } @@ -1348,11 +1345,11 @@ linker_load_dependancies(linker_file_t lf) { linker_file_t lfdep; - struct linker_set *deps; + struct mod_metadata **start, **stop, **mdpp, **mdpp2; struct mod_metadata *mp, *nmp; modlist_t mod; char *modname, *nmodname; - int i, j, ver, error = 0; + int i, j, ver, error = 0, count; /* * All files are dependant on /kernel. @@ -1364,12 +1361,10 @@ return error; } - deps = (struct linker_set*) - linker_file_lookup_symbol(lf, MDT_SETNAME, 0); - if (deps == NULL) + if (linker_file_lookup_set(ld, 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 (mdpp = start; mdpp < stop; mdpp++) { + mp = linker_reloc_ptr(lf, *mdpp); if (mp->md_type != MDT_VERSION) continue; linker_mdt_version(lf, mp, &modname, &ver); @@ -1381,21 +1376,21 @@ } } - for (i = 0; i < deps->ls_length; i++) { - mp = linker_reloc_ptr(lf, deps->ls_items[i]); + for (mdpp = start; mdpp < stop; mdpp++) { + mp = linker_reloc_ptr(lf, *mdpp); 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 (mdpp2 = start; mdpp2 < stop; mdpp2++) { + nmp = linker_reloc_ptr(lf, *mdpp2); 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 (mdpp2 < stop) /* early exit, it's a self reference */ continue; mod = modlist_lookup(modname, 0); if (mod) { /* woohoo, it's loaded already */ @@ -1416,6 +1411,6 @@ if (error) return error; - linker_addmodules(lf, deps, 0); + linker_addmodules(lf, start, stop, 0); return error; } diff -ru --exclude=compile ../sys/kern/kern_sysctl.c ./kern/kern_sysctl.c --- ../sys/kern/kern_sysctl.c Sun Jun 3 00:50:16 2001 +++ ./kern/kern_sysctl.c Mon Jun 11 18:54:37 2001 @@ -367,34 +367,18 @@ } /* - * 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 -ru --exclude=compile ../sys/kern/link_elf.c ./kern/link_elf.c --- ../sys/kern/link_elf.c Sun Jun 3 00:50:16 2001 +++ ./kern/link_elf.c Tue Jun 12 21:07:00 2001 @@ -108,6 +108,8 @@ 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 *, int *, + void ***, void ***); static kobj_method_t link_elf_methods[] = { KOBJMETHOD(linker_lookup_symbol, link_elf_lookup_symbol), @@ -117,6 +119,7 @@ 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 } }; @@ -1074,4 +1077,64 @@ *sym = (c_linker_sym_t) best; return 0; +} + +/* + * Look up a linker set on an ELF system. + */ +static int +link_elf_lookup_set(linker_file_t lf, const char *name, int *countp, + void ***startp, void ***stopp) +{ + 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(file, name, &sym); + if (error) + goto out; + link_elf_symbol_values(file, 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(file, name, &sym); + if (error) + goto out; + link_elf_symbol_values(file, sym, &symval); + if (symval.value == 0) { + error = ESRCH; + goto out; + } + stop = (void **)symval.value; + + /* and the number of entries */ + count = stop - start; + +printf("ELFSET %s: start %p, stop %p, count %d\n", name, start, stop, count); + + /* and copy out */ + if (startp) + *startp = start; + if (stopp) + *stopp = stop; + if (countp) + *countp = count; + +out: + free(setsym, M_LINKER); + return error; } diff -ru --exclude=compile ../sys/kern/linker_if.m ./kern/linker_if.m --- ../sys/kern/linker_if.m Sat Apr 29 06:26:59 2000 +++ ./kern/linker_if.m Tue Jun 12 21:04:50 2001 @@ -54,6 +54,20 @@ }; # +# 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; + int* count; + void*** start; + void*** stop; +}; + +# # Unload a file, releasing dependancies and freeing storage. # METHOD void unload { diff -ru --exclude=compile ../sys/kern/tty_cons.c ./kern/tty_cons.c --- ../sys/kern/tty_cons.c Mon Mar 26 06:42:12 2001 +++ ./kern/tty_cons.c Wed Jun 13 00:06:08 2001 @@ -99,24 +99,24 @@ 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() { - struct consdev *best_cp, *cp, **list; + struct consdev *best_cp, **list; /* * Find the first console with the highest priority. */ best_cp = NULL; - list = (struct consdev **)cons_set.ls_items; - while ((cp = *list++) != NULL) { - if (cp->cn_probe == NULL) + SET_FOREACH(list, cons_set) { + if ((*list)->cn_probe == NULL) continue; - (*cp->cn_probe)(cp); - if (cp->cn_pri > CN_DEAD && - (best_cp == NULL || cp->cn_pri > best_cp->cn_pri)) - best_cp = cp; + ((*list)->cn_probe)(*list); + if ((*list)->cn_pri > CN_DEAD && + (best_cp == NULL || (*list)->cn_pri > best_cp->cn_pri)) + best_cp = (*list); } /* diff -ru --exclude=compile ../sys/netncp/ncp_conn.c ./netncp/ncp_conn.c --- ../sys/netncp/ncp_conn.c Thu Mar 22 06:39:28 2001 +++ ./netncp/ncp_conn.c Tue Jun 12 22:50:27 2001 @@ -64,8 +64,6 @@ 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 -ru --exclude=compile ../sys/netsmb/smb_conn.c ./netsmb/smb_conn.c --- ../sys/netsmb/smb_conn.c Tue Apr 10 00:59:05 2001 +++ ./netsmb/smb_conn.c Tue Jun 12 22:50:45 2001 @@ -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 -ru --exclude=compile ../sys/pc98/pc98/scgdcrndr.c ./pc98/pc98/scgdcrndr.c --- ../sys/pc98/pc98/scgdcrndr.c Sun Oct 15 01:31:57 2000 +++ ./pc98/pc98/scgdcrndr.c Wed Jun 13 00:08:38 2001 @@ -58,7 +58,7 @@ static void gdc_nop(scr_stat *scp, ...); -static struct linker_set gdc_set; +SET_DECLARE(gdc_set, sc_rndr_sw_t); static sc_rndr_sw_t txtrndrsw = { gdc_txtclear, diff -ru --exclude=compile ../sys/sys/cons.h ./sys/cons.h --- ../sys/sys/cons.h Tue Jan 11 08:50:54 2000 +++ ./sys/cons.h Wed Jun 13 00:03:46 2001 @@ -78,7 +78,6 @@ #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 -ru --exclude=compile ../sys/sys/kernel.h ./sys/kernel.h --- ../sys/sys/kernel.h Fri Jun 8 01:01:43 2001 +++ ./sys/kernel.h Tue Jun 12 21:27:08 2001 @@ -250,7 +250,7 @@ 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 -ru --exclude=compile ../sys/sys/linker_set.h ./sys/linker_set.h --- ../sys/sys/linker_set.h Sun Feb 25 00:37:58 2001 +++ ./sys/linker_set.h Sat Apr 14 15:27:46 2001 @@ -1,5 +1,6 @@ /*- * Copyright (c) 1999 John D. Polstra + * Copyright (c) 1999,2001 Peter Wemm * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -31,56 +32,110 @@ /* * 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 + +#define __SET_BEGIN(set) \ + (&__CONCAT(__start_set_,set)) +#define __SET_END(set) \ + (&__CONCAT(__stop_set_,set)) + +/* + * 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) + + +#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 +#define __SET_BEGIN(set) \ + (&((set).ls_items[0])) +#define __SET_END(set) \ + (&((set).ls_items[(set).ls_length])) + +/* 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 + +#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_END(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_END(set) - __SET_BEGIN(set)) -#endif /* _SYS_LINKER_SET_H_ */ +#endif /* _SYS_LINKER_SET_H_ */ diff -ru --exclude=compile ../sys/sys/sysctl.h ./sys/sysctl.h --- ../sys/sys/sysctl.h Sun Jun 10 06:36:11 2001 +++ ./sys/sysctl.h Mon Jun 11 18:55:13 2001 @@ -557,8 +557,6 @@ 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, @@ -574,10 +572,6 @@ struct sysctl_oid *oidp); 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,