diff --git a/android/run-checks.sh b/android/run-checks.sh index bda99434..deb6f87a 100755 --- a/android/run-checks.sh +++ b/android/run-checks.sh @@ -462,8 +462,15 @@ esac # Extract GNU configuration name case $ARCH in - arm) GNU_CONFIG=arm-linux-androideabi;; - *) GNU_CONFIG="$ARCH-linux-android";; + arm) + GNU_CONFIG=arm-linux-androideabi + ;; + x86) + GNU_CONFIG=i686-linux-android + ;; + *) + GNU_CONFIG="$ARCH-linux-android" + ;; esac # Generate standalone NDK toolchain installation @@ -475,10 +482,10 @@ run "$NDK_DIR/build/tools/make-standalone-toolchain.sh" \ --install-dir="$NDK_STANDALONE" fail_panic "Can't generate standalone NDK toolchain installation!" -# Rebuild the client library with the auto-tools base build system. -# Even though it's not going to be used, this checks that this still -# works correctly. -echo "Building client Android library with configure/make" +# Rebuild the client library, processor and tools with the auto-tools based +# build system. Even though it's not going to be used, this checks that this +# still works correctly. +echo "Building Android binaries with configure/make" TMPTARGET="$TMPDIR/target-local" ( PATH="$NDK_STANDALONE/bin:$PATH" @@ -486,12 +493,10 @@ TMPTARGET="$TMPDIR/target-local" run mkdir "$TMPDIR"/build-target && run cd "$TMPDIR"/build-target && run2 "$PROGDIR"/../configure --prefix="$TMPTARGET" \ - --host="$GNU_CONFIG" \ - --disable-tools \ - --disable-processor && + --host="$GNU_CONFIG" && run2 make -j$NUM_JOBS install ) -fail_panic "Could not rebuild Android client library!" +fail_panic "Could not rebuild Android binaries!" # Copy sources to temporary directory PROJECT_DIR=$TMPDIR/project diff --git a/src/client/linux/handler/exception_handler.cc b/src/client/linux/handler/exception_handler.cc index 0cdde2d1..4a5932c1 100644 --- a/src/client/linux/handler/exception_handler.cc +++ b/src/client/linux/handler/exception_handler.cc @@ -457,7 +457,7 @@ bool ExceptionHandler::WriteMinidump(const string& dump_path, } bool ExceptionHandler::WriteMinidump() { -#if !defined(__ARM_EABI__) +#if !defined(__ARM_EABI__) && !defined(__ANDROID__) if (!IsOutOfProcess() && !minidump_descriptor_.IsFD()) { // Update the path of the minidump so that this can be called multiple times // and new files are created for each minidump. This is done before the @@ -485,7 +485,7 @@ bool ExceptionHandler::WriteMinidump() { return GenerateDump(&context); #else return false; -#endif // !defined(__ARM_EABI__) +#endif // !defined(__ARM_EABI__) && !defined(__ANDROID__) } void ExceptionHandler::AddMappingInfo(const string& name, diff --git a/src/tools/linux/md2core/minidump-2-core.cc b/src/tools/linux/md2core/minidump-2-core.cc index 1af4e27e..cbcbb1e6 100644 --- a/src/tools/linux/md2core/minidump-2-core.cc +++ b/src/tools/linux/md2core/minidump-2-core.cc @@ -68,12 +68,19 @@ #define ELF_ARCH EM_X86_64 #elif defined(__i386__) #define ELF_ARCH EM_386 -#elif defined(__ARM_ARCH_3__) +#elif defined(__arm__) #define ELF_ARCH EM_ARM #elif defined(__mips__) #define ELF_ARCH EM_MIPS #endif +#if defined(__arm__) +// GLibc/ARM and Android/ARM both use 'user_regs' for the structure type +// containing core registers, while they use 'user_regs_struct' on other +// architectures. This file-local typedef simplifies the source code. +typedef user_regs user_regs_struct; +#endif + using google_breakpad::MemoryMappedFile; using google_breakpad::MinidumpMemoryRange; @@ -195,7 +202,9 @@ struct CrashedProcess { struct Thread { pid_t tid; user_regs_struct regs; +#if defined(__i386__) || defined(__x86_64__) user_fpregs_struct fpregs; +#endif #if defined(__i386__) user_fpxregs_struct fpxregs; #endif @@ -322,6 +331,32 @@ ParseThreadRegisters(CrashedProcess::Thread* thread, memcpy(thread->fpregs.st_space, rawregs->flt_save.float_registers, 8 * 16); memcpy(thread->fpregs.xmm_space, rawregs->flt_save.xmm_registers, 16 * 16); } +#elif defined(__arm__) +static void +ParseThreadRegisters(CrashedProcess::Thread* thread, + const MinidumpMemoryRange& range) { + const MDRawContextARM* rawregs = range.GetData(0); + + thread->regs.uregs[0] = rawregs->iregs[0]; + thread->regs.uregs[1] = rawregs->iregs[1]; + thread->regs.uregs[2] = rawregs->iregs[2]; + thread->regs.uregs[3] = rawregs->iregs[3]; + thread->regs.uregs[4] = rawregs->iregs[4]; + thread->regs.uregs[5] = rawregs->iregs[5]; + thread->regs.uregs[6] = rawregs->iregs[6]; + thread->regs.uregs[7] = rawregs->iregs[7]; + thread->regs.uregs[8] = rawregs->iregs[8]; + thread->regs.uregs[9] = rawregs->iregs[9]; + thread->regs.uregs[10] = rawregs->iregs[10]; + thread->regs.uregs[11] = rawregs->iregs[11]; + thread->regs.uregs[12] = rawregs->iregs[12]; + thread->regs.uregs[13] = rawregs->iregs[13]; + thread->regs.uregs[14] = rawregs->iregs[14]; + thread->regs.uregs[15] = rawregs->iregs[15]; + + thread->regs.uregs[16] = rawregs->cpsr; + thread->regs.uregs[17] = 0; // what is ORIG_r0 exactly? +} #else #error "This code has not been ported to your platform yet" #endif @@ -380,6 +415,12 @@ ParseSystemInfo(CrashedProcess* crashinfo, const MinidumpMemoryRange& range, ",\nbut the minidump file is from a 32bit machine" : ""); _exit(1); } +#elif defined(__arm__) + if (sysinfo->processor_architecture != MD_CPU_ARCHITECTURE_ARM) { + fprintf(stderr, + "This version of minidump-2-core only supports ARM (32bit).\n"); + _exit(1); + } #else #error "This code has not been ported to your platform yet" #endif @@ -682,6 +723,7 @@ WriteThread(const CrashedProcess::Thread& thread, int fatal_signal) { return false; } +#if defined(__i386__) || defined(__x86_64__) nhdr.n_descsz = sizeof(user_fpregs_struct); nhdr.n_type = NT_FPREGSET; if (!writea(1, &nhdr, sizeof(nhdr)) || @@ -689,6 +731,7 @@ WriteThread(const CrashedProcess::Thread& thread, int fatal_signal) { !writea(1, &thread.fpregs, sizeof(user_fpregs_struct))) { return false; } +#endif #if defined(__i386__) nhdr.n_descsz = sizeof(user_fpxregs_struct); @@ -1018,8 +1061,10 @@ main(int argc, char** argv) { // sizeof(Nhdr) + 8 + sizeof(user) + sizeof(Nhdr) + 8 + crashinfo.auxv_length + crashinfo.threads.size() * ( - (sizeof(Nhdr) + 8 + sizeof(prstatus)) + - sizeof(Nhdr) + 8 + sizeof(user_fpregs_struct) + (sizeof(Nhdr) + 8 + sizeof(prstatus)) +#if defined(__i386__) || defined(__x86_64__) + + sizeof(Nhdr) + 8 + sizeof(user_fpregs_struct) +#endif #if defined(__i386__) + sizeof(Nhdr) + 8 + sizeof(user_fpxregs_struct) #endif