aboutsummaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
Diffstat (limited to 'src/common')
-rw-r--r--src/common/android/breakpad_getcontext.S119
-rw-r--r--src/common/android/include/link.h3
-rw-r--r--src/common/android/testing/include/wchar.h4
-rw-r--r--src/common/android/ucontext_constants.h8
-rw-r--r--src/common/linux/memory_mapped_file.cc9
-rw-r--r--src/common/memory.h3
6 files changed, 131 insertions, 15 deletions
diff --git a/src/common/android/breakpad_getcontext.S b/src/common/android/breakpad_getcontext.S
index 79fe88df..fd6326ad 100644
--- a/src/common/android/breakpad_getcontext.S
+++ b/src/common/android/breakpad_getcontext.S
@@ -229,14 +229,27 @@ 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.
+#if _MIPS_SIM == _ABIO32
#include <asm/asm.h>
#include <asm/regdef.h>
#include <asm/fpregdef.h>
+#else
+#include <machine/asm.h>
+#include <machine/regdef.h>
+#endif
+
+// from asm/asm.h
+#if _MIPS_SIM == _ABIO32
+#define ALSZ 7
+#define ALMASK ~7
+#define SZREG 4
+#else // _MIPS_SIM != _ABIO32
+#define ALSZ 15
+#define ALMASK ~15
+#define SZREG 8
+#endif
+
#include <asm/unistd.h> // for __NR_rt_sigprocmask
#define _NSIG8 128 / 8
@@ -244,12 +257,14 @@ breakpad_getcontext:
.text
-LOCALS_NUM = 2 // save gp and ra on stack
+LOCALS_NUM = 1 // save gp on stack
FRAME_SIZE = ((LOCALS_NUM * SZREG) + ALSZ) & ALMASK
-RA_FRAME_OFFSET = FRAME_SIZE - (1 * SZREG)
-GP_FRAME_OFFSET = FRAME_SIZE - (2 * SZREG)
+
+GP_FRAME_OFFSET = FRAME_SIZE - (1 * SZREG)
MCONTEXT_REG_SIZE = 8
+#if _MIPS_SIM == _ABIO32
+
NESTED (breakpad_getcontext, FRAME_SIZE, ra)
.mask 0x00000000, 0
.fmask 0x00000000, 0
@@ -262,8 +277,7 @@ NESTED (breakpad_getcontext, FRAME_SIZE, ra)
#define _SP a2
addiu sp, -FRAME_SIZE
- sw ra, RA_FRAME_OFFSET(sp)
- sw gp, GP_FRAME_OFFSET(sp)
+ .cprestore GP_FRAME_OFFSET
sw s0, (16 * MCONTEXT_REG_SIZE + MCONTEXT_GREGS_OFFSET)(a0)
sw s1, (17 * MCONTEXT_REG_SIZE + MCONTEXT_GREGS_OFFSET)(a0)
@@ -298,12 +312,95 @@ NESTED (breakpad_getcontext, FRAME_SIZE, ra)
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
+
+#ifndef NESTED
+/*
+ * NESTED - declare nested routine entry point
+ */
+#define NESTED(symbol, framesize, rpc) \
+ .globl symbol; \
+ .align 2; \
+ .type symbol,@function; \
+ .ent symbol,0; \
+symbol: .frame sp, framesize, rpc;
+#endif
+
+/*
+ * END - mark end of function
+ */
+#ifndef END
+# define END(function) \
+ .end function; \
+ .size function,.-function
+#endif
+
+/* int getcontext (ucontext_t *ucp) */
+
+NESTED (breakpad_getcontext, FRAME_SIZE, ra)
+ .mask 0x10000000, 0
+ .fmask 0x00000000, 0
+
+ move a2, sp
+#define _SP a2
+ move a3, gp
+#define _GP a3
+
+ daddiu sp, -FRAME_SIZE
+ .cpsetup $25, GP_FRAME_OFFSET, breakpad_getcontext
+
+ /* Store a magic flag. */
+ li v1, 1
+ sd v1, (0 * MCONTEXT_REG_SIZE + MCONTEXT_GREGS_OFFSET)(a0) /* zero */
+
+ sd s0, (16 * MCONTEXT_REG_SIZE + MCONTEXT_GREGS_OFFSET)(a0)
+ sd s1, (17 * MCONTEXT_REG_SIZE + MCONTEXT_GREGS_OFFSET)(a0)
+ sd s2, (18 * MCONTEXT_REG_SIZE + MCONTEXT_GREGS_OFFSET)(a0)
+ sd s3, (19 * MCONTEXT_REG_SIZE + MCONTEXT_GREGS_OFFSET)(a0)
+ sd s4, (20 * MCONTEXT_REG_SIZE + MCONTEXT_GREGS_OFFSET)(a0)
+ sd s5, (21 * MCONTEXT_REG_SIZE + MCONTEXT_GREGS_OFFSET)(a0)
+ sd s6, (22 * MCONTEXT_REG_SIZE + MCONTEXT_GREGS_OFFSET)(a0)
+ sd s7, (23 * MCONTEXT_REG_SIZE + MCONTEXT_GREGS_OFFSET)(a0)
+ sd _GP, (28 * MCONTEXT_REG_SIZE + MCONTEXT_GREGS_OFFSET)(a0)
+ sd _SP, (29 * MCONTEXT_REG_SIZE + MCONTEXT_GREGS_OFFSET)(a0)
+ sd s8, (30 * MCONTEXT_REG_SIZE + MCONTEXT_GREGS_OFFSET)(a0)
+ sd ra, (31 * MCONTEXT_REG_SIZE + MCONTEXT_GREGS_OFFSET)(a0)
+ sd ra, MCONTEXT_PC_OFFSET(a0)
+
+#ifdef __mips_hard_float
+ s.d $f24, (24 * MCONTEXT_REG_SIZE + MCONTEXT_FPREGS_OFFSET)(a0)
+ s.d $f25, (25 * MCONTEXT_REG_SIZE + MCONTEXT_FPREGS_OFFSET)(a0)
+ s.d $f26, (26 * MCONTEXT_REG_SIZE + MCONTEXT_FPREGS_OFFSET)(a0)
+ s.d $f27, (27 * MCONTEXT_REG_SIZE + MCONTEXT_FPREGS_OFFSET)(a0)
+ s.d $f28, (28 * MCONTEXT_REG_SIZE + MCONTEXT_FPREGS_OFFSET)(a0)
+ s.d $f29, (29 * MCONTEXT_REG_SIZE + MCONTEXT_FPREGS_OFFSET)(a0)
+ s.d $f30, (30 * MCONTEXT_REG_SIZE + MCONTEXT_FPREGS_OFFSET)(a0)
+ s.d $f31, (31 * MCONTEXT_REG_SIZE + MCONTEXT_FPREGS_OFFSET)(a0)
+
+ cfc1 v1, $31
+ sw v1, MCONTEXT_FPC_CSR(a0)
+#endif /* __mips_hard_float */
+
+/* rt_sigprocmask (SIG_BLOCK, NULL, &ucp->uc_sigmask, _NSIG8) */
+ li a3, _NSIG8
+ daddu a2, a0, UCONTEXT_SIGMASK_OFFSET
+ move a1, zero
+ li a0, SIG_BLOCK
+
+ li v0, __NR_rt_sigprocmask
+ syscall
+
+ .cpreturn
+ daddiu sp, FRAME_SIZE
+ move v0, zero
+ jr ra
+
+END (breakpad_getcontext)
+#endif // _MIPS_SIM == _ABIO32
#elif defined(__x86_64__)
/* The x64 implementation of breakpad_getcontext was derived in part
diff --git a/src/common/android/include/link.h b/src/common/android/include/link.h
index 0f5010c0..e7ff8e2d 100644
--- a/src/common/android/include/link.h
+++ b/src/common/android/include/link.h
@@ -36,7 +36,8 @@
// TODO(rmcilroy): Remove this file once the ndk is updated for other
// architectures - crbug.com/358831
-#if !defined(__aarch64__) && !defined(__x86_64__)
+#if !defined(__aarch64__) && !defined(__x86_64__) && \
+ !(defined(__mips__) && _MIPS_SIM == _ABI64)
#ifdef __cplusplus
extern "C" {
diff --git a/src/common/android/testing/include/wchar.h b/src/common/android/testing/include/wchar.h
index 9649cab6..85373fd2 100644
--- a/src/common/android/testing/include/wchar.h
+++ b/src/common/android/testing/include/wchar.h
@@ -38,6 +38,9 @@
#include_next <wchar.h>
+#if !defined(__aarch64__) && !defined(__x86_64__) && \
+ !(defined(__mips__) && _MIPS_SIM == _ABI64)
+
// This needs to be in an extern "C" namespace, or Googletest will not
// compile against it.
#ifdef __cplusplus
@@ -68,5 +71,6 @@ static int inline wcscasecmp(const wchar_t* s1, const wchar_t* s2) {
#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus
+#endif
#endif // GOOGLEBREAKPAD_COMMON_ANDROID_INCLUDE_WCHAR_H
diff --git a/src/common/android/ucontext_constants.h b/src/common/android/ucontext_constants.h
index e39f0234..1932d573 100644
--- a/src/common/android/ucontext_constants.h
+++ b/src/common/android/ucontext_constants.h
@@ -97,11 +97,19 @@
#elif defined(__mips__)
+#if _MIPS_SIM == _ABIO32
#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
+#define MCONTEXT_GREGS_OFFSET 40
+#define MCONTEXT_FPREGS_OFFSET 296
+#define MCONTEXT_PC_OFFSET 616
+#define MCONTEXT_FPC_CSR 624
+#define UCONTEXT_SIGMASK_OFFSET 640
+#endif
#elif defined(__x86_64__)
diff --git a/src/common/linux/memory_mapped_file.cc b/src/common/linux/memory_mapped_file.cc
index 064326bb..592b66c8 100644
--- a/src/common/linux/memory_mapped_file.cc
+++ b/src/common/linux/memory_mapped_file.cc
@@ -54,6 +54,8 @@ MemoryMappedFile::~MemoryMappedFile() {
Unmap();
}
+#include <unistd.h>
+
bool MemoryMappedFile::Map(const char* path, size_t offset) {
Unmap();
@@ -62,7 +64,9 @@ bool MemoryMappedFile::Map(const char* path, size_t offset) {
return false;
}
-#if defined(__x86_64__) || defined(__aarch64__)
+#if defined(__x86_64__) || defined(__aarch64__) || \
+ (defined(__mips__) && _MIPS_SIM == _ABI64)
+
struct kernel_stat st;
if (sys_fstat(fd, &st) == -1 || st.st_size < 0) {
#else
@@ -83,7 +87,8 @@ bool MemoryMappedFile::Map(const char* path, size_t offset) {
return true;
}
-#if defined(__x86_64__) || defined(__aarch64__)
+#if defined(__x86_64__) || defined(__aarch64__) || \
+ (defined(__mips__) && _MIPS_SIM == _ABI64)
void* data = sys_mmap(NULL, file_len, PROT_READ, MAP_PRIVATE, fd, offset);
#else
if ((offset & 4095) != 0) {
diff --git a/src/common/memory.h b/src/common/memory.h
index 03228f07..d6aa137d 100644
--- a/src/common/memory.h
+++ b/src/common/memory.h
@@ -114,7 +114,8 @@ class PageAllocator {
private:
uint8_t *GetNPages(size_t num_pages) {
-#if defined(__x86_64__) || defined(__aarch64__)
+#if defined(__x86_64__) || defined(__aarch64__) || defined(__aarch64__) || \
+ ((defined(__mips__) && _MIPS_SIM == _ABI64))
void *a = sys_mmap(NULL, page_size_ * num_pages, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
#else