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