aboutsummaryrefslogtreecommitdiff
path: root/nuttx/binfmt/binfmt_execmodule.c
diff options
context:
space:
mode:
Diffstat (limited to 'nuttx/binfmt/binfmt_execmodule.c')
-rw-r--r--nuttx/binfmt/binfmt_execmodule.c103
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: