diff options
Diffstat (limited to 'nuttx/binfmt/binfmt_execmodule.c')
-rw-r--r-- | nuttx/binfmt/binfmt_execmodule.c | 103 |
1 files changed, 94 insertions, 9 deletions
diff --git a/nuttx/binfmt/binfmt_execmodule.c b/nuttx/binfmt/binfmt_execmodule.c index 1b511b0cb..400451c40 100644 --- a/nuttx/binfmt/binfmt_execmodule.c +++ b/nuttx/binfmt/binfmt_execmodule.c @@ -47,7 +47,7 @@ #include <errno.h> #include <nuttx/arch.h> -#include <nuttx/binfmt.h> +#include <nuttx/binfmt/binfmt.h> #include "os_internal.h" #include "binfmt_internal.h" @@ -71,6 +71,62 @@ ****************************************************************************/ /**************************************************************************** + * Name: exec_ctors + * + * Description: + * Execute C++ static constructors. + * + * Input Parameters: + * loadinfo - Load state information + * + * Returned Value: + * 0 (OK) is returned on success and a negated errno is returned on + * failure. + * + ****************************************************************************/ + +#ifdef CONFIG_BINFMT_CONSTRUCTORS +static inline int exec_ctors(FAR const struct binary_s *binp) +{ + binfmt_ctor_t *ctor = binp->ctors; +#ifdef CONFIG_ADDRENV + hw_addrenv_t oldenv; + int ret; +#endif + int i; + + /* Instantiate the address enviroment containing the constructors */ + +#ifdef CONFIG_ADDRENV + ret = up_addrenv_select(binp->addrenv, &oldenv); + if (ret < 0) + { + bdbg("up_addrenv_select() failed: %d\n", ret); + return ret; + } +#endif + + /* Execute each constructor */ + + for (i = 0; i < binp->nctors; i++) + { + bvdbg("Calling ctor %d at %p\n", i, (FAR void *)ctor); + + (*ctor)(); + ctor++; + } + + /* Restore the address enviroment */ + +#ifdef CONFIG_ADDRENV + return up_addrenv_restore(oldenv); +#else + return OK; +#endif +} +#endif + +/**************************************************************************** * Public Functions ****************************************************************************/ @@ -87,7 +143,7 @@ * ****************************************************************************/ -int exec_module(FAR const struct binary_s *bin, int priority) +int exec_module(FAR const struct binary_s *binp, int priority) { FAR _TCB *tcb; #ifndef CONFIG_CUSTOM_STACK @@ -100,14 +156,14 @@ int exec_module(FAR const struct binary_s *bin, int priority) /* Sanity checking */ #ifdef CONFIG_DEBUG - if (!bin || !bin->ispace || !bin->entrypt || bin->stacksize <= 0) + if (!binp || !binp->entrypt || binp->stacksize <= 0) { err = EINVAL; goto errout; } #endif - bdbg("Executing %s\n", bin->filename); + bdbg("Executing %s\n", binp->filename); /* Allocate a TCB for the new task. */ @@ -121,7 +177,7 @@ int exec_module(FAR const struct binary_s *bin, int priority) /* Allocate the stack for the new task */ #ifndef CONFIG_CUSTOM_STACK - stack = (FAR uint32_t*)malloc(bin->stacksize); + stack = (FAR uint32_t*)malloc(binp->stacksize); if (!tcb) { err = ENOMEM; @@ -130,11 +186,13 @@ int exec_module(FAR const struct binary_s *bin, int priority) /* Initialize the task */ - ret = task_init(tcb, bin->filename, priority, stack, bin->stacksize, bin->entrypt, bin->argv); + ret = task_init(tcb, binp->filename, priority, stack, + binp->stacksize, binp->entrypt, binp->argv); #else /* Initialize the task */ - ret = task_init(tcb, bin->filename, priority, stack, bin->entrypt, bin->argv); + ret = task_init(tcb, binp->filename, priority, stack, + binp->entrypt, binp->argv); #endif if (ret < 0) { @@ -143,20 +201,46 @@ int exec_module(FAR const struct binary_s *bin, int priority) goto errout_with_stack; } - /* Add the DSpace address as the PIC base address */ + /* Add the D-Space address as the PIC base address. By convention, this + * must be the first allocated address space. + */ #ifdef CONFIG_PIC - tcb->dspace = bin->dspace; + tcb->dspace = binp->alloc[0]; /* Re-initialize the task's initial state to account for the new PIC base */ up_initial_state(tcb); #endif + /* Assign the address environment to the task */ + +#ifdef CONFIG_ADDRENV + ret = up_addrenv_assign(binp->addrenv, tcb); + if (ret < 0) + { + err = -ret; + bdbg("up_addrenv_assign() failed: %d\n", ret); + goto errout_with_stack; + } +#endif + /* Get the assigned pid before we start the task */ pid = tcb->pid; + /* Execute all of the C++ static constructors */ + +#ifdef CONFIG_BINFMT_CONSTRUCTORS + ret = exec_ctors(binp); + if (ret < 0) + { + err = -ret; + bdbg("exec_ctors() failed: %d\n", ret); + goto errout_with_stack; + } +#endif + /* Then activate the task at the provided priority */ ret = task_activate(tcb); @@ -166,6 +250,7 @@ int exec_module(FAR const struct binary_s *bin, int priority) bdbg("task_activate() failed: %d\n", err); goto errout_with_stack; } + return (int)pid; errout_with_stack: |