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