[llvm] r341226 - [XRay] Make Trace loading endian-aware

Dean Michael Berris via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 31 10:06:29 PDT 2018


Author: dberris
Date: Fri Aug 31 10:06:28 2018
New Revision: 341226

URL: http://llvm.org/viewvc/llvm-project?rev=341226&view=rev
Log:
[XRay] Make Trace loading endian-aware

This change makes the XRay Trace loading functions first use a
little-endian data extractor, then on failures try a big-endian data
extractor. Without this change, the trace loading facility will not work
with data written from a big-endian machine.

Follow-up to D51210 and D51289.

Modified:
    llvm/trunk/lib/XRay/Trace.cpp

Modified: llvm/trunk/lib/XRay/Trace.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/XRay/Trace.cpp?rev=341226&r1=341225&r2=341226&view=diff
==============================================================================
--- llvm/trunk/lib/XRay/Trace.cpp (original)
+++ llvm/trunk/lib/XRay/Trace.cpp Fri Aug 31 10:06:28 2018
@@ -31,7 +31,8 @@ using XRayRecordStorage =
 // record it is.
 constexpr auto kFDRMetadataBodySize = 15;
 
-Error loadNaiveFormatLog(StringRef Data, XRayFileHeader &FileHeader,
+Error loadNaiveFormatLog(StringRef Data, bool IsLittleEndian,
+                         XRayFileHeader &FileHeader,
                          std::vector<XRayRecord> &Records) {
   if (Data.size() < 32)
     return make_error<StringError>(
@@ -43,7 +44,7 @@ Error loadNaiveFormatLog(StringRef Data,
         "Invalid-sized XRay data.",
         std::make_error_code(std::errc::invalid_argument));
 
-  DataExtractor Reader(Data, true, 8);
+  DataExtractor Reader(Data, IsLittleEndian, 8);
   uint32_t OffsetPtr = 0;
   auto FileHeaderOrError = readBinaryFormatHeader(Reader, OffsetPtr);
   if (!FileHeaderOrError)
@@ -703,17 +704,16 @@ Error processFDRFunctionRecord(FDRState
 /// ThreadBuffer: BufferExtents NewBuffer WallClockTime Pid NewCPUId
 ///               FunctionSequence
 /// EOB: *deprecated*
-Error loadFDRLog(StringRef Data, XRayFileHeader &FileHeader,
-                 std::vector<XRayRecord> &Records) {
+Error loadFDRLog(StringRef Data, bool IsLittleEndian,
+                 XRayFileHeader &FileHeader, std::vector<XRayRecord> &Records) {
 
   if (Data.size() < 32)
     return make_error<StringError>(
         "Not enough bytes for an XRay log.",
         std::make_error_code(std::errc::invalid_argument));
 
-  DataExtractor Reader(Data, true, 8);
+  DataExtractor Reader(Data, IsLittleEndian, 8);
   uint32_t OffsetPtr = 0;
-
   auto FileHeaderOrError = readBinaryFormatHeader(Reader, OffsetPtr);
   if (!FileHeaderOrError)
     return FileHeaderOrError.takeError();
@@ -722,7 +722,7 @@ Error loadFDRLog(StringRef Data, XRayFil
   uint64_t BufferSize = 0;
   {
     StringRef ExtraDataRef(FileHeader.FreeFormData, 16);
-    DataExtractor ExtraDataExtractor(ExtraDataRef, true, 8);
+    DataExtractor ExtraDataExtractor(ExtraDataRef, IsLittleEndian, 8);
     uint32_t ExtraDataOffset = 0;
     BufferSize = ExtraDataExtractor.getU64(&ExtraDataOffset);
   }
@@ -862,8 +862,15 @@ Expected<Trace> llvm::xray::loadTraceFil
         Twine("Cannot read log from '") + Filename + "'", EC);
   }
   auto Data = StringRef(MappedFile.data(), MappedFile.size());
-  DataExtractor DE(Data, true, 8);
-  return loadTrace(DE, Sort);
+
+  // TODO: Lift the endianness and implementation selection here.
+  DataExtractor LittleEndianDE(Data, true, 8);
+  auto TraceOrError = loadTrace(LittleEndianDE, Sort);
+  if (!TraceOrError) {
+    DataExtractor BigEndianDE(Data, false, 8);
+    TraceOrError = loadTrace(BigEndianDE, Sort);
+  }
+  return TraceOrError;
 }
 
 Expected<Trace> llvm::xray::loadTrace(const DataExtractor &DE, bool Sort) {
@@ -881,7 +888,7 @@ Expected<Trace> llvm::xray::loadTrace(co
   //
   // Only if we can't load either the binary or the YAML format will we yield an
   // error.
-  DataExtractor HeaderExtractor(DE.getData(), true, 8);
+  DataExtractor HeaderExtractor(DE.getData(), DE.isLittleEndian(), 8);
   uint32_t OffsetPtr = 0;
   uint16_t Version = HeaderExtractor.getU16(&OffsetPtr);
   uint16_t Type = HeaderExtractor.getU16(&OffsetPtr);
@@ -892,7 +899,8 @@ Expected<Trace> llvm::xray::loadTrace(co
   switch (Type) {
   case NAIVE_FORMAT:
     if (Version == 1 || Version == 2 || Version == 3) {
-      if (auto E = loadNaiveFormatLog(DE.getData(), T.FileHeader, T.Records))
+      if (auto E = loadNaiveFormatLog(DE.getData(), DE.isLittleEndian(),
+                                      T.FileHeader, T.Records))
         return std::move(E);
     } else {
       return make_error<StringError>(
@@ -903,7 +911,8 @@ Expected<Trace> llvm::xray::loadTrace(co
     break;
   case FLIGHT_DATA_RECORDER_FORMAT:
     if (Version == 1 || Version == 2 || Version == 3) {
-      if (auto E = loadFDRLog(DE.getData(), T.FileHeader, T.Records))
+      if (auto E = loadFDRLog(DE.getData(), DE.isLittleEndian(), T.FileHeader,
+                              T.Records))
         return std::move(E);
     } else {
       return make_error<StringError>(




More information about the llvm-commits mailing list