diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
commit | 36d22d82aa202bb199967e9512281e9a53db42c9 (patch) | |
tree | 105e8c98ddea1c1e4784a60a5a6410fa416be2de /toolkit/crashreporter/breakpad-patches/14-handle-non-fixed-size-amd64-and-x86-contexts.patch | |
parent | Initial commit. (diff) | |
download | firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip |
Adding upstream version 115.7.0esr.upstream/115.7.0esrupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'toolkit/crashreporter/breakpad-patches/14-handle-non-fixed-size-amd64-and-x86-contexts.patch')
-rw-r--r-- | toolkit/crashreporter/breakpad-patches/14-handle-non-fixed-size-amd64-and-x86-contexts.patch | 344 |
1 files changed, 344 insertions, 0 deletions
diff --git a/toolkit/crashreporter/breakpad-patches/14-handle-non-fixed-size-amd64-and-x86-contexts.patch b/toolkit/crashreporter/breakpad-patches/14-handle-non-fixed-size-amd64-and-x86-contexts.patch new file mode 100644 index 0000000000..b9544281c2 --- /dev/null +++ b/toolkit/crashreporter/breakpad-patches/14-handle-non-fixed-size-amd64-and-x86-contexts.patch @@ -0,0 +1,344 @@ +diff --git a/src/processor/minidump.cc b/src/processor/minidump.cc +index 1f479558..aa63fe47 100644 +--- a/src/processor/minidump.cc ++++ b/src/processor/minidump.cc +@@ -444,140 +444,30 @@ MinidumpContext::MinidumpContext(Minidump* minidump) + + MinidumpContext::~MinidumpContext() { + } + + bool MinidumpContext::Read(uint32_t expected_size) { + valid_ = false; + + // Certain raw context types are currently assumed to have unique sizes. +- if (!IsContextSizeUnique(sizeof(MDRawContextAMD64))) { +- BPLOG(ERROR) << "sizeof(MDRawContextAMD64) cannot match the size of any " +- << "other raw context"; +- return false; +- } + if (!IsContextSizeUnique(sizeof(MDRawContextPPC64))) { + BPLOG(ERROR) << "sizeof(MDRawContextPPC64) cannot match the size of any " + << "other raw context"; + return false; + } + if (!IsContextSizeUnique(sizeof(MDRawContextARM64_Old))) { + BPLOG(ERROR) << "sizeof(MDRawContextARM64_Old) cannot match the size of any " + << "other raw context"; + return false; + } + + FreeContext(); + +- // First, figure out what type of CPU this context structure is for. +- // For some reason, the AMD64 Context doesn't have context_flags +- // at the beginning of the structure, so special case it here. +- if (expected_size == sizeof(MDRawContextAMD64)) { +- BPLOG(INFO) << "MinidumpContext: looks like AMD64 context"; +- +- scoped_ptr<MDRawContextAMD64> context_amd64(new MDRawContextAMD64()); +- if (!minidump_->ReadBytes(context_amd64.get(), +- sizeof(MDRawContextAMD64))) { +- BPLOG(ERROR) << "MinidumpContext could not read amd64 context"; +- return false; +- } +- +- if (minidump_->swap()) +- Swap(&context_amd64->context_flags); +- +- uint32_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. +- // https://bugs.chromium.org/p/google-breakpad/issues/detail?id=550 +- BPLOG(ERROR) << "MinidumpContext not actually amd64 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 amd64 does not match system info"; +- return false; +- } +- +- // Normalize the 128-bit types in the dump. +- // Since this is AMD64, by definition, the values are little-endian. +- for (unsigned int vr_index = 0; +- vr_index < MD_CONTEXT_AMD64_VR_COUNT; +- ++vr_index) +- Normalize128(&context_amd64->vector_register[vr_index], false); +- +- if (minidump_->swap()) { +- Swap(&context_amd64->p1_home); +- Swap(&context_amd64->p2_home); +- Swap(&context_amd64->p3_home); +- Swap(&context_amd64->p4_home); +- Swap(&context_amd64->p5_home); +- Swap(&context_amd64->p6_home); +- // context_flags is already swapped +- Swap(&context_amd64->mx_csr); +- Swap(&context_amd64->cs); +- Swap(&context_amd64->ds); +- Swap(&context_amd64->es); +- Swap(&context_amd64->fs); +- Swap(&context_amd64->ss); +- Swap(&context_amd64->eflags); +- Swap(&context_amd64->dr0); +- Swap(&context_amd64->dr1); +- Swap(&context_amd64->dr2); +- Swap(&context_amd64->dr3); +- Swap(&context_amd64->dr6); +- Swap(&context_amd64->dr7); +- Swap(&context_amd64->rax); +- Swap(&context_amd64->rcx); +- Swap(&context_amd64->rdx); +- Swap(&context_amd64->rbx); +- Swap(&context_amd64->rsp); +- Swap(&context_amd64->rbp); +- Swap(&context_amd64->rsi); +- Swap(&context_amd64->rdi); +- Swap(&context_amd64->r8); +- Swap(&context_amd64->r9); +- Swap(&context_amd64->r10); +- Swap(&context_amd64->r11); +- Swap(&context_amd64->r12); +- Swap(&context_amd64->r13); +- Swap(&context_amd64->r14); +- Swap(&context_amd64->r15); +- Swap(&context_amd64->rip); +- // FIXME: I'm not sure what actually determines +- // which member of the union {flt_save, sse_registers} +- // is valid. We're not currently using either, +- // but it would be good to have them swapped properly. +- +- for (unsigned int vr_index = 0; +- vr_index < MD_CONTEXT_AMD64_VR_COUNT; +- ++vr_index) +- Swap(&context_amd64->vector_register[vr_index]); +- Swap(&context_amd64->vector_control); +- Swap(&context_amd64->debug_control); +- Swap(&context_amd64->last_branch_to_rip); +- Swap(&context_amd64->last_branch_from_rip); +- Swap(&context_amd64->last_exception_to_rip); +- Swap(&context_amd64->last_exception_from_rip); +- } +- +- SetContextFlags(context_amd64->context_flags); +- +- SetContextAMD64(context_amd64.release()); +- } else if (expected_size == sizeof(MDRawContextPPC64)) { ++ if (expected_size == sizeof(MDRawContextPPC64)) { + // |context_flags| of MDRawContextPPC64 is 64 bits, but other MDRawContext + // in the else case have 32 bits |context_flags|, so special case it here. + 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()) +@@ -739,56 +629,152 @@ bool MinidumpContext::Read(uint32_t expected_size) { + } + } + + scoped_ptr<MDRawContextARM64> new_context(new MDRawContextARM64()); + ConvertOldARM64Context(*context_arm64.get(), new_context.get()); + SetContextFlags(new_context->context_flags); + SetContextARM64(new_context.release()); + } else { +- uint32_t context_flags; +- if (!minidump_->ReadBytes(&context_flags, sizeof(context_flags))) { +- BPLOG(ERROR) << "MinidumpContext could not read context flags"; ++ uint32_t cpu_type = 0; ++ if (!minidump_->GetContextCPUFlagsFromSystemInfo(&cpu_type)) { ++ BPLOG(ERROR) << "Failed to preserve the current stream position"; + return false; + } +- if (minidump_->swap()) +- Swap(&context_flags); + +- uint32_t cpu_type = context_flags & MD_CONTEXT_CPU_MASK; +- if (cpu_type == 0) { +- // Unfortunately the flag for MD_CONTEXT_ARM that was taken +- // from a Windows CE SDK header conflicts in practice with +- // the CONTEXT_XSTATE flag. MD_CONTEXT_ARM has been renumbered, +- // but handle dumps with the legacy value gracefully here. +- if (context_flags & MD_CONTEXT_ARM_OLD) { +- context_flags |= MD_CONTEXT_ARM; +- context_flags &= ~MD_CONTEXT_ARM_OLD; +- cpu_type = MD_CONTEXT_ARM; ++ uint32_t context_flags = 0; ++ if ((cpu_type == 0) || cpu_type != MD_CONTEXT_AMD64) { ++ if (!minidump_->ReadBytes(&context_flags, sizeof(context_flags))) { ++ BPLOG(ERROR) << "MinidumpContext could not read context flags"; ++ return false; + } +- } + +- if (cpu_type == 0) { +- if (minidump_->GetContextCPUFlagsFromSystemInfo(&cpu_type)) { +- context_flags |= cpu_type; ++ if (minidump_->swap()) ++ Swap(&context_flags); ++ ++ if ((context_flags & MD_CONTEXT_CPU_MASK) == 0) { ++ // Unfortunately the flag for MD_CONTEXT_ARM that was taken ++ // from a Windows CE SDK header conflicts in practice with ++ // the CONTEXT_XSTATE flag. MD_CONTEXT_ARM has been renumbered, ++ // but handle dumps with the legacy value gracefully here. ++ if (context_flags & MD_CONTEXT_ARM_OLD) { ++ context_flags |= MD_CONTEXT_ARM; ++ context_flags &= ~MD_CONTEXT_ARM_OLD; ++ cpu_type = MD_CONTEXT_ARM; ++ } else { ++ context_flags |= cpu_type; ++ } + } else { +- BPLOG(ERROR) << "Failed to preserve the current stream position"; +- return false; ++ cpu_type = context_flags & MD_CONTEXT_CPU_MASK; + } + } + + // 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 + // when only one of them will be used. + switch (cpu_type) { ++ case MD_CONTEXT_AMD64: { ++ if (expected_size != sizeof(MDRawContextAMD64)) { ++ BPLOG(INFO) << "MinidumpContext AMD64 size mismatch, " << ++ expected_size << " != " << sizeof(MDRawContextAMD64); ++ } ++ BPLOG(INFO) << "MinidumpContext: looks like AMD64 context"; ++ ++ scoped_ptr<MDRawContextAMD64> context_amd64(new MDRawContextAMD64()); ++ if (!minidump_->ReadBytes(context_amd64.get(), ++ sizeof(MDRawContextAMD64))) { ++ BPLOG(ERROR) << "MinidumpContext could not read amd64 context"; ++ return false; ++ } ++ ++ if (minidump_->swap()) ++ Swap(&context_amd64->context_flags); ++ ++ // Update context_flags since we haven't done it yet ++ context_flags = context_amd64->context_flags; ++ ++ if (cpu_type != (context_flags & MD_CONTEXT_CPU_MASK)) { ++ BPLOG(ERROR) << "MinidumpContext amd64 does not match system info"; ++ return false; ++ } ++ ++ // Normalize the 128-bit types in the dump. ++ // Since this is AMD64, by definition, the values are little-endian. ++ for (unsigned int vr_index = 0; ++ vr_index < MD_CONTEXT_AMD64_VR_COUNT; ++ ++vr_index) ++ Normalize128(&context_amd64->vector_register[vr_index], false); ++ ++ if (minidump_->swap()) { ++ Swap(&context_amd64->p1_home); ++ Swap(&context_amd64->p2_home); ++ Swap(&context_amd64->p3_home); ++ Swap(&context_amd64->p4_home); ++ Swap(&context_amd64->p5_home); ++ Swap(&context_amd64->p6_home); ++ // context_flags is already swapped ++ Swap(&context_amd64->mx_csr); ++ Swap(&context_amd64->cs); ++ Swap(&context_amd64->ds); ++ Swap(&context_amd64->es); ++ Swap(&context_amd64->fs); ++ Swap(&context_amd64->ss); ++ Swap(&context_amd64->eflags); ++ Swap(&context_amd64->dr0); ++ Swap(&context_amd64->dr1); ++ Swap(&context_amd64->dr2); ++ Swap(&context_amd64->dr3); ++ Swap(&context_amd64->dr6); ++ Swap(&context_amd64->dr7); ++ Swap(&context_amd64->rax); ++ Swap(&context_amd64->rcx); ++ Swap(&context_amd64->rdx); ++ Swap(&context_amd64->rbx); ++ Swap(&context_amd64->rsp); ++ Swap(&context_amd64->rbp); ++ Swap(&context_amd64->rsi); ++ Swap(&context_amd64->rdi); ++ Swap(&context_amd64->r8); ++ Swap(&context_amd64->r9); ++ Swap(&context_amd64->r10); ++ Swap(&context_amd64->r11); ++ Swap(&context_amd64->r12); ++ Swap(&context_amd64->r13); ++ Swap(&context_amd64->r14); ++ Swap(&context_amd64->r15); ++ Swap(&context_amd64->rip); ++ // FIXME: I'm not sure what actually determines ++ // which member of the union {flt_save, sse_registers} ++ // is valid. We're not currently using either, ++ // but it would be good to have them swapped properly. ++ ++ for (unsigned int vr_index = 0; ++ vr_index < MD_CONTEXT_AMD64_VR_COUNT; ++ ++vr_index) ++ Swap(&context_amd64->vector_register[vr_index]); ++ Swap(&context_amd64->vector_control); ++ Swap(&context_amd64->debug_control); ++ Swap(&context_amd64->last_branch_to_rip); ++ Swap(&context_amd64->last_branch_from_rip); ++ Swap(&context_amd64->last_exception_to_rip); ++ Swap(&context_amd64->last_exception_from_rip); ++ } ++ ++ SetContextFlags(context_amd64->context_flags); ++ ++ SetContextAMD64(context_amd64.release()); ++ minidump_->SeekSet( ++ (minidump_->Tell() - sizeof(MDRawContextAMD64)) + expected_size); ++ break; ++ } + case MD_CONTEXT_X86: { + if (expected_size != sizeof(MDRawContextX86)) { +- BPLOG(ERROR) << "MinidumpContext x86 size mismatch, " << ++ BPLOG(INFO) << "MinidumpContext x86 size mismatch, " << + expected_size << " != " << sizeof(MDRawContextX86); +- return false; + } + + scoped_ptr<MDRawContextX86> context_x86(new MDRawContextX86()); + + // 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_x86->context_flags = context_flags; +@@ -843,16 +829,18 @@ bool MinidumpContext::Read(uint32_t expected_size) { + Swap(&context_x86->eflags); + Swap(&context_x86->esp); + Swap(&context_x86->ss); + // context_x86->extended_registers[] contains 8-bit quantities and + // does not need to be swapped. + } + + SetContextX86(context_x86.release()); ++ minidump_->SeekSet( ++ (minidump_->Tell() - sizeof(MDRawContextX86)) + expected_size); + + break; + } + + case MD_CONTEXT_PPC: { + if (expected_size != sizeof(MDRawContextPPC)) { + BPLOG(ERROR) << "MinidumpContext ppc size mismatch, " << + expected_size << " != " << sizeof(MDRawContextPPC); +-- +2.26.2 + |