diff --git a/core/elf.cc b/core/elf.cc index d89954e598ce05da2324a07646338c6da101a14e..6427f86701d9869f0a80963c755072ccc869db01 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 b973f6a494995406737480494fe7930fd3d8fa83..a6c5eee9260863dfda42ec83f580dc8e90953098 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 1aeac527d7b0915431442dbbed516314f2e51fd9..d3a1cbc54305847d204f3178972357012bd252b0 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();