summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--com32/elflink/ldlinux/execute.c2
-rw-r--r--com32/include/sys/exec.h12
-rw-r--r--com32/lib/sys/module/elf_module.c51
-rw-r--r--com32/lib/sys/module/exec.c144
-rw-r--r--core/elflink/load_env32.c1
-rwxr-xr-xelf_gen_dep.sh130
7 files changed, 50 insertions, 291 deletions
diff --git a/.gitignore b/.gitignore
index 05f0d145..98ea19f8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -50,4 +50,3 @@
*GPATH
*GRTAGS
*GTAGS
-modules.dep
diff --git a/com32/elflink/ldlinux/execute.c b/com32/elflink/ldlinux/execute.c
index 635e327c..dff59e63 100644
--- a/com32/elflink/ldlinux/execute.c
+++ b/com32/elflink/ldlinux/execute.c
@@ -132,7 +132,6 @@ void execute(const char *cmdline, enum kernel_type type)
}
argv[argc] = NULL;
- module_load_dependencies(kernel, "modules.dep");
spawn_load(kernel, argc, argv);
} else if (type == KT_KERNEL) {
/* Need add one item for kernel load, as we don't use
@@ -141,7 +140,6 @@ void execute(const char *cmdline, enum kernel_type type)
} else if (type == KT_CONFIG) {
/* kernel contains the config file name */
char *spawn_load_param[2] = { args, NULL };
- module_load_dependencies("ui.c32", "modules.dep");
spawn_load(kernel, 1, spawn_load_param);
} else {
/* process the image need int 22 support */
diff --git a/com32/include/sys/exec.h b/com32/include/sys/exec.h
index 656f8e2a..9c00e4a5 100644
--- a/com32/include/sys/exec.h
+++ b/com32/include/sys/exec.h
@@ -20,16 +20,6 @@
#define EXEC_ROOT_NAME "_root_.c32"
/**
- * MODULES_DEP - The name of the standard module dependency file
- *
- * This is the file which contains information about the module dependency
- * graph ( what other modules it depends on ). The file format is identical
- * to the standard linux modules.dep file... for more information check out the
- * man page ).
- */
-#define MODULES_DEP "modules.dep"
-
-/**
* spawn_load - Load a library module or executes an executable one
* @name the name of the library/executable to use, including the extension
* (e.g. 'sort.c32')
@@ -43,8 +33,6 @@
*/
extern int spawn_load(const char *name, int argc, char **argv);
-extern int module_load_dependencies(const char*name,const char*dep_file);
-
/**
* exec_init - Initialize the dynamic execution environment.
*
diff --git a/com32/lib/sys/module/elf_module.c b/com32/lib/sys/module/elf_module.c
index 8db42208..7d8dad42 100644
--- a/com32/lib/sys/module/elf_module.c
+++ b/com32/lib/sys/module/elf_module.c
@@ -18,6 +18,8 @@
#include "elfutils.h"
#include "common.h"
+#define MAX_NR_DEPS 64
+
static int check_header(Elf32_Ehdr *elf_hdr) {
int res;
@@ -178,6 +180,8 @@ out:
return res;
}
+static int nr_needed;
+static Elf32_Word needed[MAX_NR_DEPS];;
static int prepare_dynlinking(struct elf_module *module) {
Elf32_Dyn *dyn_entry = module->dyn_table;
@@ -185,7 +189,18 @@ static int prepare_dynlinking(struct elf_module *module) {
while (dyn_entry->d_tag != DT_NULL) {
switch (dyn_entry->d_tag) {
case DT_NEEDED:
- // TODO: Manage dependencies here
+ /*
+ * It's unlikely there'll be more than
+ * MAX_NR_DEPS DT_NEEDED entries but if there
+ * are then inform the user that we ran out of
+ * space.
+ */
+ if (nr_needed < MAX_NR_DEPS)
+ needed[nr_needed++] = dyn_entry->d_un.d_ptr;
+ else {
+ printf("Too many dependencies!\n");
+ return -1;
+ }
break;
case DT_HASH:
module->hash_table =
@@ -447,11 +462,45 @@ int module_load(struct elf_module *module) {
CHECKED(res, load_segments(module, &elf_hdr), error);
//printf("bleah... 3\n");
// Obtain dynamic linking information
+ nr_needed = 0;
CHECKED(res, prepare_dynlinking(module), error);
//printf("check... 4\n");
//
//dump_elf_module(module);
+ /* Find modules we need to load as dependencies */
+ if (module->str_table) {
+ int i, n;
+
+ /*
+ * nr_needed can be modified by recursive calls to
+ * module_load() so keep a local copy on the stack.
+ */
+ n = nr_needed;
+ for (i = 0; i < n; i++) {
+ size_t len, j;
+ char *dep, *p;
+
+ dep = module->str_table + needed[i];
+
+ /* strip everything but the last component */
+ j = len = strlen(dep);
+ if (!len)
+ continue;
+
+ p = dep + len - 1;
+ while (j > 0 && *p && *p != '/') {
+ p--;
+ j--;
+ }
+
+ if (*p++ == '/') {
+ char argv[2] = { p, NULL };
+ spawn_load(p, 1, argv);
+ }
+ }
+ }
+
// Check the symbols for duplicates / missing definitions
CHECKED(res, check_symbols(module), error);
//printf("check... 5\n");
diff --git a/com32/lib/sys/module/exec.c b/com32/lib/sys/module/exec.c
index 1ed3263b..71d31929 100644
--- a/com32/lib/sys/module/exec.c
+++ b/com32/lib/sys/module/exec.c
@@ -346,150 +346,6 @@ int spawn_load(const char *name, int argc, char **argv)
*/
}
-/*
- * Avoid circular dependencies.
- *
- * It's possible that someone messed up the modules.dep file and that
- * it includes circular dependencies, so we need to take steps here to
- * avoid looping in module_load_dependencies() forever.
- *
- * We build a singly-linked list of modules that are in the middle of
- * being loaded. When they have completed loading their entry is
- * removed from this list in LIFO order (new entries are always added
- * to the head of the list).
- */
-struct loading_dep {
- const char *name;
- struct module_dep *next;
-};
-static struct loading_dep *loading_deps;
-
-/*
- * Remember that because we insert elements in a LIFO order we need to
- * start from the end of the list and work towards the front so that
- * we print the modules in the order in which we tried to load them.
- *
- * Yay for recursive function calls.
- */
-static void print_loading_dep(struct loading_dep *dep)
-{
- if (dep) {
- print_loading_dep(dep->next);
- printf("\t\t\"%s\"\n", dep->name);
- }
-}
-
-int module_load_dependencies(const char *name,const char *dep_file)
-{
- FILE *d_file=fopen(dep_file,"r");
- char line[2048],aux[2048],temp_name[MODULE_NAME_SIZE],slbz[24];
- int i=0,j=0,res=0;
- struct loading_dep *dep;
-
- if(d_file==NULL)
- {
- DBG_PRINT("Could not open object file '%s'\n",dep_file);
- return -1;
- }
-
- /*
- * Are we already in the middle of loading this module's
- * dependencies?
- */
- for (dep = loading_deps; dep; dep = dep->next) {
- if (!strcasecmp(dep->name, name))
- break; /* found */
- }
-
- if (dep) {
- struct loading_dep *last, *prev;
-
- /* Dup! */
- printf("\t\tCircular depedency detected when loading "
- "modules!\n");
- printf("\t\tModules dependency chain looks like this,\n\n");
- print_loading_dep(loading_deps);
- printf("\n\t\t... and we tried to load \"%s\" again\n", name);
-
- return -1;
- } else {
- dep = malloc(sizeof(*dep));
- if (!dep) {
- printf("Failed to alloc memory for loading_dep\n");
- return -1;
- }
-
- dep->name = name;
- dep->next = loading_deps;
-
- /* Insert at the head of the list */
- loading_deps = dep;
- }
-
- /* Note from feng:
- * new modues.dep has line like this:
- * a.c32: b.32 c.c32 d.c32
- * with desktop glibc
- * sscanf(line,"%[^:]: %[^\n]", temp_name, aux);
- * works, which doesn't work here
- */
- memset(temp_name, 0, sizeof(temp_name));
- memset(aux, 0, sizeof(aux));
- while (1) {
- if(fgets(line,2048,d_file)==NULL)
- break;
-
- //sscanf(line,"%s %[^\t\n]s",temp_name,aux);
- //sscanf(line,"%[^:]: %[^\n]", temp_name, aux);
- //sscanf(line,"%[^:]: %[^\n]\n", temp_name, aux);
-
- sscanf(line,"%[^:]:", temp_name);
- if (!strncmp(name, temp_name, strlen(name))) {
- /* The next 2 chars should be ':' and ' ' */
- i = strlen(temp_name);
- if (line[i] != ':' || line[i+1] != ' ')
- break;
-
- i +=2;
- j = 0;
- while (line[i] != '\n')
- aux[j++] = line[i++];
- aux[j] = '\0';
- //dprintf("found dependency: temp_name = %s, aux = %s, name = %s", temp_name, aux, name);
- break;
- }
- }
- fclose(d_file);
-
- /* Reuse temp_name for dependent module name buffer */
- memset(temp_name, 0, sizeof(temp_name));
- i = 0;
- while (aux[i]) {
- sscanf(aux + i, "%s", temp_name);
- //dprintf("load module: %s", temp_name);
- i += strlen(temp_name);
- i++; /* skip a space */
-
- if (strlen(temp_name)) {
- char *argv[2] = { temp_name, NULL };
- int ret;
-
- ret = module_load_dependencies(temp_name,
- MODULES_DEP);
- if (!ret) {
- if (spawn_load(temp_name, 1, argv) < 0)
- continue;
- }
- }
- }
-
- /* Remove our entry from the head of loading_deps */
- loading_deps = loading_deps->next;
- free(dep);
-
- return 0;
-}
-
void exec_term(void)
{
modules_term();
diff --git a/core/elflink/load_env32.c b/core/elflink/load_env32.c
index 793ecd5a..e6396534 100644
--- a/core/elflink/load_env32.c
+++ b/core/elflink/load_env32.c
@@ -75,6 +75,5 @@ void load_env32(com32sys_t * regs)
init_module_subsystem(&core_module);
- module_load_dependencies(LDLINUX, "modules.dep");
spawn_load(LDLINUX, 1, argv);
}
diff --git a/elf_gen_dep.sh b/elf_gen_dep.sh
deleted file mode 100755
index 1badb64c..00000000
--- a/elf_gen_dep.sh
+++ /dev/null
@@ -1,130 +0,0 @@
-#!/bin/sh
-
-#######################################################
-# Round 1: get all the loacl and external symbols
-#######################################################
-
-for i in core/isolinux.elf core/pxelinux.elf com32/*/*.c32 com32/*/*/*.c32
-do
- # module=$(echo $i | sed "s/^\(.*\).o$/\1/")
-
- # remove the path infomation
- module=$(echo $i | sed "s/^.*\/\(.*\)$/\1/")
-
- readelf -s $i > temp.txt
- #Get the last 2 items of each line
- cut -c47- temp.txt > $module.txt
- rm temp.txt
-
- #Get the unresolved symbols
- sed -n -e "/UND $/d" -e "/_GLOBAL_OFFSET_TABLE_/d" -e "s/^.UND.\(.*\)$/\1/p" $module.txt > $module.ext
-
- #Get the local symbols
- sed -n -e "/UND/d" -e "/ABS/d" -e "/...[0-9] $/d" -e "/...[0-9] \./d" -e "/...[0-9]/p" $module.txt > $module.int
- sed -i -e "s/^.....//g" $module.int
- sed -i -e "s/^\(.*\)$/\1 <$module>/g" $module.int
- # Delete all whitespace
- sed -i -e "s/^[ \t]*$//g" $module.int
-
- cat $module.int >> all.txt
-done
-
-
-touch modules.dep
-
-#######################################################
-# Round 2: get all the loacl and external symbols
-#######################################################
-
-# Consolidate the dependent modules to one line and remove
-# the redundant ones, and the "core"
-rm_cr ()
-{
- touch rmcr.tmp
- all_dep=$module:
- space=' '
-
- while read line
- do
- # skip the module which is alreay on the list
- grep $line rmcr.tmp > /dev/null && continue
-
- # grep extlinux/isolinux and remove them
- echo $line | grep extlinux > /dev/null && continue
- echo $line | grep isolinux > /dev/null && continue
- echo $line | grep pxelinux > /dev/null && continue
- echo $line | grep ldlinux > /dev/null && continue
-
- all_dep=$all_dep$space$line
- echo $all_dep > rmcr.tmp
- done
-
- echo $all_dep >> modules.dep
- rm rmcr.tmp
-}
-
-# Find the symbol belongs to which module by screening all.txt, do it
-# one by one, and the result "resolve.tmp" will be a file like:
-# a.c32
-# b.c32
-# c.c32
-resolve_sym ()
-{
- touch resolve.tmp
-
- while read symbol
- do
- # If no one provides the symbol we're trying to
- # resolve then add it to the list of unresolved
- # symbols.
- grep -q $symbol all.txt
- if [ $? -ne 0 ]; then
- # We only need to add the symbol once
- if [[ ! "$unresolved_symbols" =~ "$symbol" ]]; then
- unresolved_symbols="$unresolved_symbols $symbol"
- fi
- else
- #echo $symbol
- sed -n -e "s/^$symbol <\(.*\)>/\1/p" all.txt | head -n1 >> resolve.tmp
- #grep $symbol all.txt
- fi
- done
-
- rm_cr < resolve.tmp
- rm resolve.tmp
-}
-
-#only test name start with a/b
-#rm [c-z]*.ext
-
-if [ -e modules.dep ]
-then
- rm modules.dep
- touch modules.dep
-fi
-
-# Don't need to resolve the core symbols
-for i in extlinux isolinux pxelinux
-do
- if [ -e $i.elf.ext ]
- then
- rm $i.elf.ext
- fi
-done
-
-for i in *.ext
-do
- module=$(echo $i | sed "s/^\(.*\).ext$/\1/")
- resolve_sym < $i
-done
-
-# Do some cleanup
-rm *.txt
-rm *.ext
-rm *.int
-
-if [ "$unresolved_symbols" ]; then
- echo "WARNING: These symbols could not be resolved:" $unresolved_symbols
-fi
-
-echo ELF modules dependency is bult up, pls check modules.dep!