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 }
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 }
int nxflat_addrenv_alloc(FAR struct nxflat_loadinfo_s *loadinfo, size_t envsize) { FAR struct dspace_s *dspace; #ifdef CONFIG_ADDRENV FAR void *vaddr; hw_addrenv_t oldenv; int ret; #endif DEBUGASSERT(!loadinfo->dspace); /* Allocate the struct dspace_s container for the D-Space allocation */ dspace = (FAR struct dspace_s *)kmalloc(sizeof(struct dspace_s)); if (dspace == 0) { bdbg("ERROR: Failed to allocate DSpace\n"); return -ENOMEM; } #ifdef CONFIG_ADDRENV /* Create a D-Space address environment for the new NXFLAT task */ ret = up_addrenv_create(envsize, &loadinfo->addrenv); if (ret < 0) { bdbg("ERROR: up_addrenv_create failed: %d\n", ret); goto errout_with_dspace; } /* 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 D-Space region (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); goto errout_with_addrenv; } /* Clear all of the allocated D-Space memory. We have to temporarily * selected the D-Space address environment to do this. */ ret = up_addrenv_select(loadinfo->addrenv, &oldenv); if (ret < 0) { bdbg("ERROR: up_addrenv_select failed: %d\n", ret); goto errout_with_addrenv; } memset(vaddr, 0, envsize); ret = up_addrenv_restore(oldenv); if (ret < 0) { bdbg("ERROR: up_addrenv_restore failed: %d\n", ret); goto errout_with_addrenv; } /* Success... save the fruits of our labor */ loadinfo->dspace = dspace; dspace->crefs = 1; dspace->region = (FAR uint8_t *)vaddr; return OK; errout_with_addrenv: (void)up_addrenv_destroy(loadinfo->addrenv); loadinfo->addrenv = 0; errout_with_dspace: kfree(dspace); return ret; #else /* Allocate (and zero) memory to hold the ELF image */ dspace->region = (FAR uint8_t *)kuzalloc(envsize); if (!dspace->region) { kfree(dspace); return -ENOMEM; } loadinfo->dspace = dspace; dspace->crefs = 1; return OK; #endif }
int nxflat_addrenv_alloc(FAR struct nxflat_loadinfo_s *loadinfo, size_t envsize) { FAR struct dspace_s *dspace; #ifdef CONFIG_ARCH_ADDRENV FAR void *vdata; save_addrenv_t oldenv; size_t heapsize; int ret; #endif DEBUGASSERT(!loadinfo->dspace); /* Allocate the struct dspace_s container for the D-Space allocation */ dspace = (FAR struct dspace_s *)kmm_malloc(sizeof(struct dspace_s)); if (dspace == 0) { bdbg("ERROR: Failed to allocate DSpace\n"); return -ENOMEM; } #ifdef CONFIG_ARCH_ADDRENV /* Determine the heapsize to allocate. 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. */ #ifdef CONFIG_ARCH_STACK_DYNAMIC heapsize = ARCH_HEAP_SIZE; #else heapsize = MIN(loadinfo->stacksize, ARCH_HEAP_SIZE); #endif /* Create a D-Space address environment for the new NXFLAT task */ ret = up_addrenv_create(0, envsize, heapsize, &loadinfo->addrenv); if (ret < 0) { bdbg("ERROR: up_addrenv_create failed: %d\n", ret); goto errout_with_dspace; } /* 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 D-Space region (but only if the address environment has been * selected. */ ret = up_addrenv_vdata(&loadinfo->addrenv, 0, &vdata); if (ret < 0) { bdbg("ERROR: up_addrenv_vdata failed: %d\n", ret); goto errout_with_addrenv; } /* Clear all of the allocated D-Space memory. We have to temporarily * selected the D-Space address environment to do this. */ ret = up_addrenv_select(loadinfo->addrenv, &oldenv); if (ret < 0) { bdbg("ERROR: up_addrenv_select failed: %d\n", ret); goto errout_with_addrenv; } memset(vdata, 0, envsize); ret = up_addrenv_restore(oldenv); if (ret < 0) { bdbg("ERROR: up_addrenv_restore failed: %d\n", ret); goto errout_with_addrenv; } /* Success... save the fruits of our labor */ loadinfo->dspace = dspace; dspace->crefs = 1; dspace->region = (FAR uint8_t *)vdata; return OK; errout_with_addrenv: (void)up_addrenv_destroy(&loadinfo->addrenv); loadinfo->addrenv = 0; errout_with_dspace: kmm_free(dspace); return ret; #else /* Allocate (and zero) memory to hold the ELF image */ dspace->region = (FAR uint8_t *)kumm_zalloc(envsize); if (!dspace->region) { kmm_free(dspace); return -ENOMEM; } loadinfo->dspace = dspace; dspace->crefs = 1; return OK; #endif }