[XRay] Change function record reader to be endian-aware
authorDean Michael Berris <dberris@google.com>
Fri, 31 Aug 2018 18:36:58 +0000 (18:36 +0000)
committerDean Michael Berris <dberris@google.com>
Fri, 31 Aug 2018 18:36:58 +0000 (18:36 +0000)
This change allows us to let the compiler do the right thing for when
handling big-endian and little-endian records for FDR mode function
records.

Previously, we assumed that the encoding was little-endian that reading
the first byte to look for the function id and function record types was
ordered in a little-endian manner. This change allows us to better
handle function records where the first four bytes may actually be
encoded in big-endian thus giving us the wrong bytes where we're seeking
the function information from.

This is a follow-up to D51210 and D51289.

llvm-svn: 341236

llvm/lib/XRay/Trace.cpp

index 35a3033..69ac825 100644 (file)
@@ -601,6 +601,19 @@ Error processFDRFunctionRecord(FDRState &State, DataExtractor &RecordExtractor,
     Records.emplace_back();
     auto &Record = Records.back();
     Record.RecordType = 0; // Record is type NORMAL.
+    // Back up one byte to re-read the first byte, which is important for
+    // computing the function id for a record.
+    --OffsetPtr;
+
+    auto PreReadOffset = OffsetPtr;
+    uint32_t FuncIdBitField = RecordExtractor.getU32(&OffsetPtr);
+    if (OffsetPtr == PreReadOffset)
+      return createStringError(
+          std::make_error_code(std::errc::executable_format_error),
+          "Failed reading truncated function id field at offset %d.",
+          OffsetPtr);
+
+    FirstByte = FuncIdBitField & 0xffu;
     // Strip off record type bit and use the next three bits.
     auto T = (FirstByte >> 1) & 0x07;
     switch (T) {
@@ -626,23 +639,11 @@ Error processFDRFunctionRecord(FDRState &State, DataExtractor &RecordExtractor,
     Record.TId = State.ThreadId;
     Record.PId = State.ProcessId;
 
-    // Back up one byte to re-read the first byte, which is important for
-    // computing the function id for a record.
-    --OffsetPtr;
-
     // Despite function Id being a signed int on XRayRecord,
     // when it is written to an FDR format, the top bits are truncated,
     // so it is effectively an unsigned value. When we shift off the
     // top four bits, we want the shift to be logical, so we read as
     // uint32_t.
-    auto PreReadOffset = OffsetPtr;
-    uint32_t FuncIdBitField = RecordExtractor.getU32(&OffsetPtr);
-    if (OffsetPtr == PreReadOffset)
-      return createStringError(
-          std::make_error_code(std::errc::executable_format_error),
-          "Failed reading truncated function id field at offset %d.",
-          OffsetPtr);
-
     Record.FuncId = FuncIdBitField >> 4;
 
     // FunctionRecords have a 32 bit delta from the previous absolute TSC