From: Zhiting Zhu <zhiti...@cs.utexas.edu>
Committer: Nadav Har'El <n...@scylladb.com>
Branch: master

Implement RTLD_NEXT

Signed-off-by: Zhiting Zhu <zhiti...@cs.utexas.edu>
Message-Id: <20200120011727.1736-2-zhiti...@cs.utexas.edu>

---
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 osv-dev+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/osv-dev/000000000000a5c72c059cbe0b40%40google.com.

Reply via email to