mirror of
https://git.suyu.dev/suyu/breakpad.git
synced 2025-12-22 13:46:23 +01:00
Adding support for mips.
Support for mips cpu is added to all breakapad targets including unittests. BUG=none TEST=unittests Review URL: https://breakpad.appspot.com/614002 git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1212 4c0a9323-5329-0410-9bdc-e9ce6186880e
This commit is contained in:
parent
ae35566b8d
commit
f78839c157
31 changed files with 2095 additions and 39 deletions
|
|
@ -35,6 +35,9 @@
|
|||
#include <sys/socket.h>
|
||||
#include <sys/uio.h>
|
||||
#include <sys/wait.h>
|
||||
#if defined(__mips__)
|
||||
#include <sys/cachectl.h>
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
|
||||
|
|
@ -55,7 +58,7 @@ using namespace google_breakpad;
|
|||
namespace {
|
||||
|
||||
// Flush the instruction cache for a given memory range.
|
||||
// Only required on ARM.
|
||||
// Only required on ARM and mips.
|
||||
void FlushInstructionCache(const char* memory, uint32_t memory_size) {
|
||||
#if defined(__arm__)
|
||||
long begin = reinterpret_cast<long>(memory);
|
||||
|
|
@ -72,6 +75,13 @@ void FlushInstructionCache(const char* memory, uint32_t memory_size) {
|
|||
# else
|
||||
# error "Your operating system is not supported yet"
|
||||
# endif
|
||||
#elif defined(__mips__)
|
||||
# if defined(__linux__)
|
||||
// See http://www.linux-mips.org/wiki/Cacheflush_Syscall.
|
||||
cacheflush(const_cast<char*>(memory), memory_size, ICACHE);
|
||||
# else
|
||||
# error "Your operating system is not supported yet"
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -435,6 +445,16 @@ TEST(ExceptionHandlerTest, StackedHandlersUnhandledToBottom) {
|
|||
ASSERT_NO_FATAL_FAILURE(WaitForProcessToTerminate(child, SIGKILL));
|
||||
}
|
||||
|
||||
const unsigned char kIllegalInstruction[] = {
|
||||
#if defined(__mips__)
|
||||
// mfc2 zero,Impl - usually illegal in userspace.
|
||||
0x48, 0x00, 0x00, 0x48
|
||||
#else
|
||||
// This crashes with SIGILL on x86/x86-64/arm.
|
||||
0xff, 0xff, 0xff, 0xff
|
||||
#endif
|
||||
};
|
||||
|
||||
// Test that memory around the instruction pointer is written
|
||||
// to the dump as a MinidumpMemoryRegion.
|
||||
TEST(ExceptionHandlerTest, InstructionPointerMemory) {
|
||||
|
|
@ -446,8 +466,6 @@ TEST(ExceptionHandlerTest, InstructionPointerMemory) {
|
|||
// data from the minidump afterwards.
|
||||
const uint32_t kMemorySize = 256; // bytes
|
||||
const int kOffset = kMemorySize / 2;
|
||||
// This crashes with SIGILL on x86/x86-64/arm.
|
||||
const unsigned char instructions[] = { 0xff, 0xff, 0xff, 0xff };
|
||||
|
||||
const pid_t child = fork();
|
||||
if (child == 0) {
|
||||
|
|
@ -469,7 +487,7 @@ TEST(ExceptionHandlerTest, InstructionPointerMemory) {
|
|||
// Write some instructions that will crash. Put them in the middle
|
||||
// of the block of memory, because the minidump should contain 128
|
||||
// bytes on either side of the instruction pointer.
|
||||
memcpy(memory + kOffset, instructions, sizeof(instructions));
|
||||
memcpy(memory + kOffset, kIllegalInstruction, sizeof(kIllegalInstruction));
|
||||
FlushInstructionCache(memory, kMemorySize);
|
||||
|
||||
// Now execute the instructions, which should crash.
|
||||
|
|
@ -517,12 +535,13 @@ TEST(ExceptionHandlerTest, InstructionPointerMemory) {
|
|||
ASSERT_TRUE(bytes);
|
||||
|
||||
uint8_t prefix_bytes[kOffset];
|
||||
uint8_t suffix_bytes[kMemorySize - kOffset - sizeof(instructions)];
|
||||
uint8_t suffix_bytes[kMemorySize - kOffset - sizeof(kIllegalInstruction)];
|
||||
memset(prefix_bytes, 0, sizeof(prefix_bytes));
|
||||
memset(suffix_bytes, 0, sizeof(suffix_bytes));
|
||||
EXPECT_TRUE(memcmp(bytes, prefix_bytes, sizeof(prefix_bytes)) == 0);
|
||||
EXPECT_TRUE(memcmp(bytes + kOffset, instructions, sizeof(instructions)) == 0);
|
||||
EXPECT_TRUE(memcmp(bytes + kOffset + sizeof(instructions),
|
||||
EXPECT_TRUE(memcmp(bytes + kOffset, kIllegalInstruction,
|
||||
sizeof(kIllegalInstruction)) == 0);
|
||||
EXPECT_TRUE(memcmp(bytes + kOffset + sizeof(kIllegalInstruction),
|
||||
suffix_bytes, sizeof(suffix_bytes)) == 0);
|
||||
|
||||
unlink(minidump_path.c_str());
|
||||
|
|
@ -539,8 +558,6 @@ TEST(ExceptionHandlerTest, InstructionPointerMemoryMinBound) {
|
|||
// data from the minidump afterwards.
|
||||
const uint32_t kMemorySize = 256; // bytes
|
||||
const int kOffset = 0;
|
||||
// This crashes with SIGILL on x86/x86-64/arm.
|
||||
const unsigned char instructions[] = { 0xff, 0xff, 0xff, 0xff };
|
||||
|
||||
const pid_t child = fork();
|
||||
if (child == 0) {
|
||||
|
|
@ -562,7 +579,7 @@ TEST(ExceptionHandlerTest, InstructionPointerMemoryMinBound) {
|
|||
// Write some instructions that will crash. Put them in the middle
|
||||
// of the block of memory, because the minidump should contain 128
|
||||
// bytes on either side of the instruction pointer.
|
||||
memcpy(memory + kOffset, instructions, sizeof(instructions));
|
||||
memcpy(memory + kOffset, kIllegalInstruction, sizeof(kIllegalInstruction));
|
||||
FlushInstructionCache(memory, kMemorySize);
|
||||
|
||||
// Now execute the instructions, which should crash.
|
||||
|
|
@ -609,10 +626,11 @@ TEST(ExceptionHandlerTest, InstructionPointerMemoryMinBound) {
|
|||
const uint8_t* bytes = region->GetMemory();
|
||||
ASSERT_TRUE(bytes);
|
||||
|
||||
uint8_t suffix_bytes[kMemorySize / 2 - sizeof(instructions)];
|
||||
uint8_t suffix_bytes[kMemorySize / 2 - sizeof(kIllegalInstruction)];
|
||||
memset(suffix_bytes, 0, sizeof(suffix_bytes));
|
||||
EXPECT_TRUE(memcmp(bytes + kOffset, instructions, sizeof(instructions)) == 0);
|
||||
EXPECT_TRUE(memcmp(bytes + kOffset + sizeof(instructions),
|
||||
EXPECT_TRUE(memcmp(bytes + kOffset, kIllegalInstruction,
|
||||
sizeof(kIllegalInstruction)) == 0);
|
||||
EXPECT_TRUE(memcmp(bytes + kOffset + sizeof(kIllegalInstruction),
|
||||
suffix_bytes, sizeof(suffix_bytes)) == 0);
|
||||
unlink(minidump_path.c_str());
|
||||
}
|
||||
|
|
@ -630,9 +648,7 @@ TEST(ExceptionHandlerTest, InstructionPointerMemoryMaxBound) {
|
|||
// if a smaller size is requested, and this test wants to
|
||||
// test the upper bound of the memory range.
|
||||
const uint32_t kMemorySize = 4096; // bytes
|
||||
// This crashes with SIGILL on x86/x86-64/arm.
|
||||
const unsigned char instructions[] = { 0xff, 0xff, 0xff, 0xff };
|
||||
const int kOffset = kMemorySize - sizeof(instructions);
|
||||
const int kOffset = kMemorySize - sizeof(kIllegalInstruction);
|
||||
|
||||
const pid_t child = fork();
|
||||
if (child == 0) {
|
||||
|
|
@ -654,7 +670,7 @@ TEST(ExceptionHandlerTest, InstructionPointerMemoryMaxBound) {
|
|||
// Write some instructions that will crash. Put them in the middle
|
||||
// of the block of memory, because the minidump should contain 128
|
||||
// bytes on either side of the instruction pointer.
|
||||
memcpy(memory + kOffset, instructions, sizeof(instructions));
|
||||
memcpy(memory + kOffset, kIllegalInstruction, sizeof(kIllegalInstruction));
|
||||
FlushInstructionCache(memory, kMemorySize);
|
||||
|
||||
// Now execute the instructions, which should crash.
|
||||
|
|
@ -697,7 +713,7 @@ TEST(ExceptionHandlerTest, InstructionPointerMemoryMaxBound) {
|
|||
ASSERT_TRUE(region);
|
||||
|
||||
const size_t kPrefixSize = 128; // bytes
|
||||
EXPECT_EQ(kPrefixSize + sizeof(instructions), region->GetSize());
|
||||
EXPECT_EQ(kPrefixSize + sizeof(kIllegalInstruction), region->GetSize());
|
||||
const uint8_t* bytes = region->GetMemory();
|
||||
ASSERT_TRUE(bytes);
|
||||
|
||||
|
|
@ -705,7 +721,7 @@ TEST(ExceptionHandlerTest, InstructionPointerMemoryMaxBound) {
|
|||
memset(prefix_bytes, 0, sizeof(prefix_bytes));
|
||||
EXPECT_TRUE(memcmp(bytes, prefix_bytes, sizeof(prefix_bytes)) == 0);
|
||||
EXPECT_TRUE(memcmp(bytes + kPrefixSize,
|
||||
instructions, sizeof(instructions)) == 0);
|
||||
kIllegalInstruction, sizeof(kIllegalInstruction)) == 0);
|
||||
|
||||
unlink(minidump_path.c_str());
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue