[PATCH] D153800: [ARM] Adjust strd/ldrd codegen alignment requirements
Maurice Heumann via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Tue Jul 11 10:28:02 PDT 2023
momo5502 added a comment.
I think I figured it out:
There are 4 arguments to snprintf here: `Buffer`, `BufferSize`, `Format`, `Value`. Value being the `long long` to be formatted as `unsigned char`.
It seems that the calling convention snprintf expects is all values in registers, so `r0`, `r1`, `r2`, `r3`. Meaning it expects the `Value` to be in `r3`.
However, the code that is generated in this function prepares the arguments like this: `r0`, `r1`, `stack`, `stack`, so the last two arguments are on the stack. I assume this is what we generate if the function is a vararg.
That seems to be an ABI incompatibility. I'm not sure what the correct calling convention is, but it seems like we generate what is mentioned here: https://github.com/NationalSecurityAgency/ghidra/issues/3927
A bit of context as to why it used to work:
The value to be formatted is passed to the function is the value of `[r0+#12]`. It happens to be `0`.
The correct code should move that into r3 for the call to snprintf, however, it is instead pushed onto the stack. By chance, `r3` was overwritten with a different `0` value in the old case, so it was still 'correct'. With my change active, it is now being overwriten by the third argument passed to our function, `r2`, which happens to be `0x7F`.
I'm not an ARM expert and I'm again not sure what the right calling convention for varargs is, but that is for sure the cause of this issue.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D153800/new/
https://reviews.llvm.org/D153800
More information about the llvm-commits
mailing list