mirror of
https://github.com/yuzu-emu/breakpad.git
synced 2024-11-27 20:24:16 +01:00
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
This commit is contained in:
parent
ab52ca7d6e
commit
db877a13bb
@ -76,7 +76,12 @@ void FlushInstructionCache(const char* memory, uint32_t memory_size) {
|
||||
# error "Your operating system is not supported yet"
|
||||
# endif
|
||||
#elif defined(__mips__)
|
||||
# if defined(__linux__)
|
||||
# if defined(__ANDROID__)
|
||||
// Provided by Android's <unistd.h>
|
||||
long begin = reinterpret_cast<long>(memory);
|
||||
long end = begin + static_cast<long>(memory_size);
|
||||
cacheflush(begin, end, 0);
|
||||
# elif defined(__linux__)
|
||||
// See http://www.linux-mips.org/wiki/Cacheflush_Syscall.
|
||||
cacheflush(const_cast<char*>(memory), memory_size, ICACHE);
|
||||
# else
|
||||
|
@ -429,7 +429,11 @@ static void CPUFillFromUContext(MDRawContextMIPS* out, const ucontext* uc,
|
||||
out->cause = 0; // Not reported in signal context.
|
||||
|
||||
for (int i = 0; i < MD_FLOATINGSAVEAREA_MIPS_FPR_COUNT; ++i)
|
||||
#if defined (__ANDROID__)
|
||||
out->float_save.regs[i] = uc->uc_mcontext.fpregs[i];
|
||||
#else
|
||||
out->float_save.regs[i] = uc->uc_mcontext.fpregs.fp_r.fp_dregs[i];
|
||||
#endif
|
||||
|
||||
out->float_save.fpcsr = uc->uc_mcontext.fpc_csr;
|
||||
out->float_save.fir = uc->uc_mcontext.fpc_eir; // Unused.
|
||||
|
@ -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 <asm/asm.h>
|
||||
#include <asm/regdef.h>
|
||||
#include <asm/fpregdef.h>
|
||||
#include <asm/unistd.h> // 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
|
||||
|
@ -69,6 +69,19 @@ TEST(AndroidUContext, GRegsOffset) {
|
||||
|
||||
ASSERT_EQ(static_cast<size_t>(UCONTEXT_FPREGS_MEM_OFFSET),
|
||||
offsetof(ucontext_t,__fpregs_mem));
|
||||
#elif defined(__mips__)
|
||||
ASSERT_EQ(static_cast<size_t>(MCONTEXT_GREGS_OFFSET),
|
||||
offsetof(ucontext_t,uc_mcontext.gregs));
|
||||
|
||||
// PC for mips is not part of gregs.
|
||||
ASSERT_EQ(static_cast<size_t>(MCONTEXT_PC_OFFSET),
|
||||
offsetof(ucontext_t,uc_mcontext.pc));
|
||||
|
||||
ASSERT_EQ(static_cast<size_t>(MCONTEXT_FPREGS_OFFSET),
|
||||
offsetof(ucontext_t,uc_mcontext.fpregs));
|
||||
|
||||
ASSERT_EQ(static_cast<size_t>(MCONTEXT_FPC_CSR),
|
||||
offsetof(ucontext_t,uc_mcontext.fpc_csr));
|
||||
#else
|
||||
ASSERT_EQ(static_cast<size_t>(MCONTEXT_GREGS_OFFSET),
|
||||
offsetof(ucontext_t,uc_mcontext.gregs));
|
||||
|
@ -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;
|
||||
|
@ -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 <asm/user.h> 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"
|
||||
|
@ -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"
|
||||
|
@ -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<ElfClass>(".eh_frame", debug_section_type,
|
||||
FindElfSectionByName<ElfClass>(".eh_frame", SHT_PROGBITS,
|
||||
sections, names, names_end,
|
||||
elf_header->e_shnum);
|
||||
if (eh_frame_section) {
|
||||
|
@ -66,7 +66,7 @@
|
||||
#ifndef GOOGLE_BREAKPAD_COMMON_MINIDUMP_CPU_MIPS_H__
|
||||
#define GOOGLE_BREAKPAD_COMMON_MINIDUMP_CPU_MIPS_H__
|
||||
|
||||
#ifdef __mips__
|
||||
#if defined(__mips__) && !defined(__ANDROID__)
|
||||
typedef struct {
|
||||
uint64_t regs[32];
|
||||
uint64_t lo;
|
||||
|
Loading…
Reference in New Issue
Block a user