[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