Use general instruction/stack pointer convenience method instead of manually

finding the instruction/stack pointer for exploitability rating.

There was already a method that found the instruction pointer, so the files
for exploitability ratings had repeated code. Also a method for finding the
stack pointer is implemented in this CL.

R=ivanpe@chromium.org

Review URL: https://codereview.chromium.org/1210943005

git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1468 4c0a9323-5329-0410-9bdc-e9ce6186880e
This commit is contained in:
Liu.andrew.x@gmail.com 2015-06-30 23:22:09 +00:00
parent ca21e62ecf
commit ff4d8facbf
7 changed files with 74 additions and 33 deletions

View File

@ -140,6 +140,11 @@ typedef struct {
MDVectorSaveAreaPPC vector_save; MDVectorSaveAreaPPC vector_save;
} MDRawContextPPC; /* Based on ppc_thread_state */ } MDRawContextPPC; /* Based on ppc_thread_state */
/* Indices into gpr for registers with a dedicated or conventional purpose. */
enum MDPPCRegisterNumbers {
MD_CONTEXT_PPC_REG_SP = 1
};
#if defined(__SUNPRO_C) || defined(__SUNPRO_CC) #if defined(__SUNPRO_C) || defined(__SUNPRO_CC)
#pragma pack(0) #pragma pack(0)
#else #else

View File

@ -112,6 +112,11 @@ typedef struct {
MDVectorSaveAreaPPC vector_save; MDVectorSaveAreaPPC vector_save;
} MDRawContextPPC64; /* Based on ppc_thread_state */ } MDRawContextPPC64; /* Based on ppc_thread_state */
/* Indices into gpr for registers with a dedicated or conventional purpose. */
enum MDPPC64RegisterNumbers {
MD_CONTEXT_PPC64_REG_SP = 1
};
/* For (MDRawContextPPC).context_flags. These values indicate the type of /* For (MDRawContextPPC).context_flags. These values indicate the type of
* context stored in the structure. MD_CONTEXT_PPC is Breakpad-defined. Its * context stored in the structure. MD_CONTEXT_PPC is Breakpad-defined. Its
* value was chosen to avoid likely conflicts with MD_CONTEXT_* for other * value was chosen to avoid likely conflicts with MD_CONTEXT_* for other

View File

@ -138,6 +138,11 @@ typedef struct {
} MDRawContextSPARC; /* CONTEXT_SPARC */ } MDRawContextSPARC; /* CONTEXT_SPARC */
/* Indices into g_r for registers with a dedicated or conventional purpose. */
enum MDSPARCRegisterNumbers {
MD_CONTEXT_SPARC_REG_SP = 14
};
/* For (MDRawContextSPARC).context_flags. These values indicate the type of /* For (MDRawContextSPARC).context_flags. These values indicate the type of
* context stored in the structure. MD_CONTEXT_SPARC is Breakpad-defined. Its * context stored in the structure. MD_CONTEXT_SPARC is Breakpad-defined. Its
* value was chosen to avoid likely conflicts with MD_CONTEXT_* for other * value was chosen to avoid likely conflicts with MD_CONTEXT_* for other

View File

@ -67,6 +67,10 @@ class DumpContext : public DumpObject {
// MDRawContext, since it varies per-CPU architecture. // MDRawContext, since it varies per-CPU architecture.
bool GetInstructionPointer(uint64_t* ip) const; bool GetInstructionPointer(uint64_t* ip) const;
// Similar to the GetInstructionPointer method, this method gets the stack
// pointer for all CPU architectures.
bool GetStackPointer(uint64_t* sp) const;
// Print a human-readable representation of the object to stdout. // Print a human-readable representation of the object to stdout.
void Print(); void Print();

View File

@ -185,6 +185,49 @@ bool DumpContext::GetInstructionPointer(uint64_t* ip) const {
return true; return true;
} }
bool DumpContext::GetStackPointer(uint64_t* sp) const {
BPLOG_IF(ERROR, !sp) << "DumpContext::GetStackPointer requires |sp|";
assert(sp);
*sp = 0;
if (!valid_) {
BPLOG(ERROR) << "Invalid DumpContext for GetStackPointer";
return false;
}
switch (GetContextCPU()) {
case MD_CONTEXT_AMD64:
*sp = GetContextAMD64()->rsp;
break;
case MD_CONTEXT_ARM:
*sp = GetContextARM()->iregs[MD_CONTEXT_ARM_REG_SP];
break;
case MD_CONTEXT_ARM64:
*sp = GetContextARM64()->iregs[MD_CONTEXT_ARM64_REG_SP];
break;
case MD_CONTEXT_PPC:
*sp = GetContextPPC()->gpr[MD_CONTEXT_PPC_REG_SP];
break;
case MD_CONTEXT_PPC64:
*sp = GetContextPPC64()->gpr[MD_CONTEXT_PPC64_REG_SP];
break;
case MD_CONTEXT_SPARC:
*sp = GetContextSPARC()->g_r[MD_CONTEXT_SPARC_REG_SP];
break;
case MD_CONTEXT_X86:
*sp = GetContextX86()->esp;
break;
case MD_CONTEXT_MIPS:
*sp = GetContextMIPS()->iregs[MD_CONTEXT_MIPS_REG_SP];
break;
default:
// This should never happen.
BPLOG(ERROR) << "Unknown CPU architecture in GetStackPointer";
return false;
}
return true;
}
void DumpContext::SetContextFlags(uint32_t context_flags) { void DumpContext::SetContextFlags(uint32_t context_flags) {
context_flags_ = context_flags; context_flags_ = context_flags;
} }

View File

@ -37,8 +37,8 @@
#include "processor/exploitability_linux.h" #include "processor/exploitability_linux.h"
#include "google_breakpad/common/minidump_exception_linux.h" #include "google_breakpad/common/minidump_exception_linux.h"
#include "google_breakpad/processor/process_state.h"
#include "google_breakpad/processor/call_stack.h" #include "google_breakpad/processor/call_stack.h"
#include "google_breakpad/processor/process_state.h"
#include "google_breakpad/processor/stack_frame.h" #include "google_breakpad/processor/stack_frame.h"
#include "processor/logging.h" #include "processor/logging.h"
@ -98,26 +98,9 @@ ExploitabilityRating ExploitabilityLinux::CheckPlatformExploitability() {
return EXPLOITABILITY_ERR_PROCESSING; return EXPLOITABILITY_ERR_PROCESSING;
} }
// Getting instruction pointer based off architecture. // Getting the instruction pointer.
uint32_t architecture = context->GetContextCPU(); if (!context->GetInstructionPointer(&instruction_ptr)) {
switch (architecture) { return EXPLOITABILITY_ERR_PROCESSING;
case MD_CONTEXT_X86:
instruction_ptr = context->GetContextX86()->eip;
break;
case MD_CONTEXT_AMD64:
instruction_ptr = context->GetContextAMD64()->rip;
break;
case MD_CONTEXT_ARM:
instruction_ptr =
context->GetContextARM()->iregs[MD_CONTEXT_ARM_REG_PC];
break;
case MD_CONTEXT_ARM64:
instruction_ptr =
context->GetContextARM64()->iregs[MD_CONTEXT_ARM64_REG_PC];
break;
default:
BPLOG(INFO) << "Unsupported architecture.";
return EXPLOITABILITY_ERR_PROCESSING;
} }
// Checking for the instruction pointer in a valid instruction region. // Checking for the instruction pointer in a valid instruction region.

View File

@ -106,18 +106,14 @@ ExploitabilityRating ExploitabilityWin::CheckPlatformExploitability() {
uint64_t stack_ptr = 0; uint64_t stack_ptr = 0;
uint64_t instruction_ptr = 0; uint64_t instruction_ptr = 0;
switch (context->GetContextCPU()) { // Getting the instruction pointer.
case MD_CONTEXT_X86: if (!context->GetInstructionPointer(&instruction_ptr)) {
stack_ptr = context->GetContextX86()->esp; return EXPLOITABILITY_ERR_PROCESSING;
instruction_ptr = context->GetContextX86()->eip; }
break;
case MD_CONTEXT_AMD64: // Getting the stack pointer.
stack_ptr = context->GetContextAMD64()->rsp; if (!context->GetStackPointer(&stack_ptr)) {
instruction_ptr = context->GetContextAMD64()->rip; return EXPLOITABILITY_ERR_PROCESSING;
break;
default:
BPLOG(INFO) << "Unsupported architecture.";
return EXPLOITABILITY_ERR_PROCESSING;
} }
// Check if we are executing on the stack. // Check if we are executing on the stack.