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.
--- 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;
/**