Bug 1081034 part 3 - Resolve libc symbols with our linker. r=nfroyd
authorMike Hommey <mh+mozilla@glandium.org>
Thu, 16 Oct 2014 09:20:14 +0900
changeset 210649 fdf75d54f631cff6440ab5aee8957ed913f47de4
parent 210648 349536e12ec038ab93f1d29783216fa1b8b7c40d
child 210650 0004a6330d53c07baea3f31b7819fee5cf631540
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewersnfroyd
bugs1081034, 791419
milestone36.0a1
Bug 1081034 part 3 - Resolve libc symbols with our linker. r=nfroyd This allows to resolve weak symbols from some Android device's libc that dlsym() won't. This is effectively an alternative fix to bug 791419, without requiring wrapping symbols.
mozglue/linker/ElfLoader.cpp
mozglue/linker/ElfLoader.h
--- a/mozglue/linker/ElfLoader.cpp
+++ b/mozglue/linker/ElfLoader.cpp
@@ -494,24 +494,30 @@ ElfLoader::Init()
 {
   Dl_info info;
   /* On Android < 4.1 can't reenter dl* functions. So when the library
    * containing this code is dlopen()ed, it can't call dladdr from a
    * static initializer. */
   if (dladdr(_DYNAMIC, &info) != 0) {
     self_elf = LoadedElf::Create(info.dli_fname, info.dli_fbase);
   }
+#if defined(ANDROID)
+  if (dladdr(FunctionPtr(syscall), &info) != 0) {
+    libc = LoadedElf::Create(info.dli_fname, info.dli_fbase);
+  }
+#endif
 }
 
 ElfLoader::~ElfLoader()
 {
   LibHandleList list;
 
-  /* Release self_elf */
+  /* Release self_elf and libc */
   self_elf = nullptr;
+  libc = nullptr;
 
   /* Build up a list of all library handles with direct (external) references.
    * We actually skip system library handles because we want to keep at least
    * some of these open. Most notably, Mozilla codebase keeps a few libgnome
    * libraries deliberately open because of the mess that libORBit destruction
    * is. dlclose()ing these libraries actually leads to problems. */
   for (LibHandleList::reverse_iterator it = handles.rbegin();
        it < handles.rend(); ++it) {
--- a/mozglue/linker/ElfLoader.h
+++ b/mozglue/linker/ElfLoader.h
@@ -458,16 +458,24 @@ private:
 
   /* Initialization code that can't run during static initialization. */
   void Init();
 
   /* System loader handle for the library/program containing our code. This
    * is used to resolve wrapped functions. */
   mozilla::RefPtr<LibHandle> self_elf;
 
+#if defined(ANDROID)
+  /* System loader handle for the libc. This is used to resolve weak symbols
+   * that some libcs contain that the Android linker won't dlsym(). Normally,
+   * we wouldn't treat non-Android differently, but glibc uses versioned
+   * symbols which this linker doesn't support. */
+  mozilla::RefPtr<LibHandle> libc;
+#endif
+
   /* Bookkeeping */
   typedef std::vector<LibHandle *> LibHandleList;
   LibHandleList handles;
 
 protected:
   friend class CustomElf;
   friend class LoadedElf;
   /**