From: Zhiting Zhu <[email protected]> Committer: Nadav Har'El <[email protected]> Branch: master
Implement RTLD_NEXT Signed-off-by: Zhiting Zhu <[email protected]> Message-Id: <[email protected]> --- diff --git a/core/elf.cc b/core/elf.cc --- a/core/elf.cc +++ b/core/elf.cc @@ -42,6 +42,7 @@ TRACEPOINT(trace_elf_load, "%s", const char *); TRACEPOINT(trace_elf_unload, "%s", const char *); TRACEPOINT(trace_elf_lookup, "%s", const char *); +TRACEPOINT(trace_elf_lookup_next, "%s", const char *); TRACEPOINT(trace_elf_lookup_addr, "%p", const void *); extern void* elf_start; @@ -1557,6 +1558,38 @@ symbol_module program::lookup(const char* name, object* seeker) return ret; } +symbol_module program::lookup_next(const char* name, const void* retaddr) +{ + trace_elf_lookup_next(name); + symbol_module ret(nullptr,nullptr); + if (retaddr == nullptr) { + return ret; + } + with_modules([&](const elf::program::modules_list &ml) + { + auto start = ml.objects.end(); + for (auto it = ml.objects.begin(), end = ml.objects.end(); it != end; ++it) { + auto module = *it; + if (module->contains_addr(retaddr)) { + start = it; + break; + } + } + if (start == ml.objects.end()) { + return; + } + start = ++start; + for (auto it = start, end = ml.objects.end(); it != end; ++it) { + auto module = *it; + if (auto sym = module->lookup_symbol(name, false)) { + ret = symbol_module(sym, module); + break; + } + } + }); + return ret; +} + void* program::do_lookup_function(const char* name) { auto sym = lookup(name, nullptr); diff --git a/include/osv/elf.hh b/include/osv/elf.hh --- a/include/osv/elf.hh +++ b/include/osv/elf.hh @@ -585,6 +585,7 @@ public: void set_search_path(std::initializer_list<std::string> path); symbol_module lookup(const char* symbol, object* seeker); + symbol_module lookup_next(const char* name, const void* retaddr); template <typename T> T* lookup_function(const char* symbol); diff --git a/libc/dlfcn.cc b/libc/dlfcn.cc --- a/libc/dlfcn.cc +++ b/libc/dlfcn.cc @@ -70,8 +70,8 @@ void* dlsym(void* handle, const char* name) if ((program == handle) || (handle == RTLD_DEFAULT)) { sym = program->lookup(name, nullptr); } else if (handle == RTLD_NEXT) { - // FIXME: implement - abort(); + auto retaddr = __builtin_extract_return_addr(__builtin_return_address(0)); + sym = program->lookup_next(name, retaddr); } else { auto obj = *reinterpret_cast<std::shared_ptr<elf::object>*>(handle); sym = obj->lookup_symbol_deep(name); diff --git a/tests/tst-dlfcn.cc b/tests/tst-dlfcn.cc --- a/tests/tst-dlfcn.cc +++ b/tests/tst-dlfcn.cc @@ -12,7 +12,7 @@ #include <boost/test/unit_test.hpp> namespace utf = boost::unit_test; -const bool rtld_next = false; +const bool rtld_next = true; const bool deep_lookup = true; static bool called = false; -- You received this message because you are subscribed to the Google Groups "OSv Development" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To view this discussion on the web visit https://groups.google.com/d/msgid/osv-dev/000000000000a5c72c059cbe0b40%40google.com.
