aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Fleming <matt.fleming@intel.com>2012-06-01 13:24:51 +0100
committerMatt Fleming <matt.fleming@intel.com>2012-06-08 08:10:22 +0100
commite33c487c3930357a4f53455e019c72be0477ef98 (patch)
tree18adf73139ed8ddad5ea4bc85dffa48c82b8d67d
parent6bf3351711fe6c3f5731e519c2fbb298c6bcf2b4 (diff)
downloadsyslinux-e33c487c3930357a4f53455e019c72be0477ef98.tar.gz
syslinux-e33c487c3930357a4f53455e019c72be0477ef98.tar.xz
syslinux-e33c487c3930357a4f53455e019c72be0477ef98.zip
module: Actually use last component of DT_NEEDED pathname
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>
-rw-r--r--com32/lib/Makefile4
-rw-r--r--com32/lib/sys/module/elf_module.c24
2 files changed, 15 insertions, 13 deletions
diff --git a/com32/lib/Makefile b/com32/lib/Makefile
index daa7284e..75771d97 100644
--- a/com32/lib/Makefile
+++ b/com32/lib/Makefile
@@ -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 \
diff --git a/com32/lib/sys/module/elf_module.c b/com32/lib/sys/module/elf_module.c
index 3e373847..7d892aa9 100644
--- a/com32/lib/sys/module/elf_module.c
+++ b/com32/lib/sys/module/elf_module.c
@@ -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);
}
}