runtime_loader: dlopen() should respect RPATH of the loading module

Change-Id: Ic58edb53114dfff30cc7188957cd32508fa8bd48
Reviewed-on: https://review.haiku-os.org/c/haiku/+/3798
Reviewed-by: Jérôme Duval <jerome.duval@gmail.com>
This commit is contained in:
Jérôme Duval 2021-03-15 12:34:10 +01:00
parent a06fca85da
commit b2b83ad10f
5 changed files with 30 additions and 8 deletions

View File

@ -28,7 +28,8 @@ struct rld_export {
// runtime loader API export
image_id (*load_add_on)(char const *path, uint32 flags);
status_t (*unload_add_on)(image_id imageID);
image_id (*load_library)(char const *path, uint32 flags, void **_handle);
image_id (*load_library)(char const *path, uint32 flags, void* caller,
void **_handle);
status_t (*unload_library)(void* handle);
status_t (*get_image_symbol)(image_id imageID, char const *symbolName,
int32 symbolType, bool recursive, image_id *_inImage, void **_location);

View File

@ -25,7 +25,9 @@ void *
dlopen(char const *name, int mode)
{
void* handle;
image_id imageID = __gRuntimeLoader->load_library(name, mode, &handle);
void* caller = __builtin_return_address(0);
image_id imageID = __gRuntimeLoader->load_library(name, mode, caller,
&handle);
sStatus = imageID >= 0 ? B_OK : imageID;

View File

@ -600,11 +600,14 @@ err:
image_id
load_library(char const *path, uint32 flags, bool addOn, void** _handle)
load_library(char const *path, uint32 flags, bool addOn, void* caller,
void** _handle)
{
image_t *image = NULL;
image_type type = (addOn ? B_ADD_ON_IMAGE : B_LIBRARY_IMAGE);
status_t status;
const char* rpath = NULL;
const char* requestingObjectPath = NULL;
if (path == NULL && addOn)
return B_BAD_VALUE;
@ -634,9 +637,24 @@ load_library(char const *path, uint32 flags, bool addOn, void** _handle)
*_handle = image;
return image->id;
}
// First of all, find the caller image.
image_t* callerImage = get_loaded_images().head;
for (; callerImage != NULL; callerImage = callerImage->next) {
elf_region_t& text = callerImage->regions[0];
if ((addr_t)caller >= text.vmstart
&& (addr_t)caller < text.vmstart + text.vmsize) {
// found the image
break;
}
}
if (callerImage != NULL) {
rpath = find_dt_rpath(callerImage);
requestingObjectPath = callerImage->path;
}
}
status = load_image(path, type, NULL, NULL, &image);
status = load_image(path, type, rpath, requestingObjectPath, &image);
if (status < B_OK) {
KTRACE("rld: load_library(\"%s\") failed to load container: %s", path,
strerror(status));

View File

@ -18,7 +18,7 @@ static image_id
export_load_add_on(char const *name, uint32 flags)
{
void* handle;
return load_library(name, flags, true, &handle);
return load_library(name, flags, true, NULL, &handle);
}
@ -30,9 +30,10 @@ export_unload_add_on(image_id id)
static image_id
export_load_library(char const *name, uint32 flags, void **_handle)
export_load_library(char const *name, uint32 flags, void* caller,
void **_handle)
{
return load_library(name, flags, false, _handle);
return load_library(name, flags, false, caller, _handle);
}

View File

@ -72,7 +72,7 @@ status_t get_executable_architecture(const char* path,
void terminate_program(void);
image_id load_program(char const* path, void** entry);
image_id load_library(char const* path, uint32 flags, bool addOn,
void** _handle);
void* caller, void** _handle);
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);