[google-breakpad] r1452 committed - [MIPS]: Use mcontext_t structure for MIPS...

57 views
Skip to first unread message

google-...@googlecode.com

unread,
Apr 21, 2015, 5:34:29 PM4/21/15
to google-br...@googlegroups.com
Revision: 1452
Author: rmci...@chromium.org
Date: Tue Apr 21 21:34:14 2015 UTC
Log: [MIPS]: Use mcontext_t structure for MIPS

This change removes user_regs_struct and
user_fpregs_struct structures for mips
and uses mcontext_t instead.

R=fde...@chromium.org, ma...@chromium.org, rmci...@chromium.org

Review URL: https://breakpad.appspot.com/3744002

Patch from Gordana Cmiljanovic <Gordana.C...@imgtec.com>.
https://code.google.com/p/google-breakpad/source/detail?r=1452

Modified:
/trunk/src/client/linux/dump_writer_common/thread_info.cc
/trunk/src/client/linux/dump_writer_common/thread_info.h
/trunk/src/client/linux/minidump_writer/linux_core_dumper.cc
/trunk/src/client/linux/minidump_writer/linux_ptrace_dumper.cc
/trunk/src/client/linux/minidump_writer/linux_ptrace_dumper_unittest.cc
/trunk/src/common/android/include/sys/procfs.h
/trunk/src/common/android/include/sys/user.h
/trunk/src/google_breakpad/common/minidump_cpu_mips.h
/trunk/src/tools/linux/md2core/minidump-2-core.cc

=======================================
--- /trunk/src/client/linux/dump_writer_common/thread_info.cc Wed Apr 15
19:28:11 2015 UTC
+++ /trunk/src/client/linux/dump_writer_common/thread_info.cc Tue Apr 21
21:34:14 2015 UTC
@@ -30,6 +30,7 @@
#include "client/linux/dump_writer_common/thread_info.h"

#include <string.h>
+#include <assert.h>

#include "common/linux/linux_libc_support.h"
#include "google_breakpad/common/minidump_format.h"
@@ -230,37 +231,69 @@
#elif defined(__mips__)

uintptr_t ThreadInfo::GetInstructionPointer() const {
- return regs.epc;
+ return mcontext.pc;
}

void ThreadInfo::FillCPUContext(RawContextCPU* out) const {
out->context_flags = MD_CONTEXT_MIPS_FULL;

for (int i = 0; i < MD_CONTEXT_MIPS_GPR_COUNT; ++i)
- out->iregs[i] = regs.regs[i];
+ out->iregs[i] = mcontext.gregs[i];

- out->mdhi = regs.hi;
- out->mdlo = regs.lo;
+ out->mdhi = mcontext.mdhi;
+ out->mdlo = mcontext.mdlo;
+ out->dsp_control = mcontext.dsp;

- for (int i = 0; i < MD_CONTEXT_MIPS_DSP_COUNT; ++i) {
- out->hi[i] = hi[i];
- out->lo[i] = lo[i];
- }
- out->dsp_control = dsp_control;
+ out->hi[0] = mcontext.hi1;
+ out->lo[0] = mcontext.lo1;
+ out->hi[1] = mcontext.hi2;
+ out->lo[1] = mcontext.lo2;
+ out->hi[2] = mcontext.hi3;
+ out->lo[2] = mcontext.lo3;

- out->epc = regs.epc;
- out->badvaddr = regs.badvaddr;
- out->status = regs.status;
- out->cause = regs.cause;
+ out->epc = mcontext.pc;
+ out->badvaddr = 0; // Not stored in mcontext
+ out->status = 0; // Not stored in mcontext
+ out->cause = 0; // Not stored in mcontext

for (int i = 0; i < MD_FLOATINGSAVEAREA_MIPS_FPR_COUNT; ++i)
- out->float_save.regs[i] = fpregs.regs[i];
+ out->float_save.regs[i] = mcontext.fpregs.fp_r.fp_fregs[i]._fp_fregs;

- out->float_save.fpcsr = fpregs.fpcsr;
+ out->float_save.fpcsr = mcontext.fpc_csr;
#if _MIPS_SIM == _ABIO32
- out->float_save.fir = fpregs.fir;
+ out->float_save.fir = mcontext.fpc_eir;
+#endif
+}
+#endif // __mips__
+
+void ThreadInfo::GetGeneralPurposeRegisters(void** gp_regs, size_t* size) {
+ assert(gp_regs || size);
+#if defined(__mips__)
+ if (gp_regs)
+ *gp_regs = mcontext.gregs;
+ if (size)
+ *size = sizeof(mcontext.gregs);
+#else
+ if (gp_regs)
+ *gp_regs = &regs;
+ if (size)
+ *size = sizeof(regs);
#endif
}
+
+void ThreadInfo::GetFloatingPointRegisters(void** fp_regs, size_t* size) {
+ assert(fp_regs || size);
+#if defined(__mips__)
+ if (fp_regs)
+ *fp_regs = &mcontext.fpregs;
+ if (size)
+ *size = sizeof(mcontext.fpregs);
+#else
+ if (fp_regs)
+ *fp_regs = &fpregs;
+ if (size)
+ *size = sizeof(fpregs);
#endif
+}

} // namespace google_breakpad
=======================================
--- /trunk/src/client/linux/dump_writer_common/thread_info.h Tue Mar 24
11:25:14 2015 UTC
+++ /trunk/src/client/linux/dump_writer_common/thread_info.h Tue Apr 21
21:34:14 2015 UTC
@@ -69,11 +69,8 @@
struct user_pt_regs regs;
struct user_fpsimd_state fpregs;
#elif defined(__mips__)
- user_regs_struct regs;
- user_fpregs_struct fpregs;
- uint32_t hi[3];
- uint32_t lo[3];
- uint32_t dsp_control;
+ // Use the structure defined in <sys/ucontext.h>.
+ mcontext_t mcontext;
#endif

// Returns the instruction pointer (platform-dependent impl.).
@@ -81,6 +78,12 @@

// Fills a RawContextCPU using the context in the ThreadInfo object.
void FillCPUContext(RawContextCPU* out) const;
+
+ // Returns the pointer and size of general purpose register area.
+ void GetGeneralPurposeRegisters(void** gp_regs, size_t* size);
+
+ // Returns the pointer and size of float point register area.
+ void GetFloatingPointRegisters(void** fp_regs, size_t* size);
};

} // namespace google_breakpad
=======================================
--- /trunk/src/client/linux/minidump_writer/linux_core_dumper.cc Mon Feb 2
23:27:27 2015 UTC
+++ /trunk/src/client/linux/minidump_writer/linux_core_dumper.cc Tue Apr 21
21:34:14 2015 UTC
@@ -38,6 +38,10 @@
#include <stdio.h>
#include <string.h>
#include <sys/procfs.h>
+#if defined(__mips__) && defined(__ANDROID__)
+// To get register definitions.
+#include <asm/reg.h>
+#endif

#include "common/linux/linux_libc_support.h"

@@ -105,7 +109,7 @@
memcpy(&stack_pointer, &info->regs.sp, sizeof(info->regs.sp));
#elif defined(__mips__)
stack_pointer =
- reinterpret_cast<uint8_t*>(info->regs.regs[MD_CONTEXT_MIPS_REG_SP]);
+
reinterpret_cast<uint8_t*>(info->mcontext.gregs[MD_CONTEXT_MIPS_REG_SP]);
#else
#error "This code hasn't been ported to your platform yet."
#endif
@@ -191,18 +195,19 @@
info.tgid = status->pr_pgrp;
info.ppid = status->pr_ppid;
#if defined(__mips__)
+#if defined(__ANDROID__)
+ for (int i = EF_R0; i <= EF_R31; i++)
+ info.mcontext.gregs[i - EF_R0] = status->pr_reg[i];
+#else // __ANDROID__
for (int i = EF_REG0; i <= EF_REG31; i++)
- info.regs.regs[i - EF_REG0] = status->pr_reg[i];
-
- info.regs.lo = status->pr_reg[EF_LO];
- info.regs.hi = status->pr_reg[EF_HI];
- info.regs.epc = status->pr_reg[EF_CP0_EPC];
- info.regs.badvaddr = status->pr_reg[EF_CP0_BADVADDR];
- info.regs.status = status->pr_reg[EF_CP0_STATUS];
- info.regs.cause = status->pr_reg[EF_CP0_CAUSE];
-#else
+ info.mcontext.gregs[i - EF_REG0] = status->pr_reg[i];
+#endif // __ANDROID__
+ info.mcontext.mdlo = status->pr_reg[EF_LO];
+ info.mcontext.mdhi = status->pr_reg[EF_HI];
+ info.mcontext.pc = status->pr_reg[EF_CP0_EPC];
+#else // __mips__
memcpy(&info.regs, status->pr_reg, sizeof(info.regs));
-#endif
+#endif // __mips__
if (first_thread) {
crash_thread_ = pid;
crash_signal_ = status->pr_info.si_signo;
=======================================
--- /trunk/src/client/linux/minidump_writer/linux_ptrace_dumper.cc Mon Feb
2 23:27:27 2015 UTC
+++ /trunk/src/client/linux/minidump_writer/linux_ptrace_dumper.cc Tue Apr
21 21:34:14 2015 UTC
@@ -190,23 +190,25 @@

#ifdef PTRACE_GETREGSET
struct iovec io;
- io.iov_base = &info->regs;
- io.iov_len = sizeof(info->regs);
+ info->GetGeneralPurposeRegisters(&io.iov_base, &io.iov_len);
if (sys_ptrace(PTRACE_GETREGSET, tid, (void*)NT_PRSTATUS, (void*)&io) ==
-1) {
return false;
}

- io.iov_base = &info->fpregs;
- io.iov_len = sizeof(info->fpregs);
+ info->GetFloatingPointRegisters(&io.iov_base, &io.iov_len);
if (sys_ptrace(PTRACE_GETREGSET, tid, (void*)NT_FPREGSET, (void*)&io) ==
-1) {
return false;
}
-#else
- if (sys_ptrace(PTRACE_GETREGS, tid, NULL, &info->regs) == -1) {
+#else // PTRACE_GETREGSET
+ void* gp_addr;
+ info->GetGeneralPurposeRegisters(&gp_addr, NULL);
+ if (sys_ptrace(PTRACE_GETREGS, tid, NULL, gp_addr) == -1) {
return false;
}

- if (sys_ptrace(PTRACE_GETFPREGS, tid, NULL, &info->fpregs) == -1) {
+ void* fp_addr;
+ info->GetFloatingPointRegisters(&fp_addr, NULL);
+ if (sys_ptrace(PTRACE_GETFPREGS, tid, NULL, fp_addr) == -1) {
return false;
}
#endif
@@ -241,14 +243,20 @@
#endif

#if defined(__mips__)
- for (int i = 0; i < 3; ++i) {
- sys_ptrace(PTRACE_PEEKUSER, tid,
- reinterpret_cast<void*>(DSP_BASE + (i * 2)), &info->hi[i]);
- sys_ptrace(PTRACE_PEEKUSER, tid,
- reinterpret_cast<void*>(DSP_BASE + (i * 2) + 1),
&info->lo[i]);
- }
+ sys_ptrace(PTRACE_PEEKUSER, tid,
+ reinterpret_cast<void*>(DSP_BASE), &info->mcontext.hi1);
+ sys_ptrace(PTRACE_PEEKUSER, tid,
+ reinterpret_cast<void*>(DSP_BASE + 1), &info->mcontext.lo1);
+ sys_ptrace(PTRACE_PEEKUSER, tid,
+ reinterpret_cast<void*>(DSP_BASE + 2), &info->mcontext.hi2);
+ sys_ptrace(PTRACE_PEEKUSER, tid,
+ reinterpret_cast<void*>(DSP_BASE + 3), &info->mcontext.lo2);
+ sys_ptrace(PTRACE_PEEKUSER, tid,
+ reinterpret_cast<void*>(DSP_BASE + 4), &info->mcontext.hi3);
+ sys_ptrace(PTRACE_PEEKUSER, tid,
+ reinterpret_cast<void*>(DSP_BASE + 5), &info->mcontext.lo3);
sys_ptrace(PTRACE_PEEKUSER, tid,
- reinterpret_cast<void*>(DSP_CONTROL), &info->dsp_control);
+ reinterpret_cast<void*>(DSP_CONTROL), &info->mcontext.dsp);
#endif

const uint8_t* stack_pointer;
@@ -262,7 +270,7 @@
my_memcpy(&stack_pointer, &info->regs.sp, sizeof(info->regs.sp));
#elif defined(__mips__)
stack_pointer =
- reinterpret_cast<uint8_t*>(info->regs.regs[MD_CONTEXT_MIPS_REG_SP]);
+
reinterpret_cast<uint8_t*>(info->mcontext.gregs[MD_CONTEXT_MIPS_REG_SP]);
#else
#error "This code hasn't been ported to your platform yet."
#endif
=======================================
--- /trunk/src/client/linux/minidump_writer/linux_ptrace_dumper_unittest.cc
Tue Apr 8 17:36:11 2014 UTC
+++ /trunk/src/client/linux/minidump_writer/linux_ptrace_dumper_unittest.cc
Tue Apr 21 21:34:14 2015 UTC
@@ -441,7 +441,7 @@
pid_t* process_tid_location = (pid_t*)(one_thread.regs.rcx);
#elif defined(__mips__)
pid_t* process_tid_location =
- reinterpret_cast<pid_t*>(one_thread.regs.regs[1]);
+ reinterpret_cast<pid_t*>(one_thread.mcontext.gregs[1]);
#else
#error This test has not been ported to this platform.
#endif
=======================================
--- /trunk/src/common/android/include/sys/procfs.h Wed May 14 09:11:35 2014
UTC
+++ /trunk/src/common/android/include/sys/procfs.h Tue Apr 21 21:34:14 2015
UTC
@@ -38,6 +38,9 @@

#include <asm/ptrace.h>
#include <sys/cdefs.h>
+#if defined (__mips__)
+#include <sys/types.h>
+#endif
#include <sys/user.h>
#include <unistd.h>

=======================================
--- /trunk/src/common/android/include/sys/user.h Mon Mar 16 14:12:20 2015
UTC
+++ /trunk/src/common/android/include/sys/user.h Tue Apr 21 21:34:14 2015
UTC
@@ -33,88 +33,12 @@
// The purpose of this file is to glue the mismatching headers (Android
NDK vs
// glibc) and therefore avoid doing otherwise awkward #ifdefs in the code.
// The following quirks are currently handled by this file:
-// - MIPS: Keep using forked definitions of user.h structs. The definition
in
-// the NDK is completely different. Internal bug b/18097715
// - i386: Use the Android NDK but alias user_fxsr_struct >
user_fpxregs_struct.
// - x86_64: Override a typo in user_fpregs_struct (mxcsr_mask ->
mxcr_mask).
// The typo has been fixed in NDK r10d, but a preprocessor workaround
is
// required to make breakpad build with r10c and lower (more details
below).
// - Other platforms: Just use the Android NDK unchanged.

-#ifdef __mips__
-#ifdef __cplusplus
-extern "C" {
-#endif // __cplusplus
-
-#define EF_REG0 6
-#define EF_REG1 7
-#define EF_REG2 8
-#define EF_REG3 9
-#define EF_REG4 10
-#define EF_REG5 11
-#define EF_REG6 12
-#define EF_REG7 13
-#define EF_REG8 14
-#define EF_REG9 15
-#define EF_REG10 16
-#define EF_REG11 17
-#define EF_REG12 18
-#define EF_REG13 19
-#define EF_REG14 20
-#define EF_REG15 21
-#define EF_REG16 22
-#define EF_REG17 23
-#define EF_REG18 24
-#define EF_REG19 25
-#define EF_REG20 26
-#define EF_REG21 27
-#define EF_REG22 28
-#define EF_REG23 29
-#define EF_REG24 30
-#define EF_REG25 31
-
-/*
- * k0/k1 unsaved
- */
-#define EF_REG26 32
-#define EF_REG27 33
-#define EF_REG28 34
-#define EF_REG29 35
-#define EF_REG30 36
-#define EF_REG31 37
-
-/*
- * Saved special registers
- */
-#define EF_LO 38
-#define EF_HI 39
-#define EF_CP0_EPC 40
-#define EF_CP0_BADVADDR 41
-#define EF_CP0_STATUS 42
-#define EF_CP0_CAUSE 43
-
-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;
-};
-
-#ifdef __cplusplus
-} // extern "C"
-#endif // __cplusplus
-
-#else // __mips__
-
// TODO(primiano): remove this after Chromium has stably rolled to NDK
r10d.
// Historical context: NDK releases < r10d had a typo in sys/user.h
(mxcsr_mask
// instead of mxcr_mask), which is fixed in r10d. However, just switching
to use
@@ -143,6 +67,4 @@
#endif // __cplusplus
#endif // __i386__

-#endif // __mips__
-
#endif // GOOGLE_BREAKPAD_COMMON_ANDROID_INCLUDE_SYS_USER_H
=======================================
--- /trunk/src/google_breakpad/common/minidump_cpu_mips.h Wed Sep 25
08:18:03 2013 UTC
+++ /trunk/src/google_breakpad/common/minidump_cpu_mips.h Tue Apr 21
21:34:14 2015 UTC
@@ -66,24 +66,6 @@
#ifndef GOOGLE_BREAKPAD_COMMON_MINIDUMP_CPU_MIPS_H__
#define GOOGLE_BREAKPAD_COMMON_MINIDUMP_CPU_MIPS_H__

-#if defined(__mips__) && !defined(__ANDROID__)
-typedef struct {
- uint64_t regs[32];
- uint64_t lo;
- uint64_t hi;
- uint64_t epc;
- uint64_t badvaddr;
- uint64_t status;
- uint64_t cause;
-} user_regs_struct;
-
-typedef struct {
- uint64_t regs[32];
- uint32_t fpcsr;
- uint32_t fir;
-} user_fpregs_struct;
-#endif
-
#define MD_CONTEXT_MIPS_GPR_COUNT 32
#define MD_FLOATINGSAVEAREA_MIPS_FPR_COUNT 32
#define MD_CONTEXT_MIPS_DSP_COUNT 3
@@ -112,8 +94,8 @@

/* 32 64-bit integer registers, r0..r31.
* Note the following fixed uses:
- * r30 is the stack pointer.
- * r31 is the return address (link register).
+ * r29 is the stack pointer.
+ * r31 is the return address.
*/
uint64_t iregs[MD_CONTEXT_MIPS_GPR_COUNT];

=======================================
--- /trunk/src/tools/linux/md2core/minidump-2-core.cc Wed Apr 15 19:28:11
2015 UTC
+++ /trunk/src/tools/linux/md2core/minidump-2-core.cc Tue Apr 21 21:34:14
2015 UTC
@@ -81,6 +81,9 @@
// 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;
+#elif defined (__mips__)
+// This file-local typedef simplifies the source code.
+typedef gregset_t user_regs_struct;
#endif

using google_breakpad::MDTypeHelper;
@@ -208,13 +211,17 @@

struct Thread {
pid_t tid;
+#if defined(__mips__)
+ mcontext_t mcontext;
+#else // __mips__
user_regs_struct regs;
-#if defined(__i386__) || defined(__x86_64__) || defined(__mips__)
+#if defined(__i386__) || defined(__x86_64__)
user_fpregs_struct fpregs;
-#endif
+#endif // __i386__ || __x86_64__
#if defined(__i386__)
user_fpxregs_struct fpxregs;
-#endif
+#endif // __i386__
+#endif // __mips__
uintptr_t stack_addr;
const uint8_t* stack;
size_t stack_length;
@@ -371,21 +378,28 @@
const MDRawContextMIPS* rawregs = range.GetData<MDRawContextMIPS>(0);

for (int i = 0; i < MD_CONTEXT_MIPS_GPR_COUNT; ++i)
- thread->regs.regs[i] = rawregs->iregs[i];
+ thread->mcontext.gregs[i] = rawregs->iregs[i];

- thread->regs.lo = rawregs->mdlo;
- thread->regs.hi = rawregs->mdhi;
- thread->regs.epc = rawregs->epc;
- thread->regs.badvaddr = rawregs->badvaddr;
- thread->regs.status = rawregs->status;
- thread->regs.cause = rawregs->cause;
+ thread->mcontext.pc = rawregs->epc;

- for (int i = 0; i < MD_FLOATINGSAVEAREA_MIPS_FPR_COUNT; ++i)
- thread->fpregs.regs[i] = rawregs->float_save.regs[i];
+ thread->mcontext.mdlo = rawregs->mdlo;
+ thread->mcontext.mdhi = rawregs->mdhi;

- thread->fpregs.fpcsr = rawregs->float_save.fpcsr;
+ thread->mcontext.hi1 = rawregs->hi[0];
+ thread->mcontext.lo1 = rawregs->lo[0];
+ thread->mcontext.hi2 = rawregs->hi[1];
+ thread->mcontext.lo2 = rawregs->lo[1];
+ thread->mcontext.hi3 = rawregs->hi[2];
+ thread->mcontext.lo3 = rawregs->lo[2];
+
+ for (int i = 0; i < MD_FLOATINGSAVEAREA_MIPS_FPR_COUNT; ++i) {
+ thread->mcontext.fpregs.fp_r.fp_fregs[i]._fp_fregs =
+ rawregs->float_save.regs[i];
+ }
+
+ thread->mcontext.fpc_csr = rawregs->float_save.fpcsr;
#if _MIPS_SIM == _ABIO32
- thread->fpregs.fir = rawregs->float_save.fir;
+ thread->mcontext.fpc_eir = rawregs->float_save.fir;
#endif
}
#else
@@ -751,7 +765,11 @@
pr.pr_info.si_signo = fatal_signal;
pr.pr_cursig = fatal_signal;
pr.pr_pid = thread.tid;
+#if defined(__mips__)
+ memcpy(&pr.pr_reg, &thread.mcontext.gregs, sizeof(user_regs_struct));
+#else
memcpy(&pr.pr_reg, &thread.regs, sizeof(user_regs_struct));
+#endif

Nhdr nhdr;
memset(&nhdr, 0, sizeof(nhdr));
Reply all
Reply to author
Forward
0 new messages