Add support for protected local symbol lookup.

Bug: http://code.google.com/p/android/issues/detail?id=66048
Change-Id: Ib334223df27adad9477fb241ab099c5e26df4a7d
diff --git a/linker/dlfcn.cpp b/linker/dlfcn.cpp
index 529e20f..efb829e 100644
--- a/linker/dlfcn.cpp
+++ b/linker/dlfcn.cpp
@@ -100,30 +100,23 @@
 
   soinfo* found = NULL;
   ElfW(Sym)* sym = NULL;
-  if (handle == RTLD_DEFAULT) {
-    sym = dlsym_linear_lookup(symbol, &found, NULL);
-  } else if (handle == RTLD_NEXT) {
-    void* caller_addr = __builtin_return_address(0);
-    soinfo* si = find_containing_library(caller_addr);
+  void* caller_addr = __builtin_return_address(0);
+  soinfo* caller_si = find_containing_library(caller_addr);
 
+  if (handle == RTLD_DEFAULT) {
+    sym = dlsym_linear_lookup(symbol, &found, NULL, caller_si);
+  } else if (handle == RTLD_NEXT) {
     sym = NULL;
-    if (si && si->next) {
-      sym = dlsym_linear_lookup(symbol, &found, si->next);
+    if (caller_si && caller_si->next) {
+      sym = dlsym_linear_lookup(symbol, &found, caller_si->next, caller_si);
     }
   } else {
     found = reinterpret_cast<soinfo*>(handle);
-    sym = dlsym_handle_lookup(found, symbol);
+    sym = dlsym_handle_lookup(found, symbol, caller_si);
   }
 
-  if (sym != NULL) {
-    unsigned bind = ELF_ST_BIND(sym->st_info);
-
-    if ((bind == STB_GLOBAL || bind == STB_WEAK) && sym->st_shndx != 0) {
-      return reinterpret_cast<void*>(sym->st_value + found->load_bias);
-    }
-
-    __bionic_format_dlerror("symbol found but not global", symbol);
-    return NULL;
+  if (sym != NULL && sym->st_shndx != 0) {
+    return reinterpret_cast<void*>(sym->st_value + found->load_bias);
   } else {
     __bionic_format_dlerror("undefined symbol", symbol);
     return NULL;