Source-Changes-HG archive

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

[src/trunk]: src Ensure that rump kernel component constructors from the main...



details:   https://anonhg.NetBSD.org/src/rev/376ff0bfbe69
branches:  trunk
changeset: 785331:376ff0bfbe69
user:      pooka <pooka%NetBSD.org@localhost>
date:      Fri Mar 08 19:04:27 2013 +0000

description:
Ensure that rump kernel component constructors from the main object
get processed.  This applies to ones which were linked statically.
Unfortunately, that's where it got a bit tricky, since the dlsym()
interface searches the handle and all its dependencies.  For the main
object the list of dependencies includes all the dynamic rump kernel
components that were included when the binary is linked.  So, a long
story short, make only one pass through the objects to harvest all the
component entries, weed out the dupes, and initialize components from
an in-memory dupe-free list when so requested.

diffstat:

 lib/librumpuser/rumpuser_dl.c    |  131 +++++++++++++-------------------------
 sys/rump/include/rump/rumpuser.h |    9 +-
 sys/rump/librump/rumpkern/rump.c |   57 +++++++++++++---
 3 files changed, 94 insertions(+), 103 deletions(-)

diffs (truncated from 375 to 300 lines):

diff -r 7838dffad81e -r 376ff0bfbe69 lib/librumpuser/rumpuser_dl.c
--- a/lib/librumpuser/rumpuser_dl.c     Fri Mar 08 17:02:29 2013 +0000
+++ b/lib/librumpuser/rumpuser_dl.c     Fri Mar 08 19:04:27 2013 +0000
@@ -1,4 +1,4 @@
-/*      $NetBSD: rumpuser_dl.c,v 1.12 2013/01/14 21:00:16 pooka Exp $  */
+/*      $NetBSD: rumpuser_dl.c,v 1.13 2013/03/08 19:04:27 pooka Exp $  */
 
 /*
  * Copyright (c) 2009 Antti Kantee.  All Rights Reserved.
@@ -33,7 +33,7 @@
 #include "rumpuser_port.h"
 
 #if !defined(lint)
-__RCSID("$NetBSD: rumpuser_dl.c,v 1.12 2013/01/14 21:00:16 pooka Exp $");
+__RCSID("$NetBSD: rumpuser_dl.c,v 1.13 2013/03/08 19:04:27 pooka Exp $");
 #endif /* !lint */
 
 #include <sys/types.h>
@@ -67,12 +67,6 @@
 #define Elf_Symindx uint32_t
 #endif
 
-/*
- * Linux ld.so requires a valid handle for dlinfo(), so use the main
- * handle.  We initialize this variable in rumpuser_dl_bootstrap()
- */
-static void *mainhandle;
-
 static void *
 reservespace(void *store, size_t *storesize,
        size_t storeoff, size_t required)
@@ -146,9 +140,13 @@
  * the address the dso is mapped at.  On Linux, they seem to contain
  * the absolute address.  I couldn't find anything definite from a quick
  * read of the standard and therefore I will not go and figure beyond ifdef.
+ * On Solaris, the main object works differently ... uuuuh.
  */
-#ifdef __linux__
+#if defined(__linux__)
 #define adjptr(_map_, _ptr_) ((void *)(_ptr_))
+#elif defined(__sun__)
+#define adjptr(_map_, _ptr_) \
+    (mainmap_p(_map_) ? (void *)(_ptr_) : (void *)(_map_->l_addr + (_ptr_)))
 #else
 #define adjptr(_map_, _ptr_) ((void *)(_map_->l_addr + (_ptr_)))
 #endif
@@ -341,29 +339,24 @@
 }
 
 static void
-process(const char *soname, rump_modinit_fn domodinit)
+process_object(void *handle,
+       rump_modinit_fn domodinit, rump_compload_fn docompload)
 {
-       void *handle;
        const struct modinfo *const *mi_start, *const *mi_end;
-
-       if (strstr(soname, "librump") == NULL)
-               return;
-
-       handle = dlopen(soname, RTLD_LAZY);
-       if (handle == NULL)
-               return;
+       struct rump_component *const *rc, *const *rc_end;
 
        mi_start = dlsym(handle, "__start_link_set_modules");
-       if (!mi_start)
-               goto out;
        mi_end = dlsym(handle, "__stop_link_set_modules");
-       if (!mi_end)
-               goto out;
+       if (mi_start && mi_end)
+               domodinit(mi_start, (size_t)(mi_end-mi_start));
 
-       domodinit(mi_start, (size_t)(mi_end-mi_start));
-
- out:
-       dlclose(handle);
+       rc = dlsym(handle, "__start_link_set_rump_components");
+       rc_end = dlsym(handle, "__stop_link_set_rump_components");
+       if (rc && rc_end) {
+               for (; rc < rc_end; rc++)
+                       docompload(*rc);
+               assert(rc == rc_end);
+       }
 }
 
 /*
@@ -372,17 +365,20 @@
  */
 void
 rumpuser_dl_bootstrap(rump_modinit_fn domodinit,
-       rump_symload_fn symload)
+       rump_symload_fn symload, rump_compload_fn compload)
 {
-       struct link_map *map, *origmap;
+       struct link_map *map, *origmap, *mainmap;
+       void *mainhandle;
        int error;
 
        mainhandle = dlopen(NULL, RTLD_NOW);
-       if (dlinfo(mainhandle, RTLD_DI_LINKMAP, &origmap) == -1) {
+       if (dlinfo(mainhandle, RTLD_DI_LINKMAP, &mainmap) == -1) {
                fprintf(stderr, "warning: rumpuser module bootstrap "
                    "failed: %s\n", dlerror());
                return;
        }
+       origmap = mainmap;
+
        /*
         * Process last->first because that's the most probable
         * order for dependencies
@@ -397,10 +393,7 @@
         */
        error = 0;
        for (map = origmap; map && !error; map = map->l_prev) {
-               if (strstr(map->l_name, "librump") != NULL)
-                       error = getsymbols(map);
-               /* this should be the main object */
-               else if (!map->l_addr && map->l_prev == NULL)
+               if (strstr(map->l_name, "librump") != NULL || map == mainmap)
                        error = getsymbols(map);
        }
 
@@ -432,77 +425,45 @@
        free(strtab);
 
        /*
-        * Next, load modules from dynlibs.
+        * Next, load modules and components.
+        *
+        * Simply loop through all objects, ones unrelated to rump kernels
+        * will not contain link_set_rump_components (well, not including
+        * "sabotage", but that needs to be solved at another level anyway).
         */
-       for (map = origmap; map; map = map->l_prev)
-               process(map->l_name, domodinit);
-}
-
-void
-rumpuser_dl_component_init(int type, rump_component_init_fn compinit)
-{
-       struct link_map *map;
+       for (map = origmap; map; map = map->l_prev) {
+               void *handle;
 
-       if (dlinfo(mainhandle, RTLD_DI_LINKMAP, &map) == -1) {
-               fprintf(stderr, "warning: rumpuser module bootstrap "
-                   "failed: %s\n", dlerror());
-               return;
-       }
-
-       for (; map->l_next; map = map->l_next)
-               continue;
-       for (; map; map = map->l_prev) {
-               if (strstr(map->l_name, "librump") != NULL) {
-                       void *handle;
-                       struct rump_component **rc, **rc_end;
-
+               if (map == mainmap) {
+                       handle = mainhandle;
+               } else {
                        handle = dlopen(map->l_name, RTLD_LAZY);
                        if (handle == NULL)
                                continue;
-
-                       rc = dlsym(handle,
-                           "__start_link_set_rump_components");
-                       if (!rc)
-                               goto loop;
-                       rc_end = dlsym(handle,
-                           "__stop_link_set_rump_components");
-                       if (!rc_end)
-                               goto loop;
-
-                       for (; rc < rc_end; rc++)
-                               compinit(*rc, type);
-                       assert(rc == rc_end);
- loop:
+               }
+               process_object(handle, domodinit, compload);
+               if (map != mainmap)
                        dlclose(handle);
-               }
        }
 }
 #else
-void
-rumpuser_dl_bootstrap(rump_modinit_fn domodinit,
-       rump_symload_fn symload)
-{
-
-       fprintf(stderr, "Warning, dlinfo() unsupported on host?\n");
-}
-
 /*
  * "default" implementation for platforms where we don't support
  * dynamic linking.  Assumes that all rump kernel components are
- * statically linked with the local client.
+ * statically linked with the local client.  No need to handle modules
+ * since the module code does that all by itself.
  */
-
-extern void *__start_link_set_rump_components;
-extern void *__stop_link_set_rump_components;
 void
-rumpuser_dl_component_init(int type, rump_component_init_fn compinit)
+rumpuser_dl_bootstrap(rump_modinit_fn domodinit,
+       rump_symload_fn symload, rump_compload_fn compload)
 {
+       extern void *__start_link_set_rump_components;
+       extern void *__stop_link_set_rump_components;
        void **rc = &__start_link_set_rump_components;
        void **rc_end = &__stop_link_set_rump_components;
 
        for (; rc < rc_end; rc++)
-               compinit(*rc, type);
-
+               compload(*rc);
 }
 #endif
 
diff -r 7838dffad81e -r 376ff0bfbe69 sys/rump/include/rump/rumpuser.h
--- a/sys/rump/include/rump/rumpuser.h  Fri Mar 08 17:02:29 2013 +0000
+++ b/sys/rump/include/rump/rumpuser.h  Fri Mar 08 19:04:27 2013 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: rumpuser.h,v 1.74 2013/03/01 13:52:31 pooka Exp $      */
+/*     $NetBSD: rumpuser.h,v 1.75 2013/03/08 19:04:28 pooka Exp $      */
 
 /*
  * Copyright (c) 2007-2011 Antti Kantee.  All Rights Reserved.
@@ -38,7 +38,7 @@
 #include <stdint.h>
 #endif
 
-#define RUMPUSER_VERSION 14
+#define RUMPUSER_VERSION 15
 int rumpuser_getversion(void);
 
 int rumpuser_daemonize_begin(void);
@@ -218,9 +218,8 @@
 struct rump_component;
 typedef void (*rump_modinit_fn)(const struct modinfo *const *, size_t);
 typedef int (*rump_symload_fn)(void *, uint64_t, char *, uint64_t);
-typedef void (*rump_component_init_fn)(struct rump_component *, int);
-void rumpuser_dl_bootstrap(rump_modinit_fn, rump_symload_fn);
-void rumpuser_dl_component_init(int, rump_component_init_fn);
+typedef void (*rump_compload_fn)(const struct rump_component *);
+void rumpuser_dl_bootstrap(rump_modinit_fn, rump_symload_fn, rump_compload_fn);
 void *rumpuser_dl_globalsym(const char *);
 
 /* syscall proxy routines */
diff -r 7838dffad81e -r 376ff0bfbe69 sys/rump/librump/rumpkern/rump.c
--- a/sys/rump/librump/rumpkern/rump.c  Fri Mar 08 17:02:29 2013 +0000
+++ b/sys/rump/librump/rumpkern/rump.c  Fri Mar 08 19:04:27 2013 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: rump.c,v 1.254 2013/03/07 22:12:34 pooka Exp $ */
+/*     $NetBSD: rump.c,v 1.255 2013/03/08 19:04:28 pooka Exp $ */
 
 /*
  * Copyright (c) 2007-2011 Antti Kantee.  All Rights Reserved.
@@ -26,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rump.c,v 1.254 2013/03/07 22:12:34 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rump.c,v 1.255 2013/03/08 19:04:28 pooka Exp $");
 
 #include <sys/systm.h>
 #define ELFSIZE ARCH_ELFSIZE
@@ -106,6 +106,9 @@
 static void rump_proxy_lwpexit(void);
 static void rump_proxy_execnotify(const char *);
 
+static void rump_component_load(const struct rump_component *);
+static struct lwp *bootlwp;
+
 static char rump_msgbuf[16*1024]; /* 16k should be enough for std rump needs */
 
 #ifdef LOCKDEBUG
@@ -348,6 +351,7 @@
        rumpuser_set_curlwp(NULL);
        initproc = &proc0; /* borrow proc0 before we get initproc started */
        rump_schedule();
+       bootlwp = curlwp;
 
        percpu_init();
        inittimecounter();
@@ -400,7 +404,8 @@
                uvm.pagedaemon_lwp = NULL; /* doesn't match curlwp */
 
        /* process dso's */
-       rumpuser_dl_bootstrap(add_linkedin_modules, rump_kernelfsym_load);
+       rumpuser_dl_bootstrap(add_linkedin_modules,
+           rump_kernelfsym_load, rump_component_load);
 
        rump_component_init(RUMP_COMPONENT_KERN);
 
@@ -520,6 +525,7 @@
        rump_component_init(RUMP_COMPONENT_POSTINIT);



Home | Main Index | Thread Index | Old Index