diff --git a/headers/private/libroot/image_private.h b/headers/private/libroot/image_private.h new file mode 100644 index 0000000000..cf0080e6ad --- /dev/null +++ b/headers/private/libroot/image_private.h @@ -0,0 +1,21 @@ +/* + * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. + * Distributed under the terms of the MIT License. + */ +#ifndef _LIBROOT_IMAGE_PRIVATE_H +#define _LIBROOT_IMAGE_PRIVATE_H + +#include + +#include + + +__BEGIN_DECLS + +status_t get_image_symbol_etc(image_id id, char const* symbolName, + int32 symbolType, bool recursive, image_id* _inImage, void** _location); + +__END_DECLS + + +#endif // _LIBROOT_IMAGE_PRIVATE_H diff --git a/headers/private/runtime_loader/runtime_loader.h b/headers/private/runtime_loader/runtime_loader.h index da3005cd0b..ca57fcf25f 100644 --- a/headers/private/runtime_loader/runtime_loader.h +++ b/headers/private/runtime_loader/runtime_loader.h @@ -28,7 +28,7 @@ struct rld_export { image_id (*load_library)(char const *path, uint32 flags, void **_handle); status_t (*unload_library)(void* handle); status_t (*get_image_symbol)(image_id imageID, char const *symbolName, - int32 symbolType, void **_location); + int32 symbolType, bool recursive, image_id *_inImage, void **_location); status_t (*get_library_symbol)(void* handle, void* caller, const char* symbolName, void **_location); status_t (*get_nth_image_symbol)(image_id imageID, int32 num, char *symbolName, diff --git a/src/system/libroot/os/image.cpp b/src/system/libroot/os/image.cpp index d330382b4d..e338469542 100644 --- a/src/system/libroot/os/image.cpp +++ b/src/system/libroot/os/image.cpp @@ -3,18 +3,19 @@ * Distributed under the terms of the MIT License. */ +#include +#include + +#include +#include + +#include #include #include #include #include -#include -#include - -#include -#include - thread_id load_image(int32 argCount, const char **args, const char **environ) @@ -81,9 +82,20 @@ unload_add_on(image_id id) status_t -get_image_symbol(image_id id, char const *symbolName, int32 symbolType, void **_location) +get_image_symbol(image_id id, char const *symbolName, int32 symbolType, + void **_location) { - return __gRuntimeLoader->get_image_symbol(id, symbolName, symbolType, _location); + return __gRuntimeLoader->get_image_symbol(id, symbolName, symbolType, + false, NULL, _location); +} + + +status_t +get_image_symbol_etc(image_id id, char const *symbolName, int32 symbolType, + bool recursive, image_id *_inImage, void **_location) +{ + return __gRuntimeLoader->get_image_symbol(id, symbolName, symbolType, + recursive, _inImage, _location); } diff --git a/src/system/runtime_loader/elf.cpp b/src/system/runtime_loader/elf.cpp index 6ba5e55194..dd672bdbc4 100644 --- a/src/system/runtime_loader/elf.cpp +++ b/src/system/runtime_loader/elf.cpp @@ -2421,7 +2421,7 @@ out: status_t get_symbol(image_id imageID, char const *symbolName, int32 symbolType, - void **_location) + bool recursive, image_id *_inImage, void **_location) { status_t status = B_OK; image_t *image; @@ -2436,9 +2436,17 @@ get_symbol(image_id imageID, char const *symbolName, int32 symbolType, // get the image from those who have been already initialized image = find_loaded_image_by_id(imageID); - if (image != NULL) - status = find_symbol(image, symbolName, symbolType, _location); - else + if (image != NULL) { + if (recursive) { + // breadth-first search in the given image and its dependencies + status = find_symbol_breadth_first(image, symbolName, symbolType, + &image, _location); + } else + status = find_symbol(image, symbolName, symbolType, _location); + + if (status == B_OK && _inImage != NULL) + *_inImage = image->id; + } else status = B_BAD_IMAGE_ID; rld_unlock(); diff --git a/src/system/runtime_loader/runtime_loader_private.h b/src/system/runtime_loader/runtime_loader_private.h index 163b46e135..0ea8d82d09 100644 --- a/src/system/runtime_loader/runtime_loader_private.h +++ b/src/system/runtime_loader/runtime_loader_private.h @@ -35,7 +35,7 @@ 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_symbol(image_id imageID, char const *symbolName, int32 symbolType, - void **_location); + bool recursive, image_id *_inImage, void **_location); status_t get_library_symbol(void* handle, void* caller, const char* symbolName, void **_location); status_t get_next_image_dependency(image_id id, uint32 *cookie,