* 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:
Axel Dörfler 2008-07-22 17:57:00 +00:00
parent 33f9067b36
commit 467acc16f5

View File

@ -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 **)&regionAddress,
(void **)&regionAddress, 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 **)&regionAddress, B_EXACT_ADDRESS, bss_size, (void **)&regionAddress, 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 **)&regionAddress,
(void **)&regionAddress, 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");