-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
Error when running on big endian host (such as s390x) #1931
Comments
In Rizin we use Travis CI for S390, and we use capstone as the engine. If you send a PR with a test, it could be ensured there is no regression once fixed: It would be nice to have somehow big-endian CI for Capstone too but Travis CI is expensive. |
I think this is likely a dup of #1710 ... @michalsc provides a hint there how this could be fixed. I think something like this should do the job:
... maybe not the nicest solution on earth, but at least it is not very intrusive ...? |
I'm pretty confident that this is the same issue as #1710 ... so I'd like to suggest to close this one here and track the issue in the older ticket instead? |
duplicate of #1710 |
…ts (#2222) Disassembling single floating points with immediate values currently gives wrong results on big endian hosts (like s390x), e.g.: ./cstool/cstool m68k40 'f2 3c 44 22 40 49 0e 56' 0 f2 3c 44 22 40 49 0e 56 fadd.s #0.000000, fp0 While it should be (like on x86): ./cstool/cstool m68k40 'f2 3c 44 22 40 49 0e 56' 0 f2 3c 44 22 40 49 0e 56 fadd.s #3.141500, fp0 The problem is that these single float values are supposed to be stored in the 32-bit "simm" field of struct cs_m68k_op (see e.g. the printing of M68K_FPU_SIZE_SINGLE in printAddressingMode() in M68KInstPrinter.c), but currently the immediate is only written to the 64-bit "imm" field of the union in cs_m68k_op. This works on little endian systems, since the least significant bytes overlap in the union there. For example, let's assume that the value 0x01020304 gets written to "imm": 04 03 02 01 00 00 00 00 uint64_t imm xx xx xx xx xx xx xx xx double dimm; xx xx xx xx .. .. .. .. float simm; But on big endian hosts, the important bytes do not overlap, so "simm" is always zero there: 00 00 00 00 01 02 03 04 uint64_t imm xx xx xx xx xx xx xx xx double dimm; xx xx xx xx .. .. .. .. float simm; To fix the problem, let's always set "simm" explicitly, this works on both, big endian and little endian hosts. Thanks to Michal Schulz for his initial analysis of the problem (in #1710) and to Travis Finkenauer for providing an easy example to reproduce the issue (in #1931). Closes: #1710
When built/run on a big endian host (such as s390x), capstone has unexpected output.
Expected
When running on an amd64 Linux host (little endian):
Actual
When running on a s390x Linux host (big endian):
This was originally discovered by @plugwash in capstone-rust/capstone-rs#137 for debian testing CI tests for rust-capstone (rust-lang bindings).
Reproducing/Testing
I was able to get a s390x virtualized using multiarch/qemu-user-static container as mentioned in these docs:
https://docs.gitlab.com/omnibus/development/s390x.html
It looks like the upstream C library has a bug when running on a big endian host:
This is just one example test that failed--there are many. More testing is required to find more error cases.
Also, ideally a big endian architecture would be tested in CI.
The text was updated successfully, but these errors were encountered: