aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/google_airbag/common/airbag_types.h3
-rw-r--r--src/processor/minidump.cc35
2 files changed, 26 insertions, 12 deletions
diff --git a/src/google_airbag/common/airbag_types.h b/src/google_airbag/common/airbag_types.h
index 917d6e61..240e7f08 100644
--- a/src/google_airbag/common/airbag_types.h
+++ b/src/google_airbag/common/airbag_types.h
@@ -56,7 +56,8 @@ typedef unsigned __int64 u_int64_t;
#endif /* !_WIN32 */
typedef struct {
- u_int64_t half[2];
+ u_int64_t high;
+ u_int64_t low;
} u_int128_t;
typedef u_int64_t airbag_time_t;
diff --git a/src/processor/minidump.cc b/src/processor/minidump.cc
index 8b8c2b8f..b5d7677a 100644
--- a/src/processor/minidump.cc
+++ b/src/processor/minidump.cc
@@ -115,18 +115,23 @@ static inline void Swap(u_int64_t* value) {
}
-// Nontrivial, not often used, not inline. This will put *value into
-// native endianness even on machines where there is no native 128-bit type.
-// half[0] will be the most significant half on big-endian CPUs and half[1]
-// will be the most significant half on little-endian CPUs.
-static void Swap(u_int128_t* value) {
- Swap(&value->half[0]);
- Swap(&value->half[1]);
+// Given a pointer to a 128-bit int in the minidump data, set the "low"
+// and "high" fields appropriately.
+static void Normalize128(u_int128_t* value, bool is_big_endian) {
+ // The struct format is [high, low], so if the format is big-endian,
+ // the most significant bytes will already be in the high field.
+ if (!is_big_endian) {
+ u_int64_t temp = value->low;
+ value->low = value->high;
+ value->high = temp;
+ }
+}
- // Swap the two sections with one another.
- u_int64_t temp = value->half[0];
- value->half[0] = value->half[1];
- value->half[1] = temp;
+// This just swaps each int64 half of the 128-bit value.
+// The value should also be normalized by calling Normalize128().
+static void Swap(u_int128_t* value) {
+ Swap(&value->low);
+ Swap(&value->high);
}
@@ -378,6 +383,14 @@ bool MinidumpContext::Read(u_int32_t expected_size) {
if (!CheckAgainstSystemInfo(cpu_type))
return false;
+ // Normalize the 128-bit types in the dump.
+ // Since this is PowerPC, by definition, the values are big-endian.
+ for (unsigned int vr_index = 0;
+ vr_index < MD_VECTORSAVEAREA_PPC_VR_COUNT;
+ ++vr_index) {
+ Normalize128(&context_ppc->vector_save.save_vr[vr_index], true);
+ }
+
if (minidump_->swap()) {
// context_ppc->context_flags was already swapped.
Swap(&context_ppc->srr0);