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:
gordana.cmiljanovic@imgtec.com 2013-09-11 11:37:04 +00:00
parent ae35566b8d
commit f78839c157
31 changed files with 2095 additions and 39 deletions

View file

@ -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());
}