hrev53097 adds 1 changeset to branch 'master'
old head: 888652929c4c95ab2d639a85ffa2691a6e6df81f
new head: 35fa85dba5398fd6f00a25f2ec1afb9cba4d15ed
overview:
https://git.haiku-os.org/haiku/log/?qt=range&q=35fa85dba539+%5E888652929c4c
----------------------------------------------------------------------------
35fa85dba539: runtime_loader: load "LD_PRELOAD" libraries after the executable.
This makes the behavior more standard, is still to be used with
libroot_debug.so
for instance.
The old behavior is obtained with "LD_PRELOAD_ADDONS"; in fact a
runtime_loader add-on
needs to be entirely loaded before the executable to be effective. To be used
with
libltrace_stub.so for instance.
Change-Id: I8536c5b8873f975405bea9eb4e2b92febabfc78a
Reviewed-on: https://review.haiku-os.org/c/1409
Reviewed-by: Jérôme Duval <jerome.duval@xxxxxxxxx>
[ Jérôme Duval <jerome.duval@xxxxxxxxx> ]
----------------------------------------------------------------------------
Revision: hrev53097
Commit: 35fa85dba5398fd6f00a25f2ec1afb9cba4d15ed
URL: https://git.haiku-os.org/haiku/commit/?id=35fa85dba539
Author: Jérôme Duval <jerome.duval@xxxxxxxxx>
Date: Thu Mar 14 19:37:06 2019 UTC
----------------------------------------------------------------------------
1 file changed, 104 insertions(+), 23 deletions(-)
src/system/runtime_loader/elf.cpp | 127 ++++++++++++++++++++++++++++------
----------------------------------------------------------------------------
diff --git a/src/system/runtime_loader/elf.cpp
b/src/system/runtime_loader/elf.cpp
index 778064a8ef..916ed445cf 100644
--- a/src/system/runtime_loader/elf.cpp
+++ b/src/system/runtime_loader/elf.cpp
@@ -47,8 +47,8 @@ typedef void (*initfini_array_function)();
bool gProgramLoaded = false;
image_t* gProgramImage;
-static image_t** sPreloadedImages = NULL;
-static uint32 sPreloadedImageCount = 0;
+static image_t** sPreloadedAddons = NULL;
+static uint32 sPreloadedAddonCount = 0;
static recursive_lock sLock = RECURSIVE_LOCK_INITIALIZER(kLockName);
@@ -68,8 +68,81 @@ find_dt_rpath(image_t *image)
}
+image_id
+preload_image(char const* path, image_t **image)
+{
+ if (path == NULL)
+ return B_BAD_VALUE;
+
+ KTRACE("rld: preload_image(\"%s\")", path);
+
+ status_t status = load_image(path, B_LIBRARY_IMAGE, NULL, NULL, image);
+ if (status < B_OK) {
+ KTRACE("rld: preload_image(\"%s\") failed to load container:
%s", path,
+ strerror(status));
+ return status;
+ }
+
+ if ((*image)->find_undefined_symbol == NULL)
+ (*image)->find_undefined_symbol = find_undefined_symbol_global;
+
+ KTRACE("rld: preload_image(\"%s\") done: id: %" B_PRId32, path,
(*image)->id);
+
+ return (*image)->id;
+}
+
+
+static void
+preload_images(image_t **image, int32 *_count = NULL)
+{
+ const char* imagePaths = getenv("LD_PRELOAD");
+ if (imagePaths == NULL) {
+ if (_count != NULL)
+ *_count = 0;
+ return;
+ }
+
+ int32 count = 0;
+
+ while (*imagePaths != '\0') {
+ // find begin of image path
+ while (*imagePaths != '\0' && isspace(*imagePaths))
+ imagePaths++;
+
+ if (*imagePaths == '\0')
+ break;
+
+ // find end of image path
+ const char* imagePath = imagePaths;
+ while (*imagePaths != '\0' && !isspace(*imagePaths))
+ imagePaths++;
+
+ // extract the path
+ char path[B_PATH_NAME_LENGTH];
+ size_t pathLen = imagePaths - imagePath;
+ if (pathLen > sizeof(path) - 1)
+ continue;
+
+ if (image == NULL) {
+ count++;
+ continue;
+ }
+ memcpy(path, imagePath, pathLen);
+ path[pathLen] = '\0';
+
+ // load the image
+ preload_image(path, &image[count++]);
+ }
+
+ KTRACE("rld: preload_images count: %d", count);
+
+ if (_count != NULL)
+ *_count = count;
+}
+
+
static status_t
-load_immediate_dependencies(image_t *image)
+load_immediate_dependencies(image_t *image, bool preload)
{
elf_dyn *d = (elf_dyn *)image->dynamic_ptr;
bool reportErrors = report_errors();
@@ -82,6 +155,11 @@ load_immediate_dependencies(image_t *image)
image->flags |= RFLAG_DEPENDENCIES_LOADED;
+ int32 preloadedCount = 0;
+ if (preload) {
+ preload_images(NULL, &preloadedCount);
+ image->num_needed += preloadedCount;
+ }
if (image->num_needed == 0)
return B_OK;
@@ -97,9 +175,11 @@ load_immediate_dependencies(image_t *image)
}
memset(image->needed, 0, image->num_needed * sizeof(image_t *));
+ if (preload)
+ preload_images(image->needed);
rpath = find_dt_rpath(image);
- for (i = 0, j = 0; d[i].d_tag != DT_NULL; i++) {
+ for (i = 0, j = preloadedCount; d[i].d_tag != DT_NULL; i++) {
switch (d[i].d_tag) {
case DT_NEEDED:
{
@@ -159,14 +239,15 @@ load_immediate_dependencies(image_t *image)
static status_t
-load_dependencies(image_t* image)
+load_dependencies(image_t* image, bool preload = false)
{
// load dependencies (breadth-first)
for (image_t* otherImage = image; otherImage != NULL;
otherImage = otherImage->next) {
- status_t status = load_immediate_dependencies(otherImage);
+ status_t status = load_immediate_dependencies(otherImage,
preload);
if (status != B_OK)
return status;
+ preload = false;
}
// Check the needed versions for the given image and all newly loaded
@@ -297,34 +378,34 @@ inject_runtime_loader_api(image_t* rootImage)
static status_t
-add_preloaded_image(image_t* image)
+add_preloaded_addon(image_t* image)
{
// We realloc() everytime -- not particularly efficient, but good
enough for
- // small number of preloaded images.
- image_t** newArray = (image_t**)realloc(sPreloadedImages,
- sizeof(image_t*) * (sPreloadedImageCount + 1));
+ // small number of preloaded addons.
+ image_t** newArray = (image_t**)realloc(sPreloadedAddons,
+ sizeof(image_t*) * (sPreloadedAddonCount + 1));
if (newArray == NULL)
return B_NO_MEMORY;
- sPreloadedImages = newArray;
- newArray[sPreloadedImageCount++] = image;
+ sPreloadedAddons = newArray;
+ newArray[sPreloadedAddonCount++] = image;
return B_OK;
}
image_id
-preload_image(char const* path)
+preload_addon(char const* path)
{
if (path == NULL)
return B_BAD_VALUE;
- KTRACE("rld: preload_image(\"%s\")", path);
+ KTRACE("rld: preload_addon(\"%s\")", path);
image_t *image = NULL;
status_t status = load_image(path, B_LIBRARY_IMAGE, NULL, NULL, &image);
if (status < B_OK) {
- KTRACE("rld: preload_image(\"%s\") failed to load container:
%s", path,
+ KTRACE("rld: preload_addon(\"%s\") failed to load container:
%s", path,
strerror(status));
return status;
}
@@ -342,7 +423,7 @@ preload_image(char const* path)
if (status < B_OK)
goto err;
- status = add_preloaded_image(image);
+ status = add_preloaded_addon(image);
if (status < B_OK)
goto err;
@@ -359,12 +440,12 @@ preload_image(char const* path)
add_add_on(image, addOnStruct);
}
- KTRACE("rld: preload_image(\"%s\") done: id: %" B_PRId32, path,
image->id);
+ KTRACE("rld: preload_addon(\"%s\") done: id: %" B_PRId32, path,
image->id);
return image->id;
err:
- KTRACE("rld: preload_image(\"%s\") failed: %s", path, strerror(status));
+ KTRACE("rld: preload_addon(\"%s\") failed: %s", path, strerror(status));
dequeue_loaded_image(image);
delete_image(image);
@@ -373,9 +454,9 @@ err:
static void
-preload_images()
+preload_addons()
{
- const char* imagePaths = getenv("LD_PRELOAD");
+ const char* imagePaths = getenv("LD_PRELOAD_ADDONS");
if (imagePaths == NULL)
return;
@@ -401,7 +482,7 @@ preload_images()
path[pathLen] = '\0';
// load the image
- preload_image(path);
+ preload_addon(path);
}
}
@@ -420,7 +501,7 @@ load_program(char const *path, void **_entry)
RecursiveLocker _(sLock);
// for now, just do stupid simple global locking
- preload_images();
+ preload_addons();
TRACE(("rld: load %s\n", path));
@@ -431,7 +512,7 @@ load_program(char const *path, void **_entry)
if (gProgramImage->find_undefined_symbol == NULL)
gProgramImage->find_undefined_symbol =
find_undefined_symbol_global;
- status = load_dependencies(gProgramImage);
+ status = load_dependencies(gProgramImage, true);
if (status < B_OK)
goto err;