Ejemplo n.º 1
0
int unload_module(FAR struct binary_s *binp)
{
  int ret;
  int i;

  if (binp)
    {
      /* Perform any format-specific unload operations */

      if (binp->unload)
        {
          ret = binp->unload(binp);
          if (ret < 0)
            {
              bdbg("binp->unload() failed: %d\n", ret);
              set_errno(-ret);
              return ERROR;
            }
        }

#ifdef CONFIG_BINFMT_CONSTRUCTORS
      /* Execute C++ destructors */

      ret = exec_dtors(binp);
      if (ret < 0)
        {
          bdbg("exec_ctors() failed: %d\n", ret);
          set_errno(-ret);
          return ERROR;
        }
#endif

      /* Free any allocated argv[] strings */

      binfmt_freeargv(binp);

      /* 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++)
        {
          if (binp->alloc[i])
            {
              bvdbg("Freeing alloc[%d]: %p\n", i, binp->alloc[i]);
              kumm_free((FAR void *)binp->alloc[i]);
            }
        }

      /* Notice that the address environment is not destroyed.  This should
       * happen automatically when the task exits.
       */
    }

  return OK;
}
Ejemplo n.º 2
0
int exec(FAR const char *filename, FAR char * const *argv,
         FAR const struct symtab_s *exports, int nexports)
{
  FAR struct binary_s *bin;
  int pid;
  int errcode;
  int ret;

  /* Allocate the load information */

  bin = (FAR struct binary_s *)kmm_zalloc(sizeof(struct binary_s));
  if (!bin)
    {
      berr("ERROR: Failed to allocate binary_s\n");
      errcode = ENOMEM;
      goto errout;
    }

  /* Initialize the binary structure */

  bin->filename = filename;
  bin->exports  = exports;
  bin->nexports = nexports;

  /* Copy the argv[] list */

  ret = binfmt_copyargv(bin, argv);
  if (ret < 0)
    {
      errcode = -ret;
      berr("ERROR: Failed to copy argv[]: %d\n", errcode);
      goto errout_with_bin;
    }

  /* Load the module into memory */

  ret = load_module(bin);
  if (ret < 0)
    {
      errcode = -ret;
      berr("ERROR: Failed to load program '%s': %d\n", filename, errcode);
      goto errout_with_argv;
    }

  /* Disable pre-emption so that the executed module does
   * not return until we get a chance to connect the on_exit
   * handler.
   */

  sched_lock();

  /* Then start the module */

  pid = exec_module(bin);
  if (pid < 0)
    {
      errcode = -pid;
      berr("ERROR: Failed to execute program '%s': %d\n",
           filename, errcode);
      goto errout_with_lock;
    }

#ifdef CONFIG_BINFMT_LOADABLE
  /* Set up to unload the module (and free the binary_s structure)
   * when the task exists.
   */

  ret = group_exitinfo(pid, bin);
  if (ret < 0)
    {
      berr("ERROR: Failed to schedule unload '%s': %d\n", filename, ret);
    }

#else
  /* Free the binary_s structure here */

  binfmt_freeargv(bin);
  kmm_free(bin);

  /* TODO: How does the module get unloaded in this case? */
#endif

  sched_unlock();
  return pid;

errout_with_lock:
  sched_unlock();
  (void)unload_module(bin);
errout_with_argv:
  binfmt_freeargv(bin);
errout_with_bin:
  kmm_free(bin);
errout:
  set_errno(errcode);
  return ERROR;

}
Ejemplo n.º 3
0
int exec(FAR const char *filename, FAR char * const *argv,
         FAR const struct symtab_s *exports, int nexports)
{
#if defined(CONFIG_SCHED_ONEXIT) && defined(CONFIG_SCHED_HAVE_PARENT)
  FAR struct binary_s *bin;
  int pid;
  int err;
  int ret;

  /* Allocate the load information */

  bin = (FAR struct binary_s *)kmm_zalloc(sizeof(struct binary_s));
  if (!bin)
    {
      bdbg("ERROR: Failed to allocate binary_s\n");
      err = ENOMEM;
      goto errout;
    }

  /* Initialize the binary structure */

  bin->filename = filename;
  bin->exports  = exports;
  bin->nexports = nexports;

  /* Copy the argv[] list */

  ret = binfmt_copyargv(bin, argv);
  if (ret < 0)
    {
      err = -ret;
      bdbg("ERROR: Failed to copy argv[]: %d\n", err);
      goto errout_with_bin;
    }

  /* Load the module into memory */

  ret = load_module(bin);
  if (ret < 0)
    {
      err = get_errno();
      bdbg("ERROR: Failed to load program '%s': %d\n", filename, err);
      goto errout_with_argv;
    }

  /* Disable pre-emption so that the executed module does
   * not return until we get a chance to connect the on_exit
   * handler.
   */

  sched_lock();

  /* Then start the module */

  pid = exec_module(bin);
  if (pid < 0)
    {
      err = get_errno();
      bdbg("ERROR: Failed to execute program '%s': %d\n", filename, err);
      goto errout_with_lock;
    }

  /* Set up to unload the module (and free the binary_s structure)
   * when the task exists.
   */

  ret = schedule_unload(pid, bin);
  if (ret < 0)
    {
      err = get_errno();
      bdbg("ERROR: Failed to schedule unload '%s': %d\n", filename, err);
    }

  sched_unlock();
  return pid;

errout_with_lock:
  sched_unlock();
  unload_module(bin);
errout_with_argv:
  binfmt_freeargv(bin);
errout_with_bin:
  kmm_free(bin);
errout:
  set_errno(err);
  return ERROR;

#else
  struct binary_s bin;
  int err;
  int ret;

  /* Load the module into memory */

  memset(&bin, 0, sizeof(struct binary_s));
  bin.filename = filename;
  bin.exports  = exports;
  bin.nexports = nexports;

  ret = load_module(&bin);
  if (ret < 0)
    {
      err = get_errno();
      bdbg("ERROR: Failed to load program '%s': %d\n", filename, err);
      goto errout;
    }

  /* Then start the module */

  ret = exec_module(&bin);
  if (ret < 0)
    {
      err = get_errno();
      bdbg("ERROR: Failed to execute program '%s': %d\n", filename, err);
      goto errout_with_module;
    }

  /* TODO:  How does the module get unloaded in this case? */

  return ret;

errout_with_module:
  unload_module(&bin);
errout:
  set_errno(err);
  return ERROR;
#endif
}