diff options
author | px4dev <px4@purgatory.org> | 2013-01-11 00:39:22 -0800 |
---|---|---|
committer | px4dev <px4@purgatory.org> | 2013-01-11 00:39:22 -0800 |
commit | ccf9882dc5dbe38b621110f82c4e2ff63aef900e (patch) | |
tree | 18b0af628174bf27815dd52a376c8b72b6a626d4 /nuttx/binfmt/binfmt_loadmodule.c | |
parent | 40dfbf0d977729951d73bcb089ca8f89c7b83efe (diff) | |
parent | 0f2decb70f505b108999fcdb80e89d7aae6760ce (diff) | |
download | px4-firmware-ccf9882dc5dbe38b621110f82c4e2ff63aef900e.tar.gz px4-firmware-ccf9882dc5dbe38b621110f82c4e2ff63aef900e.tar.bz2 px4-firmware-ccf9882dc5dbe38b621110f82c4e2ff63aef900e.zip |
Merge branch 'master' into nuttx-merge-5447
Diffstat (limited to 'nuttx/binfmt/binfmt_loadmodule.c')
-rw-r--r-- | nuttx/binfmt/binfmt_loadmodule.c | 127 |
1 files changed, 105 insertions, 22 deletions
diff --git a/nuttx/binfmt/binfmt_loadmodule.c b/nuttx/binfmt/binfmt_loadmodule.c index 01ab8cc88..112a6b35b 100644 --- a/nuttx/binfmt/binfmt_loadmodule.c +++ b/nuttx/binfmt/binfmt_loadmodule.c @@ -43,7 +43,8 @@ #include <debug.h> #include <errno.h> -#include <nuttx/binfmt.h> +#include <nuttx/kmalloc.h> +#include <nuttx/binfmt/binfmt.h> #include "binfmt_internal.h" @@ -66,6 +67,57 @@ ****************************************************************************/ /**************************************************************************** + * Name: load_absmodule + * + * Description: + * Load a module into memory, bind it to an exported symbol take, and + * prep the module for execution. bin->filename is known to be an absolute + * path to the file to be loaded. + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned on + * failure. + * + ****************************************************************************/ + +static int load_absmodule(FAR struct binary_s *bin) +{ + FAR struct binfmt_s *binfmt; + int ret = -ENOENT; + + bdbg("Loading %s\n", bin->filename); + + /* Disabling pre-emption should be sufficient protection while accessing + * the list of registered binary format handlers. + */ + + sched_lock(); + + /* Traverse the list of registered binary format handlers. Stop + * when either (1) a handler recognized and loads the format, or + * (2) no handler recognizes the format. + */ + + for (binfmt = g_binfmts; binfmt; binfmt = binfmt->next) + { + /* Use this handler to try to load the format */ + + ret = binfmt->load(bin); + if (ret == OK) + { + /* Successfully loaded -- break out with ret == 0 */ + + bvdbg("Successfully loaded module %s\n", bin->filename); + dump_module(bin); + break; + } + } + + sched_unlock(); + return ret; +} + +/**************************************************************************** * Public Functions ****************************************************************************/ @@ -85,42 +137,72 @@ int load_module(FAR struct binary_s *bin) { - FAR struct binfmt_s *binfmt; - int ret = -ENOENT; + int ret = -EINVAL; + + /* Verify that we were provided something to work with */ #ifdef CONFIG_DEBUG if (bin && bin->filename) #endif { - bdbg("Loading %s\n", bin->filename); - - /* Disabling pre-emption should be sufficient protection while - * accessing the list of registered binary format handlers. + /* Were we given a relative path? Or an absolute path to the file to + * be loaded? Absolute paths start with '/'. */ - sched_lock(); +#ifdef CONFIG_BINFMT_EXEPATH + if (bin->filename[0] != '/') + { + FAR const char *relpath; + FAR char *fullpath; + EXEPATH_HANDLE handle; - /* Traverse the list of registered binary format handlers. Stop - * when either (1) a handler recognized and loads the format, or - * (2) no handler recognizes the format. - */ + /* Set aside the relative path */ - for (binfmt = g_binfmts; binfmt; binfmt = binfmt->next) - { - /* Use this handler to try to load the format */ + relpath = bin->filename; + ret = -ENOENT; + + /* Initialize to traverse the PATH variable */ - ret = binfmt->load(bin); - if (ret == OK) + handle = exepath_init(); + if (handle) { - /* Successfully loaded -- break out with ret == 0 */ + /* Get the next absolute file path */ - bvdbg("Successfully loaded module %s\n", bin->filename); - dump_module(bin); - break; + while ((fullpath = exepath_next(handle, relpath)) != NULL) + { + /* Try to load the file at this path */ + + bin->filename = fullpath; + ret = load_absmodule(bin); + + /* Free the allocated fullpath */ + + kfree(fullpath); + + /* Break out of the loop with ret == OK on success */ + + if (ret == OK) + { + break; + } + } } + + /* Restore the relative path. This is not needed for anything + * but debug output after the file has been loaded. + */ + + bin->filename = relpath; } + else +#endif + { + /* We already have the one and only absolute path to the file to + * be loaded. + */ - sched_unlock(); + ret = load_absmodule(bin); + } } /* This is an end-user function. Return failures via errno */ @@ -131,6 +213,7 @@ int load_module(FAR struct binary_s *bin) errno = -ret; return ERROR; } + return OK; } |