* Cleanup, no functional change.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@26568 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
33f9067b36
commit
467acc16f5
@ -1,12 +1,12 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2008, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
|
* Copyright 2002-2008, Axel Dörfler, axeld@pinc-software.de.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
* Copyright 2001, Travis Geiselbrecht. All rights reserved.
|
* Copyright 2001, Travis Geiselbrecht. All rights reserved.
|
||||||
* Distributed under the terms of the NewOS License.
|
* Distributed under the terms of the NewOS License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Contains the ELF loader */
|
/*! Contains the ELF loader */
|
||||||
|
|
||||||
#include <elf.h>
|
#include <elf.h>
|
||||||
|
|
||||||
@ -44,16 +44,6 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// ToDo: this shall contain a list of linked images (one day)
|
|
||||||
// this is a preparation for shared libraries in the kernel
|
|
||||||
// and not yet used.
|
|
||||||
#if 0
|
|
||||||
typedef struct elf_linked_image {
|
|
||||||
struct elf_linked_image *next;
|
|
||||||
struct elf_image_info *image;
|
|
||||||
} elf_linked_image;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define IMAGE_HASH_SIZE 16
|
#define IMAGE_HASH_SIZE 16
|
||||||
|
|
||||||
static hash_table *sImagesHash;
|
static hash_table *sImagesHash;
|
||||||
@ -115,7 +105,8 @@ register_elf_image(struct elf_image_info *image)
|
|||||||
imageInfo.data = (void *)image->data_region.start;
|
imageInfo.data = (void *)image->data_region.start;
|
||||||
imageInfo.data_size = image->data_region.size;
|
imageInfo.data_size = image->data_region.size;
|
||||||
|
|
||||||
image->id = register_image(team_get_kernel_team(), &imageInfo, sizeof(image_info));
|
image->id = register_image(team_get_kernel_team(), &imageInfo,
|
||||||
|
sizeof(image_info));
|
||||||
hash_insert(sImagesHash, image);
|
hash_insert(sImagesHash, image);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -133,11 +124,13 @@ find_image_at_address(addr_t address)
|
|||||||
|
|
||||||
// get image that may contain the address
|
// get image that may contain the address
|
||||||
|
|
||||||
while ((image = (elf_image_info *)hash_next(sImagesHash, &iterator)) != NULL) {
|
while ((image = (elf_image_info *)hash_next(sImagesHash, &iterator))
|
||||||
if ((address >= image->text_region.start
|
!= NULL) {
|
||||||
&& address <= (image->text_region.start + image->text_region.size))
|
if ((address >= image->text_region.start && address
|
||||||
|
<= (image->text_region.start + image->text_region.size))
|
||||||
|| (address >= image->data_region.start
|
|| (address >= image->data_region.start
|
||||||
&& address <= (image->data_region.start + image->data_region.size)))
|
&& address
|
||||||
|
<= (image->data_region.start + image->data_region.size)))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -187,7 +180,8 @@ find_image_by_vnode(void *vnode)
|
|||||||
mutex_lock(&sImageMutex);
|
mutex_lock(&sImageMutex);
|
||||||
hash_open(sImagesHash, &iterator);
|
hash_open(sImagesHash, &iterator);
|
||||||
|
|
||||||
while ((image = (elf_image_info *)hash_next(sImagesHash, &iterator)) != NULL) {
|
while ((image = (elf_image_info *)hash_next(sImagesHash, &iterator))
|
||||||
|
!= NULL) {
|
||||||
if (image->vnode == vnode)
|
if (image->vnode == vnode)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -202,7 +196,8 @@ find_image_by_vnode(void *vnode)
|
|||||||
static struct elf_image_info *
|
static struct elf_image_info *
|
||||||
create_image_struct()
|
create_image_struct()
|
||||||
{
|
{
|
||||||
struct elf_image_info *image = (struct elf_image_info *)malloc(sizeof(struct elf_image_info));
|
struct elf_image_info *image
|
||||||
|
= (struct elf_image_info *)malloc(sizeof(struct elf_image_info));
|
||||||
if (image == NULL)
|
if (image == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
@ -330,9 +325,11 @@ dump_symbols(int argc, char **argv)
|
|||||||
// find image at address
|
// find image at address
|
||||||
|
|
||||||
hash_open(sImagesHash, &iterator);
|
hash_open(sImagesHash, &iterator);
|
||||||
while ((image = (elf_image_info *)hash_next(sImagesHash, &iterator)) != NULL) {
|
while ((image = (elf_image_info *)hash_next(sImagesHash,
|
||||||
|
&iterator)) != NULL) {
|
||||||
if (image->text_region.start <= num
|
if (image->text_region.start <= num
|
||||||
&& image->text_region.start + image->text_region.size >= num)
|
&& image->text_region.start + image->text_region.size
|
||||||
|
>= num)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
hash_close(sImagesHash, &iterator, false);
|
hash_close(sImagesHash, &iterator, false);
|
||||||
@ -347,7 +344,8 @@ dump_symbols(int argc, char **argv)
|
|||||||
} else {
|
} else {
|
||||||
// look for image by name
|
// look for image by name
|
||||||
hash_open(sImagesHash, &iterator);
|
hash_open(sImagesHash, &iterator);
|
||||||
while ((image = (elf_image_info *)hash_next(sImagesHash, &iterator)) != NULL) {
|
while ((image = (elf_image_info *)hash_next(sImagesHash,
|
||||||
|
&iterator)) != NULL) {
|
||||||
if (!strcmp(image->name, argv[1]))
|
if (!strcmp(image->name, argv[1]))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -366,35 +364,40 @@ dump_symbols(int argc, char **argv)
|
|||||||
|
|
||||||
// dump symbols
|
// dump symbols
|
||||||
|
|
||||||
kprintf("Symbols of image %ld \"%s\":\nAddress Type Size Name\n", image->id, image->name);
|
kprintf("Symbols of image %ld \"%s\":\nAddress Type Size Name\n",
|
||||||
|
image->id, image->name);
|
||||||
|
|
||||||
if (image->num_debug_symbols > 0) {
|
if (image->num_debug_symbols > 0) {
|
||||||
// search extended debug symbol table (contains static symbols)
|
// search extended debug symbol table (contains static symbols)
|
||||||
for (i = 0; i < image->num_debug_symbols; i++) {
|
for (i = 0; i < image->num_debug_symbols; i++) {
|
||||||
struct Elf32_Sym *symbol = &image->debug_symbols[i];
|
struct Elf32_Sym *symbol = &image->debug_symbols[i];
|
||||||
|
|
||||||
if (symbol->st_value == 0
|
if (symbol->st_value == 0 || symbol->st_size
|
||||||
|| symbol->st_size >= image->text_region.size + image->data_region.size)
|
>= image->text_region.size + image->data_region.size)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
kprintf("%08lx %s/%s %5ld %s\n", symbol->st_value + image->text_region.delta,
|
kprintf("%08lx %s/%s %5ld %s\n",
|
||||||
get_symbol_type_string(symbol), get_symbol_bind_string(symbol), symbol->st_size,
|
symbol->st_value + image->text_region.delta,
|
||||||
image->debug_string_table + symbol->st_name);
|
get_symbol_type_string(symbol), get_symbol_bind_string(symbol),
|
||||||
|
symbol->st_size, image->debug_string_table + symbol->st_name);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
int32 j;
|
int32 j;
|
||||||
|
|
||||||
// search standard symbol lookup table
|
// search standard symbol lookup table
|
||||||
for (i = 0; i < HASHTABSIZE(image); i++) {
|
for (i = 0; i < HASHTABSIZE(image); i++) {
|
||||||
for (j = HASHBUCKETS(image)[i]; j != STN_UNDEF; j = HASHCHAINS(image)[j]) {
|
for (j = HASHBUCKETS(image)[i]; j != STN_UNDEF;
|
||||||
|
j = HASHCHAINS(image)[j]) {
|
||||||
struct Elf32_Sym *symbol = &image->syms[j];
|
struct Elf32_Sym *symbol = &image->syms[j];
|
||||||
|
|
||||||
if (symbol->st_value == 0
|
if (symbol->st_value == 0 || symbol->st_size
|
||||||
|| symbol->st_size >= image->text_region.size + image->data_region.size)
|
>= image->text_region.size + image->data_region.size)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
kprintf("%08lx %s/%s %5ld %s\n", symbol->st_value + image->text_region.delta,
|
kprintf("%08lx %s/%s %5ld %s\n",
|
||||||
get_symbol_type_string(symbol), get_symbol_bind_string(symbol),
|
symbol->st_value + image->text_region.delta,
|
||||||
|
get_symbol_type_string(symbol),
|
||||||
|
get_symbol_bind_string(symbol),
|
||||||
symbol->st_size, SYMNAME(image, symbol));
|
symbol->st_size, SYMNAME(image, symbol));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -407,7 +410,7 @@ dump_symbols(int argc, char **argv)
|
|||||||
static void
|
static void
|
||||||
dump_elf_region(struct elf_region *region, const char *name)
|
dump_elf_region(struct elf_region *region, const char *name)
|
||||||
{
|
{
|
||||||
kprintf(" %s.id 0x%lx\n", name, region->id);
|
kprintf(" %s.id %ld\n", name, region->id);
|
||||||
kprintf(" %s.start 0x%lx\n", name, region->start);
|
kprintf(" %s.start 0x%lx\n", name, region->start);
|
||||||
kprintf(" %s.size 0x%lx\n", name, region->size);
|
kprintf(" %s.size 0x%lx\n", name, region->size);
|
||||||
kprintf(" %s.delta %ld\n", name, region->delta);
|
kprintf(" %s.delta %ld\n", name, region->delta);
|
||||||
@ -419,7 +422,7 @@ dump_image_info(struct elf_image_info *image)
|
|||||||
{
|
{
|
||||||
kprintf("elf_image_info at %p:\n", image);
|
kprintf("elf_image_info at %p:\n", image);
|
||||||
kprintf(" next %p\n", image->next);
|
kprintf(" next %p\n", image->next);
|
||||||
kprintf(" id 0x%lx\n", image->id);
|
kprintf(" id %ld\n", image->id);
|
||||||
dump_elf_region(&image->text_region, "text");
|
dump_elf_region(&image->text_region, "text");
|
||||||
dump_elf_region(&image->data_region, "data");
|
dump_elf_region(&image->data_region, "data");
|
||||||
kprintf(" dynamic_section 0x%lx\n", image->dynamic_section);
|
kprintf(" dynamic_section 0x%lx\n", image->dynamic_section);
|
||||||
@ -434,7 +437,8 @@ dump_image_info(struct elf_image_info *image)
|
|||||||
kprintf(" pltrel %p\n", image->pltrel);
|
kprintf(" pltrel %p\n", image->pltrel);
|
||||||
kprintf(" pltrel_len 0x%x\n", image->pltrel_len);
|
kprintf(" pltrel_len 0x%x\n", image->pltrel_len);
|
||||||
|
|
||||||
kprintf(" debug_symbols %p (%ld)\n", image->debug_symbols, image->num_debug_symbols);
|
kprintf(" debug_symbols %p (%ld)\n",
|
||||||
|
image->debug_symbols, image->num_debug_symbols);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -465,7 +469,8 @@ dump_image(int argc, char **argv)
|
|||||||
|
|
||||||
hash_open(sImagesHash, &iterator);
|
hash_open(sImagesHash, &iterator);
|
||||||
|
|
||||||
while ((image = (elf_image_info *)hash_next(sImagesHash, &iterator)) != NULL) {
|
while ((image = (elf_image_info *)hash_next(sImagesHash, &iterator))
|
||||||
|
!= NULL) {
|
||||||
kprintf("%p (%ld) %s\n", image, image->id, image->name);
|
kprintf("%p (%ld) %s\n", image, image->id, image->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -502,7 +507,8 @@ elf_find_symbol(struct elf_image_info *image, const char *name)
|
|||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
hash = elf_hash(name) % HASHTABSIZE(image);
|
hash = elf_hash(name) % HASHTABSIZE(image);
|
||||||
for (i = HASHBUCKETS(image)[hash]; i != STN_UNDEF; i = HASHCHAINS(image)[i]) {
|
for (i = HASHBUCKETS(image)[hash]; i != STN_UNDEF;
|
||||||
|
i = HASHCHAINS(image)[i]) {
|
||||||
if (!strcmp(SYMNAME(image, &image->syms[i]), name))
|
if (!strcmp(SYMNAME(image, &image->syms[i]), name))
|
||||||
return &image->syms[i];
|
return &image->syms[i];
|
||||||
}
|
}
|
||||||
@ -622,13 +628,15 @@ elf_resolve_symbol(struct elf_image_info *image, struct Elf32_Sym *symbol,
|
|||||||
// make sure they're the same type
|
// make sure they're the same type
|
||||||
if (ELF32_ST_TYPE(symbol->st_info)
|
if (ELF32_ST_TYPE(symbol->st_info)
|
||||||
!= ELF32_ST_TYPE(newSymbol->st_info)) {
|
!= ELF32_ST_TYPE(newSymbol->st_info)) {
|
||||||
dprintf("elf_resolve_symbol: found symbol '%s' in shared image but wrong type\n", newName);
|
dprintf("elf_resolve_symbol: found symbol '%s' in shared image "
|
||||||
|
"but wrong type\n", newName);
|
||||||
return B_MISSING_SYMBOL;
|
return B_MISSING_SYMBOL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ELF32_ST_BIND(newSymbol->st_info) != STB_GLOBAL
|
if (ELF32_ST_BIND(newSymbol->st_info) != STB_GLOBAL
|
||||||
&& ELF32_ST_BIND(newSymbol->st_info) != STB_WEAK) {
|
&& ELF32_ST_BIND(newSymbol->st_info) != STB_WEAK) {
|
||||||
TRACE(("elf_resolve_symbol: found symbol '%s' but not exported\n", newName));
|
TRACE(("elf_resolve_symbol: found symbol '%s' but not "
|
||||||
|
"exported\n", newName));
|
||||||
return B_MISSING_SYMBOL;
|
return B_MISSING_SYMBOL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -652,7 +660,7 @@ elf_resolve_symbol(struct elf_image_info *image, struct Elf32_Sym *symbol,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*! Until we have shared library support, just links against the kernel */
|
/*! Until we have shared library support, just this links against the kernel */
|
||||||
static int
|
static int
|
||||||
elf_relocate(struct elf_image_info *image, const char *symbolPrepend)
|
elf_relocate(struct elf_image_info *image, const char *symbolPrepend)
|
||||||
{
|
{
|
||||||
@ -716,23 +724,6 @@ verify_eheader(struct Elf32_Ehdr *elfHeader)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#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
|
static status_t
|
||||||
unload_elf_image(struct elf_image_info *image)
|
unload_elf_image(struct elf_image_info *image)
|
||||||
{
|
{
|
||||||
@ -741,9 +732,6 @@ unload_elf_image(struct elf_image_info *image)
|
|||||||
|
|
||||||
TRACE(("unload image %ld, %s\n", image->id, image->name));
|
TRACE(("unload image %ld, %s\n", image->id, image->name));
|
||||||
|
|
||||||
//elf_unlink_relocs(image);
|
|
||||||
// not yet used
|
|
||||||
|
|
||||||
delete_area(image->text_region.id);
|
delete_area(image->text_region.id);
|
||||||
delete_area(image->data_region.id);
|
delete_area(image->data_region.id);
|
||||||
|
|
||||||
@ -803,13 +791,15 @@ load_elf_symbol_table(int fd, struct elf_image_info *image)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// read in symbol table
|
// read in symbol table
|
||||||
symbolTable = (struct Elf32_Sym *)malloc(size = sectionHeaders[i].sh_size);
|
symbolTable
|
||||||
|
= (struct Elf32_Sym *)malloc(size = sectionHeaders[i].sh_size);
|
||||||
if (symbolTable == NULL) {
|
if (symbolTable == NULL) {
|
||||||
status = B_NO_MEMORY;
|
status = B_NO_MEMORY;
|
||||||
goto error1;
|
goto error1;
|
||||||
}
|
}
|
||||||
|
|
||||||
length = read_pos(fd, sectionHeaders[i].sh_offset, symbolTable, size);
|
length
|
||||||
|
= read_pos(fd, sectionHeaders[i].sh_offset, symbolTable, size);
|
||||||
if (length < size) {
|
if (length < size) {
|
||||||
TRACE(("error reading in symbol table\n"));
|
TRACE(("error reading in symbol table\n"));
|
||||||
status = B_ERROR;
|
status = B_ERROR;
|
||||||
@ -974,11 +964,12 @@ public:
|
|||||||
{
|
{
|
||||||
// Note, that this function doesn't find all symbols that we would like
|
// Note, that this function doesn't find all symbols that we would like
|
||||||
// to find. E.g. static functions do not appear in the symbol table
|
// to find. E.g. static functions do not appear in the symbol table
|
||||||
// as function symbols, but as sections without name and size. The .symtab
|
// as function symbols, but as sections without name and size. The
|
||||||
// section together with the .strtab section, which apparently differ from
|
// .symtab section together with the .strtab section, which apparently
|
||||||
// the tables referred to by the .dynamic section, also contain proper names
|
// differ from the tables referred to by the .dynamic section, also
|
||||||
// and sizes for those symbols. Therefore, to get completely satisfying
|
// contain proper names and sizes for those symbols. Therefore, to get
|
||||||
// results, we would need to read those tables from the shared object.
|
// completely satisfying results, we would need to read those tables
|
||||||
|
// from the shared object.
|
||||||
|
|
||||||
// get the image for the address
|
// get the image for the address
|
||||||
image_t image;
|
image_t image;
|
||||||
@ -1016,13 +1007,13 @@ public:
|
|||||||
if (!_Read(image.syms + j, symbol))
|
if (!_Read(image.syms + j, symbol))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// The symbol table contains not only symbols referring to functions
|
// The symbol table contains not only symbols referring to
|
||||||
// and data symbols within the shared object, but also referenced
|
// functions and data symbols within the shared object, but also
|
||||||
// symbols of other shared objects, as well as section and file
|
// referenced symbols of other shared objects, as well as
|
||||||
// references. We ignore everything but function and data symbols
|
// section and file references. We ignore everything but
|
||||||
// that have an st_value != 0 (0 seems to be an indication for a
|
// function and data symbols that have an st_value != 0 (0
|
||||||
// symbol defined elsewhere -- couldn't verify that in the specs
|
// seems to be an indication for a symbol defined elsewhere
|
||||||
// though).
|
// -- couldn't verify that in the specs though).
|
||||||
if ((ELF32_ST_TYPE(symbol.st_info) != STT_FUNC
|
if ((ELF32_ST_TYPE(symbol.st_info) != STT_FUNC
|
||||||
&& ELF32_ST_TYPE(symbol.st_info) != STT_OBJECT)
|
&& ELF32_ST_TYPE(symbol.st_info) != STT_OBJECT)
|
||||||
|| symbol.st_value == 0
|
|| symbol.st_value == 0
|
||||||
@ -1080,7 +1071,6 @@ public:
|
|||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t _FindImageAtAddress(addr_t address, image_t& image)
|
status_t _FindImageAtAddress(addr_t address, image_t& image)
|
||||||
{
|
{
|
||||||
image_queue_t imageQueue;
|
image_queue_t imageQueue;
|
||||||
@ -1144,7 +1134,8 @@ UserSymbolLookup UserSymbolLookup::sLookup;
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
get_image_symbol(image_id id, const char *name, int32 sclass, void **_symbol)
|
get_image_symbol(image_id id, const char *name, int32 symbolClass,
|
||||||
|
void **_symbol)
|
||||||
{
|
{
|
||||||
struct elf_image_info *image;
|
struct elf_image_info *image;
|
||||||
struct Elf32_Sym *symbol;
|
struct Elf32_Sym *symbol;
|
||||||
@ -1166,9 +1157,10 @@ get_image_symbol(image_id id, const char *name, int32 sclass, void **_symbol)
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ToDo: support the "sclass" parameter!
|
// TODO: support the "symbolClass" parameter!
|
||||||
|
|
||||||
TRACE(("found: %lx (%lx + %lx)\n", symbol->st_value + image->text_region.delta,
|
TRACE(("found: %lx (%lx + %lx)\n",
|
||||||
|
symbol->st_value + image->text_region.delta,
|
||||||
symbol->st_value, image->text_region.delta));
|
symbol->st_value, image->text_region.delta));
|
||||||
|
|
||||||
*_symbol = (void *)(symbol->st_value + image->text_region.delta);
|
*_symbol = (void *)(symbol->st_value + image->text_region.delta);
|
||||||
@ -1223,11 +1215,12 @@ elf_debug_lookup_symbol_address(addr_t address, addr_t *_baseAddress,
|
|||||||
for (i = 0; i < image->num_debug_symbols; i++) {
|
for (i = 0; i < image->num_debug_symbols; i++) {
|
||||||
struct Elf32_Sym *symbol = &image->debug_symbols[i];
|
struct Elf32_Sym *symbol = &image->debug_symbols[i];
|
||||||
|
|
||||||
if (symbol->st_value == 0
|
if (symbol->st_value == 0 || symbol->st_size
|
||||||
|| symbol->st_size >= image->text_region.size + image->data_region.size)
|
>= image->text_region.size + image->data_region.size)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
symbolDelta = address - (symbol->st_value + image->text_region.delta);
|
symbolDelta
|
||||||
|
= address - (symbol->st_value + image->text_region.delta);
|
||||||
if (symbolDelta >= 0 && symbolDelta < symbol->st_size)
|
if (symbolDelta >= 0 && symbolDelta < symbol->st_size)
|
||||||
exactMatch = true;
|
exactMatch = true;
|
||||||
|
|
||||||
@ -1246,14 +1239,17 @@ elf_debug_lookup_symbol_address(addr_t address, addr_t *_baseAddress,
|
|||||||
TRACE((" searching standard symbols...\n"));
|
TRACE((" searching standard symbols...\n"));
|
||||||
|
|
||||||
for (i = 0; i < HASHTABSIZE(image); i++) {
|
for (i = 0; i < HASHTABSIZE(image); i++) {
|
||||||
for (j = HASHBUCKETS(image)[i]; j != STN_UNDEF; j = HASHCHAINS(image)[j]) {
|
for (j = HASHBUCKETS(image)[i]; j != STN_UNDEF;
|
||||||
|
j = HASHCHAINS(image)[j]) {
|
||||||
struct Elf32_Sym *symbol = &image->syms[j];
|
struct Elf32_Sym *symbol = &image->syms[j];
|
||||||
|
|
||||||
if (symbol->st_value == 0
|
if (symbol->st_value == 0
|
||||||
|| symbol->st_size >= image->text_region.size + image->data_region.size)
|
|| symbol->st_size >= image->text_region.size
|
||||||
|
+ image->data_region.size)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
symbolDelta = address - (long)(symbol->st_value + image->text_region.delta);
|
symbolDelta = address - (long)(symbol->st_value
|
||||||
|
+ image->text_region.delta);
|
||||||
if (symbolDelta >= 0 && symbolDelta < symbol->st_size)
|
if (symbolDelta >= 0 && symbolDelta < symbol->st_size)
|
||||||
exactMatch = true;
|
exactMatch = true;
|
||||||
|
|
||||||
@ -1329,7 +1325,8 @@ elf_debug_lookup_user_symbol_address(struct team* team, addr_t address,
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
elf_load_user_image(const char *path, struct team *team, int flags, addr_t *entry)
|
elf_load_user_image(const char *path, struct team *team, int flags,
|
||||||
|
addr_t *entry)
|
||||||
{
|
{
|
||||||
struct Elf32_Ehdr elfHeader;
|
struct Elf32_Ehdr elfHeader;
|
||||||
struct Elf32_Phdr *programHeaders = NULL;
|
struct Elf32_Phdr *programHeaders = NULL;
|
||||||
@ -1364,15 +1361,18 @@ elf_load_user_image(const char *path, struct team *team, int flags, addr_t *entr
|
|||||||
|
|
||||||
// read program header
|
// read program header
|
||||||
|
|
||||||
programHeaders = (struct Elf32_Phdr *)malloc(elfHeader.e_phnum * elfHeader.e_phentsize);
|
programHeaders = (struct Elf32_Phdr *)malloc(
|
||||||
|
elfHeader.e_phnum * elfHeader.e_phentsize);
|
||||||
if (programHeaders == NULL) {
|
if (programHeaders == NULL) {
|
||||||
dprintf("error allocating space for program headers\n");
|
dprintf("error allocating space for program headers\n");
|
||||||
status = B_NO_MEMORY;
|
status = B_NO_MEMORY;
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE(("reading in program headers at 0x%lx, length 0x%x\n", elfHeader.e_phoff, elfHeader.e_phnum * elfHeader.e_phentsize));
|
TRACE(("reading in program headers at 0x%lx, length 0x%x\n",
|
||||||
length = _kern_read(fd, elfHeader.e_phoff, programHeaders, elfHeader.e_phnum * elfHeader.e_phentsize);
|
elfHeader.e_phoff, elfHeader.e_phnum * elfHeader.e_phentsize));
|
||||||
|
length = _kern_read(fd, elfHeader.e_phoff, programHeaders,
|
||||||
|
elfHeader.e_phnum * elfHeader.e_phentsize);
|
||||||
if (length < B_OK) {
|
if (length < B_OK) {
|
||||||
status = length;
|
status = length;
|
||||||
dprintf("error reading in program headers\n");
|
dprintf("error reading in program headers\n");
|
||||||
@ -1411,23 +1411,22 @@ elf_load_user_image(const char *path, struct team *team, int flags, addr_t *entr
|
|||||||
if (programHeaders[i].p_type != PT_LOAD)
|
if (programHeaders[i].p_type != PT_LOAD)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
regionAddress = (char *)ROUNDOWN(programHeaders[i].p_vaddr, B_PAGE_SIZE);
|
regionAddress = (char *)ROUNDOWN(programHeaders[i].p_vaddr,
|
||||||
|
B_PAGE_SIZE);
|
||||||
if (programHeaders[i].p_flags & PF_WRITE) {
|
if (programHeaders[i].p_flags & PF_WRITE) {
|
||||||
/*
|
// rw/data segment
|
||||||
* rw/data segment
|
uint32 memUpperBound = (programHeaders[i].p_vaddr % B_PAGE_SIZE)
|
||||||
*/
|
+ programHeaders[i].p_memsz;
|
||||||
uint32 memUpperBound = (programHeaders[i].p_vaddr % B_PAGE_SIZE) + programHeaders[i].p_memsz;
|
uint32 fileUpperBound = (programHeaders[i].p_vaddr % B_PAGE_SIZE)
|
||||||
uint32 fileUpperBound = (programHeaders[i].p_vaddr % B_PAGE_SIZE) + programHeaders[i].p_filesz;
|
+ programHeaders[i].p_filesz;
|
||||||
|
|
||||||
memUpperBound = ROUNDUP(memUpperBound, B_PAGE_SIZE);
|
memUpperBound = ROUNDUP(memUpperBound, B_PAGE_SIZE);
|
||||||
fileUpperBound = ROUNDUP(fileUpperBound, B_PAGE_SIZE);
|
fileUpperBound = ROUNDUP(fileUpperBound, B_PAGE_SIZE);
|
||||||
|
|
||||||
sprintf(regionName, "%s_seg%drw", baseName, i);
|
sprintf(regionName, "%s_seg%drw", baseName, i);
|
||||||
|
|
||||||
id = vm_map_file(team->id, regionName,
|
id = vm_map_file(team->id, regionName, (void **)®ionAddress,
|
||||||
(void **)®ionAddress,
|
B_EXACT_ADDRESS, fileUpperBound,
|
||||||
B_EXACT_ADDRESS,
|
|
||||||
fileUpperBound,
|
|
||||||
B_READ_AREA | B_WRITE_AREA, REGION_PRIVATE_MAP,
|
B_READ_AREA | B_WRITE_AREA, REGION_PRIVATE_MAP,
|
||||||
fd, ROUNDOWN(programHeaders[i].p_offset, B_PAGE_SIZE));
|
fd, ROUNDOWN(programHeaders[i].p_offset, B_PAGE_SIZE));
|
||||||
if (id < B_OK) {
|
if (id < B_OK) {
|
||||||
@ -1438,27 +1437,25 @@ elf_load_user_image(const char *path, struct team *team, int flags, addr_t *entr
|
|||||||
|
|
||||||
// clean garbage brought by mmap (the region behind the file,
|
// clean garbage brought by mmap (the region behind the file,
|
||||||
// at least parts of it are the bss and have to be zeroed)
|
// at least parts of it are the bss and have to be zeroed)
|
||||||
{
|
uint32 start = (uint32)regionAddress
|
||||||
uint32 start = (uint32)regionAddress
|
+ (programHeaders[i].p_vaddr % B_PAGE_SIZE)
|
||||||
+ (programHeaders[i].p_vaddr % B_PAGE_SIZE)
|
+ programHeaders[i].p_filesz;
|
||||||
+ programHeaders[i].p_filesz;
|
uint32 amount = fileUpperBound
|
||||||
uint32 amount = fileUpperBound
|
- (programHeaders[i].p_vaddr % B_PAGE_SIZE)
|
||||||
- (programHeaders[i].p_vaddr % B_PAGE_SIZE)
|
- (programHeaders[i].p_filesz);
|
||||||
- (programHeaders[i].p_filesz);
|
memset((void *)start, 0, amount);
|
||||||
memset((void *)start, 0, amount);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if we need extra storage for the bss - we have to do this if
|
// Check if we need extra storage for the bss - we have to do this if
|
||||||
// the above region doesn't already comprise the memory size, too.
|
// the above region doesn't already comprise the memory size, too.
|
||||||
|
|
||||||
if (memUpperBound != fileUpperBound) {
|
if (memUpperBound != fileUpperBound) {
|
||||||
size_t bss_size = memUpperBound - fileUpperBound;
|
size_t bssSize = memUpperBound - fileUpperBound;
|
||||||
|
|
||||||
snprintf(regionName, B_OS_NAME_LENGTH, "%s_bss%d", baseName, i);
|
snprintf(regionName, B_OS_NAME_LENGTH, "%s_bss%d", baseName, i);
|
||||||
|
|
||||||
regionAddress += fileUpperBound;
|
regionAddress += fileUpperBound;
|
||||||
id = create_area_etc(team->id, regionName,
|
id = create_area_etc(team->id, regionName,
|
||||||
(void **)®ionAddress, B_EXACT_ADDRESS, bss_size,
|
(void **)®ionAddress, B_EXACT_ADDRESS, bssSize,
|
||||||
B_NO_LOCK, B_READ_AREA | B_WRITE_AREA);
|
B_NO_LOCK, B_READ_AREA | B_WRITE_AREA);
|
||||||
if (id < B_OK) {
|
if (id < B_OK) {
|
||||||
dprintf("error allocating bss area: %s!\n", strerror(id));
|
dprintf("error allocating bss area: %s!\n", strerror(id));
|
||||||
@ -1467,15 +1464,12 @@ elf_load_user_image(const char *path, struct team *team, int flags, addr_t *entr
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/*
|
// assume ro/text segment
|
||||||
* assume ro/text segment
|
|
||||||
*/
|
|
||||||
snprintf(regionName, B_OS_NAME_LENGTH, "%s_seg%dro", baseName, i);
|
snprintf(regionName, B_OS_NAME_LENGTH, "%s_seg%dro", baseName, i);
|
||||||
|
|
||||||
id = vm_map_file(team->id, regionName,
|
id = vm_map_file(team->id, regionName, (void **)®ionAddress,
|
||||||
(void **)®ionAddress,
|
B_EXACT_ADDRESS, ROUNDUP(programHeaders[i].p_memsz
|
||||||
B_EXACT_ADDRESS,
|
+ (programHeaders[i].p_vaddr % B_PAGE_SIZE), B_PAGE_SIZE),
|
||||||
ROUNDUP(programHeaders[i].p_memsz + (programHeaders[i].p_vaddr % B_PAGE_SIZE), B_PAGE_SIZE),
|
|
||||||
B_READ_AREA | B_EXECUTE_AREA, REGION_PRIVATE_MAP,
|
B_READ_AREA | B_EXECUTE_AREA, REGION_PRIVATE_MAP,
|
||||||
fd, ROUNDOWN(programHeaders[i].p_offset, B_PAGE_SIZE));
|
fd, ROUNDOWN(programHeaders[i].p_offset, B_PAGE_SIZE));
|
||||||
if (id < B_OK) {
|
if (id < B_OK) {
|
||||||
@ -1489,7 +1483,6 @@ elf_load_user_image(const char *path, struct team *team, int flags, addr_t *entr
|
|||||||
TRACE(("elf_load: done!\n"));
|
TRACE(("elf_load: done!\n"));
|
||||||
|
|
||||||
*entry = elfHeader.e_entry;
|
*entry = elfHeader.e_entry;
|
||||||
|
|
||||||
status = B_OK;
|
status = B_OK;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
@ -1823,7 +1816,8 @@ elf_init(kernel_args *args)
|
|||||||
insert_preloaded_image(image, false);
|
insert_preloaded_image(image, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
add_debugger_command("ls", &dump_address_info, "lookup symbol for a particular address");
|
add_debugger_command("ls", &dump_address_info,
|
||||||
|
"lookup symbol for a particular address");
|
||||||
add_debugger_command("symbols", &dump_symbols, "dump symbols for image");
|
add_debugger_command("symbols", &dump_symbols, "dump symbols for image");
|
||||||
add_debugger_command("symbol", &dump_symbol, "search symbol in images");
|
add_debugger_command("symbol", &dump_symbol, "search symbol in images");
|
||||||
add_debugger_command("image", &dump_image, "dump image info");
|
add_debugger_command("image", &dump_image, "dump image info");
|
||||||
|
Loading…
Reference in New Issue
Block a user