* unload_elf_image() never unloaded any image because the ref_count

check was wrong (never gets below zero if everything goes as 
  intended).
* Removed erroneous white space.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24232 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2008-03-04 12:36:53 +00:00
parent e5a5ee6eb8
commit 890c615aee
+28 -26
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2007, Axel Dörfler, [email protected]. All rights reserved. * Copyright 2002-2008, Axel Dörfler, [email protected]. All rights reserved.
* 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.
@@ -107,7 +107,7 @@ register_elf_image(struct elf_image_info *image)
imageInfo.id = image->id; imageInfo.id = image->id;
imageInfo.type = B_SYSTEM_IMAGE; imageInfo.type = B_SYSTEM_IMAGE;
strlcpy(imageInfo.name, image->name, sizeof(imageInfo.name)); strlcpy(imageInfo.name, image->name, sizeof(imageInfo.name));
imageInfo.text = (void *)image->text_region.start; imageInfo.text = (void *)image->text_region.start;
imageInfo.text_size = image->text_region.size; imageInfo.text_size = image->text_region.size;
imageInfo.data = (void *)image->data_region.start; imageInfo.data = (void *)image->data_region.start;
@@ -144,7 +144,7 @@ find_image_at_address(addr_t address)
} }
static int static int
dump_address_info(int argc, char **argv) dump_address_info(int argc, char **argv)
{ {
const char *symbol, *imageName; const char *symbol, *imageName;
@@ -273,7 +273,7 @@ dump_symbols(int argc, char **argv)
if (argc > 1) { if (argc > 1) {
if (isdigit(argv[1][0])) { if (isdigit(argv[1][0])) {
uint32 num = strtoul(argv[1], NULL, 0); uint32 num = strtoul(argv[1], NULL, 0);
if (IS_KERNEL_ADDRESS(num)) { if (IS_KERNEL_ADDRESS(num)) {
// find image at address // find image at address
@@ -284,7 +284,7 @@ dump_symbols(int argc, char **argv)
break; break;
} }
hash_close(sImagesHash, &iterator, false); hash_close(sImagesHash, &iterator, false);
if (image == NULL) if (image == NULL)
kprintf("No image covers 0x%lx in the kernel!\n", num); kprintf("No image covers 0x%lx in the kernel!\n", num);
} else { } else {
@@ -669,13 +669,13 @@ static int
elf_unlink_relocs(struct elf_image_info *image) elf_unlink_relocs(struct elf_image_info *image)
{ {
elf_linked_image *link, *next_link; elf_linked_image *link, *next_link;
for (link = image->linked_images; link; link = next_link) { for (link = image->linked_images; link; link = next_link) {
next_link = link->next; next_link = link->next;
elf_unload_image(link->image); elf_unload_image(link->image);
free(link); free(link);
} }
return B_NO_ERROR; return B_NO_ERROR;
} }
#endif #endif
@@ -684,8 +684,10 @@ elf_unlink_relocs(struct elf_image_info *image)
static status_t static status_t
unload_elf_image(struct elf_image_info *image) unload_elf_image(struct elf_image_info *image)
{ {
if (atomic_add(&image->ref_count, -1) > 0) if (atomic_add(&image->ref_count, -1) > 1)
return B_NO_ERROR; return B_OK;
TRACE(("unload image %ld, %s\n", image->id, image->name));
//elf_unlink_relocs(image); //elf_unlink_relocs(image);
// not yet used // not yet used
@@ -699,7 +701,7 @@ unload_elf_image(struct elf_image_info *image)
unregister_elf_image(image); unregister_elf_image(image);
free(image->elf_header); free(image->elf_header);
free(image->name); free(image->name);
free(image); free(image);
return B_NO_ERROR; return B_NO_ERROR;
@@ -904,7 +906,7 @@ public:
// the tables referred to by the .dynamic section, also contain proper names // the tables referred to by the .dynamic section, also contain proper names
// and sizes for those symbols. Therefore, to get completely satisfying // and sizes for those symbols. Therefore, to get completely satisfying
// results, we would need to read those tables from the shared object. // 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;
status_t error = _FindImageAtAddress(address, image); status_t error = _FindImageAtAddress(address, image);
@@ -928,7 +930,7 @@ public:
Elf32_Sym symbolFound; Elf32_Sym symbolFound;
addr_t deltaFound = INT_MAX; addr_t deltaFound = INT_MAX;
bool exactMatch = false; bool exactMatch = false;
for (uint32 i = 0; i < hashTabSize; i++) { for (uint32 i = 0; i < hashTabSize; i++) {
uint32 bucket; uint32 bucket;
if (!_Read(&hashBuckets[i], bucket)) if (!_Read(&hashBuckets[i], bucket))
@@ -936,11 +938,11 @@ public:
for (uint32 j = bucket; j != STN_UNDEF; for (uint32 j = bucket; j != STN_UNDEF;
_Read(&hashChains[j], j) ? 0 : j = STN_UNDEF) { _Read(&hashChains[j], j) ? 0 : j = STN_UNDEF) {
Elf32_Sym symbol; Elf32_Sym symbol;
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 functions
// and data symbols within the shared object, but also referenced // and data symbols within the shared object, but also referenced
// symbols of other shared objects, as well as section and file // symbols of other shared objects, as well as section and file
@@ -955,17 +957,17 @@ public:
> textRegion.vmstart + textRegion.size) { > textRegion.vmstart + textRegion.size) {
continue; continue;
} }
// skip symbols starting after the given address // skip symbols starting after the given address
addr_t symbolAddress = symbol.st_value + textRegion.delta; addr_t symbolAddress = symbol.st_value + textRegion.delta;
if (symbolAddress > address) if (symbolAddress > address)
continue; continue;
addr_t symbolDelta = address - symbolAddress; addr_t symbolDelta = address - symbolAddress;
if (symbolDelta < deltaFound) { if (symbolDelta < deltaFound) {
deltaFound = symbolDelta; deltaFound = symbolDelta;
symbolFound = symbol; symbolFound = symbol;
if (symbolDelta >= 0 && symbolDelta < symbol.st_size) { if (symbolDelta >= 0 && symbolDelta < symbol.st_size) {
// exact match // exact match
exactMatch = true; exactMatch = true;
@@ -974,10 +976,10 @@ public:
} }
} }
} }
if (_imageName) if (_imageName)
*_imageName = fImageName; *_imageName = fImageName;
if (_symbolName) { if (_symbolName) {
*_symbolName = NULL; *_symbolName = NULL;
@@ -991,17 +993,17 @@ public:
} }
} }
} }
if (_baseAddress) { if (_baseAddress) {
if (deltaFound < INT_MAX) if (deltaFound < INT_MAX)
*_baseAddress = symbolFound.st_value + textRegion.delta; *_baseAddress = symbolFound.st_value + textRegion.delta;
else else
*_baseAddress = textRegion.vmstart; *_baseAddress = textRegion.vmstart;
} }
if (_exactMatch) if (_exactMatch)
*_exactMatch = exactMatch; *_exactMatch = exactMatch;
return B_OK; return B_OK;
} }
@@ -1024,7 +1026,7 @@ public:
imageAddress = image.next; imageAddress = image.next;
} }
return B_ENTRY_NOT_FOUND; return B_ENTRY_NOT_FOUND;
} }
@@ -1093,7 +1095,7 @@ get_image_symbol(image_id id, const char *name, int32 sclass, void **_symbol)
// ToDo: support the "sclass" parameter! // ToDo: support the "sclass" 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);
@@ -1712,14 +1714,14 @@ unload_kernel_add_on(image_id id)
mutex_lock(&sImageLoadMutex); mutex_lock(&sImageLoadMutex);
mutex_lock(&sImageMutex); mutex_lock(&sImageMutex);
image = find_image(id); image = find_image(id);
if (image != NULL) if (image != NULL)
status = unload_elf_image(image); status = unload_elf_image(image);
else else
status = B_BAD_IMAGE_ID; status = B_BAD_IMAGE_ID;
mutex_unlock(&sImageMutex); mutex_unlock(&sImageMutex);
mutex_unlock(&sImageLoadMutex); mutex_unlock(&sImageLoadMutex);
return status; return status;