diff options
Diffstat (limited to 'linker/linker.cpp')
-rw-r--r-- | linker/linker.cpp | 8 |
1 files changed, 8 insertions, 0 deletions
diff --git a/linker/linker.cpp b/linker/linker.cpp index f8b35d7a8..77fb70c29 100644 --- a/linker/linker.cpp +++ b/linker/linker.cpp @@ -607,17 +607,24 @@ class SoinfoListAllocatorRW { // specified soinfo object and its dependencies in breadth first order. ElfW(Sym)* dlsym_handle_lookup(soinfo* si, soinfo** found, const char* name, soinfo* caller) { LinkedList<soinfo, SoinfoListAllocatorRW> visit_list; + LinkedList<soinfo, SoinfoListAllocatorRW> visited; visit_list.push_back(si); soinfo* current_soinfo; while ((current_soinfo = visit_list.pop_front()) != nullptr) { + if (visited.contains(current_soinfo)) { + continue; + } + ElfW(Sym)* result = soinfo_elf_lookup(current_soinfo, elfhash(name), name, caller == current_soinfo ? SymbolLookupScope::kAllowLocal : SymbolLookupScope::kExcludeLocal); if (result != nullptr) { *found = current_soinfo; visit_list.clear(); + visited.clear(); return result; } + visited.push_back(current_soinfo); current_soinfo->get_children().for_each([&](soinfo* child) { visit_list.push_back(child); @@ -625,6 +632,7 @@ ElfW(Sym)* dlsym_handle_lookup(soinfo* si, soinfo** found, const char* name, soi } visit_list.clear(); + visited.clear(); return nullptr; } |