Exemplo n.º 1
0
static void elf_dumpentrypt(FAR struct binary_s *binp,
                            FAR struct elf_loadinfo_s *loadinfo)
{
#ifdef CONFIG_ARCH_ADDRENV
  int ret;

  /* If CONFIG_ARCH_ADDRENV=y, then the loaded ELF lies in a virtual address
   * space that may not be in place now.  elf_addrenv_select() will
   * temporarily instantiate that address space.
   */

  ret = elf_addrenv_select(loadinfo);
  if (ret < 0)
    {
      bdbg("ERROR: elf_addrenv_select() failed: %d\n", ret);
      return;
    }
#endif

  elf_dumpbuffer("Entry code", (FAR const uint8_t *)binp->entrypt,
                 MIN(loadinfo->textsize - loadinfo->ehdr.e_entry, 512));

#ifdef CONFIG_ARCH_ADDRENV
  /* Restore the original address environment */

  ret = elf_addrenv_restore(loadinfo);
  if (ret < 0)
    {
      bdbg("ERROR: elf_addrenv_restore() failed: %d\n", ret);
    }
#endif
}
Exemplo n.º 2
0
int exec(FAR const char *filename, FAR const char **argv,
         FAR const struct symtab_s *exports, int nexports)
{
  struct binary_s bin;
  int ret;

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

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

  ret = exec_module(&bin, 50);
  if (ret < 0)
    {
      bdbg("ERROR: Failed to execute program '%s'\n", filename);
      unload_module(&bin);
      return ERROR;
    }

  return ret;
}
Exemplo n.º 3
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

      /* 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;
}
Exemplo n.º 4
0
static int nxflat_loadbinary(struct binary_s *binp)
{
  struct nxflat_loadinfo_s loadinfo;  /* Contains globals for libnxflat */
  int                      ret;

  bvdbg("Loading file: %s\n", binp->filename);

  /* Initialize the xflat library to load the program binary. */

  ret = nxflat_init(binp->filename, &loadinfo);
  nxflat_dumploadinfo(&loadinfo);
  if (ret != 0)
    {
      bdbg("Failed to initialize for load of NXFLT program: %d\n", ret);
      goto errout;
    }

  /* Load the program binary */

  ret = nxflat_load(&loadinfo);
  nxflat_dumploadinfo(&loadinfo);
  if (ret != 0)
    {
      bdbg("Failed to load NXFLT program binary: %d\n", ret);
      goto errout_with_init;
    }

  /* Bind the program to the exported symbol table */

  ret = nxflat_bind(&loadinfo, binp->exports, binp->nexports);
  if (ret != 0)
    {
      bdbg("Failed to bind symbols program binary: %d\n", ret);
      goto errout_with_load;
    }

  /* Return the load information */

  binp->entrypt   = (main_t)(loadinfo.ispace + loadinfo.entryoffs);
  binp->ispace    = (void*)loadinfo.ispace;
  binp->dspace    = (void*)loadinfo.dspace;
  binp->isize     = loadinfo.isize;
  binp->stacksize = loadinfo.stacksize;

  nxflat_dumpbuffer("Entry code", (FAR const uint8_t*)binp->entrypt,
                    MIN(binp->isize - loadinfo.entryoffs,512));

  nxflat_uninit(&loadinfo);
  return OK;

errout_with_load:
  nxflat_unload(&loadinfo);
errout_with_init:
  nxflat_uninit(&loadinfo);
errout:
  return ret;
}
Exemplo n.º 5
0
int nxflat_read(struct nxflat_loadinfo_s *loadinfo, char *buffer, int readsize, int offset)
{
  ssize_t nbytes;      /* Number of bytes read */
  off_t   rpos;        /* Position returned by lseek */
  char   *bufptr;      /* Next buffer location to read into */
  int     bytesleft;   /* Number of bytes of .data left to read */
  int     bytesread;   /* Total number of bytes read */

  bvdbg("Read %d bytes from offset %d\n", readsize, offset);

  /* Seek to the position in the object file where the initialized
   * data is saved.
   */

  bytesread = 0;
  bufptr    = buffer;
  bytesleft = readsize;
  do
    {
      rpos = lseek(loadinfo->filfd, offset, SEEK_SET);
      if (rpos != offset)
        {
          int errval = errno;
          bdbg("Failed to seek to position %d: %d\n", offset, errval);
          return -errval;
        }

      /* Read the file data at offset into the user buffer */

       nbytes = read(loadinfo->filfd, bufptr, bytesleft);
       if (nbytes < 0)
         {
           int errval = errno;
           if (errval != EINTR)
             {
               bdbg("Read from offset %d failed: %d\n", offset, errval);
               return -errval;
             }
         }
       else if (nbytes == 0)
         {
           bdbg("Unexpected end of file\n");
           return -ENODATA;
         }
       else
         {
           bytesread += nbytes;
           bytesleft -= nbytes;
           bufptr    += nbytes;
           offset    += nbytes;
         }
    }
  while (bytesread < readsize);

  nxflat_dumpreaddata(buffer, readsize);
  return OK;
}
static int builtin_loadbinary(struct binary_s *binp)
{
  FAR const char *filename;
  FAR const struct builtin_s *b;
  int fd;
  int index;
  int ret;

  bvdbg("Loading file: %s\n", binp->filename);

  /* Open the binary file for reading (only) */

  fd = open(binp->filename, O_RDONLY);
  if (fd < 0)
    {
      int errval = get_errno();
      bdbg("ERROR: Failed to open binary %s: %d\n", binp->filename, errval);
      return -errval;
    }

  /* If this file is a BINFS file system, then we can recover the name of
   * the file using the FIOC_FILENAME ioctl() call.
   */

  ret = ioctl(fd, FIOC_FILENAME, (unsigned long)((uintptr_t)&filename));
  if (ret < 0)
    {
      int errval = get_errno();
      bdbg("ERROR: FIOC_FILENAME ioctl failed: %d\n", errval);
      return -errval;
    }

  /* Other file systems may also support FIOC_FILENAME, so the real proof
   * is that we can look up the index to this name in g_builtins[].
   */

  index = builtin_isavail(filename);
  if (index < 0)
    {
      int errval = get_errno();
      bdbg("ERROR: %s is not a builtin application\n", filename);
      return -errval;

    }

  /* Return the load information.  NOTE: that there is no way to configure
   * the priority.  That is a bug and needs to be fixed.
   */

  b = builtin_for_index(index);
  binp->entrypt   = b->main;
  binp->stacksize = b->stacksize;
  binp->priority  = b->priority;
  return OK;
}
Exemplo n.º 7
0
int elf_load(FAR struct elf_loadinfo_s *loadinfo)
{
  int ret;

  bvdbg("loadinfo: %p\n", loadinfo);
  DEBUGASSERT(loadinfo && loadinfo->filfd >= 0);

  /* Load section headers into memory */

  ret = elf_loadshdrs(loadinfo);
  if (ret < 0)
    {
      bdbg("elf_loadshdrs failed: %d\n", ret);
      goto errout_with_buffers;
    }

  /* Determine total size to allocate */

  elf_elfsize(loadinfo);

  /* Allocate memory and load sections into memory */

  ret = elf_loadfile(loadinfo);
  if (ret < 0)
    {
      bdbg("elf_loadfile failed: %d\n", ret);
      goto errout_with_buffers;
    }

  /* Load static constructors and destructors. */

#ifdef CONFIG_BINFMT_CONSTRUCTORS
  ret = elf_loadctors(loadinfo);
  if (ret < 0)
    {
      bdbg("elf_loadctors failed: %d\n", ret);
      goto errout_with_buffers;
    }

  ret = elf_loaddtors(loadinfo);
  if (ret < 0)
    {
      bdbg("elf_loaddtors failed: %d\n", ret);
      goto errout_with_buffers;
    }
#endif

  return OK;

  /* Error exits */

errout_with_buffers:
  elf_unload(loadinfo);
  return ret;
}
int elf_addrenv_alloc(FAR struct elf_loadinfo_s *loadinfo, size_t textsize,
                      size_t datasize, size_t heapsize)
{
#ifdef CONFIG_ARCH_ADDRENV
  FAR void *vtext;
  FAR void *vdata;
  int ret;

  /* Create an address environment for the new ELF task */

  ret = up_addrenv_create(textsize, datasize, heapsize, &loadinfo->addrenv);
  if (ret < 0)
    {
      bdbg("ERROR: up_addrenv_create failed: %d\n", ret);
      return ret;
    }

  /* Get the virtual address associated with the start of the address
   * environment.  This is the base address that we will need to use to
   * access the ELF image (but only if the address environment has been
   * selected.
   */

  ret = up_addrenv_vtext(&loadinfo->addrenv, &vtext);
  if (ret < 0)
    {
      bdbg("ERROR: up_addrenv_vtext failed: %d\n", ret);
      return ret;
    }

  ret = up_addrenv_vdata(&loadinfo->addrenv, textsize, &vdata);
  if (ret < 0)
    {
      bdbg("ERROR: up_adup_addrenv_vdatadrenv_vtext failed: %d\n", ret);
      return ret;
    }

  loadinfo->textalloc = (uintptr_t)vtext;
  loadinfo->dataalloc = (uintptr_t)vdata;
  return OK;
#else
  /* Allocate memory to hold the ELF image */

  loadinfo->textalloc = (uintptr_t)kumm_zalloc(textsize + datasize);
  if (!loadinfo->textalloc)
    {
      return -ENOMEM;
    }

  loadinfo->dataalloc = loadinfo->textalloc + textsize;
  return OK;
#endif
}
Exemplo n.º 9
0
int elf_read(FAR struct elf_loadinfo_s *loadinfo, FAR uint8_t *buffer,
             size_t readsize, off_t offset)
{
  ssize_t nbytes;      /* Number of bytes read */
  off_t   rpos;        /* Position returned by lseek */

  bvdbg("Read %ld bytes from offset %ld\n", (long)readsize, (long)offset);

  /* Loop until all of the requested data has been read. */

  while (readsize > 0)
    {
      /* Seek to the next read position */

      rpos = lseek(loadinfo->filfd, offset, SEEK_SET);
      if (rpos != offset)
        {
          int errval = errno;
          bdbg("Failed to seek to position %ld: %d\n", (long)offset, errval);
          return -errval;
        }

      /* Read the file data at offset into the user buffer */

       nbytes = read(loadinfo->filfd, buffer, readsize);
       if (nbytes < 0)
         {
           int errval = errno;

           /* EINTR just means that we received a signal */

           if (errval != EINTR)
             {
               bdbg("Read of .data failed: %d\n", errval);
               return -errval;
             }
         }
       else if (nbytes == 0)
         {
           bdbg("Unexpected end of file\n");
           return -ENODATA;
         }
       else
         {
           readsize -= nbytes;
           buffer   += nbytes;
           offset   += nbytes;
         }
    }

  elf_dumpreaddata(buffer, readsize);
  return OK;
}
Exemplo n.º 10
0
int load_module(FAR struct binary_s *bin)
{
  FAR struct binfmt_s *binfmt;
  int ret = -ENOENT;

#ifdef CONFIG_DEBUG
  if (bin && bin->filename)
#endif
    {
      bdbg("Loading %s\n", bin->filename);

      /* Disabling pre-emption should be sufficient protection while
       * accessing the list of registered binary format handlers.
       */

      sched_lock();

      /* Traverse the list of registered binary format handlers.  Stop
       * when either (1) a handler recognized and loads the format, or
       * (2) no handler recognizes the format.
       */

      for (binfmt = g_binfmts; binfmt; binfmt = binfmt->next)
        {
          /* Use this handler to try to load the format */

          ret = binfmt->load(bin);
          if (ret == OK)
            {
              /* Successfully loaded -- break out with ret == 0 */

              bvdbg("Successfully loaded module %s\n", bin->filename);
              dump_module(bin);
              break;
            }
        }

      sched_unlock();
    }

  /* This is an end-user function.  Return failures via errno */

  if (ret < 0)
    {
      bdbg("Returning errno %d\n", -ret);
      errno = -ret;
      return ERROR;
    }
  return OK;
}
void elf_addrenv_free(FAR struct elf_loadinfo_s *loadinfo)
{
#ifdef CONFIG_ARCH_ADDRENV
  int ret;

  /* Free the address environment */

  ret = up_addrenv_destroy(&loadinfo->addrenv);
  if (ret < 0)
    {
      bdbg("ERROR: up_addrenv_destroy failed: %d\n", ret);
    }
#else
  /* If there is an allocation for the ELF image, free it */

  if (loadinfo->textalloc != 0)
    {
      kumm_free((FAR void *)loadinfo->textalloc);
    }
#endif

  /* Clear out all indications of the allocated address environment */

  loadinfo->textalloc = 0;
  loadinfo->dataalloc = 0;
  loadinfo->textsize  = 0;
  loadinfo->datasize  = 0;
}
int up_addrenv_ustackalloc(FAR struct tcb_s *tcb, size_t stacksize)
{
  int ret;

  bvdbg("tcb=%p stacksize=%lu\n", tcb, (unsigned long)stacksize);

  DEBUGASSERT(tcb);

  /* Initialize the address environment list to all zeroes */

  memset(tcb->xcp.ustack, 0, ARCH_STACK_NSECTS * sizeof(uintptr_t *));

  /* Back the allocation up with physical pages and set up the level 2 mapping
   * (which of course does nothing until the L2 page table is hooked into
   * the L1 page table).
   */

  /* Allocate .text space pages */

  ret = arm_addrenv_create_region(tcb->xcp.ustack, ARCH_STACK_NSECTS,
                                  CONFIG_ARCH_STACK_VBASE, stacksize,
                                  MMU_L2_UDATAFLAGS);
  if (ret < 0)
    {
      bdbg("ERROR: Failed to create stack region: %d\n", ret);
      up_addrenv_ustackfree(tcb);
      return ret;
    }

  return OK;
}
Exemplo n.º 13
0
static inline int elf_loadfile(FAR struct elf_loadinfo_s *loadinfo)
{
  FAR uint8_t *dest;
  int ret;
  int i;

  /* Allocate (and zero) memory for the ELF file. */
  
  loadinfo->elfalloc = (uintptr_t)kzalloc(loadinfo->elfsize);
  if (!loadinfo->elfalloc)
    {
      return -ENOMEM;
    }

  /* Read each section into memory that is marked SHF_ALLOC + SHT_NOBITS */

  bvdbg("Loaded sections:\n");
  dest = (FAR uint8_t*)loadinfo->elfalloc;

  for (i = 0; i < loadinfo->ehdr.e_shnum; i++)
    {
      FAR Elf32_Shdr *shdr = &loadinfo->shdr[i];

      /* SHF_ALLOC indicates that the section requires memory during
       * execution */

      if ((shdr->sh_flags & SHF_ALLOC) == 0)
        {
          continue;
        }

      /* SHT_NOBITS indicates that there is no data in the file for the
       * section.
       */

      if (shdr->sh_type != SHT_NOBITS)
        {
          /* Read the section data from sh_offset to dest */

          ret = elf_read(loadinfo, dest, shdr->sh_size, shdr->sh_offset);
          if (ret < 0)
            {
              bdbg("Failed to read section %d: %d\n", i, ret);
              return ret;
            }
        }

      /* Update sh_addr to point to copy in memory */

      bvdbg("%d. %08x->%08x\n", i, (long)shdr->sh_addr, (long)dest);
      shdr->sh_addr = (uintptr_t)dest;

      /* Setup the memory pointer for the next time through the loop */

      dest += ELF_ALIGNUP(shdr->sh_size);
    }

  return OK;
}
Exemplo n.º 14
0
int prun(FAR char *exepath, size_t varsize, size_t strsize)
{
  FAR struct pexec_s *st;
  int errcode;
  int ret = OK;

  /* Load the POFF file into memory */

  st = pload(exepath, varsize, varsize);
  if (!st)
    {
      bdbg("ERROR: Could not load %s\n", exepath);
      return -ENOEXEC;
    }

  bvdbg("Loaded %s\n", exepath);

  /* Execute the P-Code program until a stopping condition occurs */

  for (;;)
    {
      /* Execute the instruction; Check for exceptional conditions */

      errcode = pexec(st);
      if (errcode != eNOERROR)
        {
          break;
        }
    }

  if (errcode != eEXIT)
    {
      /* REVISIT: Select a more appropriated return errocode */

      bdbg("ERROR: Runtime error 0x%02x -- Execution Stopped\n", errcode);
      ret = -ENOEXEC;
    }

  /* Clean up resources used by the interpreter */

  bvdbg("Execution terminated\n");
  pexec_release(st);
  return ret;
}
Exemplo n.º 15
0
int elf_addrenv_alloc(FAR struct elf_loadinfo_s *loadinfo, size_t envsize)
{
#ifdef CONFIG_ADDRENV
  FAR void *vaddr;
  int ret;

  /* Create an address environment for the new ELF task */

  ret = up_addrenv_create(envsize, &loadinfo->addrenv);
  if (ret < 0)
    {
      bdbg("ERROR: up_addrenv_create failed: %d\n", ret);
      return ret;
    }

  /* Get the virtual address associated with the start of the address
   * environment.  This is the base address that we will need to use to
   * access the ELF image (but only if the address environment has been
   * selected.
   */

  ret = up_addrenv_vaddr(loadinfo->addrenv, &vaddr);
  if (ret < 0)
    {
      bdbg("ERROR: up_addrenv_vaddr failed: %d\n", ret);
      return ret;
    }

  loadinfo->elfalloc = (uintptr_t)vaddr;
  return OK;
#else
  /* Allocate memory to hold the ELF image */

  loadinfo->elfalloc = (uintptr_t)kuzalloc(envsize);
  if (!loadinfo->elfalloc)
    {
      return -ENOMEM;
    }

  return OK;
#endif
}
Exemplo n.º 16
0
int nxflat_initialize(void)
{
  int ret;

  /* Register ourselves as a binfmt loader */

  bvdbg("Registering NXFLAT\n");
  ret = register_binfmt(&g_nxflatbinfmt);
  if (ret != 0)
    {
      bdbg("Failed to register binfmt: %d\n", ret);
    }
  return ret;
}
int nxflat_verifyheader(const struct nxflat_hdr_s *header)
{
  if (!header)
    {
      bdbg("NULL NXFLAT header!");
      return -ENOEXEC;
    }

  /* Check the FLT header -- magic number and revision.
   *
   * If the magic number does not match.  Just return
   * silently.  This is not our binary.
   */

  if (strncmp(header->h_magic, NXFLAT_MAGIC, 4) != 0)
    {
      bdbg("Unrecognized magic=\"%c%c%c%c\"\n",
      header->h_magic[0], header->h_magic[1],
      header->h_magic[2], header->h_magic[3]);
      return -ENOEXEC;
    }

  return OK;
}
Exemplo n.º 18
0
int elf_initialize(void)
{
  int ret;

  /* Register ourselves as a binfmt loader */

  bvdbg("Registering ELF\n");

  ret = register_binfmt(&g_elfbinfmt);
  if (ret != 0)
    {
      bdbg("Failed to register binfmt: %d\n", ret);
    }

  return ret;
}
int builtin_initialize(void)
{
  int ret;

  /* Register ourselves as a binfmt loader */

  bvdbg("Registering Builtin Loader\n");

  ret = register_binfmt(&g_builtin_binfmt);
  if (ret != 0)
    {
      bdbg("Failed to register binfmt: %d\n", ret);
    }

  return ret;
}
Exemplo n.º 20
0
static int load_default_priority(FAR struct binary_s *bin)
{
  struct sched_param param;
  int ret;

  /* Get the priority of this thread */

  ret = sched_getparam(0, &param);
  if (ret < 0)
    {
      bdbg("ERROR: sched_getparam failed: %d\n", errno);
      return ERROR;
    }
  
  /* Save that as the priority of child thread */

  bin->priority = param.sched_priority;
  return ret;
}
int elf_allocbuffer(FAR struct elf_loadinfo_s *loadinfo)
{
  /* Has a buffer been allocated> */

  if (!loadinfo->iobuffer)
    {
      /* No.. allocate one now */

      loadinfo->iobuffer = (FAR uint8_t *)kmm_malloc(CONFIG_ELF_BUFFERSIZE);
      if (!loadinfo->iobuffer)
        {
          bdbg("Failed to allocate an I/O buffer\n");
          return -ENOMEM;
        }

      loadinfo->buflen = CONFIG_ELF_BUFFERSIZE;
    }

  return OK;
}
Exemplo n.º 22
0
static inline int exec_dtors(FAR struct binary_s *binp)
{
  binfmt_dtor_t *dtor = binp->dtors;
#ifdef CONFIG_ARCH_ADDRENV
  save_addrenv_t oldenv;
  int ret;
#endif
  int i;

  /* Instantiate the address environment containing the destructors */

#ifdef CONFIG_ARCH_ADDRENV
  ret = up_addrenv_select(&binp->addrenv, &oldenv);
  if (ret < 0)
    {
      bdbg("ERROR: 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 environment */

#ifdef CONFIG_ARCH_ADDRENV
  return up_addrenv_restore(&oldenv);
#else
  return OK;
#endif
}
Exemplo n.º 23
0
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
}
Exemplo n.º 24
0
void nxflat_addrenv_free(FAR struct nxflat_loadinfo_s *loadinfo)
{
  FAR struct dspace_s *dspace;
#ifdef CONFIG_ADDRENV
  int ret;
#endif

  DEBUGASSERT(loadinfo);
  dspace = loadinfo->dspace;

  if (dspace)
    {
#ifdef CONFIG_ADDRENV
      /* Destroy the address environment */

      ret = up_addrenv_destroy(loadinfo->addrenv);
      if (ret < 0)
        {
          bdbg("ERROR: up_addrenv_destroy failed: %d\n", ret);
        }

      loadinfo->addrenv = 0;
#else
      /* Free the allocated D-Space region */

      if (dspace->region)
        {
          kufree(dspace->region);
        }
#endif

      /* Now destroy the D-Space container */

      DEBUGASSERT(dspace->crefs == 1);
      kfree(dspace);
      loadinfo->dspace = NULL;
    }
}
int elf_reallocbuffer(FAR struct elf_loadinfo_s *loadinfo, size_t increment)
{
  FAR void *buffer;
  size_t newsize;

  /* Get the new size of the allocation */

  newsize = loadinfo->buflen + increment;

  /* And perform the reallocation */

   buffer = kmm_realloc((FAR void *)loadinfo->iobuffer, newsize);
   if (!buffer)
    {
      bdbg("Failed to reallocate the I/O buffer\n");
      return -ENOMEM;
    }

  /* Save the new buffer info */

  loadinfo->iobuffer = buffer;
  loadinfo->buflen   = newsize;
  return OK;
}
Exemplo n.º 26
0
static int load_absmodule(FAR struct binary_s *bin)
{
  FAR struct binfmt_s *binfmt;
  int ret = -ENOENT;

  bdbg("Loading %s\n", bin->filename);

  /* Disabling pre-emption should be sufficient protection while accessing
   * the list of registered binary format handlers.
   */

  sched_lock();

  /* Traverse the list of registered binary format handlers.  Stop
   * when either (1) a handler recognized and loads the format, or
   * (2) no handler recognizes the format.
   */

  for (binfmt = g_binfmts; binfmt; binfmt = binfmt->next)
    {
      /* Use this handler to try to load the format */

      ret = binfmt->load(bin);
      if (ret == OK)
        {
          /* Successfully loaded -- break out with ret == 0 */

          bvdbg("Successfully loaded module %s\n", bin->filename);
          dump_module(bin);
          break;
        }
    }

  sched_unlock();
  return ret;
}
Exemplo n.º 27
0
static inline int elf_loadfile(FAR struct elf_loadinfo_s *loadinfo)
{
  FAR uint8_t *dest;
  int ret;
  int i;

  /* Allocate (and zero) memory for the ELF file. */

  ret = elf_addrenv_alloc(loadinfo, loadinfo->elfsize);
  if (ret < 0)
    {
      bdbg("ERROR: elf_addrenv_alloc() failed: %d\n", ret);
      return ret;
    }

  /* Read each section into memory that is marked SHF_ALLOC + SHT_NOBITS */

  bvdbg("Loaded sections:\n");
  dest = (FAR uint8_t*)loadinfo->elfalloc;

  for (i = 0; i < loadinfo->ehdr.e_shnum; i++)
    {
      FAR Elf32_Shdr *shdr = &loadinfo->shdr[i];

      /* SHF_ALLOC indicates that the section requires memory during
       * execution */

      if ((shdr->sh_flags & SHF_ALLOC) == 0)
        {
          continue;
        }

      /* SHT_NOBITS indicates that there is no data in the file for the
       * section.
       */

      if (shdr->sh_type != SHT_NOBITS)
        {
          /* If CONFIG_ADDRENV=y, then 'dest' lies in a virtual address space
           * that may not be in place now.  elf_addrenv_select() will
           * temporarily instantiate that address space.
           */

#ifdef CONFIG_ADDRENV
          ret = elf_addrenv_select(loadinfo);
          if (ret < 0)
            {
              bdbg("ERROR: elf_addrenv_select() failed: %d\n", ret);
              return ret;
            }
#endif

          /* Read the section data from sh_offset to dest */

          ret = elf_read(loadinfo, dest, shdr->sh_size, shdr->sh_offset);
          if (ret < 0)
            {
              bdbg("Failed to read section %d: %d\n", i, ret);
              return ret;
            }

          /* Restore the original address environment */

#ifdef CONFIG_ADDRENV
          ret = elf_addrenv_restore(loadinfo);
          if (ret < 0)
            {
              bdbg("ERROR: elf_addrenv_restore() failed: %d\n", ret);
             return ret;
            }
#endif
        }

      /* Update sh_addr to point to copy in memory */

      bvdbg("%d. %08x->%08x\n", i, (long)shdr->sh_addr, (long)dest);
      shdr->sh_addr = (uintptr_t)dest;

      /* Setup the memory pointer for the next time through the loop */

      dest += ELF_ALIGNUP(shdr->sh_size);
    }

  return OK;
}
Exemplo n.º 28
0
int nxflat_init(const char *filename, struct nxflat_loadinfo_s *loadinfo)
{
  uint32_t datastart;
  uint32_t dataend;
  uint32_t bssstart;
  uint32_t bssend;
  int      ret;

  bvdbg("filename: %s loadinfo: %p\n", filename, loadinfo);

  /* Clear the load info structure */

  memset(loadinfo, 0, sizeof(struct nxflat_loadinfo_s));

  /* Open the binary file */

  loadinfo->filfd = open(filename, O_RDONLY);
  if (loadinfo->filfd < 0)
    {
      bdbg("Failed to open NXFLAT binary %s: %d\n", filename, ret);
      return -errno;      
    }

  /* Read the NXFLAT header from offset 0 */

  ret = nxflat_read(loadinfo, (char*)&loadinfo->header,
                    sizeof(struct nxflat_hdr_s), 0);
  if (ret < 0)
    {
      bdbg("Failed to read NXFLAT header: %d\n", ret);
      return ret;
    }
  nxflat_dumpbuffer("NXFLAT header", (FAR const uint8_t*)&loadinfo->header,
                    sizeof(struct nxflat_hdr_s));

  /* Verify the NXFLAT header */

  if (nxflat_verifyheader(&loadinfo->header) != 0)
    {
      /* This is not an error because we will be called to attempt loading
       * EVERY binary.  Returning -ENOEXEC simply informs the system that
       * the file is not an NXFLAT file.  Besides, if there is something worth
       * complaining about, nnxflat_verifyheader() has already
       * done so.
       */

      bdbg("Bad NXFLAT header\n");
      return -ENOEXEC;
    }

  /* Save all of the input values in the loadinfo structure 
   * and extract some additional information from the xflat
   * header.  Note that the information in the xflat header is in
   * network order.
   */

  datastart             = ntohl(loadinfo->header.h_datastart);
  dataend               = ntohl(loadinfo->header.h_dataend);
  bssstart              = dataend;
  bssend                = ntohl(loadinfo->header.h_bssend);

  /* And put this information into the loadinfo structure as well.
   *
   * Note that:
   *
   *   isize       = the address range from 0 up to datastart.
   *   datasize   = the address range from datastart up to dataend
   *   bsssize    = the address range from dataend up to bssend.
   */

  loadinfo->entryoffs   = ntohl(loadinfo->header.h_entry);
  loadinfo->isize       = datastart;

  loadinfo->datasize    = dataend - datastart;
  loadinfo->bsssize     = bssend - dataend;
  loadinfo->stacksize   = ntohl(loadinfo->header.h_stacksize);

  /* This is the initial dspace size.  We'll re-calculate this later
   * after the memory has been allocated.
   */

  loadinfo->dsize       = bssend - datastart;

  /* Get the offset to the start of the relocations (we'll relocate
   * this later).
   */

  loadinfo->relocstart  = ntohl(loadinfo->header.h_relocstart);
  loadinfo->reloccount  = ntohs(loadinfo->header.h_reloccount);

  return 0;
}
Exemplo n.º 29
0
int group_addrenv(FAR struct tcb_s *tcb)
{
  FAR struct task_group_s *group;
  FAR struct task_group_s *oldgroup;
  irqstate_t flags;
  gid_t gid;
  int ret;

  /* NULL for the tcb means to use the TCB of the task at the head of the
   * ready to run list.
   */

  if (!tcb)
    {
      tcb = (FAR struct tcb_s *)g_readytorun.head;
    }

  DEBUGASSERT(tcb && tcb->group);
  group = tcb->group;

  /* Does the group have an address environment? */

  if ((group->tg_flags & GROUP_FLAG_ADDRENV) == 0)
    {
      /* No... just return perhaps leaving a different address environment
       * intact.
       */

      return OK;
    }

  /* Get the ID of the group that needs the address environment */

  gid = group->tg_gid;
  DEBUGASSERT(gid != 0);

  /* Are we going to change address environments? */

  flags = irqsave();
  if (gid != g_gid_current)
    {
      /* Yes.. Is there a current address environment in place? */

      if (g_gid_current != 0)
        {
          /* Find the old group with this ID. */

          oldgroup = group_findbygid(g_gid_current);
          DEBUGASSERT(oldgroup &&
                     (oldgroup->tg_flags & GROUP_FLAG_ADDRENV) != 0);

          if (oldgroup)
            {
              /* We need to flush the D-Cache and Invalidate the I-Cache for
               * the group whose environment is disappearing.
               */

              up_addrenv_coherent(&oldgroup->addrenv);
            }
        }

      /* Instantiate the new address environment (removing the old
       * environment in the process).  For the case of kernel threads,
       * the old mappings will be removed and no new mappings will be
       * instantiated.
       */

      ret = up_addrenv_select(&group->addrenv, NULL);
      if (ret < 0)
        {
          bdbg("ERROR: up_addrenv_select failed: %d\n", ret);
        }

      /* Save the new, current group */
  
      g_gid_current = gid;
    }

  irqrestore(flags);
  return OK;
}
Exemplo n.º 30
0
int exec_module(FAR const struct binary_s *binp)
{
  FAR _TCB     *tcb;
#ifndef CONFIG_CUSTOM_STACK
  FAR uint32_t *stack;
#endif
  pid_t         pid;
  int           err;
  int           ret;

  /* Sanity checking */

#ifdef CONFIG_DEBUG
  if (!binp || !binp->entrypt || binp->stacksize <= 0)
    {
      err = EINVAL;
      goto errout;
    }
#endif

  bdbg("Executing %s\n", binp->filename);

  /* Allocate a TCB for the new task. */

  tcb = (FAR _TCB*)kzalloc(sizeof(_TCB));
  if (!tcb)
    {
      err = ENOMEM;
      goto errout;
    }

  /* Allocate the stack for the new task */

#ifndef CONFIG_CUSTOM_STACK
  stack = (FAR uint32_t*)kmalloc(binp->stacksize);
  if (!tcb)
    {
      err = ENOMEM;
      goto errout_with_tcb;
    }

  /* Initialize the task */

  ret = task_init(tcb, binp->filename, binp->priority, stack,
                  binp->stacksize, binp->entrypt, binp->argv);
#else
  /* Initialize the task */

  ret = task_init(tcb, binp->filename, binp->priority, stack,
                  binp->entrypt, binp->argv);
#endif
  if (ret < 0)
    {
      err = errno;
      bdbg("task_init() failed: %d\n", err);
      goto errout_with_stack;
    }

  /* Note that tcb->flags are not modified.  0=normal task */
  /* tcb->flags |= TCB_FLAG_TTYPE_TASK; */

  /* 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 = 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);
  if (ret < 0)
    {
      err = errno;
      bdbg("task_activate() failed: %d\n", err);
      goto errout_with_stack;
    }

  return (int)pid;

errout_with_stack:
#ifndef CONFIG_CUSTOM_STACK
  tcb->stack_alloc_ptr = NULL;
  sched_releasetcb(tcb);
  kfree(stack);
#else
  sched_releasetcb(tcb);
#endif
  goto errout;

errout_with_tcb:
  kfree(tcb);
errout:
  errno = err;
  bdbg("returning errno: %d\n", err);
  return ERROR;
}