Incorporated the change 1619 into our tree. Cleaned up the source.
git-svn-id: file:///srv/svn/repos/haiku/trunk/current@958 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
5813c3dff5
commit
3f8b94d3cd
@ -127,24 +127,22 @@ static struct uspace_prog_args_t const *uspa;
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static
|
static void
|
||||||
void
|
|
||||||
enqueue_image(image_queue_t *queue, image_t *img)
|
enqueue_image(image_queue_t *queue, image_t *img)
|
||||||
{
|
{
|
||||||
img->next = 0;
|
img->next = 0;
|
||||||
|
|
||||||
img->prev = queue->tail;
|
img->prev = queue->tail;
|
||||||
if(queue->tail) {
|
if (queue->tail)
|
||||||
queue->tail->next= img;
|
queue->tail->next= img;
|
||||||
}
|
|
||||||
queue->tail = img;
|
queue->tail = img;
|
||||||
if(!queue->head) {
|
if (!queue->head)
|
||||||
queue->head= img;
|
queue->head= img;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
static
|
|
||||||
void
|
static void
|
||||||
dequeue_image(image_queue_t *queue, image_t *img)
|
dequeue_image(image_queue_t *queue, image_t *img)
|
||||||
{
|
{
|
||||||
if(img->next) {
|
if(img->next) {
|
||||||
@ -163,8 +161,8 @@ dequeue_image(image_queue_t *queue, image_t *img)
|
|||||||
img->next= 0;
|
img->next= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
|
||||||
unsigned long
|
static unsigned long
|
||||||
elf_hash(const unsigned char *name)
|
elf_hash(const unsigned char *name)
|
||||||
{
|
{
|
||||||
unsigned long hash = 0;
|
unsigned long hash = 0;
|
||||||
@ -180,33 +178,27 @@ elf_hash(const unsigned char *name)
|
|||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
|
||||||
image_t *
|
static image_t *
|
||||||
find_image(char const *name)
|
find_image(char const *name)
|
||||||
{
|
{
|
||||||
image_t *iter;
|
image_t *iter;
|
||||||
|
|
||||||
iter= loaded_images.head;
|
for (iter = loaded_images.head; iter; iter = iter->next) {
|
||||||
while(iter) {
|
if (strncmp(iter->name, name, sizeof(iter->name)) == 0)
|
||||||
if(strncmp(iter->name, name, sizeof(iter->name)) == 0) {
|
|
||||||
return iter;
|
return iter;
|
||||||
}
|
}
|
||||||
iter= iter->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
iter= loading_images.head;
|
for (iter = loading_images.head; iter; iter = iter->next) {
|
||||||
while(iter) {
|
if (strncmp(iter->name, name, sizeof(iter->name)) == 0)
|
||||||
if(strncmp(iter->name, name, sizeof(iter->name)) == 0) {
|
|
||||||
return iter;
|
return iter;
|
||||||
}
|
}
|
||||||
iter= iter->next;
|
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static
|
static int
|
||||||
int
|
|
||||||
parse_eheader(struct Elf32_Ehdr *eheader)
|
parse_eheader(struct Elf32_Ehdr *eheader)
|
||||||
{
|
{
|
||||||
if (memcmp(eheader->e_ident, ELF_MAGIC, 4) != 0)
|
if (memcmp(eheader->e_ident, ELF_MAGIC, 4) != 0)
|
||||||
@ -224,15 +216,14 @@ parse_eheader(struct Elf32_Ehdr *eheader)
|
|||||||
return eheader->e_phentsize*eheader->e_phnum;
|
return eheader->e_phentsize*eheader->e_phnum;
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
|
||||||
int
|
static int
|
||||||
count_regions(char const *buff, int phnum, int phentsize)
|
count_regions(char const *buff, int phnum, int phentsize)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int retval;
|
int retval = 0;
|
||||||
struct Elf32_Phdr *pheaders;
|
struct Elf32_Phdr *pheaders;
|
||||||
|
|
||||||
retval= 0;
|
|
||||||
for (i = 0; i < phnum; i++) {
|
for (i = 0; i < phnum; i++) {
|
||||||
pheaders = (struct Elf32_Phdr *)(buff + i * phentsize);
|
pheaders = (struct Elf32_Phdr *)(buff + i * phentsize);
|
||||||
|
|
||||||
@ -244,15 +235,14 @@ count_regions(char const *buff, int phnum, int phentsize)
|
|||||||
retval += 1;
|
retval += 1;
|
||||||
if (pheaders->p_memsz!= pheaders->p_filesz) {
|
if (pheaders->p_memsz!= pheaders->p_filesz) {
|
||||||
unsigned A = pheaders->p_vaddr + pheaders->p_memsz;
|
unsigned A = pheaders->p_vaddr + pheaders->p_memsz;
|
||||||
unsigned B= pheaders->p_vaddr+pheaders->p_filesz;
|
unsigned B = pheaders->p_vaddr + pheaders->p_filesz - 1;
|
||||||
|
|
||||||
A = PAGE_BASE(A);
|
A = PAGE_BASE(A);
|
||||||
B = PAGE_BASE(B);
|
B = PAGE_BASE(B);
|
||||||
|
|
||||||
if(A!= B) {
|
if (A != B)
|
||||||
retval += 1;
|
retval += 1;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case PT_DYNAMIC:
|
case PT_DYNAMIC:
|
||||||
/* will be handled at some other place */
|
/* will be handled at some other place */
|
||||||
@ -279,15 +269,14 @@ count_regions(char const *buff, int phnum, int phentsize)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* create_image() & destroy_image()
|
* create_image() & destroy_image()
|
||||||
*
|
*
|
||||||
* Create and destroy image_t structures. The destroyer makes sure that the
|
* Create and destroy image_t structures. The destroyer makes sure that the
|
||||||
* memory buffers are full of garbage before freeing.
|
* memory buffers are full of garbage before freeing.
|
||||||
*/
|
*/
|
||||||
static
|
|
||||||
image_t *
|
static image_t *
|
||||||
create_image(char const *name, int num_regions)
|
create_image(char const *name, int num_regions)
|
||||||
{
|
{
|
||||||
image_t *retval;
|
image_t *retval;
|
||||||
@ -309,8 +298,8 @@ create_image(char const *name, int num_regions)
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
|
||||||
void
|
static void
|
||||||
destroy_image(image_t *image)
|
destroy_image(image_t *image)
|
||||||
{
|
{
|
||||||
size_t alloc_size;
|
size_t alloc_size;
|
||||||
@ -325,9 +314,7 @@ destroy_image(image_t *image)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
static
|
|
||||||
void
|
|
||||||
parse_program_headers(image_t *image, char *buff, int phnum, int phentsize)
|
parse_program_headers(image_t *image, char *buff, int phnum, int phentsize)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@ -364,7 +351,7 @@ parse_program_headers(image_t *image, char *buff, int phnum, int phentsize)
|
|||||||
* may require splitting
|
* may require splitting
|
||||||
*/
|
*/
|
||||||
unsigned A = pheaders->p_vaddr + pheaders->p_memsz;
|
unsigned A = pheaders->p_vaddr + pheaders->p_memsz;
|
||||||
unsigned B= pheaders->p_vaddr+pheaders->p_filesz;
|
unsigned B = pheaders->p_vaddr + pheaders->p_filesz - 1;
|
||||||
|
|
||||||
A = PAGE_BASE(A);
|
A = PAGE_BASE(A);
|
||||||
B = PAGE_BASE(B);
|
B = PAGE_BASE(B);
|
||||||
@ -425,29 +412,26 @@ parse_program_headers(image_t *image, char *buff, int phnum, int phentsize)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
|
||||||
bool
|
static bool
|
||||||
assert_dynamic_loadable(image_t *image)
|
assert_dynamic_loadable(image_t *image)
|
||||||
{
|
{
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
|
||||||
if(!image->dynamic_ptr) {
|
if (!image->dynamic_ptr)
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < image->num_regions; i++) {
|
for (i = 0; i < image->num_regions; i++) {
|
||||||
if(image->dynamic_ptr>= image->regions[i].start) {
|
if (image->dynamic_ptr >= image->regions[i].start
|
||||||
if(image->dynamic_ptr< image->regions[i].start+image->regions[i].size) {
|
&& image->dynamic_ptr < image->regions[i].start + image->regions[i].size)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
|
||||||
bool
|
static bool
|
||||||
map_image(int fd, char const *path, image_t *image, bool fixed)
|
map_image(int fd, char const *path, image_t *image, bool fixed)
|
||||||
{
|
{
|
||||||
unsigned i;
|
unsigned i;
|
||||||
@ -459,13 +443,8 @@ map_image(int fd, char const *path, image_t *image, bool fixed)
|
|||||||
addr load_address;
|
addr load_address;
|
||||||
unsigned addr_specifier;
|
unsigned addr_specifier;
|
||||||
|
|
||||||
sprintf(
|
sprintf(region_name, "%s:seg_%d(%s)",
|
||||||
region_name,
|
path, i, (image->regions[i].flags & RFLAG_RW) ? "RW" : "RO");
|
||||||
"%s:seg_%d(%s)",
|
|
||||||
path,
|
|
||||||
i,
|
|
||||||
(image->regions[i].flags&RFLAG_RW)?"RW":"RO"
|
|
||||||
);
|
|
||||||
|
|
||||||
if (image->dynamic_ptr && !fixed) {
|
if (image->dynamic_ptr && !fixed) {
|
||||||
/*
|
/*
|
||||||
@ -499,9 +478,9 @@ map_image(int fd, char const *path, image_t *image, bool fixed)
|
|||||||
LOCK_RW
|
LOCK_RW
|
||||||
);
|
);
|
||||||
|
|
||||||
if(image->regions[i].id < 0) {
|
if (image->regions[i].id < 0)
|
||||||
goto error;
|
goto error;
|
||||||
}
|
|
||||||
image->regions[i].delta = load_address - image->regions[i].vmstart;
|
image->regions[i].delta = load_address - image->regions[i].vmstart;
|
||||||
image->regions[i].vmstart = load_address;
|
image->regions[i].vmstart = load_address;
|
||||||
} else {
|
} else {
|
||||||
@ -515,9 +494,9 @@ map_image(int fd, char const *path, image_t *image, bool fixed)
|
|||||||
path,
|
path,
|
||||||
_ROUNDOWN(image->regions[i].fdstart, PAGE_SIZE)
|
_ROUNDOWN(image->regions[i].fdstart, PAGE_SIZE)
|
||||||
);
|
);
|
||||||
if(image->regions[i].id < 0) {
|
if (image->regions[i].id < 0)
|
||||||
goto error;
|
goto error;
|
||||||
}
|
|
||||||
image->regions[i].delta = load_address - image->regions[i].vmstart;
|
image->regions[i].delta = load_address - image->regions[i].vmstart;
|
||||||
image->regions[i].vmstart = load_address;
|
image->regions[i].vmstart = load_address;
|
||||||
|
|
||||||
@ -528,12 +507,10 @@ map_image(int fd, char const *path, image_t *image, bool fixed)
|
|||||||
unsigned start_clearing;
|
unsigned start_clearing;
|
||||||
unsigned to_clear;
|
unsigned to_clear;
|
||||||
|
|
||||||
start_clearing=
|
start_clearing = image->regions[i].vmstart
|
||||||
image->regions[i].vmstart
|
|
||||||
+ PAGE_OFFS(image->regions[i].start)
|
+ PAGE_OFFS(image->regions[i].start)
|
||||||
+ image->regions[i].size;
|
+ image->regions[i].size;
|
||||||
to_clear=
|
to_clear = image->regions[i].vmsize
|
||||||
image->regions[i].vmsize
|
|
||||||
- PAGE_OFFS(image->regions[i].start)
|
- PAGE_OFFS(image->regions[i].start)
|
||||||
- image->regions[i].size;
|
- image->regions[i].size;
|
||||||
memset((void*)start_clearing, 0, to_clear);
|
memset((void*)start_clearing, 0, to_clear);
|
||||||
@ -541,9 +518,8 @@ map_image(int fd, char const *path, image_t *image, bool fixed)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(image->dynamic_ptr) {
|
if (image->dynamic_ptr)
|
||||||
image->dynamic_ptr += image->regions[0].delta;
|
image->dynamic_ptr += image->regions[0].delta;
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
@ -551,8 +527,8 @@ error:
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
|
||||||
void
|
static void
|
||||||
unmap_image(image_t *image)
|
unmap_image(image_t *image)
|
||||||
{
|
{
|
||||||
unsigned i;
|
unsigned i;
|
||||||
@ -564,8 +540,8 @@ unmap_image(image_t *image)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
|
||||||
bool
|
static bool
|
||||||
parse_dynamic_segment(image_t *image)
|
parse_dynamic_segment(image_t *image)
|
||||||
{
|
{
|
||||||
struct Elf32_Dyn *d;
|
struct Elf32_Dyn *d;
|
||||||
@ -576,9 +552,8 @@ parse_dynamic_segment(image_t *image)
|
|||||||
image->strtab = 0;
|
image->strtab = 0;
|
||||||
|
|
||||||
d = (struct Elf32_Dyn *)image->dynamic_ptr;
|
d = (struct Elf32_Dyn *)image->dynamic_ptr;
|
||||||
if(!d) {
|
if (!d)
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; d[i].d_tag != DT_NULL; i++) {
|
for (i = 0; d[i].d_tag != DT_NULL; i++) {
|
||||||
switch (d[i].d_tag) {
|
switch (d[i].d_tag) {
|
||||||
@ -619,68 +594,63 @@ parse_dynamic_segment(image_t *image)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// lets make sure we found all the required sections
|
// lets make sure we found all the required sections
|
||||||
if(!image->symhash || !image->syms || !image->strtab) {
|
if (!image->symhash || !image->syms || !image->strtab)
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
|
||||||
struct Elf32_Sym *
|
static struct Elf32_Sym *
|
||||||
find_symbol_xxx(image_t *img, const char *name)
|
find_symbol_xxx(image_t *img, const char *name)
|
||||||
{
|
{
|
||||||
unsigned int hash;
|
unsigned int hash;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
if(img->dynamic_ptr) {
|
if (img->dynamic_ptr == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
hash = elf_hash(name) % HASHTABSIZE(img);
|
hash = elf_hash(name) % HASHTABSIZE(img);
|
||||||
|
|
||||||
for (i = HASHBUCKETS(img)[hash]; i != STN_UNDEF; i = HASHCHAINS(img)[i]) {
|
for (i = HASHBUCKETS(img)[hash]; i != STN_UNDEF; i = HASHCHAINS(img)[i]) {
|
||||||
if(img->syms[i].st_shndx!= SHN_UNDEF) {
|
if (img->syms[i].st_shndx != SHN_UNDEF
|
||||||
if((ELF32_ST_BIND(img->syms[i].st_info)== STB_GLOBAL) || (ELF32_ST_BIND(img->syms[i].st_info)== STB_WEAK)) {
|
&& ((ELF32_ST_BIND(img->syms[i].st_info)== STB_GLOBAL) || (ELF32_ST_BIND(img->syms[i].st_info) == STB_WEAK))
|
||||||
if(!strcmp(SYMNAME(img, &img->syms[i]), name)) {
|
&& !strcmp(SYMNAME(img, &img->syms[i]), name))
|
||||||
return &img->syms[i];
|
return &img->syms[i];
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
|
||||||
struct Elf32_Sym *
|
static struct Elf32_Sym *
|
||||||
find_symbol(image_t **shimg, const char *name)
|
find_symbol(image_t **shimg, const char *name)
|
||||||
{
|
{
|
||||||
image_t *iter;
|
image_t *iter;
|
||||||
unsigned int hash;
|
unsigned int hash;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
iter= loaded_images.head;
|
for (iter = loaded_images.head; iter; iter = iter->next) {
|
||||||
while(iter) {
|
if (iter->dynamic_ptr == NULL)
|
||||||
if(iter->dynamic_ptr) {
|
continue;
|
||||||
|
|
||||||
hash = elf_hash(name) % HASHTABSIZE(iter);
|
hash = elf_hash(name) % HASHTABSIZE(iter);
|
||||||
|
|
||||||
for(i = HASHBUCKETS(iter)[hash]; i != STN_UNDEF; i = HASHCHAINS(iter)[i]) {
|
for(i = HASHBUCKETS(iter)[hash]; i != STN_UNDEF; i = HASHCHAINS(iter)[i]) {
|
||||||
if(iter->syms[i].st_shndx!= SHN_UNDEF) {
|
if (iter->syms[i].st_shndx!= SHN_UNDEF
|
||||||
if((ELF32_ST_BIND(iter->syms[i].st_info)== STB_GLOBAL) || (ELF32_ST_BIND(iter->syms[i].st_info)== STB_WEAK)) {
|
&& ((ELF32_ST_BIND(iter->syms[i].st_info)== STB_GLOBAL) || (ELF32_ST_BIND(iter->syms[i].st_info)== STB_WEAK))
|
||||||
if(!strcmp(SYMNAME(iter, &iter->syms[i]), name)) {
|
&& !strcmp(SYMNAME(iter, &iter->syms[i]), name)) {
|
||||||
*shimg = iter;
|
*shimg = iter;
|
||||||
return &iter->syms[i];
|
return &iter->syms[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
iter= iter->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
|
||||||
int
|
static int
|
||||||
resolve_symbol(image_t *image, struct Elf32_Sym *sym, addr *sym_addr)
|
resolve_symbol(image_t *image, struct Elf32_Sym *sym, addr *sym_addr)
|
||||||
{
|
{
|
||||||
struct Elf32_Sym *sym2;
|
struct Elf32_Sym *sym2;
|
||||||
@ -700,27 +670,30 @@ resolve_symbol(image_t *image, struct Elf32_Sym *sym, addr *sym_addr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// make sure they're the same type
|
// make sure they're the same type
|
||||||
if(ELF32_ST_TYPE(sym->st_info)!= STT_NOTYPE) {
|
if (ELF32_ST_TYPE(sym->st_info) != STT_NOTYPE
|
||||||
if(ELF32_ST_TYPE(sym->st_info) != ELF32_ST_TYPE(sym2->st_info)) {
|
&& ELF32_ST_TYPE(sym->st_info) != ELF32_ST_TYPE(sym2->st_info)) {
|
||||||
printf("elf_resolve_symbol: found symbol '%s' in shared image but wrong type\n", symname);
|
printf("elf_resolve_symbol: found symbol '%s' in shared image but wrong type\n", symname);
|
||||||
return ERR_ELF_RESOLVING_SYMBOL;
|
return ERR_ELF_RESOLVING_SYMBOL;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if(ELF32_ST_BIND(sym2->st_info) != STB_GLOBAL && ELF32_ST_BIND(sym2->st_info) != STB_WEAK) {
|
if (ELF32_ST_BIND(sym2->st_info) != STB_GLOBAL
|
||||||
|
&& ELF32_ST_BIND(sym2->st_info) != STB_WEAK) {
|
||||||
printf("elf_resolve_symbol: found symbol '%s' but not exported\n", symname);
|
printf("elf_resolve_symbol: found symbol '%s' but not exported\n", symname);
|
||||||
return ERR_ELF_RESOLVING_SYMBOL;
|
return ERR_ELF_RESOLVING_SYMBOL;
|
||||||
}
|
}
|
||||||
|
|
||||||
*sym_addr = sym2->st_value + shimg->regions[0].delta;
|
*sym_addr = sym2->st_value + shimg->regions[0].delta;
|
||||||
return B_NO_ERROR;
|
return B_NO_ERROR;
|
||||||
|
|
||||||
case SHN_ABS:
|
case SHN_ABS:
|
||||||
*sym_addr = sym->st_value + image->regions[0].delta;
|
*sym_addr = sym->st_value + image->regions[0].delta;
|
||||||
return B_NO_ERROR;
|
return B_NO_ERROR;
|
||||||
|
|
||||||
case SHN_COMMON:
|
case SHN_COMMON:
|
||||||
// XXX finish this
|
// XXX finish this
|
||||||
printf("elf_resolve_symbol: COMMON symbol, finish me!\n");
|
printf("elf_resolve_symbol: COMMON symbol, finish me!\n");
|
||||||
return ERR_NOT_IMPLEMENTED_YET;
|
return ERR_NOT_IMPLEMENTED_YET;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// standard symbol
|
// standard symbol
|
||||||
*sym_addr = sym->st_value + image->regions[0].delta;
|
*sym_addr = sym->st_value + image->regions[0].delta;
|
||||||
@ -732,8 +705,7 @@ resolve_symbol(image_t *image, struct Elf32_Sym *sym, addr *sym_addr)
|
|||||||
#include "arch/rldreloc.inc"
|
#include "arch/rldreloc.inc"
|
||||||
|
|
||||||
|
|
||||||
static
|
static image_t *
|
||||||
image_t *
|
|
||||||
load_container(char const *path, char const *name, bool fixed)
|
load_container(char const *path, char const *name, bool fixed)
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
@ -792,8 +764,7 @@ load_container(char const *path, char const *name, bool fixed)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static
|
static void
|
||||||
void
|
|
||||||
load_dependencies(image_t *img)
|
load_dependencies(image_t *img)
|
||||||
{
|
{
|
||||||
unsigned i;
|
unsigned i;
|
||||||
@ -833,8 +804,8 @@ load_dependencies(image_t *img)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
|
||||||
unsigned
|
static unsigned
|
||||||
topological_sort(image_t *img, unsigned slot, image_t **init_list)
|
topological_sort(image_t *img, unsigned slot, image_t **init_list)
|
||||||
{
|
{
|
||||||
unsigned i;
|
unsigned i;
|
||||||
@ -850,8 +821,8 @@ topological_sort(image_t *img, unsigned slot, image_t **init_list)
|
|||||||
return slot+1;
|
return slot+1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
|
||||||
void
|
static void
|
||||||
init_dependencies(image_t *img, bool init_head)
|
init_dependencies(image_t *img, bool init_head)
|
||||||
{
|
{
|
||||||
unsigned i;
|
unsigned i;
|
||||||
@ -865,10 +836,9 @@ init_dependencies(image_t *img, bool init_head)
|
|||||||
img->flags |= RFLAG_SORTED; /* make sure we don't visit this one */
|
img->flags |= RFLAG_SORTED; /* make sure we don't visit this one */
|
||||||
slot = 0;
|
slot = 0;
|
||||||
for (i = 0; i < img->num_needed; i++) {
|
for (i = 0; i < img->num_needed; i++) {
|
||||||
if(!(img->needed[i]->flags & RFLAG_SORTED)) {
|
if (!(img->needed[i]->flags & RFLAG_SORTED))
|
||||||
slot = topological_sort(img->needed[i], slot, init_list);
|
slot = topological_sort(img->needed[i], slot, init_list);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (init_head) {
|
if (init_head) {
|
||||||
init_list[slot] = img;
|
init_list[slot] = img;
|
||||||
@ -879,17 +849,15 @@ init_dependencies(image_t *img, bool init_head)
|
|||||||
addr _initf = init_list[i]->entry_point;
|
addr _initf = init_list[i]->entry_point;
|
||||||
libinit_f *initf = (libinit_f *)(_initf);
|
libinit_f *initf = (libinit_f *)(_initf);
|
||||||
|
|
||||||
if(initf) {
|
if (initf)
|
||||||
initf(init_list[i]->imageid, uspa);
|
initf(init_list[i]->imageid, uspa);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
rldfree(init_list);
|
rldfree(init_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static
|
static void
|
||||||
void
|
|
||||||
put_image(image_t *img)
|
put_image(image_t *img)
|
||||||
{
|
{
|
||||||
img->refcount -= 1;
|
img->refcount -= 1;
|
||||||
@ -917,31 +885,25 @@ put_image(image_t *img)
|
|||||||
* + unload_addon()
|
* + unload_addon()
|
||||||
* + dynamic_symbol()
|
* + dynamic_symbol()
|
||||||
*/
|
*/
|
||||||
|
|
||||||
dynmodule_id
|
dynmodule_id
|
||||||
load_program(char const *path, void **entry)
|
load_program(char const *path, void **entry)
|
||||||
{
|
{
|
||||||
image_t *image;
|
image_t *image;
|
||||||
image_t *iter;
|
image_t *iter;
|
||||||
|
|
||||||
|
|
||||||
image = load_container(path, NEWOS_MAGIC_APPNAME, true);
|
image = load_container(path, NEWOS_MAGIC_APPNAME, true);
|
||||||
|
|
||||||
iter= loaded_images.head;
|
for (iter = loaded_images.head; iter; iter = iter->next) {
|
||||||
while(iter) {
|
|
||||||
load_dependencies(iter);
|
load_dependencies(iter);
|
||||||
|
}
|
||||||
|
|
||||||
iter= iter->next;
|
for (iter = loaded_images.head; iter; iter = iter->next) {
|
||||||
};
|
|
||||||
|
|
||||||
iter= loaded_images.head;
|
|
||||||
while(iter) {
|
|
||||||
bool relocate_success;
|
bool relocate_success;
|
||||||
|
|
||||||
relocate_success = relocate_image(iter);
|
relocate_success = relocate_image(iter);
|
||||||
FATAL(!relocate_success, "troubles relocating\n");
|
FATAL(!relocate_success, "troubles relocating\n");
|
||||||
|
}
|
||||||
iter= iter->next;
|
|
||||||
};
|
|
||||||
|
|
||||||
init_dependencies(loaded_images.head, false);
|
init_dependencies(loaded_images.head, false);
|
||||||
|
|
||||||
@ -949,13 +911,13 @@ load_program(char const *path, void **entry)
|
|||||||
return image->imageid;
|
return image->imageid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
dynmodule_id
|
dynmodule_id
|
||||||
load_library(char const *path)
|
load_library(char const *path)
|
||||||
{
|
{
|
||||||
image_t *image;
|
image_t *image;
|
||||||
image_t *iter;
|
image_t *iter;
|
||||||
|
|
||||||
|
|
||||||
image = find_image(path);
|
image = find_image(path);
|
||||||
if (image) {
|
if (image) {
|
||||||
image->refcount += 1;
|
image->refcount += 1;
|
||||||
@ -964,28 +926,23 @@ load_library(char const *path)
|
|||||||
|
|
||||||
image = load_container(path, path, false);
|
image = load_container(path, path, false);
|
||||||
|
|
||||||
iter= loaded_images.head;
|
for (iter = loaded_images.head; iter; iter = iter->next) {
|
||||||
while(iter) {
|
|
||||||
load_dependencies(iter);
|
load_dependencies(iter);
|
||||||
|
}
|
||||||
|
|
||||||
iter= iter->next;
|
for (iter = loaded_images.head; iter; iter = iter->next) {
|
||||||
};
|
|
||||||
|
|
||||||
iter= loaded_images.head;
|
|
||||||
while(iter) {
|
|
||||||
bool relocate_success;
|
bool relocate_success;
|
||||||
|
|
||||||
relocate_success = relocate_image(iter);
|
relocate_success = relocate_image(iter);
|
||||||
FATAL(!relocate_success, "troubles relocating\n");
|
FATAL(!relocate_success, "troubles relocating\n");
|
||||||
|
}
|
||||||
iter= iter->next;
|
|
||||||
};
|
|
||||||
|
|
||||||
init_dependencies(image, true);
|
init_dependencies(image, true);
|
||||||
|
|
||||||
return image->imageid;
|
return image->imageid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
dynmodule_id
|
dynmodule_id
|
||||||
unload_library(dynmodule_id imid)
|
unload_library(dynmodule_id imid)
|
||||||
{
|
{
|
||||||
@ -995,8 +952,8 @@ unload_library(dynmodule_id imid)
|
|||||||
/*
|
/*
|
||||||
* we only check images that have been already initialized
|
* we only check images that have been already initialized
|
||||||
*/
|
*/
|
||||||
iter= loaded_images.head;
|
|
||||||
while(iter) {
|
for (iter = loaded_images.head; iter; iter = iter->next) {
|
||||||
if (iter->imageid == imid) {
|
if (iter->imageid == imid) {
|
||||||
/*
|
/*
|
||||||
* do the unloading
|
* do the unloading
|
||||||
@ -1005,31 +962,23 @@ unload_library(dynmodule_id imid)
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
iter= iter->next;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(iter) {
|
retval = iter ? 0 : -1;
|
||||||
retval= 0;
|
|
||||||
} else {
|
|
||||||
retval= -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
iter= disposable_images.head;
|
while ((iter = disposable_images.head) != NULL) {
|
||||||
while(iter) {
|
|
||||||
// call image fini here...
|
// call image fini here...
|
||||||
|
|
||||||
dequeue_image(&disposable_images, iter);
|
dequeue_image(&disposable_images, iter);
|
||||||
unmap_image(iter);
|
unmap_image(iter);
|
||||||
|
|
||||||
destroy_image(iter);
|
destroy_image(iter);
|
||||||
iter= disposable_images.head;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void *
|
void *
|
||||||
dynamic_symbol(dynmodule_id imid, char const *symname)
|
dynamic_symbol(dynmodule_id imid, char const *symname)
|
||||||
{
|
{
|
||||||
@ -1038,25 +987,25 @@ dynamic_symbol(dynmodule_id imid, char const *symname)
|
|||||||
/*
|
/*
|
||||||
* we only check images that have been already initialized
|
* we only check images that have been already initialized
|
||||||
*/
|
*/
|
||||||
iter= loaded_images.head;
|
for (iter = loaded_images.head; iter; iter = iter->next) {
|
||||||
while(iter) {
|
struct Elf32_Sym *sym;
|
||||||
if(iter->imageid== imid) {
|
|
||||||
struct Elf32_Sym *sym= find_symbol_xxx(iter, symname);
|
|
||||||
|
|
||||||
if(sym) {
|
if (iter->imageid != imid)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
sym = find_symbol_xxx(iter, symname);
|
||||||
|
if (sym)
|
||||||
return (void*)(sym->st_value + iter->regions[0].delta);
|
return (void*)(sym->st_value + iter->regions[0].delta);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
iter= iter->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* init routine, just get hold of the uspa args
|
* init routine, just get hold of the uspa args
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
rldelf_init(struct uspace_prog_args_t const *_uspa)
|
rldelf_init(struct uspace_prog_args_t const *_uspa)
|
||||||
{
|
{
|
||||||
@ -1064,3 +1013,4 @@ rldelf_init(struct uspace_prog_args_t const *_uspa)
|
|||||||
|
|
||||||
rld_sem = create_sem(1, "rld_lock\n");
|
rld_sem = create_sem(1, "rld_lock\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user