Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

spirv-remap tool does not function properly with cross-endian binaries #3799

Open
awilfox opened this issue Nov 22, 2024 · 0 comments
Open

Comments

@awilfox
Copy link

awilfox commented Nov 22, 2024

The test suite for glslang includes a little-endian binary, and on Power9 (big endian) the remap tests fail with:

Testing remapper error handling
1c1
< ID out of range: 4160749568
---
> bad magic number
1c1
< ID not found
---
> bad magic number

A naive patch makes it pass:

--- glslang-14.3.0/StandAlone/spirv-remap.cpp.old	2024-06-25 17:42:43.000000000 -0500
+++ glslang-14.3.0/StandAlone/spirv-remap.cpp	2024-11-22 15:27:02.655869572 -0600
@@ -38,6 +38,7 @@
 #include <cstring>
 #include <stdexcept>
 #include <filesystem>
+#include <byteswap.h>
 
 //
 // Include remapper
@@ -48,6 +49,8 @@
 
     typedef unsigned int SpvWord;
 
+    static const SpvWord MagicNumber = 0x07230203;
+
     // Poor man's basename: given a complete path, return file portion.
     // E.g:
     //      Linux:  /foo/bar/test  -> test
@@ -82,6 +85,7 @@
     void read(std::vector<SpvWord>& spv, const std::string& inFilename, int verbosity)
     {
         std::ifstream fp;
+        bool isNativeEndian = true;
 
         if (verbosity > 0)
             logHandler(std::string("  reading: ") + inFilename);
@@ -97,11 +101,16 @@
         spv.reserve(size_t(fp.tellg()) / sizeof(SpvWord));
         fp.seekg(0, fp.beg);
 
+        char begin = fp.peek();
+        char native_begin = reinterpret_cast<const char*>(&MagicNumber)[0];
+        if (begin != native_begin) isNativeEndian = false;
+
         while (!fp.eof()) {
             SpvWord inWord;
             fp.read((char *)&inWord, sizeof(inWord));
 
             if (!fp.eof()) {
+                if (!isNativeEndian) inWord = __bswap_32(inWord);
                 spv.push_back(inWord);
                 if (fp.fail())
                     errHandler(std::string("error reading file: ") + inFilename);

However, I don't think this is the best way forward. It depends on __bswap_32 which is gcc/clang specific and wouldn't work on Windows. The MagicNumber cast is also ugly though it does not violate strict-aliasing rules.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant