Description
Describe the bug
This issue is related to #3977. That issue report is about how double-word sized function arguments (ulonglong
and double
for 32-bit ARM) don't use registers in the ARM calling convention due to missing cspec entries. Specifically, that issue report describes the modern AAPCS standard, which requires double-word sized values to be passed using r1:4,r0:4
, r3:4,r2:4
, or the stack. However, the older APCS standard is more permissive about where the value starts, such as allowing it to passed using r2:4,r1:4
. This is where the problem occurs.
I'm analyzing a little-endian APCS binary currently, and I'm using the "Use Custom Storage" option to correct for the calling convention issues. However, one function has a double
argument as the third argument (with the preceding 3 arguments being word sized). For the little-endian APCS standard, this stores the least-significant half in r3
, and the other half on the stack. (See this goldbolt example for reference. Note that r3
gets written to the stack, then immediately read to r0
for returning.) This means that the storage should be set to Stack[0x0]:4,r3:4
. However, trying to set this in the Storage Address Editor window gives the message "Only the last entry may be of type Stack" and it stops me from applying the storage layout. Swapping the order lets me apply the storage, but it puts the halves in the wrong order.
I understand that having values split between the stack and registers is an uncommon case that probably hadn't been considered, but since there is a calling convention that uses it (even if it's an outdated one), this case should probably be supported by Ghidra
To Reproduce
Steps to reproduce the behavior:
- Create a project for a 32-bit ARM binary (I used an ARMv4T binary) that uses the older APCS ABI (eg. using
-mabi=atpcs
with gcc) - Open the Edit Function window for a function
- Check the box for "Uses Custom Storage"
- Double click an argument's storage to open the Storage Address Editor
- Set the Storage Locations to
Stack[0x0]:4
first andr3:4
second - Note the error and grayed out OK button
Expected behavior
Ghidra should accept the storage layout, since it's part of a standardized calling convention.
Screenshots
Environment (please complete the following information):
- OS: Windows 10 22H2
- Java Version: 23.0.1
- Ghidra Version: 11.2.1
- Ghidra Origin: Github precompiled release