aboutsummaryrefslogtreecommitdiff
path: root/src/processor/minidump.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/processor/minidump.cc')
-rw-r--r--src/processor/minidump.cc87
1 files changed, 85 insertions, 2 deletions
diff --git a/src/processor/minidump.cc b/src/processor/minidump.cc
index 0c13e00e..0bd1f6ba 100644
--- a/src/processor/minidump.cc
+++ b/src/processor/minidump.cc
@@ -286,8 +286,8 @@ MinidumpStream::MinidumpStream(Minidump* minidump)
MinidumpContext::MinidumpContext(Minidump* minidump)
: MinidumpStream(minidump),
- context_flags_(0),
- context_() {
+ context_(),
+ context_flags_(0) {
}
@@ -318,6 +318,14 @@ bool MinidumpContext::Read(u_int32_t expected_size) {
Swap(&context_amd64->context_flags);
u_int32_t cpu_type = context_amd64->context_flags & MD_CONTEXT_CPU_MASK;
+ if (cpu_type == 0) {
+ if (minidump_->GetContextCPUFlagsFromSystemInfo(&cpu_type)) {
+ context_amd64->context_flags |= cpu_type;
+ } else {
+ BPLOG(ERROR) << "Failed to preserve the current stream position";
+ return false;
+ }
+ }
if (cpu_type != MD_CONTEXT_AMD64) {
//TODO: fall through to switch below?
@@ -422,6 +430,15 @@ bool MinidumpContext::Read(u_int32_t expected_size) {
}
}
+ if (cpu_type == 0) {
+ if (minidump_->GetContextCPUFlagsFromSystemInfo(&cpu_type)) {
+ context_flags |= cpu_type;
+ } else {
+ BPLOG(ERROR) << "Failed to preserve the current stream position";
+ return false;
+ }
+ }
+
// Allocate the context structure for the correct CPU and fill it. The
// casts are slightly unorthodox, but it seems better to do that than to
// maintain a separate pointer for each type of CPU context structure
@@ -3816,6 +3833,72 @@ bool Minidump::Open() {
return true;
}
+bool Minidump::GetContextCPUFlagsFromSystemInfo(u_int32_t *context_cpu_flags) {
+ // Initialize output parameters
+ *context_cpu_flags = 0;
+
+ // Save the current stream position
+ off_t saved_position = Tell();
+ if (saved_position == -1) {
+ // Failed to save the current stream position.
+ // Returns true because the current position of the stream is preserved.
+ return true;
+ }
+
+ const MDRawSystemInfo* system_info =
+ GetSystemInfo() ? GetSystemInfo()->system_info() : NULL;
+
+ if (system_info != NULL) {
+ switch (system_info->processor_architecture) {
+ case MD_CPU_ARCHITECTURE_X86:
+ *context_cpu_flags = MD_CONTEXT_X86;
+ break;
+ case MD_CPU_ARCHITECTURE_MIPS:
+ *context_cpu_flags = MD_CONTEXT_MIPS;
+ break;
+ case MD_CPU_ARCHITECTURE_ALPHA:
+ *context_cpu_flags = MD_CONTEXT_ALPHA;
+ break;
+ case MD_CPU_ARCHITECTURE_PPC:
+ *context_cpu_flags = MD_CONTEXT_PPC;
+ break;
+ case MD_CPU_ARCHITECTURE_SHX:
+ *context_cpu_flags = MD_CONTEXT_SHX;
+ break;
+ case MD_CPU_ARCHITECTURE_ARM:
+ *context_cpu_flags = MD_CONTEXT_ARM;
+ break;
+ case MD_CPU_ARCHITECTURE_IA64:
+ *context_cpu_flags = MD_CONTEXT_IA64;
+ break;
+ case MD_CPU_ARCHITECTURE_ALPHA64:
+ *context_cpu_flags = 0;
+ break;
+ case MD_CPU_ARCHITECTURE_MSIL:
+ *context_cpu_flags = 0;
+ break;
+ case MD_CPU_ARCHITECTURE_AMD64:
+ *context_cpu_flags = MD_CONTEXT_AMD64;
+ break;
+ case MD_CPU_ARCHITECTURE_X86_WIN64:
+ *context_cpu_flags = 0;
+ break;
+ case MD_CPU_ARCHITECTURE_SPARC:
+ *context_cpu_flags = MD_CONTEXT_SPARC;
+ break;
+ case MD_CPU_ARCHITECTURE_UNKNOWN:
+ *context_cpu_flags = 0;
+ break;
+ default:
+ *context_cpu_flags = 0;
+ break;
+ }
+ }
+
+ // Restore position and return
+ return SeekSet(saved_position);
+}
+
bool Minidump::Read() {
// Invalidate cached data.