crazy_status_t crazy_library_find_symbol(crazy_library_t* library, const char* symbol_name, void** symbol_address) { LibraryView* wrap = reinterpret_cast<LibraryView*>(library); // TODO(digit): Handle NULL symbols properly. *symbol_address = wrap->LookupSymbol(symbol_name); return (*symbol_address == NULL) ? CRAZY_STATUS_FAILURE : CRAZY_STATUS_SUCCESS; }
void* LibraryList::FindSymbolFrom(const char* symbol_name, LibraryView* from) { SymbolLookupState lookup_state; if (!from) return NULL; // Use a work-queue and a set to ensure to perform a breadth-first // search. Vector<LibraryView*> work_queue; Set<LibraryView*> visited_set; work_queue.PushBack(from); while (!work_queue.IsEmpty()) { LibraryView* lib = work_queue.PopFirst(); if (lib->IsCrazy()) { if (lookup_state.CheckSymbol(symbol_name, lib->GetCrazy())) return lookup_state.found_addr; } else if (lib->IsSystem()) { // TODO(digit): Support weak symbols in system libraries. // With the current code, all symbols in system libraries // are assumed to be non-weak. void* addr = lib->LookupSymbol(symbol_name); if (addr) return addr; } // If this is a crazy library, add non-visited dependencies // to the work queue. if (lib->IsCrazy()) { SharedLibrary::DependencyIterator iter(lib->GetCrazy()); while (iter.GetNext()) { LibraryView* dependency = FindKnownLibrary(iter.GetName()); if (dependency && !visited_set.Has(dependency)) { work_queue.PushBack(dependency); visited_set.Add(dependency); } } } } if (lookup_state.weak_count >= 1) { // There was at least a single weak symbol definition, so use // the first one found in breadth-first search order. return lookup_state.weak_addr; } // There was no symbol definition. return NULL; }