From 466b38518b3d9f43f056b5e8b1029e4d9bce2841 Mon Sep 17 00:00:00 2001
From: Avi Kivity <avi@cloudius-systems.com>
Date: Tue, 19 Feb 2013 11:54:57 +0200
Subject: [PATCH] dlfcn: implement dlsym(handle, sym) with handle !=
 RTLD_DEFAULT

fixes loading unit tests with "main" as the entry point.
---
 core/elf.cc    |  6 ++++++
 include/elf.hh |  1 +
 libc/dlfcn.cc  | 14 +++++++++++---
 3 files changed, 18 insertions(+), 3 deletions(-)

diff --git a/core/elf.cc b/core/elf.cc
index d89954e59..6427f8670 100644
--- a/core/elf.cc
+++ b/core/elf.cc
@@ -27,6 +27,12 @@ namespace elf {
 
     }
 
+    symbol_module::symbol_module()
+        : symbol()
+        , object()
+    {
+    }
+
     symbol_module::symbol_module(Elf64_Sym* _sym, elf_object* _obj)
         : symbol(_sym)
         , object(_obj)
diff --git a/include/elf.hh b/include/elf.hh
index b973f6a49..a6c5eee92 100644
--- a/include/elf.hh
+++ b/include/elf.hh
@@ -315,6 +315,7 @@ namespace elf {
 
     struct symbol_module {
     public:
+        symbol_module();
         symbol_module(Elf64_Sym* sym, elf_object* object);
         void* relocated_addr() const;
         Elf64_Sym* symbol;
diff --git a/libc/dlfcn.cc b/libc/dlfcn.cc
index 1aeac527d..d3a1cbc54 100644
--- a/libc/dlfcn.cc
+++ b/libc/dlfcn.cc
@@ -12,9 +12,17 @@ void* dlopen(const char* filename, int flags)
 
 void* dlsym(void* handle, const char* name)
 {
-    // FIXME: don't ignore handle
-    auto sym = elf::get_program()->lookup(name);
-    if (!sym.object) {
+    elf::symbol_module sym;
+    if (handle == RTLD_DEFAULT) {
+        sym = elf::get_program()->lookup(name);
+    } else if (handle == RTLD_NEXT) {
+        // FIXME: implement
+        abort();
+    } else {
+        auto obj = reinterpret_cast<elf::elf_object*>(handle);
+        sym = { obj->lookup_symbol(name), obj };
+    }
+    if (!sym.object || !sym.symbol) {
         return nullptr;
     }
     return sym.relocated_addr();
-- 
GitLab