[llvm] 046e23f - [llvm lib] Fix endian bug in #189098 (#189778)

via llvm-commits llvm-commits at lists.llvm.org
Wed Apr 1 08:59:07 PDT 2026


Author: Roy Shi
Date: 2026-04-01T08:59:02-07:00
New Revision: 046e23fa4adaf4cdee23f4f3416d7d57009f19d5

URL: https://github.com/llvm/llvm-project/commit/046e23fa4adaf4cdee23f4f3416d7d57009f19d5
DIFF: https://github.com/llvm/llvm-project/commit/046e23fa4adaf4cdee23f4f3416d7d57009f19d5.diff

LOG: [llvm lib] Fix endian bug in #189098 (#189778)

The bug was added in #189098. Both functions that I added/changed
assumed little-endian host memory layout when reading/writing
non-power-of-two byte sizes (3, 5, 6, 7). On big-endian hosts (SPARC,
s390x), memcpy copies bytes into the MSB end of a uint64_t, leaving the
value in the wrong bit position. Fix by offsetting the memcpy/write
pointer to always target the LSB bytes.

Added: 
    

Modified: 
    llvm/lib/DebugInfo/GSYM/FileWriter.cpp
    llvm/lib/Support/DataExtractor.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/DebugInfo/GSYM/FileWriter.cpp b/llvm/lib/DebugInfo/GSYM/FileWriter.cpp
index 7c55ae03b6f0b..5d6d81dfbc3b6 100644
--- a/llvm/lib/DebugInfo/GSYM/FileWriter.cpp
+++ b/llvm/lib/DebugInfo/GSYM/FileWriter.cpp
@@ -55,15 +55,13 @@ void FileWriter::writeUnsigned(uint64_t Value, size_t ByteSize) {
   assert((ByteSize == 8 || (Value & (uint64_t)-1 << (8 * ByteSize)) == 0) &&
          "potential data loss: higher bits are non-zero");
   // Swap and shift bytes if endianness doesn't match.
-  if (ByteOrder != llvm::endianness::native) {
-    // Say ByteSize is 3.
-    //                high                low
-    // Input bytes:   00 00 00 00 00 AA BB CC
-    // Swapped bytes: CC BB AA 00 00 00 00 00
-    // Shifted bytes: 00 00 00 00 00 CC BB AA
+  if (ByteOrder != llvm::endianness::native)
     Value = sys::getSwappedBytes(Value) >> (8 * (8 - ByteSize));
-  }
-  OS.write(reinterpret_cast<const char *>(&Value), ByteSize);
+  // Write from the least significant bytes of Value regardless of host
+  // endianness.
+  OS.write(reinterpret_cast<const char *>(&Value) +
+               (sys::IsLittleEndianHost ? 0 : 8 - ByteSize),
+           ByteSize);
 }
 
 void FileWriter::fixup32(uint32_t U, uint64_t Offset) {

diff  --git a/llvm/lib/Support/DataExtractor.cpp b/llvm/lib/Support/DataExtractor.cpp
index 071093504e591..6b58b492002fd 100644
--- a/llvm/lib/Support/DataExtractor.cpp
+++ b/llvm/lib/Support/DataExtractor.cpp
@@ -144,16 +144,15 @@ uint64_t DataExtractor::getUnsigned(uint64_t *offset_ptr, uint32_t byte_size,
   uint64_t offset = *offset_ptr;
   if (!prepareRead(offset, byte_size, Err))
     return val;
-  std::memcpy(&val, &Data.data()[offset], byte_size);
+  // Copy into the least significant bytes of val regardless of host
+  // endianness.
+  std::memcpy(reinterpret_cast<char *>(&val) +
+                  (sys::IsLittleEndianHost ? 0 : 8 - byte_size),
+              &Data.data()[offset], byte_size);
+  // Swap the least significant bytes of val if endianness doesn't match.
   if (sys::IsLittleEndianHost != IsLittleEndian)
-    // Say byte_size is 3.
-    //                high                low
-    // Read bytes:    00 00 00 00 00 AA BB CC
-    // Swapped bytes: CC BB AA 00 00 00 00 00
-    // Shifted bytes: 00 00 00 00 00 CC BB AA
     val = sys::getSwappedBytes(val) >> (8 * (8 - byte_size));
 
-  // Advance the offset
   *offset_ptr += byte_size;
   return val;
 }


        


More information about the llvm-commits mailing list