--- a/mozglue/android/APKOpen.cpp
+++ b/mozglue/android/APKOpen.cpp
@@ -48,27 +48,32 @@
#include <sys/stat.h>
#include <sys/mman.h>
#include <sys/limits.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
-#include <endian.h>
#include <unistd.h>
#include <zlib.h>
+#ifdef MOZ_OLD_LINKER
#include <linux/ashmem.h>
+#include <endian.h>
+#endif
#include "dlfcn.h"
#include "APKOpen.h"
#include <sys/time.h>
#include <sys/resource.h>
#include "Zip.h"
#include "sqlite3.h"
#include "SQLiteBridge.h"
+#ifndef MOZ_OLD_LINKER
+#include "ElfLoader.h"
+#endif
/* Android headers don't define RUSAGE_THREAD */
#ifndef RUSAGE_THREAD
#define RUSAGE_THREAD 1
#endif
enum StartupEvent {
#define mozilla_StartupTimeline_Event(ev, z) ev,
@@ -86,16 +91,17 @@ void StartupTimeline_Record(StartupEvent
static struct mapping_info * lib_mapping = NULL;
NS_EXPORT const struct mapping_info *
getLibraryMapping()
{
return lib_mapping;
}
+#ifdef MOZ_OLD_LINKER
static int
createAshmem(size_t bytes, const char *name)
{
int fd = open("/" ASHMEM_NAME_DEF, O_RDWR, 0600);
if (fd < 0)
return -1;
char buf[ASHMEM_NAME_LEN];
@@ -104,16 +110,17 @@ createAshmem(size_t bytes, const char *n
/*ret = */ioctl(fd, ASHMEM_SET_NAME, buf);
if (!ioctl(fd, ASHMEM_SET_SIZE, bytes))
return fd;
close(fd);
return -1;
}
+#endif
#define SHELL_WRAPPER0(name) \
typedef void (*name ## _t)(JNIEnv *, jclass); \
static name ## _t f_ ## name; \
extern "C" NS_EXPORT void JNICALL \
Java_org_mozilla_gecko_GeckoAppShell_ ## name(JNIEnv *jenv, jclass jc) \
{ \
f_ ## name(jenv, jc); \
@@ -299,16 +306,17 @@ SHELL_WRAPPER3(notifySmsDeleted, jboolea
SHELL_WRAPPER3(notifySmsDeleteFailed, jint, jint, jlong)
SHELL_WRAPPER2(notifyNoMessageInList, jint, jlong)
SHELL_WRAPPER8(notifyListCreated, jint, jint, jstring, jstring, jstring, jlong, jint, jlong)
SHELL_WRAPPER7(notifyGotNextMessage, jint, jstring, jstring, jstring, jlong, jint, jlong)
SHELL_WRAPPER3(notifyReadingMessageListFailed, jint, jint, jlong)
static void * xul_handle = NULL;
static void * sqlite_handle = NULL;
+#ifdef MOZ_OLD_LINKER
static time_t apk_mtime = 0;
#ifdef DEBUG
extern "C" int extractLibs = 1;
#else
extern "C" int extractLibs = 0;
#endif
static void
@@ -370,16 +378,17 @@ extractFile(const char * path, Zip::Stre
close(fd);
#ifdef ANDROID_ARM_LINKER
/* We just extracted data that is going to be executed in the future.
* We thus need to ensure Instruction and Data cache coherency. */
cacheflush((unsigned) buf, (unsigned) buf + size, 0);
#endif
munmap(buf, size);
}
+#endif
static void
extractLib(Zip::Stream &s, void * dest)
{
z_stream strm = {
next_in: (Bytef *)s.GetBuffer(),
avail_in: s.GetSize(),
total_in: 0,
@@ -410,16 +419,17 @@ static int cache_count = 0;
static struct lib_cache_info *cache_mapping = NULL;
NS_EXPORT const struct lib_cache_info *
getLibraryCache()
{
return cache_mapping;
}
+#ifdef MOZ_OLD_LINKER
static void
ensureLibCache()
{
if (!cache_mapping)
cache_mapping = (struct lib_cache_info *)calloc(MAX_LIB_CACHE_ENTRIES,
sizeof(*cache_mapping));
}
@@ -570,17 +580,19 @@ static void * mozload(const char * path,
#ifdef DEBUG
gettimeofday(&t1, 0);
__android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "%s: spent %d", path, (((long long)t1.tv_sec * 1000000LL) + (long long)t1.tv_usec) -
(((long long)t0.tv_sec * 1000000LL) + (long long)t0.tv_usec));
#endif
return handle;
}
+#endif
+#ifdef MOZ_CRASHREPORTER
static void *
extractBuf(const char * path, Zip *zip)
{
Zip::Stream s;
if (!zip->GetStream(path, &s))
return NULL;
void * buf = malloc(s.GetUncompressedSize());
@@ -590,16 +602,17 @@ extractBuf(const char * path, Zip *zip)
}
if (s.GetType() == Zip::Stream::DEFLATE)
extractLib(s, buf);
else
memcpy(buf, s.GetBuffer(), s.GetUncompressedSize());
return buf;
}
+#endif
static int mapping_count = 0;
static char *file_ids = NULL;
#define MAX_MAPPING_INFO 32
extern "C" void
report_mapping(char *name, void *base, uint32_t len, uint32_t offset)
@@ -613,53 +626,66 @@ report_mapping(char *name, void *base, u
info->len = len;
info->offset = offset;
char * entry = strstr(file_ids, name);
if (entry)
info->file_id = strndup(entry + strlen(name) + 1, 32);
}
+#ifdef MOZ_OLD_LINKER
extern "C" void simple_linker_init(void);
+#endif
static void
loadGeckoLibs(const char *apkName)
{
chdir(getenv("GRE_HOME"));
+#ifdef MOZ_OLD_LINKER
struct stat status;
if (!stat(apkName, &status))
apk_mtime = status.st_mtime;
+#endif
struct timeval t0, t1;
gettimeofday(&t0, 0);
struct rusage usage1;
getrusage(RUSAGE_THREAD, &usage1);
Zip *zip = new Zip(apkName);
#ifdef MOZ_CRASHREPORTER
file_ids = (char *)extractBuf("lib.id", zip);
#endif
+#ifndef MOZ_OLD_LINKER
+ char *file = new char[strlen(apkName) + sizeof("!/libxpcom.so")];
+ sprintf(file, "%s!/libxpcom.so", apkName);
+ __wrap_dlopen(file, RTLD_GLOBAL | RTLD_LAZY);
+ // libxul.so is pulled from libxpcom.so, so we don't need to give the full path
+ xul_handle = __wrap_dlopen("libxul.so", RTLD_GLOBAL | RTLD_LAZY);
+ delete[] file;
+#else
#define MOZLOAD(name) mozload("lib" name ".so", zip)
MOZLOAD("mozalloc");
MOZLOAD("nspr4");
MOZLOAD("plc4");
MOZLOAD("plds4");
MOZLOAD("nssutil3");
MOZLOAD("nss3");
MOZLOAD("ssl3");
MOZLOAD("smime3");
xul_handle = MOZLOAD("xul");
MOZLOAD("xpcom");
MOZLOAD("nssckbi");
MOZLOAD("freebl3");
MOZLOAD("softokn3");
#undef MOZLOAD
+#endif
delete zip;
#ifdef MOZ_CRASHREPORTER
free(file_ids);
file_ids = NULL;
#endif
@@ -710,32 +736,41 @@ loadGeckoLibs(const char *apkName)
StartupTimeline_Record(LINKER_INITIALIZED, &t0);
StartupTimeline_Record(LIBRARIES_LOADED, &t1);
}
static void loadSQLiteLibs(const char *apkName)
{
chdir(getenv("GRE_HOME"));
+#ifdef MOZ_OLD_LINKER
simple_linker_init();
struct stat status;
if (!stat(apkName, &status))
apk_mtime = status.st_mtime;
+#endif
Zip *zip = new Zip(apkName);
lib_mapping = (struct mapping_info *)calloc(MAX_MAPPING_INFO, sizeof(*lib_mapping));
#ifdef MOZ_CRASHREPORTER
file_ids = (char *)extractBuf("lib.id", zip);
#endif
+#ifndef MOZ_OLD_LINKER
+ char *file = new char[strlen(apkName) + sizeof("!/mozsqlite3.so")];
+ sprintf(file, "%s!/mozsqlite3.so", apkName);
+ __wrap_dlopen(file, RTLD_GLOBAL | RTLD_LAZY);
+ delete [] file;
+#else
#define MOZLOAD(name) mozload("lib" name ".so", zip)
sqlite_handle = MOZLOAD("mozsqlite3");
#undef MOZLOAD
+#endif
delete zip;
#ifdef MOZ_CRASHREPORTER
free(file_ids);
file_ids = NULL;
#endif
@@ -756,18 +791,23 @@ Java_org_mozilla_gecko_GeckoAppShell_loa
return;
loadGeckoLibs(str);
jenv->ReleaseStringUTFChars(jApkName, str);
}
extern "C" NS_EXPORT void JNICALL
Java_org_mozilla_gecko_GeckoAppShell_loadSQLiteLibsNative(JNIEnv *jenv, jclass jGeckoAppShellClass, jstring jApkName, jboolean jShouldExtract) {
- if (jShouldExtract)
+ if (jShouldExtract) {
+#ifdef MOZ_OLD_LINKER
extractLibs = 1;
+#else
+ putenv("MOZ_LINKER_EXTRACT=1");
+#endif
+ }
const char* str;
// XXX: java doesn't give us true UTF8, we should figure out something
// better to do here
str = jenv->GetStringUTFChars(jApkName, NULL);
if (str == NULL)
return;
@@ -785,17 +825,19 @@ ChildProcessInit(int argc, char* argv[])
for (i = 0; i < (argc - 1); i++) {
if (strcmp(argv[i], "-greomni"))
continue;
i = i + 1;
break;
}
+#ifdef MOZ_OLD_LINKER
fillLibCache(argv[argc - 1]);
+#endif
loadSQLiteLibs(argv[i]);
loadGeckoLibs(argv[i]);
// don't pass the last arg - it's only recognized by the lib cache
argc--;
typedef GeckoProcessType (*XRE_StringToChildProcessType_t)(char*);
typedef nsresult (*XRE_InitChildProcess_t)(int, char**, GeckoProcessType);