Bye, bye elf_lookup_symbol(), hello get_image_symbol().
Also renamed elf_load_kspace() to load_kernel_add_on(), and friends. The new unload_kernel_add_on() now has an image_id as parameter, no longer a path (like the former elf_unload_kspace()). Fixed missign file system unload. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@7527 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
81c323a767
commit
b918b5035f
@ -55,8 +55,6 @@ static struct elf_image_info *sKernelImage = NULL;
|
|||||||
static mutex sImageMutex;
|
static mutex sImageMutex;
|
||||||
static mutex sImageLoadMutex;
|
static mutex sImageLoadMutex;
|
||||||
|
|
||||||
static status_t elf_unload_image(struct elf_image_info *image);
|
|
||||||
|
|
||||||
|
|
||||||
/** calculates hash for an image using its ID */
|
/** calculates hash for an image using its ID */
|
||||||
|
|
||||||
@ -114,79 +112,6 @@ register_elf_image(struct elf_image_info *image)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
|
||||||
elf_lookup_symbol_address(addr address, addr *baseAddress, char *text, size_t length)
|
|
||||||
{
|
|
||||||
struct hash_iterator iterator;
|
|
||||||
struct elf_image_info *image;
|
|
||||||
struct Elf32_Sym *sym;
|
|
||||||
struct elf_image_info *found_image;
|
|
||||||
struct Elf32_Sym *found_sym;
|
|
||||||
long found_delta;
|
|
||||||
uint32 i;
|
|
||||||
int j,rv;
|
|
||||||
|
|
||||||
TRACE(("looking up %p\n",(void *)address));
|
|
||||||
|
|
||||||
mutex_lock(&sImageMutex);
|
|
||||||
hash_open(sImagesHash, &iterator);
|
|
||||||
|
|
||||||
found_sym = 0;
|
|
||||||
found_image = 0;
|
|
||||||
found_delta = 0x7fffffff;
|
|
||||||
|
|
||||||
while ((image = hash_next(sImagesHash, &iterator)) != NULL) {
|
|
||||||
TRACE((" image %p, base = %p, size = %p\n", image, (void *)image->regions[0].start, (void *)image->regions[0].size));
|
|
||||||
if ((address < image->regions[0].start) || (address >= (image->regions[0].start + image->regions[0].size)))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
TRACE((" searching...\n"));
|
|
||||||
found_image = image;
|
|
||||||
for (i = 0; i < HASHTABSIZE(image); i++) {
|
|
||||||
for (j = HASHBUCKETS(image)[i]; j != STN_UNDEF; j = HASHCHAINS(image)[j]) {
|
|
||||||
long d;
|
|
||||||
sym = &image->syms[j];
|
|
||||||
|
|
||||||
TRACE((" %p looking at %s, type = %d, bind = %d, addr = %p\n",sym,SYMNAME(image, sym),ELF32_ST_TYPE(sym->st_info),ELF32_ST_BIND(sym->st_info),(void *)sym->st_value));
|
|
||||||
TRACE((" symbol: %lx (%x + %lx)\n", sym->st_value + image->regions[0].delta, sym->st_value, image->regions[0].delta));
|
|
||||||
|
|
||||||
if ((ELF32_ST_TYPE(sym->st_info) != STT_FUNC) || (ELF32_ST_BIND(sym->st_info) != STB_GLOBAL))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
d = (long)address - (long)(sym->st_value + image->regions[0].delta);
|
|
||||||
if ((d >= 0) && (d < found_delta)) {
|
|
||||||
found_delta = d;
|
|
||||||
found_sym = sym;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (found_sym != 0) {
|
|
||||||
TRACE(("symbol at %p, in image %p, name = %s\n", found_sym, found_image, found_image->name));
|
|
||||||
TRACE(("name index %d, '%s'\n", found_sym->st_name, SYMNAME(found_image, found_sym)));
|
|
||||||
TRACE(("addr = %#lx, offset = %#lx\n",(found_sym->st_value + found_image->regions[0].delta),found_delta));
|
|
||||||
|
|
||||||
strlcpy(text, SYMNAME(found_image, found_sym), length);
|
|
||||||
|
|
||||||
if (baseAddress)
|
|
||||||
*baseAddress = found_sym->st_value + found_image->regions[0].delta;
|
|
||||||
|
|
||||||
rv = B_OK;
|
|
||||||
} else {
|
|
||||||
TRACE(("symbol not found!\n"));
|
|
||||||
strlcpy(text, "symbol not found", length);
|
|
||||||
rv = B_ENTRY_NOT_FOUND;
|
|
||||||
}
|
|
||||||
|
|
||||||
hash_close(sImagesHash, &iterator, false);
|
|
||||||
mutex_unlock(&sImageMutex);
|
|
||||||
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
print_address_info(int argc, char **argv)
|
print_address_info(int argc, char **argv)
|
||||||
{
|
{
|
||||||
@ -368,32 +293,6 @@ elf_find_symbol(struct elf_image_info *image, const char *name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
addr_t
|
|
||||||
elf_lookup_symbol(image_id id, const char *symbol)
|
|
||||||
{
|
|
||||||
struct elf_image_info *image;
|
|
||||||
struct Elf32_Sym *sym;
|
|
||||||
|
|
||||||
TRACE(("elf_lookup_symbol: %s\n", symbol));
|
|
||||||
|
|
||||||
image = find_image(id);
|
|
||||||
if (!image)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
sym = elf_find_symbol(image, symbol);
|
|
||||||
if (!sym)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (sym->st_shndx == SHN_UNDEF)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
TRACE(("found: %lx (%x + %lx)\n", sym->st_value + image->regions[0].delta,
|
|
||||||
sym->st_value, image->regions[0].delta));
|
|
||||||
|
|
||||||
return sym->st_value + image->regions[0].delta;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
elf_parse_dynamic_section(struct elf_image_info *image)
|
elf_parse_dynamic_section(struct elf_image_info *image)
|
||||||
{
|
{
|
||||||
@ -517,7 +416,7 @@ elf_resolve_symbol(struct elf_image_info *image, struct Elf32_Sym *sym, struct e
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// XXX for now just link against the kernel
|
/** Until we have shared library support, just links against the kernel */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
elf_relocate(struct elf_image_info *image, const char *sym_prepend)
|
elf_relocate(struct elf_image_info *image, const char *sym_prepend)
|
||||||
@ -575,8 +474,220 @@ verify_eheader(struct Elf32_Ehdr *eheader)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
static int
|
||||||
|
elf_unlink_relocs(struct elf_image_info *image)
|
||||||
|
{
|
||||||
|
elf_linked_image *link, *next_link;
|
||||||
|
|
||||||
|
for (link = image->linked_images; link; link = next_link) {
|
||||||
|
next_link = link->next;
|
||||||
|
elf_unload_image(link->image);
|
||||||
|
free(link);
|
||||||
|
}
|
||||||
|
|
||||||
|
return B_NO_ERROR;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
static status_t
|
||||||
|
unload_elf_image(struct elf_image_info *image)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (atomic_add(&image->ref_count, -1) > 0)
|
||||||
|
return B_NO_ERROR;
|
||||||
|
|
||||||
|
//elf_unlink_relocs(image);
|
||||||
|
// not yet used
|
||||||
|
|
||||||
|
for (i = 0; i < 2; ++i) {
|
||||||
|
delete_area(image->regions[i].id);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (image->vnode)
|
||||||
|
vfs_put_vnode_ptr(image->vnode);
|
||||||
|
|
||||||
|
unregister_elf_image(image);
|
||||||
|
|
||||||
|
free(image->eheader);
|
||||||
|
free(image->name);
|
||||||
|
free(image);
|
||||||
|
|
||||||
|
return B_NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static status_t
|
||||||
|
insert_preloaded_image(struct preloaded_image *preloadedImage)
|
||||||
|
{
|
||||||
|
struct Elf32_Ehdr *elfHeader;
|
||||||
|
struct elf_image_info *image;
|
||||||
|
status_t status;
|
||||||
|
|
||||||
|
elfHeader = (struct Elf32_Ehdr *)malloc(sizeof(struct Elf32_Ehdr));
|
||||||
|
if (elfHeader == NULL)
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
|
memcpy(elfHeader, &preloadedImage->elf_header, sizeof(struct Elf32_Ehdr));
|
||||||
|
status = verify_eheader(elfHeader);
|
||||||
|
if (status < B_OK)
|
||||||
|
goto error1;
|
||||||
|
|
||||||
|
image = create_image_struct();
|
||||||
|
if (image == NULL) {
|
||||||
|
status = B_NO_MEMORY;
|
||||||
|
goto error1;
|
||||||
|
}
|
||||||
|
|
||||||
|
image->vnode = NULL;
|
||||||
|
image->eheader = elfHeader;
|
||||||
|
image->name = strdup(preloadedImage->name);
|
||||||
|
image->dynamic_ptr = preloadedImage->dynamic_section.start;
|
||||||
|
|
||||||
|
image->regions[0] = preloadedImage->text_region;
|
||||||
|
image->regions[1] = preloadedImage->data_region;
|
||||||
|
|
||||||
|
status = elf_parse_dynamic_section(image);
|
||||||
|
if (status < B_OK)
|
||||||
|
goto error2;
|
||||||
|
|
||||||
|
status = elf_relocate(image, "");
|
||||||
|
if (status < B_OK)
|
||||||
|
goto error2;
|
||||||
|
|
||||||
|
register_elf_image(image);
|
||||||
|
return B_OK;
|
||||||
|
|
||||||
|
error2:
|
||||||
|
free(image);
|
||||||
|
error1:
|
||||||
|
free(elfHeader);
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
// public kernel API
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
elf_load_uspace(const char *path, struct team *p, int flags, addr *entry)
|
get_image_symbol(image_id id, const char *name, int32 sclass, void **_symbol)
|
||||||
|
{
|
||||||
|
struct elf_image_info *image;
|
||||||
|
struct Elf32_Sym *symbol;
|
||||||
|
status_t status = B_OK;
|
||||||
|
|
||||||
|
TRACE(("get_image_symbol(%s)\n", name));
|
||||||
|
|
||||||
|
mutex_lock(&sImageMutex);
|
||||||
|
|
||||||
|
image = find_image(id);
|
||||||
|
if (image == NULL) {
|
||||||
|
status = B_BAD_IMAGE_ID;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
symbol = elf_find_symbol(image, name);
|
||||||
|
if (symbol == NULL || symbol->st_shndx == SHN_UNDEF) {
|
||||||
|
status = B_ENTRY_NOT_FOUND;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToDo: support the "sclass" parameter!
|
||||||
|
|
||||||
|
TRACE(("found: %lx (%x + %lx)\n", sym->st_value + image->regions[0].delta,
|
||||||
|
sym->st_value, image->regions[0].delta));
|
||||||
|
|
||||||
|
*_symbol = (void *)(symbol->st_value + image->regions[0].delta);
|
||||||
|
|
||||||
|
done:
|
||||||
|
mutex_unlock(&sImageMutex);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
// kernel private API
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
elf_lookup_symbol_address(addr address, addr *baseAddress, char *text, size_t length)
|
||||||
|
{
|
||||||
|
struct hash_iterator iterator;
|
||||||
|
struct elf_image_info *image;
|
||||||
|
struct Elf32_Sym *sym;
|
||||||
|
struct elf_image_info *found_image;
|
||||||
|
struct Elf32_Sym *found_sym;
|
||||||
|
long found_delta;
|
||||||
|
uint32 i;
|
||||||
|
int j,rv;
|
||||||
|
|
||||||
|
TRACE(("looking up %p\n",(void *)address));
|
||||||
|
|
||||||
|
mutex_lock(&sImageMutex);
|
||||||
|
hash_open(sImagesHash, &iterator);
|
||||||
|
|
||||||
|
found_sym = 0;
|
||||||
|
found_image = 0;
|
||||||
|
found_delta = 0x7fffffff;
|
||||||
|
|
||||||
|
while ((image = hash_next(sImagesHash, &iterator)) != NULL) {
|
||||||
|
TRACE((" image %p, base = %p, size = %p\n", image, (void *)image->regions[0].start, (void *)image->regions[0].size));
|
||||||
|
if ((address < image->regions[0].start) || (address >= (image->regions[0].start + image->regions[0].size)))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
TRACE((" searching...\n"));
|
||||||
|
found_image = image;
|
||||||
|
for (i = 0; i < HASHTABSIZE(image); i++) {
|
||||||
|
for (j = HASHBUCKETS(image)[i]; j != STN_UNDEF; j = HASHCHAINS(image)[j]) {
|
||||||
|
long d;
|
||||||
|
sym = &image->syms[j];
|
||||||
|
|
||||||
|
TRACE((" %p looking at %s, type = %d, bind = %d, addr = %p\n",sym,SYMNAME(image, sym),ELF32_ST_TYPE(sym->st_info),ELF32_ST_BIND(sym->st_info),(void *)sym->st_value));
|
||||||
|
TRACE((" symbol: %lx (%x + %lx)\n", sym->st_value + image->regions[0].delta, sym->st_value, image->regions[0].delta));
|
||||||
|
|
||||||
|
if ((ELF32_ST_TYPE(sym->st_info) != STT_FUNC) || (ELF32_ST_BIND(sym->st_info) != STB_GLOBAL))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
d = (long)address - (long)(sym->st_value + image->regions[0].delta);
|
||||||
|
if ((d >= 0) && (d < found_delta)) {
|
||||||
|
found_delta = d;
|
||||||
|
found_sym = sym;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (found_sym != 0) {
|
||||||
|
TRACE(("symbol at %p, in image %p, name = %s\n", found_sym, found_image, found_image->name));
|
||||||
|
TRACE(("name index %d, '%s'\n", found_sym->st_name, SYMNAME(found_image, found_sym)));
|
||||||
|
TRACE(("addr = %#lx, offset = %#lx\n",(found_sym->st_value + found_image->regions[0].delta),found_delta));
|
||||||
|
|
||||||
|
strlcpy(text, SYMNAME(found_image, found_sym), length);
|
||||||
|
|
||||||
|
if (baseAddress)
|
||||||
|
*baseAddress = found_sym->st_value + found_image->regions[0].delta;
|
||||||
|
|
||||||
|
rv = B_OK;
|
||||||
|
} else {
|
||||||
|
TRACE(("symbol not found!\n"));
|
||||||
|
strlcpy(text, "symbol not found", length);
|
||||||
|
rv = B_ENTRY_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
hash_close(sImagesHash, &iterator, false);
|
||||||
|
mutex_unlock(&sImageMutex);
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
elf_load_user_image(const char *path, struct team *p, int flags, addr *entry)
|
||||||
{
|
{
|
||||||
struct Elf32_Ehdr eheader;
|
struct Elf32_Ehdr eheader;
|
||||||
struct Elf32_Phdr *pheaders = NULL;
|
struct Elf32_Phdr *pheaders = NULL;
|
||||||
@ -735,7 +846,7 @@ error:
|
|||||||
|
|
||||||
|
|
||||||
image_id
|
image_id
|
||||||
elf_load_kspace(const char *path, const char *sym_prepend)
|
load_kernel_add_on(const char *path)
|
||||||
{
|
{
|
||||||
bool ro_segment_handled = false;
|
bool ro_segment_handled = false;
|
||||||
bool rw_segment_handled = false;
|
bool rw_segment_handled = false;
|
||||||
@ -905,7 +1016,7 @@ elf_load_kspace(const char *path, const char *sym_prepend)
|
|||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto error4;
|
goto error4;
|
||||||
|
|
||||||
err = elf_relocate(image, sym_prepend);
|
err = elf_relocate(image, "");
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto error4;
|
goto error4;
|
||||||
|
|
||||||
@ -942,140 +1053,26 @@ error0:
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
static int
|
|
||||||
elf_unlink_relocs(struct elf_image_info *image)
|
|
||||||
{
|
|
||||||
elf_linked_image *link, *next_link;
|
|
||||||
|
|
||||||
for (link = image->linked_images; link; link = next_link) {
|
|
||||||
next_link = link->next;
|
|
||||||
elf_unload_image(link->image);
|
|
||||||
free(link);
|
|
||||||
}
|
|
||||||
|
|
||||||
return B_NO_ERROR;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void
|
|
||||||
elf_unload_image_final(struct elf_image_info *image)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < 2; ++i) {
|
|
||||||
delete_area(image->regions[i].id);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (image->vnode)
|
|
||||||
vfs_put_vnode_ptr(image->vnode);
|
|
||||||
|
|
||||||
unregister_elf_image(image);
|
|
||||||
|
|
||||||
free(image->eheader);
|
|
||||||
free(image->name);
|
|
||||||
free(image);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static status_t
|
|
||||||
elf_unload_image(struct elf_image_info *image)
|
|
||||||
{
|
|
||||||
if (atomic_add(&image->ref_count, -1) > 0)
|
|
||||||
return B_NO_ERROR;
|
|
||||||
|
|
||||||
//elf_unlink_relocs(image);
|
|
||||||
// not yet used
|
|
||||||
elf_unload_image_final(image);
|
|
||||||
|
|
||||||
return B_NO_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
elf_unload_kspace(const char *path)
|
unload_kernel_add_on(image_id id)
|
||||||
{
|
{
|
||||||
int fd;
|
|
||||||
int err;
|
|
||||||
void *vnode;
|
|
||||||
struct elf_image_info *image;
|
|
||||||
|
|
||||||
fd = sys_open(path, 0);
|
|
||||||
if (fd < 0)
|
|
||||||
return fd;
|
|
||||||
|
|
||||||
err = vfs_get_vnode_from_fd(fd, true, &vnode);
|
|
||||||
if (err < 0)
|
|
||||||
goto error0;
|
|
||||||
|
|
||||||
mutex_lock(&sImageLoadMutex);
|
|
||||||
|
|
||||||
image = find_image_by_vnode(vnode);
|
|
||||||
if (!image) {
|
|
||||||
dprintf("Tried to unload image that wasn't loaded (%s)\n", path);
|
|
||||||
err = B_ENTRY_NOT_FOUND;
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
err = elf_unload_image(image);
|
|
||||||
|
|
||||||
error:
|
|
||||||
mutex_unlock(&sImageLoadMutex);
|
|
||||||
error0:
|
|
||||||
if(vnode)
|
|
||||||
vfs_put_vnode_ptr(vnode);
|
|
||||||
sys_close(fd);
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static status_t
|
|
||||||
insert_preloaded_image(struct preloaded_image *preloadedImage)
|
|
||||||
{
|
|
||||||
struct Elf32_Ehdr *elfHeader;
|
|
||||||
struct elf_image_info *image;
|
struct elf_image_info *image;
|
||||||
status_t status;
|
status_t status;
|
||||||
|
|
||||||
elfHeader = (struct Elf32_Ehdr *)malloc(sizeof(struct Elf32_Ehdr));
|
mutex_lock(&sImageMutex);
|
||||||
if (elfHeader == NULL)
|
|
||||||
return B_NO_MEMORY;
|
image = find_image(id);
|
||||||
|
if (image != NULL) {
|
||||||
|
mutex_lock(&sImageLoadMutex);
|
||||||
|
|
||||||
memcpy(elfHeader, &preloadedImage->elf_header, sizeof(struct Elf32_Ehdr));
|
status = unload_elf_image(image);
|
||||||
status = verify_eheader(elfHeader);
|
|
||||||
if (status < B_OK)
|
|
||||||
goto error1;
|
|
||||||
|
|
||||||
image = create_image_struct();
|
mutex_unlock(&sImageLoadMutex);
|
||||||
if (image == NULL) {
|
} else
|
||||||
status = B_NO_MEMORY;
|
status = B_BAD_IMAGE_ID;
|
||||||
goto error1;
|
|
||||||
}
|
|
||||||
|
|
||||||
image->vnode = NULL;
|
|
||||||
image->eheader = elfHeader;
|
|
||||||
image->name = strdup(preloadedImage->name);
|
|
||||||
image->dynamic_ptr = preloadedImage->dynamic_section.start;
|
|
||||||
|
|
||||||
image->regions[0] = preloadedImage->text_region;
|
|
||||||
image->regions[1] = preloadedImage->data_region;
|
|
||||||
|
|
||||||
status = elf_parse_dynamic_section(image);
|
|
||||||
if (status < B_OK)
|
|
||||||
goto error2;
|
|
||||||
|
|
||||||
status = elf_relocate(image, "");
|
|
||||||
if (status < B_OK)
|
|
||||||
goto error2;
|
|
||||||
|
|
||||||
register_elf_image(image);
|
|
||||||
return B_OK;
|
|
||||||
|
|
||||||
error2:
|
|
||||||
free(image);
|
|
||||||
error1:
|
|
||||||
free(elfHeader);
|
|
||||||
|
|
||||||
|
mutex_unlock(&sImageMutex);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -364,11 +364,11 @@ unload_file_system(file_system *fs)
|
|||||||
if (fs->image < B_OK)
|
if (fs->image < B_OK)
|
||||||
return B_OK;
|
return B_OK;
|
||||||
|
|
||||||
uninit = (void (*)())elf_lookup_symbol(fs->image, "uninit_file_system");
|
if (get_image_symbol(fs->image, "uninit_file_system",
|
||||||
if (uninit != NULL)
|
B_SYMBOL_TYPE_TEXT, (void **)&uninit) == B_OK)
|
||||||
uninit();
|
uninit();
|
||||||
|
|
||||||
// ToDo: unloading is not yet supported - we need a unload image_id first...
|
unload_kernel_add_on(fs->image);
|
||||||
free(fs);
|
free(fs);
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
@ -385,22 +385,25 @@ load_file_system(const char *name)
|
|||||||
void (*init)();
|
void (*init)();
|
||||||
image_id image;
|
image_id image;
|
||||||
|
|
||||||
|
// ToDo: don't use fixed paths!!
|
||||||
|
|
||||||
// search in the user directory
|
// search in the user directory
|
||||||
sprintf(path, "/boot/home/config/add-ons/kernel/file_systems/%s", name);
|
sprintf(path, "/boot/home/config/add-ons/kernel/file_systems/%s", name);
|
||||||
image = elf_load_kspace(path, "");
|
|
||||||
|
image = load_kernel_add_on(path);
|
||||||
if (image == B_ENTRY_NOT_FOUND) {
|
if (image == B_ENTRY_NOT_FOUND) {
|
||||||
|
// ToDo: this is not a BeOS compatible system directory (bootfs)
|
||||||
// search in the system directory
|
// search in the system directory
|
||||||
sprintf(path, "/boot/addons/fs/%s", name);
|
sprintf(path, "/boot/addons/fs/%s", name);
|
||||||
//sprintf(path, "/boot/beos/system/add-ons/kernel/file_systems/%s", name);
|
//sprintf(path, "/boot/beos/system/add-ons/kernel/file_systems/%s", name);
|
||||||
image = elf_load_kspace(path, "");
|
image = load_kernel_add_on(path);
|
||||||
}
|
}
|
||||||
if (image < B_OK)
|
if (image < B_OK)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
init = (void (*)())elf_lookup_symbol(image, "init_file_system");
|
if (get_image_symbol(image, "init_file_system", B_SYMBOL_TYPE_TEXT, (void **)&init) != B_OK
|
||||||
version = (int32 *)elf_lookup_symbol(image, "api_version");
|
|| get_image_symbol(image, "api_version", B_SYMBOL_TYPE_DATA, (void **)&version) != B_OK
|
||||||
ops = (fs_ops **)elf_lookup_symbol(image, "fs_entry");
|
|| get_image_symbol(image, "fs_entry", B_SYMBOL_TYPE_DATA, (void **)&ops) != B_OK) {
|
||||||
if (init == NULL || version == NULL || ops == NULL) {
|
|
||||||
dprintf("vfs: add-on \"%s\" doesn't export all necessary symbols.\n", name);
|
dprintf("vfs: add-on \"%s\" doesn't export all necessary symbols.\n", name);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
@ -422,7 +425,7 @@ load_file_system(const char *name)
|
|||||||
return fs;
|
return fs;
|
||||||
|
|
||||||
err:
|
err:
|
||||||
elf_unload_kspace(path);
|
unload_kernel_add_on(image);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -237,7 +237,7 @@ load_module_image(const char *path, module_image **_moduleImage)
|
|||||||
TRACE(("load_module_image(path = \"%s\", _image = %p)\n", path, _moduleImage));
|
TRACE(("load_module_image(path = \"%s\", _image = %p)\n", path, _moduleImage));
|
||||||
ASSERT(_moduleImage != NULL);
|
ASSERT(_moduleImage != NULL);
|
||||||
|
|
||||||
image = elf_load_kspace(path, "");
|
image = load_kernel_add_on(path);
|
||||||
if (image < 0) {
|
if (image < 0) {
|
||||||
dprintf("load_module_image failed: %s\n", strerror(image));
|
dprintf("load_module_image failed: %s\n", strerror(image));
|
||||||
return image;
|
return image;
|
||||||
@ -249,14 +249,16 @@ load_module_image(const char *path, module_image **_moduleImage)
|
|||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
moduleImage->info = (module_info **)elf_lookup_symbol(image, "modules");
|
if (get_image_symbol(image, "modules", B_SYMBOL_TYPE_DATA,
|
||||||
if (!moduleImage->info) {
|
(void **)&moduleImage->info) != B_OK) {
|
||||||
FATAL(("load_module_image: Failed to load %s due to lack of 'modules' symbol\n", path));
|
FATAL(("load_module_image: Failed to load %s due to lack of 'modules' symbol\n", path));
|
||||||
status = B_BAD_TYPE;
|
status = B_BAD_TYPE;
|
||||||
goto err1;
|
goto err1;
|
||||||
}
|
}
|
||||||
|
|
||||||
moduleImage->dependencies = (module_dependency *)elf_lookup_symbol(image, "module_dependencies");
|
moduleImage->dependencies = NULL;
|
||||||
|
get_image_symbol(image, "module_dependencies", B_SYMBOL_TYPE_DATA,
|
||||||
|
(void **)&moduleImage->dependencies);
|
||||||
// this is allowed to be NULL
|
// this is allowed to be NULL
|
||||||
|
|
||||||
moduleImage->path = strdup(path);
|
moduleImage->path = strdup(path);
|
||||||
@ -279,7 +281,7 @@ load_module_image(const char *path, module_image **_moduleImage)
|
|||||||
err1:
|
err1:
|
||||||
free(moduleImage);
|
free(moduleImage);
|
||||||
err:
|
err:
|
||||||
elf_unload_kspace(path);
|
unload_kernel_add_on(image);
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
@ -306,7 +308,7 @@ unload_module_image(module_image *moduleImage, const char *path)
|
|||||||
hash_remove(sModuleImagesHash, moduleImage);
|
hash_remove(sModuleImagesHash, moduleImage);
|
||||||
recursive_lock_unlock(&sModulesLock);
|
recursive_lock_unlock(&sModulesLock);
|
||||||
|
|
||||||
elf_unload_kspace(moduleImage->path);
|
unload_kernel_add_on(moduleImage->image);
|
||||||
free(moduleImage->path);
|
free(moduleImage->path);
|
||||||
free(moduleImage);
|
free(moduleImage);
|
||||||
|
|
||||||
|
@ -160,6 +160,7 @@ kfree_strings_array(char **strings, int strc)
|
|||||||
{
|
{
|
||||||
int cnt = strc;
|
int cnt = strc;
|
||||||
|
|
||||||
|
|
||||||
if (strings != NULL) {
|
if (strings != NULL) {
|
||||||
for (cnt = 0; cnt < strc; cnt++){
|
for (cnt = 0; cnt < strc; cnt++){
|
||||||
free(strings[cnt]);
|
free(strings[cnt]);
|
||||||
@ -543,7 +544,7 @@ team_create_team2(void *args)
|
|||||||
uargs[arg_cnt] = NULL;
|
uargs[arg_cnt] = NULL;
|
||||||
|
|
||||||
team->user_env_base = t->user_stack_base + STACK_SIZE + TLS_SIZE;
|
team->user_env_base = t->user_stack_base + STACK_SIZE + TLS_SIZE;
|
||||||
uenv = (char **)team->user_env_base;
|
uenv = (char **)team->user_env_base;
|
||||||
udest = (char *)team->user_env_base + ENV_SIZE - 1;
|
udest = (char *)team->user_env_base + ENV_SIZE - 1;
|
||||||
|
|
||||||
TRACE(("team_create_team2: envc: %d, envp: 0x%p\n", teamArgs->envc, (void *)teamArgs->envp));
|
TRACE(("team_create_team2: envc: %d, envp: 0x%p\n", teamArgs->envc, (void *)teamArgs->envp));
|
||||||
@ -563,16 +564,14 @@ team_create_team2(void *args)
|
|||||||
uspa->envc = env_cnt;
|
uspa->envc = env_cnt;
|
||||||
uspa->envp = uenv;
|
uspa->envp = uenv;
|
||||||
|
|
||||||
if (teamArgs->args != NULL)
|
kfree_strings_array(teamArgs->args, teamArgs->argc);
|
||||||
kfree_strings_array(teamArgs->args, teamArgs->argc);
|
kfree_strings_array(teamArgs->envp, teamArgs->envc);
|
||||||
if (teamArgs->envp != NULL)
|
|
||||||
kfree_strings_array(teamArgs->envp, teamArgs->envc);
|
|
||||||
|
|
||||||
path = teamArgs->path;
|
path = teamArgs->path;
|
||||||
TRACE(("team_create_team2: loading elf binary '%s'\n", path));
|
TRACE(("team_create_team2: loading elf binary '%s'\n", path));
|
||||||
|
|
||||||
err = elf_load_uspace("/boot/libexec/rld.so", team, 0, &entry);
|
err = elf_load_user_image("/boot/libexec/rld.so", team, 0, &entry);
|
||||||
if (err < 0){
|
if (err < 0) {
|
||||||
// XXX clean up team
|
// XXX clean up team
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user