aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormark@chromium.org <mark@chromium.org>2015-04-15 19:28:11 +0000
committermark@chromium.org <mark@chromium.org>2015-04-15 19:28:11 +0000
commitd88401cca9ff7640387a0d88d75de1e7d8fff294 (patch)
treeb47c776a127bb465572e382e752d5d63ca9b544c
parentUse __NR_rt_sigaction instead of __NR_sigaction (diff)
downloadbreakpad-d88401cca9ff7640387a0d88d75de1e7d8fff294.tar.xz
MIPS64: Initial MIPS64 related change.
With this change Breakpad can be compiled for MIPS64, but it is not yet functional. Patch by Gordana Cmiljanovic <Gordana.Cmiljanovic@imgtec.com> Review URL: https://breakpad.appspot.com/6824002/ git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1446 4c0a9323-5329-0410-9bdc-e9ce6186880e
-rw-r--r--src/client/linux/dump_writer_common/thread_info.cc2
-rw-r--r--src/client/linux/dump_writer_common/ucontext_reader.cc2
-rw-r--r--src/client/linux/handler/exception_handler_unittest.cc4
-rw-r--r--src/client/linux/minidump_writer/linux_dumper.h6
-rw-r--r--src/client/linux/minidump_writer/minidump_writer.cc10
-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
-rw-r--r--src/third_party/curl/curl.h2
-rw-r--r--src/third_party/curl/curlbuild.h2
-rw-r--r--src/tools/linux/md2core/minidump-2-core.cc2
14 files changed, 156 insertions, 20 deletions
diff --git a/src/client/linux/dump_writer_common/thread_info.cc b/src/client/linux/dump_writer_common/thread_info.cc
index 9fe253c6..a3072b6c 100644
--- a/src/client/linux/dump_writer_common/thread_info.cc
+++ b/src/client/linux/dump_writer_common/thread_info.cc
@@ -257,7 +257,9 @@ void ThreadInfo::FillCPUContext(RawContextCPU* out) const {
out->float_save.regs[i] = fpregs.regs[i];
out->float_save.fpcsr = fpregs.fpcsr;
+#if _MIPS_SIM == _ABIO32
out->float_save.fir = fpregs.fir;
+#endif
}
#endif
diff --git a/src/client/linux/dump_writer_common/ucontext_reader.cc b/src/client/linux/dump_writer_common/ucontext_reader.cc
index b20a68bf..d37fdeb0 100644
--- a/src/client/linux/dump_writer_common/ucontext_reader.cc
+++ b/src/client/linux/dump_writer_common/ucontext_reader.cc
@@ -244,7 +244,9 @@ void UContextReader::FillCPUContext(RawContextCPU *out, const ucontext *uc) {
out->float_save.regs[i] = uc->uc_mcontext.fpregs.fp_r.fp_dregs[i];
out->float_save.fpcsr = uc->uc_mcontext.fpc_csr;
+#if _MIPS_SIM == _ABIO32
out->float_save.fir = uc->uc_mcontext.fpc_eir; // Unused.
+#endif
}
#endif
diff --git a/src/client/linux/handler/exception_handler_unittest.cc b/src/client/linux/handler/exception_handler_unittest.cc
index 6deea55b..289c9cd1 100644
--- a/src/client/linux/handler/exception_handler_unittest.cc
+++ b/src/client/linux/handler/exception_handler_unittest.cc
@@ -80,7 +80,11 @@ void FlushInstructionCache(const char* memory, uint32_t memory_size) {
// Provided by Android's <unistd.h>
long begin = reinterpret_cast<long>(memory);
long end = begin + static_cast<long>(memory_size);
+#if _MIPS_SIM == _ABIO32
cacheflush(begin, end, 0);
+#else
+ syscall(__NR_cacheflush, begin, end, ICACHE);
+#endif
# elif defined(__linux__)
// See http://www.linux-mips.org/wiki/Cacheflush_Syscall.
cacheflush(const_cast<char*>(memory), memory_size, ICACHE);
diff --git a/src/client/linux/minidump_writer/linux_dumper.h b/src/client/linux/minidump_writer/linux_dumper.h
index 2fc88486..87dfadb4 100644
--- a/src/client/linux/minidump_writer/linux_dumper.h
+++ b/src/client/linux/minidump_writer/linux_dumper.h
@@ -52,9 +52,11 @@
namespace google_breakpad {
// Typedef for our parsing of the auxv variables in /proc/pid/auxv.
-#if defined(__i386) || defined(__ARM_EABI__) || defined(__mips__)
+#if defined(__i386) || defined(__ARM_EABI__) || \
+ (defined(__mips__) && _MIPS_SIM == _ABIO32)
typedef Elf32_auxv_t elf_aux_entry;
-#elif defined(__x86_64) || defined(__aarch64__)
+#elif defined(__x86_64) || defined(__aarch64__) || \
+ (defined(__mips__) && _MIPS_SIM != _ABIO32)
typedef Elf64_auxv_t elf_aux_entry;
#endif
diff --git a/src/client/linux/minidump_writer/minidump_writer.cc b/src/client/linux/minidump_writer/minidump_writer.cc
index edc7e47d..0414bb72 100644
--- a/src/client/linux/minidump_writer/minidump_writer.cc
+++ b/src/client/linux/minidump_writer/minidump_writer.cc
@@ -689,10 +689,18 @@ class MinidumpWriter {
return false;
}
+#ifdef __mips__
+ if (dyn.d_tag == DT_MIPS_RLD_MAP) {
+ r_debug = reinterpret_cast<struct r_debug*>(dyn.d_un.d_ptr);
+ continue;
+ }
+#else
if (dyn.d_tag == DT_DEBUG) {
r_debug = reinterpret_cast<struct r_debug*>(dyn.d_un.d_ptr);
continue;
- } else if (dyn.d_tag == DT_NULL) {
+ }
+#endif
+ else if (dyn.d_tag == DT_NULL) {
break;
}
}
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
diff --git a/src/third_party/curl/curl.h b/src/third_party/curl/curl.h
index 160cd98a..0d80936f 100644
--- a/src/third_party/curl/curl.h
+++ b/src/third_party/curl/curl.h
@@ -74,7 +74,7 @@
require it! */
#if defined(_AIX) || defined(__NOVELL_LIBC__) || defined(__NetBSD__) || \
defined(__minix) || defined(__SYMBIAN32__) || defined(__INTEGRITY) || \
- defined(ANDROID)
+ defined(__ANDROID__)
#include <sys/select.h>
#endif
diff --git a/src/third_party/curl/curlbuild.h b/src/third_party/curl/curlbuild.h
index 87d0c7bb..b0a53e6c 100644
--- a/src/third_party/curl/curlbuild.h
+++ b/src/third_party/curl/curlbuild.h
@@ -155,7 +155,7 @@
/* The size of `long', as computed by sizeof. */
#if defined(_M_X64) || (defined(__x86_64__) && !defined(__ILP32__)) || \
- defined(__aarch64__)
+ defined(__aarch64__) || (defined(__mips__) && _MIPS_SIM == _ABI64)
#define CURL_SIZEOF_LONG 8
#else
#define CURL_SIZEOF_LONG 4
diff --git a/src/tools/linux/md2core/minidump-2-core.cc b/src/tools/linux/md2core/minidump-2-core.cc
index 82007604..bcb0076e 100644
--- a/src/tools/linux/md2core/minidump-2-core.cc
+++ b/src/tools/linux/md2core/minidump-2-core.cc
@@ -384,7 +384,9 @@ ParseThreadRegisters(CrashedProcess::Thread* thread,
thread->fpregs.regs[i] = rawregs->float_save.regs[i];
thread->fpregs.fpcsr = rawregs->float_save.fpcsr;
+#if _MIPS_SIM == _ABIO32
thread->fpregs.fir = rawregs->float_save.fir;
+#endif
}
#else
#error "This code has not been ported to your platform yet"