runtime_loader: Implement DT_RUNPATH
DT_RUNPATH is generated by the linker instead of DT_RPATH when using --enable-new-dtags It seems to be the default when using ld.lld Normally one difference is LD_LIBRARY_PATH is checked before DT_RUNPATH (and not with DT_RPATH), but we don't check LD_LIBRARY_PATH at the moment. Checking LIBRARY_PATH isn't an option, because runtime_loader dosesn't use default paths, test suites would define LIBRARY_PATH empty. Tested with tcpdump build_matrix.sh script, with clang 17, local libpcap, which requires --disable-new-dtags on r1beta4. Change-Id: Iacccde8d20e25ad14c5c548dd8832ea32b67e228 Reviewed-on: https://review.haiku-os.org/c/haiku/+/7539 Reviewed-by: waddlesplash <waddlesplash@gmail.com> Tested-by: Commit checker robot <no-reply+buildbot@haiku-os.org>
This commit is contained in:
parent
76142a9377
commit
43d1a0dc3c
@ -54,13 +54,13 @@ static recursive_lock sLock = RECURSIVE_LOCK_INITIALIZER(kLockName);
|
||||
|
||||
|
||||
static const char *
|
||||
find_dt_rpath(image_t *image)
|
||||
find_dt_string(image_t *image, int32 d_tag)
|
||||
{
|
||||
int i;
|
||||
elf_dyn *d = (elf_dyn *)image->dynamic_ptr;
|
||||
|
||||
for (i = 0; d[i].d_tag != DT_NULL; i++) {
|
||||
if (d[i].d_tag == DT_RPATH)
|
||||
if (d[i].d_tag == d_tag)
|
||||
return STRING(image, d[i].d_un.d_val);
|
||||
}
|
||||
|
||||
@ -68,6 +68,20 @@ find_dt_rpath(image_t *image)
|
||||
}
|
||||
|
||||
|
||||
static const char *
|
||||
find_dt_rpath(image_t *image)
|
||||
{
|
||||
return find_dt_string(image, DT_RPATH);
|
||||
}
|
||||
|
||||
|
||||
static const char *
|
||||
find_dt_runpath(image_t *image)
|
||||
{
|
||||
return find_dt_string(image, DT_RUNPATH);
|
||||
}
|
||||
|
||||
|
||||
image_id
|
||||
preload_image(char const* path, image_t **image)
|
||||
{
|
||||
@ -76,7 +90,7 @@ preload_image(char const* path, image_t **image)
|
||||
|
||||
KTRACE("rld: preload_image(\"%s\")", path);
|
||||
|
||||
status_t status = load_image(path, B_LIBRARY_IMAGE, NULL, NULL, image);
|
||||
status_t status = load_image(path, B_LIBRARY_IMAGE, NULL, NULL, NULL, image);
|
||||
if (status < B_OK) {
|
||||
KTRACE("rld: preload_image(\"%s\") failed to load container: %s", path,
|
||||
strerror(status));
|
||||
@ -148,8 +162,7 @@ load_immediate_dependencies(image_t *image, bool preload)
|
||||
bool reportErrors = report_errors();
|
||||
status_t status = B_OK;
|
||||
uint32 i, j;
|
||||
const char *rpath;
|
||||
|
||||
const char *rpath = NULL, *runpath;
|
||||
if (!d || (image->flags & RFLAG_DEPENDENCIES_LOADED))
|
||||
return B_OK;
|
||||
|
||||
@ -177,7 +190,9 @@ load_immediate_dependencies(image_t *image, bool preload)
|
||||
memset(image->needed, 0, image->num_needed * sizeof(image_t *));
|
||||
if (preload)
|
||||
preload_images(image->needed);
|
||||
rpath = find_dt_rpath(image);
|
||||
runpath = find_dt_runpath(image);
|
||||
if (runpath == NULL)
|
||||
rpath = find_dt_rpath(image);
|
||||
|
||||
for (i = 0, j = preloadedCount; d[i].d_tag != DT_NULL; i++) {
|
||||
switch (d[i].d_tag) {
|
||||
@ -187,7 +202,7 @@ load_immediate_dependencies(image_t *image, bool preload)
|
||||
const char *name = STRING(image, neededOffset);
|
||||
|
||||
status_t loadStatus = load_image(name, B_LIBRARY_IMAGE,
|
||||
rpath, image->path, &image->needed[j]);
|
||||
rpath, runpath, image->path, &image->needed[j]);
|
||||
if (loadStatus < B_OK) {
|
||||
status = loadStatus;
|
||||
// correct error code in case the file could not been found
|
||||
@ -433,7 +448,7 @@ preload_addon(char const* path)
|
||||
KTRACE("rld: preload_addon(\"%s\")", path);
|
||||
|
||||
image_t *image = NULL;
|
||||
status_t status = load_image(path, B_LIBRARY_IMAGE, NULL, NULL, &image);
|
||||
status_t status = load_image(path, B_LIBRARY_IMAGE, NULL, NULL, NULL, &image);
|
||||
if (status < B_OK) {
|
||||
KTRACE("rld: preload_addon(\"%s\") failed to load container: %s", path,
|
||||
strerror(status));
|
||||
@ -535,7 +550,7 @@ load_program(char const *path, void **_entry)
|
||||
|
||||
TRACE(("rld: load %s\n", path));
|
||||
|
||||
status = load_image(path, B_APP_IMAGE, NULL, NULL, &gProgramImage);
|
||||
status = load_image(path, B_APP_IMAGE, NULL, NULL, NULL, &gProgramImage);
|
||||
if (status < B_OK)
|
||||
goto err;
|
||||
|
||||
@ -606,7 +621,7 @@ load_library(char const *path, uint32 flags, bool addOn, void* caller,
|
||||
image_t *image = NULL;
|
||||
image_type type = (addOn ? B_ADD_ON_IMAGE : B_LIBRARY_IMAGE);
|
||||
status_t status;
|
||||
const char* rpath = NULL;
|
||||
const char* rpath = NULL, *runpath = NULL;
|
||||
const char* requestingObjectPath = NULL;
|
||||
|
||||
if (path == NULL && addOn)
|
||||
@ -649,12 +664,14 @@ load_library(char const *path, uint32 flags, bool addOn, void* caller,
|
||||
}
|
||||
}
|
||||
if (callerImage != NULL) {
|
||||
rpath = find_dt_rpath(callerImage);
|
||||
runpath = find_dt_runpath(callerImage);
|
||||
if (runpath == NULL)
|
||||
rpath = find_dt_rpath(callerImage);
|
||||
requestingObjectPath = callerImage->path;
|
||||
}
|
||||
}
|
||||
|
||||
status = load_image(path, type, rpath, requestingObjectPath, &image);
|
||||
status = load_image(path, type, rpath, runpath, requestingObjectPath, &image);
|
||||
if (status < B_OK) {
|
||||
KTRACE("rld: load_library(\"%s\") failed to load container: %s", path,
|
||||
strerror(status));
|
||||
|
@ -389,7 +389,6 @@ parse_dynamic_segment(image_t* image)
|
||||
// DT_SYMENT: The size of a symbol table entry.
|
||||
// DT_PLTREL: The type of the PLT relocation entries (DT_JMPREL).
|
||||
// DT_BIND_NOW/DF_BIND_NOW: No lazy binding allowed.
|
||||
// DT_RUNPATH: Library search path (supersedes DT_RPATH).
|
||||
// DT_TEXTREL/DF_TEXTREL: Indicates whether text relocations are
|
||||
// required (for optimization purposes only).
|
||||
}
|
||||
@ -491,7 +490,7 @@ parse_elf64_header(Elf64_Ehdr* eheader, int32* _pheaderSize,
|
||||
|
||||
|
||||
status_t
|
||||
load_image(char const* name, image_type type, const char* rpath,
|
||||
load_image(char const* name, image_type type, const char* rpath, const char* runpath,
|
||||
const char* requestingObjectPath, image_t** _image)
|
||||
{
|
||||
int32 pheaderSize, sheaderSize;
|
||||
@ -523,19 +522,20 @@ load_image(char const* name, image_type type, const char* rpath,
|
||||
if (found) {
|
||||
atomic_add(&found->ref_count, 1);
|
||||
*_image = found;
|
||||
KTRACE("rld: load_container(\"%s\", type: %d, rpath: \"%s\") "
|
||||
"already loaded", name, type, rpath);
|
||||
KTRACE("rld: load_container(\"%s\", type: %d, %s: \"%s\") "
|
||||
"already loaded", name, type,
|
||||
runpath != NULL ? "runpath" : "rpath", runpath != NULL ? runpath : rpath);
|
||||
return B_OK;
|
||||
}
|
||||
}
|
||||
|
||||
KTRACE("rld: load_container(\"%s\", type: %d, rpath: \"%s\")", name, type,
|
||||
rpath);
|
||||
KTRACE("rld: load_container(\"%s\", type: %d, %s: \"%s\")", name, type,
|
||||
runpath != NULL ? "runpath" : "rpath", runpath != NULL ? runpath : rpath);
|
||||
|
||||
strlcpy(path, name, sizeof(path));
|
||||
|
||||
// find and open the file
|
||||
fd = open_executable(path, type, rpath, get_program_path(),
|
||||
fd = open_executable(path, type, rpath, runpath, get_program_path(),
|
||||
requestingObjectPath, sSearchPathSubDir);
|
||||
if (fd < 0) {
|
||||
FATAL("Cannot open file %s (needed by %s): %s\n", name, requestingObjectPath, strerror(fd));
|
||||
|
@ -20,7 +20,7 @@ status_t parse_elf64_header(Elf64_Ehdr* eheader, int32* _pheaderSize,
|
||||
#endif
|
||||
#endif
|
||||
status_t load_image(char const* name, image_type type, const char* rpath,
|
||||
const char* requestingObjectPath, image_t** _image);
|
||||
const char* runpath, const char* requestingObjectPath, image_t** _image);
|
||||
|
||||
|
||||
#endif // ELF_LOAD_IMAGE_H
|
||||
|
@ -299,7 +299,7 @@ search_executable_in_path_list(const char *name, const char *pathList,
|
||||
|
||||
|
||||
int
|
||||
open_executable(char *name, image_type type, const char *rpath,
|
||||
open_executable(char *name, image_type type, const char *rpath, const char* runpath,
|
||||
const char *programPath, const char *requestingObjectPath,
|
||||
const char *abiSpecificSubDir)
|
||||
{
|
||||
@ -328,14 +328,17 @@ open_executable(char *name, image_type type, const char *rpath,
|
||||
}
|
||||
}
|
||||
|
||||
// try rpath (DT_RPATH)
|
||||
if (rpath != NULL) {
|
||||
// try runpath or rpath (DT_RUNPATH or DT_RPATH)
|
||||
const char* pathString = runpath;
|
||||
if (pathString == NULL)
|
||||
pathString = rpath;
|
||||
if (pathString != NULL) {
|
||||
// It consists of a colon-separated search path list. Optionally a
|
||||
// second search path list follows, separated from the first by a
|
||||
// semicolon.
|
||||
const char *semicolon = strchr(rpath, ';');
|
||||
const char *firstList = (semicolon ? rpath : NULL);
|
||||
const char *secondList = (semicolon ? semicolon + 1 : rpath);
|
||||
const char *firstList = (semicolon ? pathString : NULL);
|
||||
const char *secondList = (semicolon ? semicolon + 1 : pathString);
|
||||
// If there is no ';', we set only secondList to simplify things.
|
||||
if (firstList) {
|
||||
fd = search_executable_in_path_list(name, firstList,
|
||||
@ -404,7 +407,7 @@ test_executable(const char *name, char *invoker)
|
||||
|
||||
strlcpy(path, name, sizeof(path));
|
||||
|
||||
fd = open_executable(path, B_APP_IMAGE, NULL, NULL, NULL, NULL);
|
||||
fd = open_executable(path, B_APP_IMAGE, NULL, NULL, NULL, NULL, NULL);
|
||||
if (fd < B_OK)
|
||||
return fd;
|
||||
|
||||
|
@ -63,7 +63,7 @@ extern "C" {
|
||||
|
||||
int runtime_loader(void* arg, void* commpage);
|
||||
int open_executable(char* name, image_type type, const char* rpath,
|
||||
const char* programPath, const char* requestingObjectPath,
|
||||
const char* runpath, const char* programPath, const char* requestingObjectPath,
|
||||
const char* abiSpecificSubDir);
|
||||
status_t test_executable(const char* path, char* interpreter);
|
||||
status_t get_executable_architecture(const char* path,
|
||||
|
Loading…
Reference in New Issue
Block a user