module: Actually use last component of DT_NEEDED pathname
authorMatt Fleming <matt.fleming@intel.com>
Fri, 1 Jun 2012 12:24:51 +0000 (13:24 +0100)
committerMatt Fleming <matt.fleming@intel.com>
Fri, 8 Jun 2012 07:10:22 +0000 (08:10 +0100)
The comment in module_load() claims that we strip everything from the
DT_NEEDED pathnames but the last component. That's not true as we
leave the initial '/', which works fine if the module is in the root
directory, but not so well if we're in a sub-directory. Worse still,
if the DT_NEEDED entry pathname doesn't include a '/' the module is
skipped entirely.

We should also be loading dependencies in reverse order, as modules
loaded because of DT_NEEDED entries may also have dependencies and
their dependencies should be loaded first.

Also, now we need the strrchr() implementation in the core, so move
strrchr.o into $CORELIBOBJS.

Signed-off-by: Matt Fleming <matt.fleming@intel.com>
com32/lib/Makefile
com32/lib/sys/module/elf_module.c

index daa7284..75771d9 100644 (file)
@@ -125,7 +125,7 @@ LIBOTHER_OBJS = \
        strnlen.o                                                       \
        strncat.o strndup.o             \
        stpncpy.o                                               \
-       strntoimax.o strntoumax.o strrchr.o strsep.o strspn.o strstr.o  \
+       strntoimax.o strntoumax.o strsep.o strspn.o strstr.o    \
        strtoimax.o strtok.o strtol.o strtoll.o strtoul.o strtoull.o    \
        strtoumax.o vprintf.o vsprintf.o                \
        asprintf.o vasprintf.o                  \
@@ -169,7 +169,7 @@ CORELIBOBJS = \
        fputs.o fwrite2.o fwrite.o fgetc.o fclose.o errno.o lmalloc.o   \
        sys/err_read.o sys/err_write.o sys/null_read.o                  \
        sys/stdcon_write.o sys/openconsole.o                            \
-       syslinux/memscan.o                                              \
+       syslinux/memscan.o strrchr.o                                    \
        libgcc/__ashldi3.o libgcc/__udivdi3.o                           \
        libgcc/__negdi2.o libgcc/__ashrdi3.o libgcc/__lshrdi3.o         \
        libgcc/__muldi3.o libgcc/__udivmoddi4.o libgcc/__umoddi3.o      \
index 3e37384..7d892aa 100644 (file)
@@ -513,11 +513,15 @@ int module_load(struct elf_module *module) {
                /*
                 * nr_needed can be modified by recursive calls to
                 * module_load() so keep a local copy on the stack.
+                *
+                * Note that we have to load the dependencies in
+                * reverse order.
                 */
-               n = nr_needed;
-               for (i = 0; i < n; i++) {
+               n = nr_needed - 1;
+               for (i = n; i >= 0; i--) {
                        size_t len, j;
                        char *dep, *p;
+                       char *argv[2] = { NULL, NULL };
 
                        dep = module->str_table + needed[i];
 
@@ -526,16 +530,14 @@ int module_load(struct elf_module *module) {
                        if (!len)
                                continue;
 
-                       p = dep + len - 1;
-                       while (j > 0 && *p && *p != '/') {
-                               p--;
-                               j--;
-                       }
+                       if (strchr(dep, '/')) {
+                               p = strrchr(dep, '/');
+                               p++;
+                       } else
+                               p = dep;
 
-                       if (*p++ == '/') {
-                               char *argv[2] = { p, NULL };
-                               spawn_load(p, 1, argv);
-                       }
+                       argv[0] = p;
+                       spawn_load(p, 1, argv);
                }
        }