Scattered argument locations

On x64 and other processors the compiler sometimes passes structures and unions partially on registers and partially on the stack. Consider the following structure:
  #pragma pack(push, 4)
  struct struc_1
    char c1;
    short s2;
    char c3;
    int i4;
  #pragma pack(pop)
In binary form it looks like this:
  00000000 struc_1         struc ; (sizeof=0xC)
  00000000 c1              db ?
  00000001                 db ? ; undefined
  00000002 s2              dw ?
  00000004 c3              db ?
  00000005                 db ? ; undefined
  00000006                 db ? ; undefined
  00000007                 db ? ; undefined
  00000008 i4              dd ?
  0000000C struc_1         ends
If we have this function prototype:
  void myfunc(struc_1 s);
the 64bit GNU compiler will pass the structure like this:
  RDI: c1, s2, and c3
  RSI: i4
Since compilers can use such complex calling conventions, IDA needs some mechanism to describe them. Scattered argument locations are used for that. The above calling convention can be described like this:
  void __usercall myfunc(struc_1 s@<0:rdi.1, 2:rdi^2.2, 4:rdi^4.1, 8:rsi.4>);
It reads:
  1 byte  at offset 0 of the argument is  passed in the byte 0 of RDI
  2 bytes at offset 2 of the argument are passed in the byte 1,2 of RDI
  1 byte  at offset 4 of the argument is  passed in the byte 3 of RDI
  4 bytes at offset 8 of the argument are passed starting from the byte 0 of RSI
In other words, the following syntax is used:
  argoff - offset within the argument
  register - register name used to pass part of the argument
  regoff - offset within the register
  size - number of bytes
The regoff and size fields can be omitted if there is no ambiguity.

If the register is not specified, the expression describes a stack location:

  argoff - offset within the argument
  stkoff - offset in the stack frame (the first stack argument is at offset 0)
  size - number of bytes
Please note that while IDA checks the argument location specifiers for soundness, it can not perform all checks and some wrong locations may be accepted. In particular, IDA in general does not know the register sizes and accepts any offsets within them and any sizes.
         Set type command.
Index | Previous topic | Next topic