1diff --git a/src/processor/minidump.cc b/src/processor/minidump.cc 2index 1f479558..aa63fe47 100644 3--- a/src/processor/minidump.cc 4+++ b/src/processor/minidump.cc 5@@ -444,140 +444,30 @@ MinidumpContext::MinidumpContext(Minidump* minidump) 6 7 MinidumpContext::~MinidumpContext() { 8 } 9 10 bool MinidumpContext::Read(uint32_t expected_size) { 11 valid_ = false; 12 13 // Certain raw context types are currently assumed to have unique sizes. 14- if (!IsContextSizeUnique(sizeof(MDRawContextAMD64))) { 15- BPLOG(ERROR) << "sizeof(MDRawContextAMD64) cannot match the size of any " 16- << "other raw context"; 17- return false; 18- } 19 if (!IsContextSizeUnique(sizeof(MDRawContextPPC64))) { 20 BPLOG(ERROR) << "sizeof(MDRawContextPPC64) cannot match the size of any " 21 << "other raw context"; 22 return false; 23 } 24 if (!IsContextSizeUnique(sizeof(MDRawContextARM64_Old))) { 25 BPLOG(ERROR) << "sizeof(MDRawContextARM64_Old) cannot match the size of any " 26 << "other raw context"; 27 return false; 28 } 29 30 FreeContext(); 31 32- // First, figure out what type of CPU this context structure is for. 33- // For some reason, the AMD64 Context doesn't have context_flags 34- // at the beginning of the structure, so special case it here. 35- if (expected_size == sizeof(MDRawContextAMD64)) { 36- BPLOG(INFO) << "MinidumpContext: looks like AMD64 context"; 37- 38- scoped_ptr<MDRawContextAMD64> context_amd64(new MDRawContextAMD64()); 39- if (!minidump_->ReadBytes(context_amd64.get(), 40- sizeof(MDRawContextAMD64))) { 41- BPLOG(ERROR) << "MinidumpContext could not read amd64 context"; 42- return false; 43- } 44- 45- if (minidump_->swap()) 46- Swap(&context_amd64->context_flags); 47- 48- uint32_t cpu_type = context_amd64->context_flags & MD_CONTEXT_CPU_MASK; 49- if (cpu_type == 0) { 50- if (minidump_->GetContextCPUFlagsFromSystemInfo(&cpu_type)) { 51- context_amd64->context_flags |= cpu_type; 52- } else { 53- BPLOG(ERROR) << "Failed to preserve the current stream position"; 54- return false; 55- } 56- } 57- 58- if (cpu_type != MD_CONTEXT_AMD64) { 59- // TODO: Fall through to switch below. 60- // https://bugs.chromium.org/p/google-breakpad/issues/detail?id=550 61- BPLOG(ERROR) << "MinidumpContext not actually amd64 context"; 62- return false; 63- } 64- 65- // Do this after reading the entire MDRawContext structure because 66- // GetSystemInfo may seek minidump to a new position. 67- if (!CheckAgainstSystemInfo(cpu_type)) { 68- BPLOG(ERROR) << "MinidumpContext amd64 does not match system info"; 69- return false; 70- } 71- 72- // Normalize the 128-bit types in the dump. 73- // Since this is AMD64, by definition, the values are little-endian. 74- for (unsigned int vr_index = 0; 75- vr_index < MD_CONTEXT_AMD64_VR_COUNT; 76- ++vr_index) 77- Normalize128(&context_amd64->vector_register[vr_index], false); 78- 79- if (minidump_->swap()) { 80- Swap(&context_amd64->p1_home); 81- Swap(&context_amd64->p2_home); 82- Swap(&context_amd64->p3_home); 83- Swap(&context_amd64->p4_home); 84- Swap(&context_amd64->p5_home); 85- Swap(&context_amd64->p6_home); 86- // context_flags is already swapped 87- Swap(&context_amd64->mx_csr); 88- Swap(&context_amd64->cs); 89- Swap(&context_amd64->ds); 90- Swap(&context_amd64->es); 91- Swap(&context_amd64->fs); 92- Swap(&context_amd64->ss); 93- Swap(&context_amd64->eflags); 94- Swap(&context_amd64->dr0); 95- Swap(&context_amd64->dr1); 96- Swap(&context_amd64->dr2); 97- Swap(&context_amd64->dr3); 98- Swap(&context_amd64->dr6); 99- Swap(&context_amd64->dr7); 100- Swap(&context_amd64->rax); 101- Swap(&context_amd64->rcx); 102- Swap(&context_amd64->rdx); 103- Swap(&context_amd64->rbx); 104- Swap(&context_amd64->rsp); 105- Swap(&context_amd64->rbp); 106- Swap(&context_amd64->rsi); 107- Swap(&context_amd64->rdi); 108- Swap(&context_amd64->r8); 109- Swap(&context_amd64->r9); 110- Swap(&context_amd64->r10); 111- Swap(&context_amd64->r11); 112- Swap(&context_amd64->r12); 113- Swap(&context_amd64->r13); 114- Swap(&context_amd64->r14); 115- Swap(&context_amd64->r15); 116- Swap(&context_amd64->rip); 117- // FIXME: I'm not sure what actually determines 118- // which member of the union {flt_save, sse_registers} 119- // is valid. We're not currently using either, 120- // but it would be good to have them swapped properly. 121- 122- for (unsigned int vr_index = 0; 123- vr_index < MD_CONTEXT_AMD64_VR_COUNT; 124- ++vr_index) 125- Swap(&context_amd64->vector_register[vr_index]); 126- Swap(&context_amd64->vector_control); 127- Swap(&context_amd64->debug_control); 128- Swap(&context_amd64->last_branch_to_rip); 129- Swap(&context_amd64->last_branch_from_rip); 130- Swap(&context_amd64->last_exception_to_rip); 131- Swap(&context_amd64->last_exception_from_rip); 132- } 133- 134- SetContextFlags(context_amd64->context_flags); 135- 136- SetContextAMD64(context_amd64.release()); 137- } else if (expected_size == sizeof(MDRawContextPPC64)) { 138+ if (expected_size == sizeof(MDRawContextPPC64)) { 139 // |context_flags| of MDRawContextPPC64 is 64 bits, but other MDRawContext 140 // in the else case have 32 bits |context_flags|, so special case it here. 141 uint64_t context_flags; 142 if (!minidump_->ReadBytes(&context_flags, sizeof(context_flags))) { 143 BPLOG(ERROR) << "MinidumpContext could not read context flags"; 144 return false; 145 } 146 if (minidump_->swap()) 147@@ -739,56 +629,152 @@ bool MinidumpContext::Read(uint32_t expected_size) { 148 } 149 } 150 151 scoped_ptr<MDRawContextARM64> new_context(new MDRawContextARM64()); 152 ConvertOldARM64Context(*context_arm64.get(), new_context.get()); 153 SetContextFlags(new_context->context_flags); 154 SetContextARM64(new_context.release()); 155 } else { 156- uint32_t context_flags; 157- if (!minidump_->ReadBytes(&context_flags, sizeof(context_flags))) { 158- BPLOG(ERROR) << "MinidumpContext could not read context flags"; 159+ uint32_t cpu_type = 0; 160+ if (!minidump_->GetContextCPUFlagsFromSystemInfo(&cpu_type)) { 161+ BPLOG(ERROR) << "Failed to preserve the current stream position"; 162 return false; 163 } 164- if (minidump_->swap()) 165- Swap(&context_flags); 166 167- uint32_t cpu_type = context_flags & MD_CONTEXT_CPU_MASK; 168- if (cpu_type == 0) { 169- // Unfortunately the flag for MD_CONTEXT_ARM that was taken 170- // from a Windows CE SDK header conflicts in practice with 171- // the CONTEXT_XSTATE flag. MD_CONTEXT_ARM has been renumbered, 172- // but handle dumps with the legacy value gracefully here. 173- if (context_flags & MD_CONTEXT_ARM_OLD) { 174- context_flags |= MD_CONTEXT_ARM; 175- context_flags &= ~MD_CONTEXT_ARM_OLD; 176- cpu_type = MD_CONTEXT_ARM; 177+ uint32_t context_flags = 0; 178+ if ((cpu_type == 0) || cpu_type != MD_CONTEXT_AMD64) { 179+ if (!minidump_->ReadBytes(&context_flags, sizeof(context_flags))) { 180+ BPLOG(ERROR) << "MinidumpContext could not read context flags"; 181+ return false; 182 } 183- } 184 185- if (cpu_type == 0) { 186- if (minidump_->GetContextCPUFlagsFromSystemInfo(&cpu_type)) { 187- context_flags |= cpu_type; 188+ if (minidump_->swap()) 189+ Swap(&context_flags); 190+ 191+ if ((context_flags & MD_CONTEXT_CPU_MASK) == 0) { 192+ // Unfortunately the flag for MD_CONTEXT_ARM that was taken 193+ // from a Windows CE SDK header conflicts in practice with 194+ // the CONTEXT_XSTATE flag. MD_CONTEXT_ARM has been renumbered, 195+ // but handle dumps with the legacy value gracefully here. 196+ if (context_flags & MD_CONTEXT_ARM_OLD) { 197+ context_flags |= MD_CONTEXT_ARM; 198+ context_flags &= ~MD_CONTEXT_ARM_OLD; 199+ cpu_type = MD_CONTEXT_ARM; 200+ } else { 201+ context_flags |= cpu_type; 202+ } 203 } else { 204- BPLOG(ERROR) << "Failed to preserve the current stream position"; 205- return false; 206+ cpu_type = context_flags & MD_CONTEXT_CPU_MASK; 207 } 208 } 209 210 // Allocate the context structure for the correct CPU and fill it. The 211 // casts are slightly unorthodox, but it seems better to do that than to 212 // maintain a separate pointer for each type of CPU context structure 213 // when only one of them will be used. 214 switch (cpu_type) { 215+ case MD_CONTEXT_AMD64: { 216+ if (expected_size != sizeof(MDRawContextAMD64)) { 217+ BPLOG(INFO) << "MinidumpContext AMD64 size mismatch, " << 218+ expected_size << " != " << sizeof(MDRawContextAMD64); 219+ } 220+ BPLOG(INFO) << "MinidumpContext: looks like AMD64 context"; 221+ 222+ scoped_ptr<MDRawContextAMD64> context_amd64(new MDRawContextAMD64()); 223+ if (!minidump_->ReadBytes(context_amd64.get(), 224+ sizeof(MDRawContextAMD64))) { 225+ BPLOG(ERROR) << "MinidumpContext could not read amd64 context"; 226+ return false; 227+ } 228+ 229+ if (minidump_->swap()) 230+ Swap(&context_amd64->context_flags); 231+ 232+ // Update context_flags since we haven't done it yet 233+ context_flags = context_amd64->context_flags; 234+ 235+ if (cpu_type != (context_flags & MD_CONTEXT_CPU_MASK)) { 236+ BPLOG(ERROR) << "MinidumpContext amd64 does not match system info"; 237+ return false; 238+ } 239+ 240+ // Normalize the 128-bit types in the dump. 241+ // Since this is AMD64, by definition, the values are little-endian. 242+ for (unsigned int vr_index = 0; 243+ vr_index < MD_CONTEXT_AMD64_VR_COUNT; 244+ ++vr_index) 245+ Normalize128(&context_amd64->vector_register[vr_index], false); 246+ 247+ if (minidump_->swap()) { 248+ Swap(&context_amd64->p1_home); 249+ Swap(&context_amd64->p2_home); 250+ Swap(&context_amd64->p3_home); 251+ Swap(&context_amd64->p4_home); 252+ Swap(&context_amd64->p5_home); 253+ Swap(&context_amd64->p6_home); 254+ // context_flags is already swapped 255+ Swap(&context_amd64->mx_csr); 256+ Swap(&context_amd64->cs); 257+ Swap(&context_amd64->ds); 258+ Swap(&context_amd64->es); 259+ Swap(&context_amd64->fs); 260+ Swap(&context_amd64->ss); 261+ Swap(&context_amd64->eflags); 262+ Swap(&context_amd64->dr0); 263+ Swap(&context_amd64->dr1); 264+ Swap(&context_amd64->dr2); 265+ Swap(&context_amd64->dr3); 266+ Swap(&context_amd64->dr6); 267+ Swap(&context_amd64->dr7); 268+ Swap(&context_amd64->rax); 269+ Swap(&context_amd64->rcx); 270+ Swap(&context_amd64->rdx); 271+ Swap(&context_amd64->rbx); 272+ Swap(&context_amd64->rsp); 273+ Swap(&context_amd64->rbp); 274+ Swap(&context_amd64->rsi); 275+ Swap(&context_amd64->rdi); 276+ Swap(&context_amd64->r8); 277+ Swap(&context_amd64->r9); 278+ Swap(&context_amd64->r10); 279+ Swap(&context_amd64->r11); 280+ Swap(&context_amd64->r12); 281+ Swap(&context_amd64->r13); 282+ Swap(&context_amd64->r14); 283+ Swap(&context_amd64->r15); 284+ Swap(&context_amd64->rip); 285+ // FIXME: I'm not sure what actually determines 286+ // which member of the union {flt_save, sse_registers} 287+ // is valid. We're not currently using either, 288+ // but it would be good to have them swapped properly. 289+ 290+ for (unsigned int vr_index = 0; 291+ vr_index < MD_CONTEXT_AMD64_VR_COUNT; 292+ ++vr_index) 293+ Swap(&context_amd64->vector_register[vr_index]); 294+ Swap(&context_amd64->vector_control); 295+ Swap(&context_amd64->debug_control); 296+ Swap(&context_amd64->last_branch_to_rip); 297+ Swap(&context_amd64->last_branch_from_rip); 298+ Swap(&context_amd64->last_exception_to_rip); 299+ Swap(&context_amd64->last_exception_from_rip); 300+ } 301+ 302+ SetContextFlags(context_amd64->context_flags); 303+ 304+ SetContextAMD64(context_amd64.release()); 305+ minidump_->SeekSet( 306+ (minidump_->Tell() - sizeof(MDRawContextAMD64)) + expected_size); 307+ break; 308+ } 309 case MD_CONTEXT_X86: { 310 if (expected_size != sizeof(MDRawContextX86)) { 311- BPLOG(ERROR) << "MinidumpContext x86 size mismatch, " << 312+ BPLOG(INFO) << "MinidumpContext x86 size mismatch, " << 313 expected_size << " != " << sizeof(MDRawContextX86); 314- return false; 315 } 316 317 scoped_ptr<MDRawContextX86> context_x86(new MDRawContextX86()); 318 319 // Set the context_flags member, which has already been read, and 320 // read the rest of the structure beginning with the first member 321 // after context_flags. 322 context_x86->context_flags = context_flags; 323@@ -843,16 +829,18 @@ bool MinidumpContext::Read(uint32_t expected_size) { 324 Swap(&context_x86->eflags); 325 Swap(&context_x86->esp); 326 Swap(&context_x86->ss); 327 // context_x86->extended_registers[] contains 8-bit quantities and 328 // does not need to be swapped. 329 } 330 331 SetContextX86(context_x86.release()); 332+ minidump_->SeekSet( 333+ (minidump_->Tell() - sizeof(MDRawContextX86)) + expected_size); 334 335 break; 336 } 337 338 case MD_CONTEXT_PPC: { 339 if (expected_size != sizeof(MDRawContextPPC)) { 340 BPLOG(ERROR) << "MinidumpContext ppc size mismatch, " << 341 expected_size << " != " << sizeof(MDRawContextPPC); 342-- 3432.26.2 344 345