From 31926c3db54fe49b8940e4ef49a8a701a87ce443 Mon Sep 17 00:00:00 2001 From: Waldemar Kozaczuk Date: Fri, 17 May 2019 18:01:53 -0400 Subject: [PATCH] elf: handle new DT_RUNPATH This patch enhances dynamic linker to resolve dependent objects that rely on DT_RUNPATH entry to specify directories to search for. Some ELFs have both DT_RUNPATH and DT_RPATH in which case our linker disregards the latter per specification. For details read slide "Finding shared libraries at run time" under http://man7.org/training/download/shlib_dynlinker_slides.pdf. Fixes #1039 Signed-off-by: Waldemar Kozaczuk Message-Id: <20190517220153.22066-1-jwkozaczuk@gmail.com> --- core/elf.cc | 13 +++++++++++-- include/osv/elf.hh | 3 ++- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/core/elf.cc b/core/elf.cc index 552622cf26..fc2ee0c368 100644 --- a/core/elf.cc +++ b/core/elf.cc @@ -932,8 +932,17 @@ static std::string dirname(std::string path) void object::load_needed(std::vector>& loaded_objects) { std::vector rpath; - if (dynamic_exists(DT_RPATH)) { - std::string rpath_str = dynamic_str(DT_RPATH); + + std::string rpath_str; + // Prefer newer DT_RUNPATH + if (dynamic_exists(DT_RUNPATH)) { + rpath_str = dynamic_str(DT_RUNPATH); + // Otherwise fall back to older DT_RPATH + } else if (dynamic_exists(DT_RPATH)) { + rpath_str = dynamic_str(DT_RPATH); + } + + if (!rpath_str.empty()) { boost::replace_all(rpath_str, "$ORIGIN", dirname(_pathname)); boost::split(rpath, rpath_str, boost::is_any_of(":")); } diff --git a/include/osv/elf.hh b/include/osv/elf.hh index 8c7441b68a..894ea237f9 100644 --- a/include/osv/elf.hh +++ b/include/osv/elf.hh @@ -167,7 +167,7 @@ enum { DT_INIT = 12, // d_ptr Address of the initialization function. DT_FINI = 13, // d_ptr Address of the termination function. DT_SONAME = 14, // d_val The string table offset of the name of this shared object. - DT_RPATH = 15, // d_val The string table offset of a shared library search path string. + DT_RPATH = 15, // d_val The string table offset of a shared library search path string (deprecated) DT_SYMBOLIC = 16, // ignored The presence of this dynamic table entry modifies the // symbol resolution algorithm for references within the // library. Symbols defined within the library are used to @@ -191,6 +191,7 @@ enum { DT_FINI_ARRAY = 26, // d_ptr Pointer to an array of pointers to termination functions. DT_INIT_ARRAYSZ = 27, // d_val Size, in bytes, of the array of initialization functions. DT_FINI_ARRAYSZ = 28, // d_val Size, in bytes, of the array of termination functions. + DT_RUNPATH = 29, // d_val The string table offset of a shared library search path string. DT_FLAGS = 30, // value is various flags, bits from DF_*. DT_FLAGS_1 = 0x6ffffffb, // value is various flags, bits from DF_1_*. DT_LOOS = 0x60000000, // Defines a range of dynamic table tags that are reserved for