author | Michael Wu <mwu@mozilla.com> |
Wed, 20 Oct 2010 20:44:03 -0400 | |
changeset 56285 | 8fc42e3e185f22dbfbb13944f61c19d0f45e74c7 |
parent 56284 | 781d0b2374705e2863cbf147fa16f7fe75251a35 |
child 56286 | a72ca32bac1d7e071fa21c526d2fc8fdd193981f |
push id | unknown |
push user | unknown |
push date | unknown |
reviewers | ted, blocking-fennec |
bugs | 603592 |
milestone | 2.0b8pre |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/other-licenses/android/APKOpen.cpp +++ b/other-licenses/android/APKOpen.cpp @@ -43,22 +43,25 @@ #include <errno.h> #include <string.h> #include <stdio.h> #include <fcntl.h> #include <endian.h> #include <unistd.h> #include <zlib.h> #include "dlfcn.h" +#include "APKOpen.h" /* compression methods */ #define STORE 0 #define DEFLATE 8 #define LZMA 14 +#define NS_EXPORT __attribute__ ((visibility("default"))) + struct local_file_header { uint32_t signature; uint16_t min_version; uint16_t general_flag; uint16_t compression; uint16_t lastmod_time; uint16_t lastmod_date; uint32_t crc32; @@ -101,16 +104,17 @@ struct cdir_end { uint32_t cdir_size; uint32_t cdir_offset; uint16_t comment_size; char comment[0]; } __attribute__((__packed__)); static size_t zip_size; static int zip_fd; +NS_EXPORT struct mapping_info * lib_mapping; static void * map_file (const char *file) { int fd = open(file, O_RDONLY); if (fd == -1) { __android_log_print(ANDROID_LOG_ERROR, "GeckoMapFile", "map_file open %s", strerror(errno)); return NULL; } @@ -168,18 +172,16 @@ static uint32_t simple_write(int fd, con } } out_offset += written; } return out_offset; } -#define NS_EXPORT __attribute__ ((visibility("default"))) - #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); \ } @@ -388,24 +390,67 @@ static void * mozload(const char * path, 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; } +static void * +extractBuf(const char * path, void *zip, + struct cdir_entry *cdir_start, uint16_t cdir_entries) +{ + struct cdir_entry *entry = find_cdir_entry(cdir_start, cdir_entries, path); + struct local_file_header *file = (struct local_file_header *)(zip + letoh32(entry->offset)); + void * data = ((void *)&file->data) + letoh16(file->filename_size) + letoh16(file->extra_field_size); + + void * buf = malloc(letoh32(entry->uncompressed_size)); + if (buf == (void *)-1) { + __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "Couldn't alloc decompression buffer for %s", path); + return NULL; + } + if (letoh16(file->compression) == DEFLATE) + extractLib(entry, data, buf); + else + memcpy(buf, data, letoh32(entry->uncompressed_size)); + + return buf; +} + +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) +{ + if (!file_ids || mapping_count >= MAX_MAPPING_INFO) + return; + + struct mapping_info *info = &lib_mapping[mapping_count++]; + info->name = strdup(name); + info->base = (uintptr_t)base; + info->len = len; + info->offset = offset; + + char * entry = strstr(file_ids, name); + if (entry) + info->file_id = strndup(entry + strlen(name) + 1, 32); +} + extern "C" void simple_linker_init(void); static void loadLibs(const char *apkName) { - simple_linker_init(); + chdir("/data/data/org.mozilla.fennec"); - chdir("/data/data/org.mozilla.fennec"); + simple_linker_init(); struct stat status; if (!stat(apkName, &status)) apk_mtime = status.st_mtime; #ifdef DEBUG struct timeval t0, t1; gettimeofday(&t0, 0); @@ -421,16 +466,21 @@ loadLibs(const char *apkName) return; } uint32_t cdir_offset = letoh32(dirend->cdir_offset); uint16_t cdir_entries = letoh16(dirend->cdir_entries); struct cdir_entry *cdir_start = (struct cdir_entry *)(zip + cdir_offset); +#ifdef MOZ_CRASHREPORTER + lib_mapping = (struct mapping_info *)calloc(MAX_MAPPING_INFO, sizeof(*lib_mapping)); + file_ids = (char *)extractBuf("lib.id", zip, cdir_start, cdir_entries); +#endif + #define MOZLOAD(name) mozload("lib/lib" name ".so", zip, cdir_start, cdir_entries) MOZLOAD("mozalloc"); MOZLOAD("nspr4"); MOZLOAD("plc4"); MOZLOAD("plds4"); MOZLOAD("mozsqlite3"); MOZLOAD("nssutil3"); MOZLOAD("nss3"); @@ -440,31 +490,35 @@ loadLibs(const char *apkName) MOZLOAD("xpcom"); MOZLOAD("nssckbi"); MOZLOAD("freebl3"); MOZLOAD("softokn3"); #undef MOZLOAD close(zip_fd); +#ifdef MOZ_CRASHREPORTER + free(file_ids); + file_ids = NULL; +#endif + if (!xul_handle) __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "Couldn't get a handle to libxul!"); #define GETFUNC(name) f_ ## name = (name ## _t) __wrap_dlsym(xul_handle, "Java_org_mozilla_gecko_GeckoAppShell_" #name) GETFUNC(nativeInit); GETFUNC(nativeRun); GETFUNC(notifyGeckoOfEvent); GETFUNC(setSurfaceView); GETFUNC(setInitialSize); GETFUNC(onResume); GETFUNC(onLowMemory); GETFUNC(callObserver); GETFUNC(removeObserver); #undef GETFUNC - #ifdef DEBUG gettimeofday(&t1, 0); __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "spent %d total", (((long long)t1.tv_sec * 1000000LL) + (long long)t1.tv_usec) - (((long long)t0.tv_sec * 1000000LL) + (long long)t0.tv_usec)); __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "All libraries loaded!"); #endif }
new file mode 100644 --- /dev/null +++ b/other-licenses/android/APKOpen.h @@ -0,0 +1,50 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Android code. + * + * The Initial Developer of the Original Code is Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Michael Wu <mwu@mozilla.com> + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef APKOpen_h +#define APKOpen_h + +struct mapping_info { + char * name; + char * file_id; + uintptr_t base; + size_t len; + size_t offset; +}; + +extern struct mapping_info * lib_mapping; + +#endif /* APKOpen_h */
--- a/other-licenses/android/Makefile.in +++ b/other-licenses/android/Makefile.in @@ -64,14 +64,16 @@ CSRCS = \ ba.c \ debugger.c \ dlfcn.c \ linker.c \ linker_format.c \ rt.c \ $(NULL) +EXPORTS = APKOpen.h + EXTRA_DSO_LDOPTS += $(ZLIB_LIBS) WRAP_MALLOC_LIB = WRAP_MALLOC_CFLAGS = include $(topsrcdir)/config/rules.mk
--- a/other-licenses/android/linker.c +++ b/other-licenses/android/linker.c @@ -77,16 +77,18 @@ * - after linking, set as much stuff as possible to READONLY * and NOEXEC * - linker hardcodes PAGE_SIZE and PAGE_MASK because the kernel * headers provide versions that are negative... * - allocate space for soinfo structs dynamically instead of * having a hard limit (64) */ +/* Implemented in APKOpen */ +extern void report_mapping(char *name, void *base, uint32_t len, uint32_t offset); static int link_image(soinfo *si, unsigned wr_offset); static int socount = 0; static soinfo sopool[SO_MAX]; static soinfo *freelist = NULL; static soinfo *solist = &libdl_info; static soinfo *sonext = &libdl_info; @@ -130,27 +132,29 @@ struct _link_stats linker_stats; #if COUNT_PAGES unsigned bitmask[4096]; #endif #ifndef PT_ARM_EXIDX #define PT_ARM_EXIDX 0x70000001 /* .ARM.exidx segment */ #endif +#ifndef MOZ_LINKER #define HOODLUM(name, ret, ...) \ ret name __VA_ARGS__ \ { \ char errstr[] = "ERROR: " #name " called from the dynamic linker!\n"; \ write(2, errstr, sizeof(errstr)); \ abort(); \ } HOODLUM(malloc, void *, (size_t size)); HOODLUM(free, void, (void *ptr)); HOODLUM(realloc, void *, (void *ptr, size_t size)); HOODLUM(calloc, void *, (size_t cnt, size_t size)); +#endif static char tmp_err_buf[768]; static char __linker_dl_err_buf[768]; #define DL_ERR(fmt, x...) \ do { \ format_buffer(__linker_dl_err_buf, sizeof(__linker_dl_err_buf), \ "%s[%d]: " fmt, __func__, __LINE__, ##x); \ ERROR(fmt "\n", ##x); \ @@ -940,16 +944,18 @@ load_segments(int fd, size_t offset, voi offset + ((phdr->p_offset) & (~PAGE_MASK))); if (pbase == MAP_FAILED) { DL_ERR("%d failed to map segment from '%s' @ 0x%08x (0x%08x). " "p_vaddr=0x%08x p_offset=0x%08x", pid, si->name, (unsigned)tmp, len, phdr->p_vaddr, phdr->p_offset); goto fail; } + report_mapping(si->name, pbase, len, phdr->p_offset & (~PAGE_MASK)); + /* If 'len' didn't end on page boundary, and it's a writable * segment, zero-fill the rest. */ if ((len & PAGE_MASK) && (phdr->p_flags & PF_W)) memset((void *)(pbase + len), 0, PAGE_SIZE - (len & PAGE_MASK)); /* Check to see if we need to extend the map for this segment to * cover the diff between filesz and memsz (i.e. for bss). *
--- a/toolkit/mozapps/installer/packager.mk +++ b/toolkit/mozapps/installer/packager.mk @@ -165,16 +165,17 @@ DIST_FILES = \ resources.arsc \ AndroidManifest.xml \ chrome \ components \ defaults \ modules \ res \ lib \ + lib.id \ extensions \ application.ini \ platform.ini \ greprefs.js \ browserconfig.properties \ blocklist.xml \ chrome.manifest \ update.locale \ @@ -195,16 +196,21 @@ endif PKG_SUFFIX = .apk INNER_MAKE_PACKAGE = \ rm -f $(_ABS_DIST)/gecko.ap_ && \ ( cd $(STAGEPATH)$(MOZ_PKG_DIR)$(_BINPATH) && \ rm -rf lib && \ mkdir -p lib/armeabi && \ cp lib*.so lib && \ mv lib/libmozutils.so lib/armeabi && \ + rm -f lib.id && \ + for SOMELIB in lib/*.so ; \ + do \ + printf "`basename $$SOMELIB`:`$(_ABS_DIST)/host/bin/file_id $$SOMELIB`\n" >> lib.id ; \ + done && \ $(ZIP) -r9D $(_ABS_DIST)/gecko.ap_ $(DIST_FILES) -x $(NON_DIST_FILES) ) && \ rm -f $(_ABS_DIST)/gecko.apk && \ $(APKBUILDER) $(_ABS_DIST)/gecko.apk -v $(APKBUILDER_FLAGS) -z $(_ABS_DIST)/gecko.ap_ -f $(STAGEPATH)$(MOZ_PKG_DIR)$(_BINPATH)/classes.dex && \ cp $(_ABS_DIST)/gecko.apk $(_ABS_DIST)/gecko-unsigned-unaligned.apk && \ $(JARSIGNER) $(_ABS_DIST)/gecko.apk && \ $(ZIPALIGN) -f -v 4 $(_ABS_DIST)/gecko.apk $(PACKAGE) INNER_UNMAKE_PACKAGE = \ mkdir $(MOZ_PKG_DIR) && \
--- a/toolkit/xre/nsAndroidStartup.cpp +++ b/toolkit/xre/nsAndroidStartup.cpp @@ -47,16 +47,18 @@ #include <string.h> #include <pthread.h> #include "nsTArray.h" #include "nsString.h" #include "nsILocalFile.h" #include "nsAppRunner.h" #include "AndroidBridge.h" +#include "APKOpen.h" +#include "nsExceptionHandler.h" #define LOG(args...) __android_log_print(ANDROID_LOG_INFO, MOZ_APP_NAME, args) static pthread_t gGeckoThread = 0; struct AutoAttachJavaThread { AutoAttachJavaThread() { attached = mozilla_AndroidBridge_SetMainThread((void*)pthread_self()); @@ -67,16 +69,25 @@ struct AutoAttachJavaThread { } PRBool attached; }; static void* GeckoStart(void *data) { +#ifdef MOZ_CRASHREPORTER + struct mapping_info *info = lib_mapping; + while (info->name) { + CrashReporter::AddLibraryMapping(info->name, info->file_id, info->base, + info->len, info->offset); + info++; + } +#endif + AutoAttachJavaThread attacher; if (!attacher.attached) return 0; if (!data) { LOG("Failed to get arguments for GeckoStart\n"); return 0; } @@ -104,25 +115,24 @@ GeckoStart(void *data) getter_AddRefs(xreDir)); if (NS_FAILED(rv)) { LOG("Failed to create nsIFile for xreDirectory"); return 0; } appData->xreDirectory = xreDir.get(); - nsTArray<char *> targs; char *arg = strtok(static_cast<char *>(data), " "); while (arg) { targs.AppendElement(arg); arg = strtok(NULL, " "); } targs.AppendElement(static_cast<char *>(nsnull)); - + int result = XRE_main(targs.Length() - 1, targs.Elements(), appData); if (result) LOG("XRE_main returned %d", result); XRE_FreeAppData(appData); mozilla::AndroidBridge::Bridge()->NotifyXreExit();