[flang-commits] [PATCH] D132168: [flang][runtime] Handle endian-swapped record headers & footers on input

Peter Klausler via Phabricator via flang-commits flang-commits at lists.llvm.org
Thu Aug 18 11:31:03 PDT 2022


klausler created this revision.
klausler added reviewers: vdonaldson, jpenix-quic.
klausler added a project: Flang.
Herald added a subscriber: jdoerfert.
Herald added a project: All.
klausler requested review of this revision.

The runtime I/O library correctly handles endianness conversions on payload
data I/O and on the output of sequential record headers and footers, but
does not swap endianness when required when reading sequential record headers
and footers back in for READ and BACKSPACE statements.  Mea culpa.  Fix.

Fixes https://github.com/llvm/llvm-project/issues/57126


https://reviews.llvm.org/D132168

Files:
  flang/runtime/unit.cpp
  flang/runtime/unit.h


Index: flang/runtime/unit.h
===================================================================
--- flang/runtime/unit.h
+++ flang/runtime/unit.h
@@ -133,6 +133,7 @@
   void CommitWrites();
   bool CheckDirectAccess(IoErrorHandler &);
   void HitEndOnRead(IoErrorHandler &);
+  std::int32_t ReadHeaderOrFooter(std::int64_t frameOffset);
 
   Lock lock_;
   // TODO: replace with a thread ID
Index: flang/runtime/unit.cpp
===================================================================
--- flang/runtime/unit.cpp
+++ flang/runtime/unit.cpp
@@ -263,7 +263,7 @@
   }
 }
 
-static void SwapEndianness(
+static inline void SwapEndianness(
     char *data, std::size_t bytes, std::size_t elementBytes) {
   if (elementBytes > 1) {
     auto half{elementBytes >> 1};
@@ -717,7 +717,7 @@
               "record #%jd (file offset %jd): truncated record header";
     }
   } else {
-    std::memcpy(&header, Frame() + recordOffsetInFrame_, sizeof header);
+    header = ReadHeaderOrFooter(recordOffsetInFrame_);
     recordLength = sizeof header + header; // does not include footer
     need = recordOffsetInFrame_ + *recordLength + sizeof footer;
     got = ReadFrame(frameOffsetInFile_, need, handler);
@@ -726,8 +726,7 @@
               "record #%jd (file offset %jd): hit EOF reading record with "
               "length %jd bytes";
     } else {
-      std::memcpy(&footer, Frame() + recordOffsetInFrame_ + *recordLength,
-          sizeof footer);
+      footer = ReadHeaderOrFooter(recordOffsetInFrame_ + *recordLength);
       if (footer != header) {
         error = "Unformatted variable-length sequential file input failed at "
                 "record #%jd (file offset %jd): record header has length %jd "
@@ -784,7 +783,7 @@
 
 void ExternalFileUnit::BackspaceVariableUnformattedRecord(
     IoErrorHandler &handler) {
-  std::int32_t header{0}, footer{0};
+  std::int32_t header{0};
   auto headerBytes{static_cast<std::int64_t>(sizeof header)};
   frameOffsetInFile_ += recordOffsetInFrame_;
   recordOffsetInFrame_ = 0;
@@ -801,8 +800,7 @@
     handler.SignalError(IostatShortRead);
     return;
   }
-  std::memcpy(&footer, Frame(), sizeof footer);
-  recordLength = footer;
+  recordLength = ReadHeaderOrFooter(0);
   if (frameOffsetInFile_ < *recordLength + 2 * headerBytes) {
     handler.SignalError(IostatBadUnformattedRecord);
     return;
@@ -819,7 +817,7 @@
     handler.SignalError(IostatShortRead);
     return;
   }
-  std::memcpy(&header, Frame() + recordOffsetInFrame_, sizeof header);
+  header = ReadHeaderOrFooter(recordOffsetInFrame_);
   if (header != *recordLength) {
     handler.SignalError(IostatBadUnformattedRecord);
     return;
@@ -977,6 +975,16 @@
   }
 }
 
+std::int32_t ExternalFileUnit::ReadHeaderOrFooter(std::int64_t frameOffset) {
+  std::int32_t word;
+  char *wordPtr{reinterpret_cast<char *>(&word)};
+  std::memcpy(wordPtr, Frame() + frameOffset, sizeof word);
+  if (swapEndianness_) {
+    SwapEndianness(wordPtr, sizeof word, sizeof word);
+  }
+  return word;
+}
+
 void ChildIo::EndIoStatement() {
   io_.reset();
   u_.emplace<std::monostate>();


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D132168.453739.patch
Type: text/x-patch
Size: 3102 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/flang-commits/attachments/20220818/3a5829c9/attachment.bin>


More information about the flang-commits mailing list