From ebdc1d480e809b6ab0b1ad58822a21395706be25 Mon Sep 17 00:00:00 2001 From: Michael Lotz Date: Sat, 11 Apr 2015 11:00:07 +0200 Subject: [PATCH] runtime_loader: Add imageName and exactMatch to symbol lookup. Extend the get_nearest_symbol_at_address() private runtime_loader export to include imageName and exactMatch arguments. The imageName holds the SONAME of the image, if available, so cannot neccessarily be extracted from the image path. Whether or not there was an exact match, i.e. the symbol with its size contains the address, is now returned in exactMatch. --- headers/private/runtime_loader/runtime_loader.h | 4 ++-- src/system/libroot/posix/dlfcn.c | 2 +- src/system/runtime_loader/elf.cpp | 15 ++++++++++----- .../runtime_loader/runtime_loader_private.h | 3 ++- 4 files changed, 15 insertions(+), 9 deletions(-) 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,