aboutsummaryrefslogtreecommitdiff
path: root/nuttx/binfmt/binfmt_unloadmodule.c
diff options
context:
space:
mode:
authorpx4dev <px4@purgatory.org>2013-01-14 21:01:58 -0800
committerpx4dev <px4@purgatory.org>2013-01-14 21:01:58 -0800
commit854c6436b4e3b292fd04843795d0369dc8856783 (patch)
tree4d5602f5c70926d2dcd01294561ddd8df4378462 /nuttx/binfmt/binfmt_unloadmodule.c
parent6d138a845aabad31060bd00da0d20d177d3f4be4 (diff)
parentc38ad4ded570eddadeeca3579d02dfc63dcc8a9d (diff)
downloadpx4-firmware-854c6436b4e3b292fd04843795d0369dc8856783.tar.gz
px4-firmware-854c6436b4e3b292fd04843795d0369dc8856783.tar.bz2
px4-firmware-854c6436b4e3b292fd04843795d0369dc8856783.zip
Pull NuttX up to the 6.24 release.
Merge branch 'nuttx-merge-5447'
Diffstat (limited to 'nuttx/binfmt/binfmt_unloadmodule.c')
-rw-r--r--nuttx/binfmt/binfmt_unloadmodule.c113
1 files changed, 102 insertions, 11 deletions
diff --git a/nuttx/binfmt/binfmt_unloadmodule.c b/nuttx/binfmt/binfmt_unloadmodule.c
index 04859a291..365f26a34 100644
--- a/nuttx/binfmt/binfmt_unloadmodule.c
+++ b/nuttx/binfmt/binfmt_unloadmodule.c
@@ -1,7 +1,7 @@
/****************************************************************************
* binfmt/binfmt_loadmodule.c
*
- * Copyright (C) 2009 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2009, 2012 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@@ -45,7 +45,7 @@
#include <debug.h>
#include <errno.h>
-#include <nuttx/binfmt.h>
+#include <nuttx/binfmt/binfmt.h>
#include "binfmt_internal.h"
@@ -68,6 +68,62 @@
****************************************************************************/
/****************************************************************************
+ * Name: exec_dtors
+ *
+ * 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_dtors(FAR const struct binary_s *binp)
+{
+ binfmt_dtor_t *dtor = binp->dtors;
+#ifdef CONFIG_ADDRENV
+ hw_addrenv_t oldenv;
+ int ret;
+#endif
+ int i;
+
+ /* Instantiate the address enviroment containing the destructors */
+
+#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 destructor */
+
+ for (i = 0; i < binp->ndtors; i++)
+ {
+ bvdbg("Calling dtor %d at %p\n", i, (FAR void *)dtor);
+
+ (*dtor)();
+ dtor++;
+ }
+
+ /* Restore the address enviroment */
+
+#ifdef CONFIG_ADDRENV
+ return up_addrenv_restore(oldenv);
+#else
+ return OK;
+#endif
+}
+#endif
+
+/****************************************************************************
* Public Functions
****************************************************************************/
@@ -76,7 +132,12 @@
*
* Description:
* Unload a (non-executing) module from memory. If the module has
- * been started (via exec_module), calling this will be fatal.
+ * been started (via exec_module) and has not exited, calling this will
+ * be fatal.
+ *
+ * However, this function must be called after the module exist. How
+ * this is done is up to your logic. Perhaps you register it to be
+ * called by on_exit()?
*
* Returned Value:
* This is a NuttX internal function so it follows the convention that
@@ -85,22 +146,52 @@
*
****************************************************************************/
-int unload_module(FAR const struct binary_s *bin)
+int unload_module(FAR const struct binary_s *binp)
{
- if (bin)
+#ifdef CONFIG_BINFMT_CONSTRUCTORS
+ int ret;
+#endif
+ int i;
+
+ if (binp)
{
- if (bin->ispace)
+ /* Execute C++ desctructors */
+
+#ifdef CONFIG_BINFMT_CONSTRUCTORS
+ ret = exec_dtors(binp);
+ if (ret < 0)
{
- bvdbg("Unmapping ISpace: %p\n", bin->ispace);
- munmap(bin->ispace, bin->isize);
+ bdbg("exec_ctors() failed: %d\n", ret);
+ set_errno(-ret);
+ return ERROR;
}
+#endif
- if (bin->dspace)
+ /* Unmap mapped address spaces */
+
+ if (binp->mapped)
+ {
+ bvdbg("Unmapping address space: %p\n", binp->mapped);
+
+ munmap(binp->mapped, binp->mapsize);
+ }
+
+ /* Free allocated address spaces */
+
+ for (i = 0; i < BINFMT_NALLOC; i++)
{
- bvdbg("Freeing DSpace: %p\n", bin->dspace);
- free(bin->dspace);
+ if (binp->alloc[i])
+ {
+ bvdbg("Freeing alloc[%d]: %p\n", i, binp->alloc[i]);
+ free((FAR void *)binp->alloc[i]);
+ }
}
+
+ /* Notice that the address environment is not destroyed. This should
+ * happen automatically when the task exits.
+ */
}
+
return OK;
}