summaryrefslogtreecommitdiff
path: root/nuttx/binfmt
diff options
context:
space:
mode:
authorGregory Nutt <gnutt@nuttx.org>2014-09-10 15:55:36 -0600
committerGregory Nutt <gnutt@nuttx.org>2014-09-10 15:55:36 -0600
commit7b3a98b2ec57f8c56a1669b818d03dfcd1a84fb2 (patch)
tree776264ed920f68eed300648dffe198e286495000 /nuttx/binfmt
parent22c64f6c542675d4865d2a013468089c92f43869 (diff)
downloadnuttx-7b3a98b2ec57f8c56a1669b818d03dfcd1a84fb2.tar.gz
nuttx-7b3a98b2ec57f8c56a1669b818d03dfcd1a84fb2.tar.bz2
nuttx-7b3a98b2ec57f8c56a1669b818d03dfcd1a84fb2.zip
Add logic to initialize the per-process user heap when each user process is started
Diffstat (limited to 'nuttx/binfmt')
-rw-r--r--nuttx/binfmt/binfmt_execmodule.c40
-rw-r--r--nuttx/binfmt/libelf/libelf.h6
-rw-r--r--nuttx/binfmt/libelf/libelf_addrenv.c8
-rw-r--r--nuttx/binfmt/libelf/libelf_load.c18
-rw-r--r--nuttx/binfmt/libnxflat/libnxflat.h2
-rw-r--r--nuttx/binfmt/libnxflat/libnxflat_addrenv.c15
6 files changed, 65 insertions, 24 deletions
diff --git a/nuttx/binfmt/binfmt_execmodule.c b/nuttx/binfmt/binfmt_execmodule.c
index 1afb4e8b3..b9a1dde79 100644
--- a/nuttx/binfmt/binfmt_execmodule.c
+++ b/nuttx/binfmt/binfmt_execmodule.c
@@ -48,6 +48,7 @@
#include <nuttx/arch.h>
#include <nuttx/kmalloc.h>
+#include <nuttx/mm.h>
#include <nuttx/binfmt/binfmt.h>
#include "sched/sched.h"
@@ -164,9 +165,9 @@ int exec_module(FAR const struct binary_s *binp)
goto errout;
}
- /* Instantiate the address environment containing the destructors */
-
#ifdef CONFIG_ARCH_ADDRENV
+ /* Instantiate the address environment containing the user heap */
+
ret = up_addrenv_select(&binp->addrenv, &oldenv);
if (ret < 0)
{
@@ -174,9 +175,18 @@ int exec_module(FAR const struct binary_s *binp)
err = -ret;
goto errout_with_tcb;
}
+
+ /* Initialize the user heap */
+
+ umm_initialize((FAR void *)CONFIG_ARCH_HEAP_VBASE,
+ up_addrenv_heapsize(&binp->addrenv));
#endif
- /* Allocate the stack for the new task (always from the user heap) */
+ /* Allocate the stack for the new task.
+ *
+ * REVISIT: This allocation is currently always from the user heap. That
+ * will need to change if/when we want to support dynamic stack allocation.
+ */
stack = (FAR uint32_t*)kumm_malloc(binp->stacksize);
if (!stack)
@@ -185,18 +195,6 @@ int exec_module(FAR const struct binary_s *binp)
goto errout_with_addrenv;
}
- /* Restore the address environment */
-
-#ifdef CONFIG_ARCH_ADDRENV
- ret = up_addrenv_restore(&oldenv);
- if (ret < 0)
- {
- bdbg("ERROR: up_addrenv_select() failed: %d\n", ret);
- err = -ret;
- goto errout_with_stack;
- }
-#endif
-
/* Initialize the task */
ret = task_init((FAR struct tcb_s *)tcb, binp->filename, binp->priority,
@@ -262,6 +260,18 @@ int exec_module(FAR const struct binary_s *binp)
goto errout_with_stack;
}
+#ifdef CONFIG_ARCH_ADDRENV
+ /* Restore the address environment of the caller */
+
+ ret = up_addrenv_restore(&oldenv);
+ if (ret < 0)
+ {
+ bdbg("ERROR: up_addrenv_select() failed: %d\n", ret);
+ err = -ret;
+ goto errout_with_stack;
+ }
+#endif
+
return (int)pid;
errout_with_stack:
diff --git a/nuttx/binfmt/libelf/libelf.h b/nuttx/binfmt/libelf/libelf.h
index 4304e64f2..58ec757b8 100644
--- a/nuttx/binfmt/libelf/libelf.h
+++ b/nuttx/binfmt/libelf/libelf.h
@@ -283,6 +283,8 @@ int elf_loaddtors(FAR struct elf_loadinfo_s *loadinfo);
* for the ELF image (read/execute).
* datasize - The size (in bytes) of the .bss/.data address environment
* needed for the ELF image (read/write).
+ * heapsize - The initial size (in bytes) of the heap address environment
+ * needed by the task. This region may be read/write only.
*
* Returned Value:
* Zero (OK) on success; a negated errno value on failure.
@@ -290,13 +292,13 @@ int elf_loaddtors(FAR struct elf_loadinfo_s *loadinfo);
****************************************************************************/
int elf_addrenv_alloc(FAR struct elf_loadinfo_s *loadinfo, size_t textsize,
- size_t datasize);
+ size_t datasize, size_t heapsize);
/****************************************************************************
* Name: elf_addrenv_select
*
* Description:
- * Temporarity select the task's address environemnt.
+ * Temporarily select the task's address environemnt.
*
* Input Parameters:
* loadinfo - Load state information
diff --git a/nuttx/binfmt/libelf/libelf_addrenv.c b/nuttx/binfmt/libelf/libelf_addrenv.c
index 08beed008..6b3be4306 100644
--- a/nuttx/binfmt/libelf/libelf_addrenv.c
+++ b/nuttx/binfmt/libelf/libelf_addrenv.c
@@ -80,6 +80,8 @@
* for the ELF image (read/execute).
* datasize - The size (in bytes) of the .bss/.data address environment
* needed for the ELF image (read/write).
+ * heapsize - The initial size (in bytes) of the heap address environment
+ * needed by the task. This region may be read/write only.
*
* Returned Value:
* Zero (OK) on success; a negated errno value on failure.
@@ -87,7 +89,7 @@
****************************************************************************/
int elf_addrenv_alloc(FAR struct elf_loadinfo_s *loadinfo, size_t textsize,
- size_t datasize)
+ size_t datasize, size_t heapsize)
{
#ifdef CONFIG_ARCH_ADDRENV
FAR void *vtext;
@@ -96,7 +98,7 @@ int elf_addrenv_alloc(FAR struct elf_loadinfo_s *loadinfo, size_t textsize,
/* Create an address environment for the new ELF task */
- ret = up_addrenv_create(textsize, datasize, &loadinfo->addrenv);
+ ret = up_addrenv_create(textsize, datasize, heapsize, &loadinfo->addrenv);
if (ret < 0)
{
bdbg("ERROR: up_addrenv_create failed: %d\n", ret);
@@ -145,7 +147,7 @@ int elf_addrenv_alloc(FAR struct elf_loadinfo_s *loadinfo, size_t textsize,
*
* Description:
* Release the address environment previously created by
- * elf_addrenv_create(). This function is called only under certain error
+ * elf_addrenv_alloc(). This function is called only under certain error
* conditions after the module has been loaded but not yet started.
* After the module has been started, the address environment will
* automatically be freed when the module exits.
diff --git a/nuttx/binfmt/libelf/libelf_load.c b/nuttx/binfmt/libelf/libelf_load.c
index 5fd4ce570..75ecb30fc 100644
--- a/nuttx/binfmt/libelf/libelf_load.c
+++ b/nuttx/binfmt/libelf/libelf_load.c
@@ -49,6 +49,7 @@
#include <errno.h>
#include <debug.h>
+#include <nuttx/addrenv.h>
#include <nuttx/binfmt/elf.h>
#include "libelf.h"
@@ -62,7 +63,11 @@
#define ELF_ALIGNDOWN(a) ((unsigned long)(a) & ~ELF_ALIGN_MASK)
#ifndef MAX
-#define MAX(x,y) ((x) > (y) ? (x) : (y))
+# define MAX(x,y) ((x) > (y) ? (x) : (y))
+#endif
+
+#ifndef MIN
+# define MIN(x,y) ((x) < (y) ? (x) : (y))
#endif
/****************************************************************************
@@ -229,6 +234,7 @@ static inline int elf_loadfile(FAR struct elf_loadinfo_s *loadinfo)
int elf_load(FAR struct elf_loadinfo_s *loadinfo)
{
+ size_t heapsize;
int ret;
bvdbg("loadinfo: %p\n", loadinfo);
@@ -247,9 +253,17 @@ int elf_load(FAR struct elf_loadinfo_s *loadinfo)
elf_elfsize(loadinfo);
+ /* Determine the heapsize to allocate */
+
+#ifdef CONFIG_ARCH_STACK_DYNAMIC
+ heapsize = ARCH_HEAP_SIZE;
+#else
+ heapsize = MIN(ARCH_HEAP_SIZE, CONFIG_ELF_STACKSIZE);
+#endif
+
/* Allocate (and zero) memory for the ELF file. */
- ret = elf_addrenv_alloc(loadinfo, loadinfo->textsize, loadinfo->datasize);
+ ret = elf_addrenv_alloc(loadinfo, loadinfo->textsize, loadinfo->datasize, heapsize);
if (ret < 0)
{
bdbg("ERROR: elf_addrenv_alloc() failed: %d\n", ret);
diff --git a/nuttx/binfmt/libnxflat/libnxflat.h b/nuttx/binfmt/libnxflat/libnxflat.h
index fc3826295..32d82df74 100644
--- a/nuttx/binfmt/libnxflat/libnxflat.h
+++ b/nuttx/binfmt/libnxflat/libnxflat.h
@@ -116,7 +116,7 @@ int nxflat_addrenv_alloc(FAR struct nxflat_loadinfo_s *loadinfo, size_t envsize)
*
* Description:
* Release the address environment previously created by
- * nxflat_addrenv_create(). This function is called only under certain
+ * nxflat_addrenv_alloc(). This function is called only under certain
* error conditions after the module has been loaded but not yet
* started. After the module has been started, the address environment
* will automatically be freed when the module exits.
diff --git a/nuttx/binfmt/libnxflat/libnxflat_addrenv.c b/nuttx/binfmt/libnxflat/libnxflat_addrenv.c
index fb3dbe09a..c7e82f537 100644
--- a/nuttx/binfmt/libnxflat/libnxflat_addrenv.c
+++ b/nuttx/binfmt/libnxflat/libnxflat_addrenv.c
@@ -52,6 +52,10 @@
* Pre-Processor Definitions
****************************************************************************/
+#ifndef MIN
+# define MIN(x,y) ((x) < (y) ? (x) : (y))
+#endif
+
/****************************************************************************
* Private Constant Data
****************************************************************************/
@@ -88,6 +92,7 @@ int nxflat_addrenv_alloc(FAR struct nxflat_loadinfo_s *loadinfo, size_t envsize)
#ifdef CONFIG_ARCH_ADDRENV
FAR void *vdata;
save_addrenv_t oldenv;
+ size_t heapsize;
int ret;
#endif
@@ -103,9 +108,17 @@ int nxflat_addrenv_alloc(FAR struct nxflat_loadinfo_s *loadinfo, size_t envsize)
}
#ifdef CONFIG_ARCH_ADDRENV
+ /* Determine the heapsize to allocate */
+
+#ifdef CONFIG_ARCH_STACK_DYNAMIC
+ heapsize = ARCH_HEAP_SIZE;
+#else
+ heapsize = MIN(loadinfo->stacksize, ARCH_HEAP_SIZE);
+#endif
+
/* Create a D-Space address environment for the new NXFLAT task */
- ret = up_addrenv_create(envsize, &loadinfo->addrenv);
+ ret = up_addrenv_create(0, envsize, heapsize, &loadinfo->addrenv);
if (ret < 0)
{
bdbg("ERROR: up_addrenv_create failed: %d\n", ret);