systems-nuts / unifico

Compiler and build harness for heterogeneous-ISA binaries with the same stack layout.
4 stars 1 forks source link

`lu::main` #223

Open blackgeorge-boom opened 1 year ago

blackgeorge-boom commented 1 year ago

AArch64:

0000000000501050 main:
  501050: ff 83 02 d1                   sub sp, sp, #0xa0
  501054: f4 4f 08 a9                   stp x20, x19, [sp, #0x80]
  501058: fd 7b 09 a9                   stp x29, x30, [sp, #0x90]
  50105c: fd 43 02 91                   add x29, sp, #0x90
  501060: e8 17 00 f0                   adrp    x8, #0x2ff000
  501064: f0 17 00 f0                   adrp    x16, #0x2ff000
  501068: 11 89 40 b9                   ldr w17, [x8, #0x88]
  50106c: 14 8e 40 b9                   ldr w20, [x16, #0x8c]
...
  5010f8: f1 07 07 29                   stp w17, w1, [sp, #0x38] <--- 

X86:


0000000000501050 <main>:
  501050:   55                      push   rbp
  501051:   48 89 e5                mov    rbp,rsp
  501054:   53                      push   rbx
  501055:   41 57                   push   r15
  501057:   48 81 ec 90 00 00 00    sub    rsp,0x90
  50105e:   c7 45 e4 00 00 00 00    mov    DWORD PTR [rbp-0x1c],0x0
  501065:   89 7d e0                mov    DWORD PTR [rbp-0x20],edi
  501068:   48 89 75 d8             mov    QWORD PTR [rbp-0x28],rsi
  50106c:   8b 0d 16 f0 2f 00       mov    ecx,DWORD PTR [rip+0x2ff016]        # 800088 <nx0>
  501072:   44 8b 3d 13 f0 2f 00    mov    r15d,DWORD PTR [rip+0x2ff013]        # 80008c <ny0>
  501079:   42 8d 04 39             lea    eax,[rcx+r15*1]
  50107d:   48 89 ca                mov    rdx,rcx
  501080:   48 89 4d a0             mov    QWORD PTR [rbp-0x60],rcx <---

The value of nx0 in the case of X86 is extended to 64 bits and then it is stored as an 8-byte value (instead of a 4-byte value in AArch64), which makes the stacks different.

blackgeorge-boom commented 1 year ago

The MIR for X86 that exhibits this issue is:

96B   %2:gr32 = MOV32rm $rip, 1, $noreg, @nx0, $noreg :: (dereferenceable load 4 from @nx0)
112B      %3:gr32 = MOV32rm $rip, 1, $noreg, @ny0, $noreg :: (dereferenceable load 4 from @ny0)
128B      undef %20.sub_32bit:gr64 = COPY %2:gr32
144B      undef %21.sub_32bit:gr64_nosp = COPY %3:gr32
160B      %4:gr32 = LEA64_32r %20:gr64, 1, %21:gr64_nosp, 0, $noreg

This is converted from:

  %2:gr32 = MOV32rm $rip, 1, $noreg, @nx0, $noreg :: (dereferenceable load 4 from @nx0)
  %3:gr32 = MOV32rm $rip, 1, $noreg, @ny0, $noreg :: (dereferenceable load 4 from @ny0)
  %4:gr32 = nsw ADD32rr %2:gr32(tied-def 0), %3:gr32, implicit-def dead $eflags

after the twoaddressinstruction pass.

The problem here is that the ADD32rr instruction is converted to a three address LEA64_32r, which has 64-bit operands.