Example #1
0
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;
}