get_library_symbol(): Simplified the RTLD_NEXT case. The caller is not bound

to search for a function with the same name as the calling function, so we
really don't need to find the calling function; the calling image suffices.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@29645 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold
2009-03-22 01:39:34 +00:00
parent 89569e1852
commit a2dad9e1a9
+26 -45
View File
@@ -2486,47 +2486,36 @@ get_library_symbol(void* handle, void* caller, const char* symbolName,
// Look in the default scope, but also in the dependencies of the // Look in the default scope, but also in the dependencies of the
// calling image. Return the next after the caller symbol. // calling image. Return the next after the caller symbol.
// First of all, find the caller symbol and its image. // First of all, find the caller image.
Elf32_Sym* callerSymbol = NULL;
image_t* callerImage = sLoadedImages.head; image_t* callerImage = sLoadedImages.head;
for (; callerImage != NULL; callerImage = callerImage->next) { for (; callerImage != NULL; callerImage = callerImage->next) {
elf_region_t& text = callerImage->regions[0]; elf_region_t& text = callerImage->regions[0];
if ((addr_t)caller < text.vmstart if ((addr_t)caller >= text.vmstart
|| (addr_t)caller >= text.vmstart + text.vmsize) { && (addr_t)caller < text.vmstart + text.vmsize) {
continue; // found the image
break;
} }
// found the image -- now find the symbol
for (uint32 i = 0; i < callerImage->symhash[1]; i++) {
Elf32_Sym& symbol = callerImage->syms[i];
if ((ELF32_ST_TYPE(symbol.st_info) != STT_FUNC)
|| symbol.st_value == 0) {
continue;
}
addr_t address = symbol.st_value
+ callerImage->regions[0].delta;
if ((addr_t)caller >= address
&& (addr_t)caller < address + symbol.st_size) {
callerSymbol = &symbol;
break;
}
}
break;
} }
if (callerSymbol != NULL) { if (callerImage != NULL) {
// found the caller -- now search the global scope until we find // found the caller -- now search the global scope until we find
// the next symbol // the next symbol
bool hitCallerImage = false;
set_image_flags_recursively(callerImage, RFLAG_USE_FOR_RESOLVING); set_image_flags_recursively(callerImage, RFLAG_USE_FOR_RESOLVING);
image_t* image = sLoadedImages.head; image_t* image = sLoadedImages.head;
for (; image != NULL; image = image->next) { for (; image != NULL; image = image->next) {
if (image != callerImage // skip the caller image
&& (image->type == B_ADD_ON_IMAGE if (image == callerImage) {
|| (image->flags hitCallerImage = true;
& (RTLD_GLOBAL | RFLAG_USE_FOR_RESOLVING)) == 0)) { continue;
}
// skip all images up to the caller image; also skip add-on
// images and those not marked above for resolution
if (!hitCallerImage || image->type == B_ADD_ON_IMAGE
|| (image->flags
& (RTLD_GLOBAL | RFLAG_USE_FOR_RESOLVING)) == 0) {
continue; continue;
} }
@@ -2535,26 +2524,18 @@ get_library_symbol(void* handle, void* caller, const char* symbolName,
if (symbol == NULL) if (symbol == NULL)
continue; continue;
if (callerSymbol == NULL) { // found the symbol
// already skipped the caller symbol -- so this is *_location = (void*)(symbol->st_value
// the one we're looking for + image->regions[0].delta);
*_location = (void*)(symbol->st_value int32 symbolType = B_SYMBOL_TYPE_TEXT;
+ image->regions[0].delta); patch_defined_symbol(image, symbolName, _location,
int32 symbolType = B_SYMBOL_TYPE_TEXT; &symbolType);
patch_defined_symbol(image, symbolName, _location, status = B_OK;
&symbolType); break;
status = B_OK;
break;
}
if (symbol == callerSymbol) {
// found the caller symbol
callerSymbol = NULL;
}
} }
clear_image_flags_recursively(callerImage, RFLAG_USE_FOR_RESOLVING); clear_image_flags_recursively(callerImage, RFLAG_USE_FOR_RESOLVING);
} }
} else { } else {
// breadth-first search in the given image and its dependencies // breadth-first search in the given image and its dependencies
image_t* inImage; image_t* inImage;