--- a/mozglue/android/APKOpen.cpp
+++ b/mozglue/android/APKOpen.cpp
@@ -28,19 +28,21 @@
#include <sys/resource.h>
#include <sys/prctl.h>
#include "sqlite3.h"
#include "SQLiteBridge.h"
#include "NSSBridge.h"
#include "ElfLoader.h"
#include "application.ini.h"
+#include "mozilla/Bootstrap.h"
#include "mozilla/TimeStamp.h"
#include "mozilla/UniquePtr.h"
#include "XREChildData.h"
+#include "nsXPCOMGlue.h"
/* Android headers don't define RUSAGE_THREAD */
#ifndef RUSAGE_THREAD
#define RUSAGE_THREAD 1
#endif
#ifndef RELEASE_OR_BETA
/* Official builds have the debuggable flag set to false, which disables
@@ -161,34 +163,28 @@ getJavaUiThread()
}
extern "C" APKOPEN_EXPORT void MOZ_JNICALL
Java_org_mozilla_gecko_GeckoThread_registerUiThread(JNIEnv*, jclass)
{
sJavaUiThread = pthread_self();
}
-static void * xul_handle = nullptr;
+Bootstrap::UniquePtr gBootstrap;
#ifndef MOZ_FOLD_LIBS
static void * sqlite_handle = nullptr;
static void * nspr_handle = nullptr;
static void * plc_handle = nullptr;
#else
#define sqlite_handle nss_handle
#define nspr_handle nss_handle
#define plc_handle nss_handle
#endif
static void * nss_handle = nullptr;
-template <typename T> inline void
-xul_dlsym(const char *symbolName, T *value)
-{
- *value = (T) (uintptr_t) __wrap_dlsym(xul_handle, symbolName);
-}
-
static int mapping_count = 0;
extern "C" void
report_mapping(char *name, void *base, uint32_t len, uint32_t offset)
{
if (mapping_count >= MAX_MAPPING_INFO)
return;
@@ -209,46 +205,50 @@ delete_mapping(const char *name)
free(info->name);
*info = *last;
--mapping_count;
break;
}
}
}
-static void*
-dlopenAPKLibrary(const char* apkName, const char* libraryName)
+static UniquePtr<char[]>
+getAPKLibraryName(const char* apkName, const char* libraryName)
{
#define APK_ASSETS_PATH "!/assets/" ANDROID_CPU_ARCH "/"
size_t filenameLength = strlen(apkName) +
sizeof(APK_ASSETS_PATH) + // includes \0 terminator
strlen(libraryName);
auto file = MakeUnique<char[]>(filenameLength);
snprintf(file.get(), filenameLength, "%s" APK_ASSETS_PATH "%s",
apkName, libraryName);
- return __wrap_dlopen(file.get(), RTLD_GLOBAL | RTLD_LAZY);
+ return file;
#undef APK_ASSETS_PATH
}
+
+static void*
+dlopenAPKLibrary(const char* apkName, const char* libraryName)
+{
+ return __wrap_dlopen(getAPKLibraryName(apkName, libraryName).get(), RTLD_GLOBAL | RTLD_LAZY);
+}
+
static mozglueresult
loadGeckoLibs(const char *apkName)
{
TimeStamp t0 = TimeStamp::Now();
struct rusage usage1_thread, usage1;
getrusage(RUSAGE_THREAD, &usage1_thread);
getrusage(RUSAGE_SELF, &usage1);
- xul_handle = dlopenAPKLibrary(apkName, "libxul.so");
- if (!xul_handle) {
+ gBootstrap = GetBootstrap(getAPKLibraryName(apkName, "libxul.so").get());
+ if (!gBootstrap) {
__android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "Couldn't get a handle to libxul!");
return FAILURE;
}
- void (*XRE_StartupTimelineRecord)(int, TimeStamp);
- xul_dlsym("XRE_StartupTimelineRecord", &XRE_StartupTimelineRecord);
-
TimeStamp t1 = TimeStamp::Now();
struct rusage usage2_thread, usage2;
getrusage(RUSAGE_THREAD, &usage2_thread);
getrusage(RUSAGE_SELF, &usage2);
#define RUSAGE_TIMEDIFF(u1, u2, field) \
((u2.ru_ ## field.tv_sec - u1.ru_ ## field.tv_sec) * 1000 + \
(u2.ru_ ## field.tv_usec - u1.ru_ ## field.tv_usec) / 1000)
@@ -257,18 +257,18 @@ loadGeckoLibs(const char *apkName)
(t1 - t0).ToMilliseconds(),
RUSAGE_TIMEDIFF(usage1_thread, usage2_thread, utime),
RUSAGE_TIMEDIFF(usage1, usage2, utime),
RUSAGE_TIMEDIFF(usage1_thread, usage2_thread, stime),
RUSAGE_TIMEDIFF(usage1, usage2, stime),
usage2_thread.ru_majflt - usage1_thread.ru_majflt,
usage2.ru_majflt - usage1.ru_majflt);
- XRE_StartupTimelineRecord(LINKER_INITIALIZED, t0);
- XRE_StartupTimelineRecord(LIBRARIES_LOADED, t1);
+ gBootstrap->XRE_StartupTimelineRecord(LINKER_INITIALIZED, t0);
+ gBootstrap->XRE_StartupTimelineRecord(LIBRARIES_LOADED, t1);
return SUCCESS;
}
static mozglueresult loadNSSLibs(const char *apkName);
static mozglueresult
loadSQLiteLibs(const char *apkName)
{
@@ -439,54 +439,40 @@ FreeArgv(char** argv, int argc)
{
for (int ix=0; ix < argc; ix++) {
// String was allocated with strndup, so need to use free to deallocate.
free(argv[ix]);
}
delete[](argv);
}
-typedef void (*GeckoStart_t)(JNIEnv*, char**, int, const StaticXREAppData&);
-typedef int GeckoProcessType;
-
extern "C" APKOPEN_EXPORT void MOZ_JNICALL
Java_org_mozilla_gecko_mozglue_GeckoLoader_nativeRun(JNIEnv *jenv, jclass jc, jobjectArray jargs, int crashFd, int ipcFd)
{
int argc = 0;
char** argv = CreateArgvFromObjectArray(jenv, jargs, &argc);
if (ipcFd < 0) {
- GeckoStart_t GeckoStart;
- xul_dlsym("GeckoStart", &GeckoStart);
-
- if (GeckoStart == nullptr) {
+ if (gBootstrap == nullptr) {
FreeArgv(argv, argc);
return;
}
ElfLoader::Singleton.ExpectShutdown(false);
- GeckoStart(jenv, argv, argc, sAppData);
+ gBootstrap->GeckoStart(jenv, argv, argc, sAppData);
ElfLoader::Singleton.ExpectShutdown(true);
} else {
- void (*fXRE_SetAndroidChildFds)(int, int);
- xul_dlsym("XRE_SetAndroidChildFds", &fXRE_SetAndroidChildFds);
-
- void (*fXRE_SetProcessType)(char*);
- xul_dlsym("XRE_SetProcessType", &fXRE_SetProcessType);
-
- mozglueresult (*fXRE_InitChildProcess)(int, char**, void*);
- xul_dlsym("XRE_InitChildProcess", &fXRE_InitChildProcess);
-
- fXRE_SetAndroidChildFds(crashFd, ipcFd);
- fXRE_SetProcessType(argv[argc - 1]);
+ gBootstrap->XRE_SetAndroidChildFds(crashFd, ipcFd);
+ gBootstrap->XRE_SetProcessType(argv[argc - 1]);
XREChildData childData;
- fXRE_InitChildProcess(argc - 1, argv, &childData);
+ gBootstrap->XRE_InitChildProcess(argc - 1, argv, &childData);
}
+ gBootstrap.reset();
FreeArgv(argv, argc);
}
extern "C" APKOPEN_EXPORT mozglueresult
ChildProcessInit(int argc, char* argv[])
{
int i;
for (i = 0; i < (argc - 1); i++) {
@@ -502,20 +488,14 @@ ChildProcessInit(int argc, char* argv[])
}
if (loadSQLiteLibs(argv[i]) != SUCCESS) {
return FAILURE;
}
if (loadGeckoLibs(argv[i]) != SUCCESS) {
return FAILURE;
}
- void (*fXRE_SetProcessType)(char*);
- xul_dlsym("XRE_SetProcessType", &fXRE_SetProcessType);
-
- mozglueresult (*fXRE_InitChildProcess)(int, char**, void*);
- xul_dlsym("XRE_InitChildProcess", &fXRE_InitChildProcess);
-
- fXRE_SetProcessType(argv[--argc]);
+ gBootstrap->XRE_SetProcessType(argv[--argc]);
XREChildData childData;
- return fXRE_InitChildProcess(argc, argv, &childData);
+ return NS_FAILED(gBootstrap->XRE_InitChildProcess(argc, argv, &childData));
}
--- a/xpcom/glue/standalone/nsXPCOMGlue.cpp
+++ b/xpcom/glue/standalone/nsXPCOMGlue.cpp
@@ -74,17 +74,17 @@ static void
CloseLibHandle(LibHandleType aLibHandle)
{
FreeLibrary(aLibHandle);
}
#else
#include <dlfcn.h>
-#if defined(MOZ_LINKER) && !defined(ANDROID)
+#if defined(MOZ_LINKER)
extern "C" {
NS_HIDDEN __typeof(dlopen) __wrap_dlopen;
NS_HIDDEN __typeof(dlsym) __wrap_dlsym;
NS_HIDDEN __typeof(dlclose) __wrap_dlclose;
}
#define dlopen __wrap_dlopen
#define dlsym __wrap_dlsym
@@ -142,18 +142,20 @@ AppendDependentLib(LibHandleType aLibHan
d->libHandle = aLibHandle;
sTop = d;
}
static bool
ReadDependentCB(pathstr_t aDependentLib)
{
+#ifndef MOZ_LINKER
// We do this unconditionally because of data in bug 771745
ReadAheadLib(aDependentLib);
+#endif
LibHandleType libHandle = GetLibHandle(aDependentLib);
if (libHandle) {
AppendDependentLib(libHandle);
}
return libHandle;
}
@@ -226,16 +228,21 @@ ns_strrpbrk(const char* string, const ch
return found;
}
#endif
static GetFrozenFunctionsFunc
XPCOMGlueLoad(const char* aXPCOMFile)
{
+#ifdef MOZ_LINKER
+ if (!ReadDependentCB(aXPCOMFile)) {
+ return nullptr;
+ }
+#else
char xpcomDir[MAXPATHLEN];
#ifdef XP_WIN
const char* lastSlash = ns_strrpbrk(aXPCOMFile, "/\\");
#elif XP_MACOSX
// On OSX, the dependentlibs.list file lives under Contents/Resources.
// However, the actual libraries listed in dependentlibs.list live under
// Contents/MacOS. We want to read the list from Contents/Resources, then
// load the libraries from Contents/MacOS.
@@ -318,16 +325,17 @@ XPCOMGlueLoad(const char* aXPCOMFile)
}
strcpy(cursor, buffer);
if (!ReadDependentCB(xpcomDir)) {
XPCOMGlueUnload();
return nullptr;
}
}
+#endif
GetFrozenFunctionsFunc sym =
(GetFrozenFunctionsFunc)GetSymbol(sTop->libHandle,
"NS_GetFrozenFunctions");
if (!sym) { // No symbol found.
XPCOMGlueUnload();
return nullptr;