From db877a13bbb35f8d6b2c645177aee8f3be51800e Mon Sep 17 00:00:00 2001 From: "gordana.cmiljanovic@imgtec.com" Date: Wed, 25 Sep 2013 08:18:03 +0000 Subject: Adding mips support for Android. Mips linux support has been added previously in r1212. Some additional changes are required to make breakpad functional on Android. BUG=none TEST=build, unittests, chrome test application Review URL: https://breakpad.appspot.com/632002 git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1215 4c0a9323-5329-0410-9bdc-e9ce6186880e --- src/common/android/breakpad_getcontext.S | 79 ++++++++++++++++++++++ src/common/android/breakpad_getcontext_unittest.cc | 13 ++++ src/common/android/include/sys/ucontext.h | 1 - src/common/android/include/sys/user.h | 19 +++++- src/common/android/ucontext_constants.h | 7 +- src/common/linux/dump_symbols.cc | 2 +- 6 files changed, 115 insertions(+), 6 deletions(-) (limited to 'src/common') diff --git a/src/common/android/breakpad_getcontext.S b/src/common/android/breakpad_getcontext.S index 13ccd46b..13f242d8 100644 --- a/src/common/android/breakpad_getcontext.S +++ b/src/common/android/breakpad_getcontext.S @@ -140,6 +140,85 @@ breakpad_getcontext: .size breakpad_getcontext, . - breakpad_getcontext +#elif defined(__mips__) + +#if _MIPS_SIM != _ABIO32 +#error "Unsupported mips ISA. Only mips o32 is supported." +#endif + +// This implementation is inspired by implementation of getcontext in glibc. +#include +#include +#include +#include // for __NR_rt_sigprocmask + +#define _NSIG8 128 / 8 +#define SIG_BLOCK 1 + + + .text +LOCALS_NUM = 2 // save gp and ra on stack +FRAME_SIZE = ((LOCALS_NUM * SZREG) + ALSZ) & ALMASK +RA_FRAME_OFFSET = FRAME_SIZE - (1 * SZREG) +GP_FRAME_OFFSET = FRAME_SIZE - (2 * SZREG) +MCONTEXT_REG_SIZE = 8 + +NESTED (breakpad_getcontext, FRAME_SIZE, ra) + .mask 0x00000000, 0 + .fmask 0x00000000, 0 + + .set noreorder + .cpload t9 + .set reorder + + move a2, sp +#define _SP a2 + + addiu sp, -FRAME_SIZE + sw ra, RA_FRAME_OFFSET(sp) + sw gp, GP_FRAME_OFFSET(sp) + + sw s0, (16 * MCONTEXT_REG_SIZE + MCONTEXT_GREGS_OFFSET)(a0) + sw s1, (17 * MCONTEXT_REG_SIZE + MCONTEXT_GREGS_OFFSET)(a0) + sw s2, (18 * MCONTEXT_REG_SIZE + MCONTEXT_GREGS_OFFSET)(a0) + sw s3, (19 * MCONTEXT_REG_SIZE + MCONTEXT_GREGS_OFFSET)(a0) + sw s4, (20 * MCONTEXT_REG_SIZE + MCONTEXT_GREGS_OFFSET)(a0) + sw s5, (21 * MCONTEXT_REG_SIZE + MCONTEXT_GREGS_OFFSET)(a0) + sw s6, (22 * MCONTEXT_REG_SIZE + MCONTEXT_GREGS_OFFSET)(a0) + sw s7, (23 * MCONTEXT_REG_SIZE + MCONTEXT_GREGS_OFFSET)(a0) + sw _SP, (29 * MCONTEXT_REG_SIZE + MCONTEXT_GREGS_OFFSET)(a0) + sw fp, (30 * MCONTEXT_REG_SIZE + MCONTEXT_GREGS_OFFSET)(a0) + sw ra, (31 * MCONTEXT_REG_SIZE + MCONTEXT_GREGS_OFFSET)(a0) + sw ra, MCONTEXT_PC_OFFSET(a0) + +#ifdef __mips_hard_float + s.d fs0, (20 * MCONTEXT_REG_SIZE + MCONTEXT_FPREGS_OFFSET)(a0) + s.d fs1, (22 * MCONTEXT_REG_SIZE + MCONTEXT_FPREGS_OFFSET)(a0) + s.d fs2, (24 * MCONTEXT_REG_SIZE + MCONTEXT_FPREGS_OFFSET)(a0) + s.d fs3, (26 * MCONTEXT_REG_SIZE + MCONTEXT_FPREGS_OFFSET)(a0) + s.d fs4, (28 * MCONTEXT_REG_SIZE + MCONTEXT_FPREGS_OFFSET)(a0) + s.d fs5, (30 * MCONTEXT_REG_SIZE + MCONTEXT_FPREGS_OFFSET)(a0) + + cfc1 v1, fcr31 + sw v1, MCONTEXT_FPC_CSR(a0) +#endif // __mips_hard_float + + /* rt_sigprocmask (SIG_BLOCK, NULL, &ucp->uc_sigmask, _NSIG8) */ + li a3, _NSIG8 + addu a2, a0, UCONTEXT_SIGMASK_OFFSET + move a1, zero + li a0, SIG_BLOCK + li v0, __NR_rt_sigprocmask + syscall + + lw ra, RA_FRAME_OFFSET(sp) + lw gp, GP_FRAME_OFFSET(sp) + addiu sp, FRAME_SIZE + jr ra + +END (breakpad_getcontext) + + #else #error "This file has not been ported for your CPU!" #endif diff --git a/src/common/android/breakpad_getcontext_unittest.cc b/src/common/android/breakpad_getcontext_unittest.cc index 3bafb9a6..c1b69c25 100644 --- a/src/common/android/breakpad_getcontext_unittest.cc +++ b/src/common/android/breakpad_getcontext_unittest.cc @@ -69,6 +69,19 @@ TEST(AndroidUContext, GRegsOffset) { ASSERT_EQ(static_cast(UCONTEXT_FPREGS_MEM_OFFSET), offsetof(ucontext_t,__fpregs_mem)); +#elif defined(__mips__) + ASSERT_EQ(static_cast(MCONTEXT_GREGS_OFFSET), + offsetof(ucontext_t,uc_mcontext.gregs)); + + // PC for mips is not part of gregs. + ASSERT_EQ(static_cast(MCONTEXT_PC_OFFSET), + offsetof(ucontext_t,uc_mcontext.pc)); + + ASSERT_EQ(static_cast(MCONTEXT_FPREGS_OFFSET), + offsetof(ucontext_t,uc_mcontext.fpregs)); + + ASSERT_EQ(static_cast(MCONTEXT_FPC_CSR), + offsetof(ucontext_t,uc_mcontext.fpc_csr)); #else ASSERT_EQ(static_cast(MCONTEXT_GREGS_OFFSET), offsetof(ucontext_t,uc_mcontext.gregs)); diff --git a/src/common/android/include/sys/ucontext.h b/src/common/android/include/sys/ucontext.h index 4a4e77c1..85c69ebd 100644 --- a/src/common/android/include/sys/ucontext.h +++ b/src/common/android/include/sys/ucontext.h @@ -128,7 +128,6 @@ typedef struct ucontext { #elif defined(__mips__) -// Not supported by Google Breakpad at this point, but just in case. typedef struct { uint32_t regmask; uint32_t status; diff --git a/src/common/android/include/sys/user.h b/src/common/android/include/sys/user.h index d13e5f6e..bc275bbe 100644 --- a/src/common/android/include/sys/user.h +++ b/src/common/android/include/sys/user.h @@ -120,8 +120,23 @@ struct user { #elif defined(__mips__) -// TODO: Provide some useful definitions here, once the rest of Breakpad -// requires them. +#define _ASM_USER_H 1 // Prevent conflicts + +struct user_regs_struct { + unsigned long long regs[32]; + unsigned long long lo; + unsigned long long hi; + unsigned long long epc; + unsigned long long badvaddr; + unsigned long long status; + unsigned long long cause; +}; + +struct user_fpregs_struct { + unsigned long long regs[32]; + unsigned int fpcsr; + unsigned int fir; +}; #else # error "Unsupported Android CPU ABI" diff --git a/src/common/android/ucontext_constants.h b/src/common/android/ucontext_constants.h index 9c7a6971..c99c51fa 100644 --- a/src/common/android/ucontext_constants.h +++ b/src/common/android/ucontext_constants.h @@ -75,8 +75,11 @@ #elif defined(__mips__) -#define MCONTEXT_GREGS_OFFSET 0 -#define UCONTEXT_SIGMASK_OFFSET 0 +#define MCONTEXT_PC_OFFSET 32 +#define MCONTEXT_GREGS_OFFSET 40 +#define MCONTEXT_FPREGS_OFFSET 296 +#define MCONTEXT_FPC_CSR 556 +#define UCONTEXT_SIGMASK_OFFSET 616 #else #error "This header has not been ported for your CPU" diff --git a/src/common/linux/dump_symbols.cc b/src/common/linux/dump_symbols.cc index 1f58d10f..75dcfd4c 100644 --- a/src/common/linux/dump_symbols.cc +++ b/src/common/linux/dump_symbols.cc @@ -617,7 +617,7 @@ bool LoadSymbols(const string& obj_file, // Linux C++ exception handling information can also provide // unwinding data. const Shdr* eh_frame_section = - FindElfSectionByName(".eh_frame", debug_section_type, + FindElfSectionByName(".eh_frame", SHT_PROGBITS, sections, names, names_end, elf_header->e_shnum); if (eh_frame_section) { -- cgit v1.2.1