diff --git a/headers/private/runtime_loader/runtime_loader.h b/headers/private/runtime_loader/runtime_loader.h index 6fa83bbc9d..ab4c3b2030 100644 --- a/headers/private/runtime_loader/runtime_loader.h +++ b/headers/private/runtime_loader/runtime_loader.h @@ -38,8 +38,8 @@ struct rld_export { char *symbolName, int32 *nameLength, int32 *symbolType, void **_location); status_t (*get_nearest_symbol_at_address)(void* address, - image_id* _imageID, char** _imagePath, char** _symbolName, - int32* _type, void** _location); + image_id* _imageID, char** _imagePath, char** _imageName, + char** _symbolName, int32* _type, void** _location, bool* _exactMatch); status_t (*test_executable)(const char *path, char *interpreter); status_t (*get_executable_architecture)(const char *path, const char** _architecture); diff --git a/src/system/libroot/posix/dlfcn.c b/src/system/libroot/posix/dlfcn.c index d85c649364..58fb161f3d 100644 --- a/src/system/libroot/posix/dlfcn.c +++ b/src/system/libroot/posix/dlfcn.c @@ -81,7 +81,7 @@ dladdr(void *address, Dl_info *info) image_info imageInfo; sStatus = __gRuntimeLoader->get_nearest_symbol_at_address(address, &image, - &imagePath, &symbolName, NULL, &location); + &imagePath, NULL, &symbolName, NULL, &location, NULL); if (sStatus != B_OK) return 0; diff --git a/src/system/runtime_loader/elf.cpp b/src/system/runtime_loader/elf.cpp index 37ccc5e239..6d30bbb7f2 100644 --- a/src/system/runtime_loader/elf.cpp +++ b/src/system/runtime_loader/elf.cpp @@ -713,7 +713,8 @@ out: status_t get_nearest_symbol_at_address(void* address, image_id* _imageID, - char** _imagePath, char** _symbolName, int32* _type, void** _location) + char** _imagePath, char** _imageName, char** _symbolName, int32* _type, + void** _location, bool* _exactMatch) { rld_lock(); @@ -723,11 +724,11 @@ get_nearest_symbol_at_address(void* address, image_id* _imageID, return B_BAD_VALUE; } + bool exactMatch = false; elf_sym* foundSymbol = NULL; addr_t foundLocation = (addr_t)NULL; - bool found = false; - for (uint32 i = 0; i < HASHTABSIZE(image) && !found; i++) { + for (uint32 i = 0; i < HASHTABSIZE(image) && !exactMatch; i++) { for (int32 j = HASHBUCKETS(image)[i]; j != STN_UNDEF; j = HASHCHAINS(image)[j]) { elf_sym *symbol = &image->syms[j]; @@ -738,8 +739,8 @@ get_nearest_symbol_at_address(void* address, image_id* _imageID, foundLocation = location; // jump out if we have an exact match - if (foundLocation == (addr_t)address) { - found = true; + if (location + symbol->st_size > (addr_t)address) { + exactMatch = true; break; } } @@ -750,6 +751,10 @@ get_nearest_symbol_at_address(void* address, image_id* _imageID, *_imageID = image->id; if (_imagePath != NULL) *_imagePath = image->path; + if (_imageName != NULL) + *_imageName = image->name; + if (_exactMatch != NULL) + *_exactMatch = exactMatch; if (foundSymbol != NULL) { *_symbolName = SYMNAME(image, foundSymbol); diff --git a/src/system/runtime_loader/runtime_loader_private.h b/src/system/runtime_loader/runtime_loader_private.h index 7774e1297c..be40233378 100644 --- a/src/system/runtime_loader/runtime_loader_private.h +++ b/src/system/runtime_loader/runtime_loader_private.h @@ -68,7 +68,8 @@ status_t unload_library(void* handle, image_id imageID, bool addOn); status_t get_nth_symbol(image_id imageID, int32 num, char* nameBuffer, int32* _nameLength, int32* _type, void** _location); status_t get_nearest_symbol_at_address(void* address, image_id* _imageID, - char** _imagePath, char** _symbolName, int32* _type, void** _location); + char** _imagePath, char** _imageName, char** _symbolName, int32* _type, + void** _location, bool* _exactMatch); status_t get_symbol(image_id imageID, char const* symbolName, int32 symbolType, bool recursive, image_id* _inImage, void** _location); status_t get_library_symbol(void* handle, void* caller, const char* symbolName,