This is the mail archive of the libc-help@sourceware.org mailing list for the glibc project.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Other format: | [Raw text] |
Hello, Recently I started the migration from DT_RPATH to DT_RUNPATH in our distro in order to make the LD_LIBRARY_PATH work the right way, and detected that these two tags are processed differently in RTLD. We have a loader which opens executables (pie ones) with dlopen() and then calls main(). This approach allows to speedup running application with large number library dependencies. Usual application has the following structure: app/ bin/app lib/library.so During the launch procedure 'bin/app' is opened by loader and executed through the dlopen(). In order to load the application-specific library.so the directory is changed to app/lib and 'loader' has DT_RPATH set to ":" to allow loading from current working directory. After changing DT_RPATH to DT_RUNPATH the mechanism stopped working. I investigated the elf/dl-load.c and found that 'main_map' and dependent objects rpaths are only checked in case of DT_RPATH tag. Can someone tell if this behavior is intended or not? I've prepared a patch to process these places for DT_RUNPATH and resolved the launcher issue. The patch and reprocase are attached. Best Regards, Vyacheslav Barinov
>From e3579769f447e7222a08e031b2f678d25bb3ff52 Mon Sep 17 00:00:00 2001 From: Slava Barinov <v.barinov@samsung.com> Date: Wed, 28 Jun 2017 11:49:56 +0300 Subject: [PATCH] elf: Treat DT_RUNPATH exactly like DT_RPATH in rtld * elf/dl-load.c: Add handling of DT_RUNPATH for dependent objects and executable itself. Now situations loader.elf[RPATH=:] -> app.elf -> library.so loader.elf[RUNPATH=:] -> app.elf -> library.so are processed equally. Signed-off-by: Slava Barinov <v.barinov@samsung.com> --- elf/dl-load.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/elf/dl-load.c b/elf/dl-load.c index c0d6249373..bd33b5f587 100644 --- a/elf/dl-load.c +++ b/elf/dl-load.c @@ -2072,6 +2072,40 @@ _dl_map_object (struct link_map *loader, const char *name, loader ?: GL(dl_ns)[LM_ID_BASE]._ns_loaded, LA_SER_LIBPATH, &found_other_class); + if (loader != NULL && loader->l_info[DT_RUNPATH] != NULL) + { + /* This is the executable's map (if there is one). Make sure that + we do not look at it twice. */ + struct link_map *main_map = GL(dl_ns)[LM_ID_BASE]._ns_loaded; + bool did_main_map = false; + + /* First try the DT_RUNPATH of the dependent object that caused NAME + to be loaded. Then that object's dependent, and on up. */ + for (l = loader; l; l = l->l_loader) + if (cache_rpath (l, &l->l_runpath_dirs, DT_RUNPATH, "RUNPATH")) + { + fd = open_path (name, namelen, mode, + &l->l_runpath_dirs, + &realname, &fb, loader, LA_SER_RUNPATH, + &found_other_class); + if (fd != -1) + break; + + did_main_map |= l == main_map; + } + + /* If dynamically linked, try the DT_RUNPATH of the executable + itself. NB: we do this for lookups in any namespace. */ + if (fd == -1 && !did_main_map + && main_map != NULL && main_map->l_type != lt_loaded + && cache_rpath (main_map, &main_map->l_runpath_dirs, DT_RUNPATH, + "RUNPATH")) + fd = open_path (name, namelen, mode, + &main_map->l_runpath_dirs, + &realname, &fb, loader ?: main_map, LA_SER_RUNPATH, + &found_other_class); + } + /* Look at the RUNPATH information for this binary. */ if (fd == -1 && loader != NULL && cache_rpath (loader, &loader->l_runpath_dirs, -- 2.13.1
Attachment:
dlopen-test.tar.xz
Description: application/xz
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |