Exemplo n.º 1
0
static int
sha_fs_boot()
{
	binfo("starting");
	binfo("storage is file system");
	binfo("git blk_SHA1() hash algorithm");

	strcpy(boot_data.root_dir_path, sha_fs_root);
	binfo2("fs root directory", boot_data.root_dir_path);

	/*
	 *  Verify or create root directory path.
	 */
	if (_mkdir((struct request *)0, boot_data.root_dir_path, 1))
		panic("sha: boot: _mkdir(root_dir) failed");

	/*
	 *  Create the temporary scratch directory data/sha_fs/tmp
	 */
	strcpy(boot_data.tmp_dir_path, boot_data.root_dir_path);
	strcat(boot_data.tmp_dir_path, "/tmp");

	if (_mkdir((struct request *)0, boot_data.tmp_dir_path, 1))
		panic("sha: boot: _mkdir(tmp) failed");
	binfo2("sha temporary directory", boot_data.tmp_dir_path);
	return 0;
}
Exemplo n.º 2
0
int up_addrenv_destroy(FAR group_addrenv_t *addrenv)
{
  binfo("addrenv=%p\n", addrenv);
  DEBUGASSERT(addrenv);

  /* Destroy the .text region */

  arm_addrenv_destroy_region(addrenv->text, ARCH_TEXT_NSECTS,
                             CONFIG_ARCH_TEXT_VBASE, false);

  /* Destroy the .bss/.data region */

  arm_addrenv_destroy_region(addrenv->data, ARCH_DATA_NSECTS,
                             CONFIG_ARCH_DATA_VBASE, false);

#ifdef CONFIG_BUILD_KERNEL
  /* Destroy the heap region */

  arm_addrenv_destroy_region(addrenv->heap, ARCH_HEAP_NSECTS,
                             CONFIG_ARCH_HEAP_VBASE, false);
#ifdef CONFIG_MM_SHM
  /* Destroy the shared memory region (without freeing the physical page
   * data).
   */

  arm_addrenv_destroy_region(addrenv->heap, ARCH_SHM_NSECTS,
                             CONFIG_ARCH_SHM_VBASE, true);
#endif
#endif

  memset(addrenv, 0, sizeof(group_addrenv_t));
  return OK;
}
Exemplo n.º 3
0
int up_addrenv_detach(FAR struct task_group_s *group, FAR struct tcb_s *tcb)
{
  binfo("group=%p tcb=%p\n", group, tcb);

  /* Nothing needs to be done in this implementation */

  return OK;
}
Exemplo n.º 4
0
static int builtin_loadbinary(struct binary_s *binp)
{
  FAR const char *filename;
  FAR const struct builtin_s *b;
  int fd;
  int index;
  int ret;

  binfo("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();
      berr("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();
      berr("ERROR: FIOC_FILENAME ioctl failed: %d\n", errval);
      close(fd);
      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();
      berr("ERROR: %s is not a builtin application\n", filename);
      close(fd);
      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;
  close(fd);
  return OK;
}
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 */

  binfo("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 = get_errno();
          berr("Failed to seek to position %d: %d\n", offset, errval);
          return -errval;
        }

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

       nbytes = nx_read(loadinfo->filfd, bufptr, bytesleft);
       if (nbytes < 0)
         {
           if (nbytes != -EINTR)
             {
               berr("Read from offset %d failed: %d\n",
                    offset, (int)nbytes);
               return nbytes;
             }
         }
       else if (nbytes == 0)
         {
           berr("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;
}
Exemplo n.º 6
0
int up_addrenv_vtext(FAR group_addrenv_t *addrenv, FAR void **vtext)
{
  binfo("return=%p\n", (FAR void *)CONFIG_ARCH_TEXT_VBASE);

  /* Not much to do in this case */

  DEBUGASSERT(addrenv && vtext);
  *vtext = (FAR void *)CONFIG_ARCH_TEXT_VBASE;
  return OK;
}
Exemplo n.º 7
0
int up_addrenv_clone(FAR const group_addrenv_t *src,
                     FAR group_addrenv_t *dest)
{
  binfo("src=%p dest=%p\n", src, dest);
  DEBUGASSERT(src && dest);

  /* Just copy the address environment from the source to the destination */

  memcpy(dest, src, sizeof(group_addrenv_t));
  return OK;
}
Exemplo n.º 8
0
int up_addrenv_vdata(FAR group_addrenv_t *addrenv, uintptr_t textsize,
                     FAR void **vdata)
{
  binfo("return=%p\n",
        (FAR void *)(CONFIG_ARCH_DATA_VBASE + ARCH_DATA_RESERVE_SIZE));

  /* Not much to do in this case */

  DEBUGASSERT(addrenv && vdata);
  *vdata = (FAR void *)(CONFIG_ARCH_DATA_VBASE + ARCH_DATA_RESERVE_SIZE);
  return OK;
}
Exemplo n.º 9
0
int up_addrenv_restore(FAR const save_addrenv_t *oldenv)
{
  uintptr_t vaddr;
  int i;

  binfo("oldenv=%p\n", oldenv);
  DEBUGASSERT(oldenv);

  for (vaddr = CONFIG_ARCH_TEXT_VBASE, i = 0;
       i < ARCH_TEXT_NSECTS;
       vaddr += SECTION_SIZE, i++)
    {
      /* Restore the L1 page table entry */

      mmu_l1_restore(vaddr, oldenv->text[i]);
    }

  for (vaddr = CONFIG_ARCH_DATA_VBASE, i = 0;
       i < ARCH_DATA_NSECTS;
       vaddr += SECTION_SIZE, i++)
    {
      /* Restore the L1 page table entry */

      mmu_l1_restore(vaddr, oldenv->data[i]);
    }

#ifdef CONFIG_BUILD_KERNEL
  for (vaddr = CONFIG_ARCH_HEAP_VBASE, i = 0;
       i < ARCH_HEAP_NSECTS;
       vaddr += SECTION_SIZE, i++)
    {
      /* Restore the L1 page table entry */

      mmu_l1_restore(vaddr, oldenv->heap[i]);
    }

#ifdef CONFIG_MM_SHM
  for (vaddr = CONFIG_ARCH_SHM_VBASE, i = 0;
       i < ARCH_SHM_NSECTS;
       vaddr += SECTION_SIZE, i++)
    {
      /* Restore the L1 page table entry */

      mmu_l1_restore(vaddr, oldenv->shm[i]);
    }

#endif
#endif

  return OK;
}
Exemplo n.º 10
0
static inline int nxflat_bindrel32id(FAR struct nxflat_loadinfo_s *loadinfo,
                                     uint32_t offset)
{
  FAR uint32_t *addr;

  binfo("NXFLAT_RELOC_TYPE_REL32D Offset: %08x D-Space: %p\n",
        offset, loadinfo->dspace->region);

  if (offset < loadinfo->dsize)
    {
      addr = (FAR uint32_t *)(offset + loadinfo->dspace->region);
      binfo("  Before: %08x\n", *addr);
     *addr += ((uint32_t)loadinfo->ispace - (uint32_t)(loadinfo->dspace->region));
      binfo("  After: %08x\n", *addr);
      return OK;
    }
  else
    {
      berr("Offset: %08 does not lie in D-Space size: %08x\n",
           offset, loadinfo->dsize);
      return -EINVAL;
    }
}
Exemplo n.º 11
0
int builtin_initialize(void)
{
  int ret;

  /* Register ourselves as a binfmt loader */

  binfo("Registering Builtin Loader\n");

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

  return ret;
}
Exemplo n.º 12
0
Arquivo: elf.c Projeto: dagar/NuttX
int elf_initialize(void)
{
  int ret;

  /* Register ourselves as a binfmt loader */

  binfo("Registering ELF\n");

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

  return ret;
}
Exemplo n.º 13
0
int elf_verifyheader(FAR const Elf32_Ehdr *ehdr)
{
  if (!ehdr)
    {
      berr("NULL ELF header!");
      return -ENOEXEC;
    }

  /* Verify that the magic number indicates an ELF file */

  if (memcmp(ehdr->e_ident, g_elfmagic, EI_MAGIC_SIZE) != 0)
    {
      binfo("Not ELF magic {%02x, %02x, %02x, %02x}\n",
            ehdr->e_ident[0], ehdr->e_ident[1], ehdr->e_ident[2], ehdr->e_ident[3]);
      return -ENOEXEC;
    }

  /* Verify that this is a relocatable file */

  if (ehdr->e_type != ET_REL)
    {
      berr("Not a relocatable file: e_type=%d\n", ehdr->e_type);
      return -EINVAL;
    }

  /* Verify that this file works with the currently configured architecture */

  if (up_checkarch(ehdr))
    {
      berr("Not a supported architecture\n");
      return -ENOEXEC;
    }

  /* Looks good so far... we still might find some problems later. */

  return OK;
}
Exemplo n.º 14
0
int modlib_symvalue(FAR struct module_s *modp,
                    FAR struct mod_loadinfo_s *loadinfo, FAR Elf32_Sym *sym)
{
  FAR const struct symtab_s *symbol;
  struct mod_exportinfo_s exportinfo;
  uintptr_t secbase;
  int ret;

  switch (sym->st_shndx)
    {
    case SHN_COMMON:
      {
        /* NuttX ELF modules should be compiled with -fno-common. */

        berr("ERROR: SHN_COMMON: Re-compile with -fno-common\n");
        return -ENOSYS;
      }

    case SHN_ABS:
      {
        /* st_value already holds the correct value */

        binfo("SHN_ABS: st_value=%08lx\n", (long)sym->st_value);
        return OK;
      }

    case SHN_UNDEF:
      {
        /* Get the name of the undefined symbol */

        ret = modlib_symname(loadinfo, sym);
        if (ret < 0)
          {
            /* There are a few relocations for a few architectures that do
             * no depend upon a named symbol.  We don't know if that is the
             * case here, but return and special error to the caller to
             * indicate the nameless symbol.
             */

            berr("ERROR: SHN_UNDEF: Failed to get symbol name: %d\n", ret);
            return ret;
          }

        /* First check if the symbol is exported by an installed module.
         * Newest modules are installed at the head of the list.  Therefore,
         * if the symbol is exported by numerous modules, then the most
         * recently installed will take precedence.
         */

        exportinfo.name   = (FAR const char *)loadinfo->iobuffer;
        exportinfo.modp   = modp;
        exportinfo.symbol = NULL;

        ret = modlib_registry_foreach(modlib_symcallback, (FAR void *)&exportinfo);
        if (ret < 0)
          {
            berr("ERROR: modlib_symcallback failed: \n", ret);
            return ret;
          }

        symbol = exportinfo.symbol;

        /* If the symbol is not exported by any module, then check if the
         * base code exports a symbol of this name.
         */

        if (symbol == NULL)
          {
#ifdef CONFIG_SYMTAB_ORDEREDBYNAME
            symbol = symtab_findorderedbyname(g_modlib_symtab, exportinfo.name,
                                              g_modlib_nsymbols);
#else
            symbol = symtab_findbyname(g_modlib_symtab, exportinfo.name,
                                       g_modlib_nsymbols);
#endif
          }

        /* Was the symbol found from any exporter? */

        if (symbol == NULL)
          {
            berr("ERROR: SHN_UNDEF: Exported symbol \"%s\" not found\n",
                 loadinfo->iobuffer);
            return -ENOENT;
          }

        /* Yes... add the exported symbol value to the ELF symbol table entry */

        binfo("SHN_ABS: name=%s %08x+%08x=%08x\n",
              loadinfo->iobuffer, sym->st_value, symbol->sym_value,
              sym->st_value + symbol->sym_value);

        sym->st_value += (Elf32_Word)((uintptr_t)symbol->sym_value);
      }
      break;

    default:
      {
        secbase = loadinfo->shdr[sym->st_shndx].sh_addr;

        binfo("Other: %08x+%08x=%08x\n",
              sym->st_value, secbase, sym->st_value + secbase);

        sym->st_value += secbase;
      }
      break;
    }

  return OK;
}
Exemplo n.º 15
0
int up_addrenv_create(size_t textsize, size_t datasize, size_t heapsize,
                      FAR group_addrenv_t *addrenv)
{
  int ret;

  binfo("addrenv=%p textsize=%lu datasize=%lu\n",
        addrenv, (unsigned long)textsize, (unsigned long)datasize);

  DEBUGASSERT(addrenv);

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

  memset(addrenv, 0, sizeof(group_addrenv_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(addrenv->text, ARCH_TEXT_NSECTS,
                                  CONFIG_ARCH_TEXT_VBASE, textsize,
                                  MMU_L2_UTEXTFLAGS);
  if (ret < 0)
    {
      berr("ERROR: Failed to create .text region: %d\n", ret);
      goto errout;
    }

  /* Allocate .bss/.data space pages.  NOTE that a configurable offset is
   * added to the allocted size.  This is matched by the offset that is
   * used when reporting the virtual data address in up_addrenv_vdata().
   */

  ret = arm_addrenv_create_region(addrenv->data, ARCH_DATA_NSECTS,
                                  CONFIG_ARCH_DATA_VBASE,
                                  datasize + ARCH_DATA_RESERVE_SIZE,
                                  MMU_L2_UDATAFLAGS);
  if (ret < 0)
    {
      berr("ERROR: Failed to create .bss/.data region: %d\n", ret);
      goto errout;
    }

#ifdef CONFIG_BUILD_KERNEL
  /* Initialize the shared data are at the beginning of the .bss/.data
   * region.
   */

  ret = up_addrenv_initdata((uintptr_t)addrenv->data[0] & PMD_PTE_PADDR_MASK);
  if (ret < 0)
    {
      berr("ERROR: Failed to initialize .bss/.data region: %d\n", ret);
      goto errout;
    }
#endif

#ifdef CONFIG_BUILD_KERNEL
  /* Allocate heap space pages */

  ret = arm_addrenv_create_region(addrenv->heap, ARCH_HEAP_NSECTS,
                                  CONFIG_ARCH_HEAP_VBASE, heapsize,
                                  MMU_L2_UDATAFLAGS);
  if (ret < 0)
    {
      berr("ERROR: Failed to create heap region: %d\n", ret);
      goto errout;
    }

  /* Save the initial heap size allocated.  This will be needed when
   * the heap data structures are initialized.
   */

  addrenv->heapsize = (size_t)ret << MM_PGSHIFT;
#endif
  return OK;

errout:
  up_addrenv_destroy(addrenv);
  return ret;
}
Exemplo n.º 16
0
int elf_load(FAR struct elf_loadinfo_s *loadinfo)
{
  size_t heapsize;
#ifdef CONFIG_UCLIBCXX_EXCEPTION
  int exidx;
#endif
  int ret;

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

  /* Load section headers into memory */

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

  /* Determine total size to allocate */

  elf_elfsize(loadinfo);

  /* Determine the heapsize to allocate.  heapsize is ignored if there is
   * no address environment because the heap is a shared resource in that
   * case.  If there is no dynamic stack then heapsize must at least as big
   * as the fixed stack size since the stack will be allocated from the heap
   * in that case.
   */

#if !defined(CONFIG_ARCH_ADDRENV)
  heapsize = 0;
#elif defined(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, heapsize);
  if (ret < 0)
    {
      berr("ERROR: elf_addrenv_alloc() failed: %d\n", ret);
      goto errout_with_buffers;
    }

#ifdef CONFIG_ARCH_ADDRENV
  /* 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)
    {
      berr("ERROR: elf_addrenv_select() failed: %d\n", ret);
      goto errout_with_buffers;
    }
#endif

  /* Load ELF section data into memory */

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

  /* Load static constructors and destructors. */

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

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

#ifdef CONFIG_UCLIBCXX_EXCEPTION
  exidx = elf_findsection(loadinfo, CONFIG_ELF_EXIDX_SECTNAME);
  if (exidx < 0)
    {
      binfo("elf_findsection: Exception Index section not found: %d\n", exidx);
    }
  else
    {
      up_init_exidx(loadinfo->shdr[exidx].sh_addr, loadinfo->shdr[exidx].sh_size);
    }
#endif

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

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

  return OK;

  /* Error exits */

errout_with_addrenv:
#ifdef CONFIG_ARCH_ADDRENV
  (void)elf_addrenv_restore(loadinfo);
#endif

errout_with_buffers:
  elf_unload(loadinfo);
  return ret;
}
Exemplo n.º 17
0
Arquivo: elf.c Projeto: dagar/NuttX
static int elf_loadbinary(FAR struct binary_s *binp)
{
  struct elf_loadinfo_s loadinfo;  /* Contains globals for libelf */
  int                   ret;

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

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

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

  /* Load the program binary */

  ret = elf_load(&loadinfo);
  elf_dumploadinfo(&loadinfo);
  if (ret != 0)
    {
      berr("Failed to load ELF program binary: %d\n", ret);
      goto errout_with_init;
    }

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

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

  /* Return the load information */

  binp->entrypt   = (main_t)(loadinfo.textalloc + loadinfo.ehdr.e_entry);
  binp->stacksize = CONFIG_ELF_STACKSIZE;

  /* Add the ELF allocation to the alloc[] only if there is no address
   * environment.  If there is an address environment, it will automatically
   * be freed when the function exits
   *
   * REVISIT:  If the module is loaded then unloaded, wouldn't this cause
   * a memory leak?
   */

#ifdef CONFIG_ARCH_ADDRENV
#  warning "REVISIT"
#else
  binp->alloc[0]  = (FAR void *)loadinfo.textalloc;
#endif

#ifdef CONFIG_BINFMT_CONSTRUCTORS
  /* Save information about constructors.  NOTE:  destructors are not
   * yet supported.
   */

  binp->alloc[1]  = loadinfo.ctoralloc;
  binp->ctors     = loadinfo.ctors;
  binp->nctors    = loadinfo.nctors;

  binp->alloc[2]  = loadinfo.dtoralloc;
  binp->dtors     = loadinfo.dtors;
  binp->ndtors    = loadinfo.ndtors;
#endif

#ifdef CONFIG_ARCH_ADDRENV
  /* Save the address environment in the binfmt structure.  This will be
   * needed when the module is executed.
   */

  up_addrenv_clone(&loadinfo.addrenv, &binp->addrenv);
#endif

  elf_dumpentrypt(binp, &loadinfo);
  elf_uninit(&loadinfo);
  return OK;

errout_with_load:
  elf_unload(&loadinfo);
errout_with_init:
  elf_uninit(&loadinfo);
errout:
  return ret;
}
Exemplo n.º 18
0
template<class BASE> void pod_simulate<BASE>::init(input_map& inmap, void *gin) {
	std::string filename,keyword,linebuff;
	std::ostringstream nstr;
	std::istringstream instr;
	int i;

	/* Initialize base class */
	/* If restart is not equal to 0, this will load DNS data */
	BASE::init(inmap,gin);

	inmap.getwdefault(BASE::gbl->idprefix + "_groups",pod_id,0);

	nstr.str("");
	nstr << "pod" << pod_id << "_nmodes";
	if (!inmap.get(nstr.str(),nmodes)) inmap.getwdefault("nmodes",nmodes,5); 
	nstr.clear();

	vsi ugstore;
	ugstore.v.reference(BASE::ugbd(0).v);
	ugstore.s.reference(BASE::ugbd(0).s);
	ugstore.i.reference(BASE::ugbd(0).i);

	modes.resize(nmodes);
	for(i=0;i<nmodes;++i) {
		nstr.str("");
		nstr << i << std::flush;
		filename = "mode" +nstr.str();
		nstr.clear();
		modes(i).v.resize(BASE::maxpst,BASE::NV);
		modes(i).s.resize(BASE::maxpst,BASE::sm0,BASE::NV);
		modes(i).i.resize(BASE::maxpst,BASE::im0,BASE::NV);
		BASE::ugbd(0).v.reference(modes(i).v);
		BASE::ugbd(0).s.reference(modes(i).s);
		BASE::ugbd(0).i.reference(modes(i).i);
		BASE::input(filename, BASE::binary);
	}
	BASE::ugbd(0).v.reference(ugstore.v);
	BASE::ugbd(0).s.reference(ugstore.s);
	BASE::ugbd(0).i.reference(ugstore.i);

#ifdef POD_BDRY
	pod_ebdry.resize(BASE::nebd);
	/* Count how many boundary modes there are so we can size arrays before initializing boundaries */
	/* For each mesh block that is part of this pod block need to know
	/* # of pod boundaries, ids, and # of pod modes for each unique id */

	/* First need to know what block # I am and how many total blocks there are in this pod group */
	int localid = sim::blks.allreduce_local_id(pod_id,BASE::gbl->idnum);
	int npodblk = sim::blks.allreduce_nmember(pod_id);
	Array<int,1> binfo(npodblk),binfo_recv(npodblk);
	binfo = 0;

	for (int i=0;i<BASE::nebd;++i) {
		/* Not going to initialize until I can resize coeffs & rsdls arrays to accomodate boundary modes */
		pod_ebdry(i) = new pod_sim_edge_bdry<BASE>(*this,*BASE::ebdry(i));

		keyword = pod_ebdry(i)->base.idprefix +"_pod";
		inmap.getwdefault(keyword,pod_ebdry(i)->active,false);
		if (!pod_ebdry(i)->active) {
			pod_ebdry(i)->nmodes = 0;
			continue;
		}
		binfo(localid)++;

		keyword = pod_ebdry(i)->base.idprefix + "_pod_id";
		inmap.getwdefault(keyword,pod_ebdry(i)->pod_id,pod_ebdry(i)->base.idnum);

		nstr.str("");
		nstr << "bdry_pod" << pod_ebdry(i)->pod_id << "_nmodes";
		if (!inmap.get(nstr.str(),pod_ebdry(i)->nmodes)) inmap.getwdefault("bdry_nmodes",pod_ebdry(i)->nmodes,nmodes); 
		nstr.clear();
	}

	/* Send number of pod boundaries belonging to each block of pod group */
	sim::blks.allreduce(binfo.data(), binfo_recv.data(), npodblk,blocks::int_msg, blocks::sum, pod_id);


	/* Second thing is to pass id, nmodes for each active boundary */
	/* Count # of pod_boundaries before this block and total # of pod boundaries in pod group */
	int nbefore = 0;
	for (int i=0;i<localid;++i) {
		nbefore += binfo_recv(i);
	}

	int ntotal = nbefore;
	for (int i=localid;i<npodblk;++i) {
		ntotal += binfo_recv(i);
	}

	binfo.resize(ntotal*2);
	binfo_recv.resize(ntotal*2);
	nbefore *= 2;
	binfo = 0;
	for (int i=0;i<BASE::nebd;++i) {
		if (!pod_ebdry(i)->active) continue;

		binfo(nbefore++) = pod_ebdry(i)->pod_id;
		binfo(nbefore++) = pod_ebdry(i)->nmodes;
	}
	sim::blks.allreduce(binfo.data(), binfo_recv.data(), ntotal*2,blocks::int_msg, blocks::sum, pod_id);

	/* Now make a map from pod_id to number of modes & multiplicity */
	std::map<int,bd_str> pod_bdry_map;
	tmodes = nmodes;
	for (int i=0;i<2*ntotal;i+=2) {
		if (pod_bdry_map.find(binfo_recv(i)) != pod_bdry_map.end()) {
			++pod_bdry_map[binfo_recv(i)].multiplicity;
		}
		else {
			pod_bdry_map[binfo_recv(i)] = bd_str();
			pod_bdry_map[binfo_recv(i)].multiplicity = 1;
			pod_bdry_map[binfo_recv(i)].nmodes = binfo_recv(i+1);
			tmodes += binfo_recv(i+1);
		}
	}
	*BASE::gbl->log << "#There are " << tmodes << " total modes on pod block " << pod_id << std::endl;
	multiplicity.resize(tmodes);
#else
	tmodes = nmodes;
#endif

	coeffs.resize(tmodes);
	rsdls.resize(tmodes);
	rsdls0.resize(tmodes);
	rsdls_recv.resize(tmodes);
	jacobian.resize(tmodes,tmodes);
	ipiv.resize(tmodes);

#ifdef POD_BDRY
	/* Count total number of boundary modes */
	/* and make map be an accrual of previous modes */
	multiplicity = 1.0;
	int bindex = nmodes;
	for (std::map<int,bd_str>::iterator mi = pod_bdry_map.begin(); mi != pod_bdry_map.end(); ++mi) {
		int n = mi->second.nmodes;
		mi->second.nmodes = bindex;
		multiplicity(Range(bindex,bindex+n-1)) = mi->second.multiplicity;
		bindex += n;
	}
#endif


	int load_coeffs;
	inmap.getwdefault("load_coeffs",load_coeffs,0);
	
	if (load_coeffs) {
		/* This is the old way */
		/* This loads coefficient vector made by pod_generate for this timestep */
		nstr.str("");
		nstr << load_coeffs << std::flush;
		filename = "coeff" +nstr.str() +"_" +BASE::gbl->idprefix +".bin";
		binifstream bin;
		bin.open(filename.c_str());
		if (bin.error()) {
				*BASE::gbl->log << "couldn't open coefficient input file " << filename << std::endl;
				sim::abort(__LINE__,__FILE__,BASE::gbl->log);
		}
		bin.setFlag(binio::BigEndian,bin.readInt(1));
		bin.setFlag(binio::FloatIEEE,bin.readInt(1));
		/* CONSTRUCT INITIAL SOLUTION DESCRIPTION */
		BASE::ug.v(Range(0,BASE::npnt-1)) = 0.;
		BASE::ug.s(Range(0,BASE::nseg-1)) = 0.;
		BASE::ug.i(Range(0,BASE::ntri-1)) = 0.;
		
		for (int l=0;l<nmodes;++l) {
			coeffs(l) = bin.readFloat(binio::Double); 
			BASE::ug.v(Range(0,BASE::npnt-1)) += coeffs(l)*modes(l).v(Range(0,BASE::npnt-1));
			BASE::ug.s(Range(0,BASE::nseg-1)) += coeffs(l)*modes(l).s(Range(0,BASE::nseg-1));
			BASE::ug.i(Range(0,BASE::ntri-1)) += coeffs(l)*modes(l).i(Range(0,BASE::ntri-1));
		}
		bin.close();
	}
	else {
		/* THIS IS TO CHANGE THE WAY SNAPSHOT MATRIX ENTRIES ARE FORMED */
		scaling.resize(BASE::NV);
		scaling = 1;
		if (inmap.getline(BASE::gbl->idprefix + "_scale_vector",linebuff) || inmap.getline("scale_vector",linebuff)) {
			instr.str(linebuff);
			for(i=0;i<BASE::NV;++i)
				instr >> scaling(i);
		}
		
		/* This is the new way */
		calc_coeffs();
	
		/* CONSTRUCT INITIAL SOLUTION DESCRIPTION */
		BASE::ug.v(Range(0,BASE::npnt-1)) = 0.;
		BASE::ug.s(Range(0,BASE::nseg-1)) = 0.;
		BASE::ug.i(Range(0,BASE::ntri-1)) = 0.;

		for (int l=0;l<nmodes;++l) {
			BASE::ug.v(Range(0,BASE::npnt-1)) += coeffs(l)*modes(l).v(Range(0,BASE::npnt-1));
			BASE::ug.s(Range(0,BASE::nseg-1)) += coeffs(l)*modes(l).s(Range(0,BASE::nseg-1));
			BASE::ug.i(Range(0,BASE::ntri-1)) += coeffs(l)*modes(l).i(Range(0,BASE::ntri-1));
		}
	}
Exemplo n.º 19
0
static inline int nxflat_bindimports(FAR struct nxflat_loadinfo_s *loadinfo,
                                     FAR const struct symtab_s *exports,
                                     int nexports)
{
  FAR struct nxflat_import_s *imports;
  FAR struct nxflat_hdr_s    *hdr;
  FAR const struct symtab_s  *symbol;

  char    *symname;
  uint32_t offset;
  uint16_t nimports;
#ifdef CONFIG_ARCH_ADDRENV
  int      ret;
#endif
  int      i;

  /* The NXFLAT header is the first thing at the beginning of the ISpace. */

  hdr = (FAR struct nxflat_hdr_s *)loadinfo->ispace;

  /* From this, we can get the offset to the list of symbols imported by
   * this module and the number of symbols imported by this module.
   */

  offset   = ntohl(hdr->h_importsymbols);
  nimports = ntohs(hdr->h_importcount);
  binfo("Imports offset: %08x nimports: %d\n", offset, nimports);

  /* The import[] table resides within the D-Space allocation.  If
   * CONFIG_ARCH_ADDRENV=y, then that D-Space allocation lies in an address
   * environment that may not be in place.  So, in that case, we must call
   * nxflat_addrenv_select to temporarily instantiate that address space
   * before the import[] table can be modified.
   */

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

  /* Verify that this module requires imported symbols */

  if (offset != 0 && nimports > 0)
    {
      /* It does.. make sure that exported symbols are provided */

      DEBUGASSERT(exports && nexports > 0);

      /* If non-zero, the value of the imported symbol list that we get
       * from the header is a file offset.  We will have to convert this
       * to an offset into the DSpace segment to get the pointer to the
       * beginning of the imported symbol list.
       */

      DEBUGASSERT(offset >= loadinfo->isize &&
                  offset < loadinfo->isize + loadinfo->dsize);

      imports = (FAR struct nxflat_import_s *)
        (offset - loadinfo->isize + loadinfo->dspace->region);

      /* Now, traverse the list of imported symbols and attempt to bind
       * each symbol to the value exported by from the exported symbol
       * table.
       */

      for (i = 0; i < nimports; i++)
        {
          binfo("Import[%d] (%08p) offset: %08x func: %08x\n",
                i, &imports[i], imports[i].i_funcname, imports[i].i_funcaddress);

          /* Get a pointer to the imported symbol name.  The name itself
           * lies in the TEXT segment.  But the reference to the name
           * lies in DATA segment.  Therefore, the name reference should
           * have been relocated when the module was loaded.
           */

          offset = imports[i].i_funcname;
          DEBUGASSERT(offset < loadinfo->isize);

          symname = (FAR char *)(offset + loadinfo->ispace + sizeof(struct nxflat_hdr_s));

          /* Find the exported symbol value for this this symbol name. */

#ifdef CONFIG_SYMTAB_ORDEREDBYNAME
          symbol = symtab_findorderedbyname(exports, symname, nexports);
#else
          symbol = symtab_findbyname(exports, symname, nexports);
#endif
          if (!symbol)
            {
              berr("Exported symbol \"%s\" not found\n", symname);
#ifdef CONFIG_ARCH_ADDRENV
              (void)nxflat_addrenv_restore(loadinfo);
#endif
              return -ENOENT;
            }

          /* And put this into the module's import structure. */

          imports[i].i_funcaddress =  (uint32_t)symbol->sym_value;

          binfo("Bound import[%d] (%08p) to export '%s' (%08x)\n",
                i, &imports[i], symname, imports[i].i_funcaddress);
        }
    }

  /* Dump the relocation import table */

#ifdef CONFIG_NXFLAT_DUMPBUFFER
  if (nimports > 0)
    {
      nxflat_dumpbuffer("Imports", (FAR const uint8_t *)imports, nimports * sizeof(struct nxflat_import_s));
    }
#endif

  /* Restore the original address environment */

#ifdef CONFIG_ARCH_ADDRENV
  ret = nxflat_addrenv_restore(loadinfo);
  if (ret < 0)
    {
      berr("ERROR: nxflat_addrenv_restore() failed: %d\n", ret);
    }

  return ret;
#else
  return OK;
#endif
}
Exemplo n.º 20
0
static inline int nxflat_gotrelocs(FAR struct nxflat_loadinfo_s *loadinfo)
{
  FAR struct nxflat_reloc_s *relocs;
  FAR struct nxflat_reloc_s  reloc;
  FAR struct nxflat_hdr_s   *hdr;
  uint32_t offset;
  uint16_t nrelocs;
  int      ret;
  int      result;
  int      i;

  /* The NXFLAT header is the first thing at the beginning of the ISpace. */

  hdr = (FAR struct nxflat_hdr_s *)loadinfo->ispace;

  /* From this, we can get the offset to the list of relocation entries */

  offset  = ntohl(hdr->h_relocstart);
  nrelocs = ntohs(hdr->h_reloccount);
  binfo("offset: %08lx nrelocs: %d\n", (long)offset, nrelocs);

  /* The value of the relocation list that we get from the header is a
   * file offset.  We will have to convert this to an offset into the
   * DSpace segment to get the pointer to the beginning of the relocation
   * list.
   */

  DEBUGASSERT(offset >= loadinfo->isize);
  DEBUGASSERT(offset + nrelocs * sizeof(struct nxflat_reloc_s)
              <= (loadinfo->isize + loadinfo->dsize));

  relocs = (FAR struct nxflat_reloc_s *)
        (offset - loadinfo->isize + loadinfo->dspace->region);
  binfo("isize: %08lx dpsace: %p relocs: %p\n",
        (long)loadinfo->isize, loadinfo->dspace->region, relocs);

  /* All relocations are performed within the D-Space allocation.  If
   * CONFIG_ARCH_ADDRENV=y, then that D-Space allocation lies in an address
   * environment that may not be in place.  So, in that case, we must call
   * nxflat_addrenv_select to temporarily instantiate that address space
   * before the relocations can be performed.
   */

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

  /* Now, traverse the relocation list of and bind each GOT relocation. */

  ret = OK; /* Assume success */
  for (i = 0; i < nrelocs; i++)
    {
      /* Handle the relocation by the relocation type */

#ifdef CONFIG_CAN_PASS_STRUCTS
      reloc = *relocs++;
#else
      memcpy(&reloc, relocs, sizeof(struct nxflat_reloc_s));
      relocs++;
#endif

      result = OK;
      switch (NXFLAT_RELOC_TYPE(reloc.r_info))
        {
        /* NXFLAT_RELOC_TYPE_REL32I  Meaning: Object file contains a 32-bit offset
         *                                    into I-Space at the offset.
         *                           Fixup:   Add mapped I-Space address to the offset.
         */

        case NXFLAT_RELOC_TYPE_REL32I:
          {
            result = nxflat_bindrel32i(loadinfo, NXFLAT_RELOC_OFFSET(reloc.r_info));
          }
          break;

        /* NXFLAT_RELOC_TYPE_REL32D  Meaning: Object file contains a 32-bit offset
         *                                    into D-Space at the offset.
         *                           Fixup:   Add allocated D-Space address to the
         *                                    offset.
         */

        case NXFLAT_RELOC_TYPE_REL32D:
          {
            result = nxflat_bindrel32d(loadinfo, NXFLAT_RELOC_OFFSET(reloc.r_info));
          }
          break;

        /* NXFLAT_RELOC_TYPE_REL32ID Meaning: Object file contains a 32-bit offset
         *                                    into I-Space at the offset that will
         *                                    unfortunately be references relative
         *                                    to the GOT
         *                           Fixup:   Add allocated the mapped I-Space
         *                                    address MINUS the allocated D-Space
         *                                    address to the offset.
         */

#ifdef NXFLAT_RELOC_TYPE_REL32ID
        case NXFLAT_RELOC_TYPE_REL32ID:
          {
            result = nxflat_bindrel32id(loadinfo, NXFLAT_RELOC_OFFSET(reloc.r_info));
          }
          break;
#endif

        default:
          {
            berr("ERROR: Unrecognized relocation type: %d\n", NXFLAT_RELOC_TYPE(reloc.r_info));
            result = -EINVAL;
          }
          break;
        }

      /* Check for failures */

      if (result < 0 && ret == OK)
        {
          ret = result;
        }
    }

  /* Dump the relocation got */

#ifdef CONFIG_NXFLAT_DUMPBUFFER
  if (ret == OK && nrelocs > 0)
    {
      relocs = (FAR struct nxflat_reloc_s *)(offset - loadinfo->isize + loadinfo->dspace->region);
      nxflat_dumpbuffer("GOT", (FAR const uint8_t *)relocs, nrelocs * sizeof(struct nxflat_reloc_s));
    }
#endif

  /* Restore the original address environment */

#ifdef CONFIG_ARCH_ADDRENV
  ret = nxflat_addrenv_restore(loadinfo);
  if (ret < 0)
    {
      berr("ERROR: nxflat_addrenv_restore() failed: %d\n", ret);
    }
#endif

  return ret;
}
Exemplo n.º 21
0
int binfmt_copyargv(FAR struct binary_s *bin, FAR char * const *argv)
{
#if defined(CONFIG_ARCH_ADDRENV) && defined(CONFIG_BUILD_KERNEL)
  FAR char *ptr;
  size_t argvsize;
  size_t argsize;
  int nargs;
  int i;

  /* Get the number of arguments and the size of the argument list */

  bin->argv      = (FAR char **)NULL;
  bin->argbuffer = (FAR char *)NULL;

  if (argv)
    {
      argsize = 0;
      nargs   = 0;

      for (i = 0; argv[i]; i++)
        {
          /* Increment the size of the allocation with the size of the next string */

          argsize += (strlen(argv[i]) + 1);
          nargs++;

          /* This is a sanity check to prevent running away with an unterminated
           * argv[] list.  MAX_EXEC_ARGS should be sufficiently large that this
           * never happens in normal usage.
           */

          if (nargs > MAX_EXEC_ARGS)
            {
              berr("ERROR: Too many arguments: %lu\n", (unsigned long)argvsize);
              return -E2BIG;
            }
        }

      binfo("args=%d argsize=%lu\n", nargs, (unsigned long)argsize);

      /* Allocate the argv array and an argument buffer */

      if (argsize > 0)
        {
          argvsize  = (nargs + 1) * sizeof(FAR char *);
          bin->argbuffer = (FAR char *)kmm_malloc(argvsize + argsize);
          if (!bin->argbuffer)
            {
              berr("ERROR: Failed to allocate the argument buffer\n");
              return -ENOMEM;
            }

          /* Copy the argv list */

          bin->argv = (FAR char **)bin->argbuffer;
          ptr       = bin->argbuffer + argvsize;
          for (i = 0; argv[i]; i++)
            {
              bin->argv[i] = ptr;
              argsize      = strlen(argv[i]) + 1;
              memcpy(ptr, argv[i], argsize);
              ptr         += argsize;
            }

          /* Terminate the argv[] list */

          bin->argv[i] = (FAR char *)NULL;
        }
    }

  return OK;

#else
  /* Just save the caller's argv pointer */

  bin->argv = argv;
  return OK;
#endif
}
Exemplo n.º 22
0
static inline int elf_loadfile(FAR struct elf_loadinfo_s *loadinfo)
{
  FAR uint8_t *text;
  FAR uint8_t *data;
  FAR uint8_t **pptr;
  int ret;
  int i;

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

  binfo("Loaded sections:\n");
  text = (FAR uint8_t *)loadinfo->textalloc;
  data = (FAR uint8_t *)loadinfo->dataalloc;

  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;
        }

      /* SHF_WRITE indicates that the section address space is write-
       * able
       */

      if ((shdr->sh_flags & SHF_WRITE) != 0)
        {
          pptr = &data;
        }
      else
        {
          pptr = &text;
        }

      /* 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 the memory region */

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

      /* If there is no data in an allocated section, then the allocated
       * section must be cleared.
       */

      else
        {
          memset(*pptr, 0, shdr->sh_size);
        }

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

      binfo("%d. %08lx->%08lx\n", i,
            (unsigned long)shdr->sh_addr, (unsigned long)*pptr);

      shdr->sh_addr = (uintptr_t)*pptr;

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

      *pptr += ELF_ALIGNUP(shdr->sh_size);
    }

  return OK;
}