diff options
author | thestig@chromium.org <thestig@chromium.org@4c0a9323-5329-0410-9bdc-e9ce6186880e> | 2013-04-12 23:24:02 +0000 |
---|---|---|
committer | thestig@chromium.org <thestig@chromium.org@4c0a9323-5329-0410-9bdc-e9ce6186880e> | 2013-04-12 23:24:02 +0000 |
commit | 0c759c6f62c9eff18087b04b1de3285978858629 (patch) | |
tree | 4b82392c19807cec5316faf130890de59b719f32 /src/processor/minidump.cc | |
parent | Fix build on Android - put the missing NT_GNU_BUILD_ID #define in elf_gnu_com... (diff) | |
download | breakpad-0c759c6f62c9eff18087b04b1de3285978858629.tar.xz |
Add PPC64 support to breakpad processor.
A=Jia Ji <jijia@google.com>
Original review: https://breakpad.appspot.com/557002/
Review URL: https://breakpad.appspot.com/558002
git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1147 4c0a9323-5329-0410-9bdc-e9ce6186880e
Diffstat (limited to 'src/processor/minidump.cc')
-rwxr-xr-x | src/processor/minidump.cc | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/src/processor/minidump.cc b/src/processor/minidump.cc index 43d22e61..17232b8d 100755 --- a/src/processor/minidump.cc +++ b/src/processor/minidump.cc @@ -409,6 +409,78 @@ bool MinidumpContext::Read(uint32_t expected_size) { context_.amd64 = context_amd64.release(); } + // |context_flags| of MDRawContextPPC64 is 64 bits, but other MDRawContext + // in the else case have 32 bits |context_flags|, so special case it here. + else if (expected_size == sizeof(MDRawContextPPC64)) { + uint64_t context_flags; + if (!minidump_->ReadBytes(&context_flags, sizeof(context_flags))) { + BPLOG(ERROR) << "MinidumpContext could not read context flags"; + return false; + } + if (minidump_->swap()) + Swap(&context_flags); + + uint32_t cpu_type = context_flags & MD_CONTEXT_CPU_MASK; + + scoped_ptr<MDRawContextPPC64> context_ppc64(new MDRawContextPPC64()); + + // Set the context_flags member, which has already been read, and + // read the rest of the structure beginning with the first member + // after context_flags. + context_ppc64->context_flags = context_flags; + + size_t flags_size = sizeof(context_ppc64->context_flags); + uint8_t* context_after_flags = + reinterpret_cast<uint8_t*>(context_ppc64.get()) + flags_size; + if (!minidump_->ReadBytes(context_after_flags, + sizeof(MDRawContextPPC64) - flags_size)) { + BPLOG(ERROR) << "MinidumpContext could not read ppc64 context"; + return false; + } + + // Do this after reading the entire MDRawContext structure because + // GetSystemInfo may seek minidump to a new position. + if (!CheckAgainstSystemInfo(cpu_type)) { + BPLOG(ERROR) << "MinidumpContext ppc64 does not match system info"; + return false; + } + if (minidump_->swap()) { + // context_ppc64->context_flags was already swapped. + Swap(&context_ppc64->srr0); + Swap(&context_ppc64->srr1); + for (unsigned int gpr_index = 0; + gpr_index < MD_CONTEXT_PPC64_GPR_COUNT; + ++gpr_index) { + Swap(&context_ppc64->gpr[gpr_index]); + } + Swap(&context_ppc64->cr); + Swap(&context_ppc64->xer); + Swap(&context_ppc64->lr); + Swap(&context_ppc64->ctr); + Swap(&context_ppc64->vrsave); + for (unsigned int fpr_index = 0; + fpr_index < MD_FLOATINGSAVEAREA_PPC_FPR_COUNT; + ++fpr_index) { + Swap(&context_ppc64->float_save.fpregs[fpr_index]); + } + // Don't swap context_ppc64->float_save.fpscr_pad because it is only + // used for padding. + Swap(&context_ppc64->float_save.fpscr); + for (unsigned int vr_index = 0; + vr_index < MD_VECTORSAVEAREA_PPC_VR_COUNT; + ++vr_index) { + Normalize128(&context_ppc64->vector_save.save_vr[vr_index], true); + Swap(&context_ppc64->vector_save.save_vr[vr_index]); + } + Swap(&context_ppc64->vector_save.save_vscr); + // Don't swap the padding fields in vector_save. + Swap(&context_ppc64->vector_save.save_vrvalid); + } + + context_flags_ = context_ppc64->context_flags; + context_.ppc64 = context_ppc64.release(); + } + else { uint32_t context_flags; if (!minidump_->ReadBytes(&context_flags, sizeof(context_flags))) { @@ -753,6 +825,9 @@ bool MinidumpContext::GetInstructionPointer(uint64_t* ip) const { case MD_CONTEXT_PPC: *ip = context_.ppc->srr0; break; + case MD_CONTEXT_PPC64: + *ip = context_.ppc64->srr0; + break; case MD_CONTEXT_SPARC: *ip = context_.ctx_sparc->pc; break; @@ -787,6 +862,15 @@ const MDRawContextPPC* MinidumpContext::GetContextPPC() const { return context_.ppc; } +const MDRawContextPPC64* MinidumpContext::GetContextPPC64() const { + if (GetContextCPU() != MD_CONTEXT_PPC64) { + BPLOG(ERROR) << "MinidumpContext cannot get ppc64 context"; + return NULL; + } + + return context_.ppc64; +} + const MDRawContextAMD64* MinidumpContext::GetContextAMD64() const { if (GetContextCPU() != MD_CONTEXT_AMD64) { BPLOG(ERROR) << "MinidumpContext cannot get amd64 context"; @@ -824,6 +908,10 @@ void MinidumpContext::FreeContext() { delete context_.ppc; break; + case MD_CONTEXT_PPC64: + delete context_.ppc64; + break; + case MD_CONTEXT_AMD64: delete context_.amd64; break; @@ -886,6 +974,11 @@ bool MinidumpContext::CheckAgainstSystemInfo(uint32_t context_cpu_type) { return_value = true; break; + case MD_CONTEXT_PPC64: + if (system_info_cpu_type == MD_CPU_ARCHITECTURE_PPC64) + return_value = true; + break; + case MD_CONTEXT_AMD64: if (system_info_cpu_type == MD_CPU_ARCHITECTURE_AMD64) return_value = true; @@ -1020,6 +1113,44 @@ void MinidumpContext::Print() { break; } + case MD_CONTEXT_PPC64: { + const MDRawContextPPC64* context_ppc64 = GetContextPPC64(); + printf("MDRawContextPPC64\n"); + printf(" context_flags = 0x%lx\n", + context_ppc64->context_flags); + printf(" srr0 = 0x%lx\n", context_ppc64->srr0); + printf(" srr1 = 0x%lx\n", context_ppc64->srr1); + for (unsigned int gpr_index = 0; + gpr_index < MD_CONTEXT_PPC64_GPR_COUNT; + ++gpr_index) { + printf(" gpr[%2d] = 0x%lx\n", + gpr_index, context_ppc64->gpr[gpr_index]); + } + printf(" cr = 0x%lx\n", context_ppc64->cr); + printf(" xer = 0x%lx\n", context_ppc64->xer); + printf(" lr = 0x%lx\n", context_ppc64->lr); + printf(" ctr = 0x%lx\n", context_ppc64->ctr); + printf(" vrsave = 0x%lx\n", context_ppc64->vrsave); + for (unsigned int fpr_index = 0; + fpr_index < MD_FLOATINGSAVEAREA_PPC_FPR_COUNT; + ++fpr_index) { + printf(" float_save.fpregs[%2d] = 0x%" PRIx64 "\n", + fpr_index, context_ppc64->float_save.fpregs[fpr_index]); + } + printf(" float_save.fpscr = 0x%x\n", + context_ppc64->float_save.fpscr); + // TODO(mmentovai): print the 128-bit quantities in + // context_ppc64->vector_save. This isn't done yet because printf + // doesn't support 128-bit quantities, and printing them using + // PRIx64 as two 64-bit quantities requires knowledge of the CPU's + // byte ordering. + printf(" vector_save.save_vrvalid = 0x%x\n", + context_ppc64->vector_save.save_vrvalid); + printf("\n"); + + break; + } + case MD_CONTEXT_AMD64: { const MDRawContextAMD64* context_amd64 = GetContextAMD64(); printf("MDRawContextAMD64\n"); @@ -3198,6 +3329,10 @@ string MinidumpSystemInfo::GetCPU() { cpu = "ppc"; break; + case MD_CPU_ARCHITECTURE_PPC64: + cpu = "ppc64"; + break; + case MD_CPU_ARCHITECTURE_SPARC: cpu = "sparc"; break; @@ -3863,6 +3998,9 @@ bool Minidump::GetContextCPUFlagsFromSystemInfo(uint32_t *context_cpu_flags) { case MD_CPU_ARCHITECTURE_PPC: *context_cpu_flags = MD_CONTEXT_PPC; break; + case MD_CPU_ARCHITECTURE_PPC64: + *context_cpu_flags = MD_CONTEXT_PPC64; + break; case MD_CPU_ARCHITECTURE_SHX: *context_cpu_flags = MD_CONTEXT_SHX; break; |