diff options
| author | Alexandre Julliard <julliard@winehq.org> | 2023-07-03 21:54:37 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-07-03 21:54:37 +0200 |
| commit | a450806dd2da14cf29b6b01dc8e7e385e65f8dcb (patch) | |
| tree | 813f68ac9f6b2f5214460ca1d3bef1407edfedf7 /src | |
| parent | cf6048419baf5c7a29ddf5a2463d7ae744832463 (diff) | |
| download | box64-a450806dd2da14cf29b6b01dc8e7e385e65f8dcb.tar.gz box64-a450806dd2da14cf29b6b01dc8e7e385e65f8dcb.zip | |
A few Push/Pop fixes and cleanups (#878)
* Use 32-bit push/pop for PUSHAD/POPAD. * Always specify the Push/Pop size explicitly. * Make the Push/Pop functions inline.
Diffstat (limited to 'src')
| -rwxr-xr-x | src/elfs/elfloader.c | 1 | ||||
| -rwxr-xr-x | src/emu/x64run.c | 82 | ||||
| -rw-r--r-- | src/emu/x64run64.c | 12 | ||||
| -rw-r--r-- | src/emu/x64run66.c | 4 | ||||
| -rw-r--r-- | src/emu/x64run67.c | 2 | ||||
| -rwxr-xr-x | src/emu/x64run_private.h | 45 | ||||
| -rwxr-xr-x | src/include/box64stack.h | 9 | ||||
| -rwxr-xr-x | src/main.c | 1 | ||||
| -rwxr-xr-x | src/tools/box64stack.c | 99 |
9 files changed, 119 insertions, 136 deletions
diff --git a/src/elfs/elfloader.c b/src/elfs/elfloader.c index e10de870..701f1164 100755 --- a/src/elfs/elfloader.c +++ b/src/elfs/elfloader.c @@ -37,6 +37,7 @@ #include "dynablock.h" #endif #include "../emu/x64emu_private.h" +#include "../emu/x64run_private.h" #include "x64tls.h" void* my__IO_2_1_stderr_ = NULL; diff --git a/src/emu/x64run.c b/src/emu/x64run.c index de927757..98fc4564 100755 --- a/src/emu/x64run.c +++ b/src/emu/x64run.c @@ -295,14 +295,14 @@ x64emurun: break; case 0x54: /* PUSH ESP */ if(rex.b) - Push(emu, R_R12); + Push64(emu, R_R12); else { if(rex.is32bits) { tmp32u = R_ESP; Push32(emu, tmp32u); } else { tmp64u = R_RSP; - Push(emu, tmp64u); + Push64(emu, tmp64u); } } break; @@ -317,7 +317,7 @@ x64emurun: if(rex.is32bits) Push32(emu, emu->regs[tmp8u].dword[0]); else - Push(emu, emu->regs[tmp8u].q[0]); + Push64(emu, emu->regs[tmp8u].q[0]); break; case 0x58: case 0x59: @@ -328,19 +328,19 @@ x64emurun: case 0x5E: case 0x5F: /* POP Reg */ tmp8u = (opcode&7)+(rex.b<<3); - emu->regs[tmp8u].q[0] = is32bits?Pop32(emu):Pop(emu); + emu->regs[tmp8u].q[0] = is32bits?Pop32(emu):Pop64(emu); break; case 0x60: /* PUSHAD */ if(rex.is32bits) { tmp32u = R_ESP; - Push(emu, R_EAX); - Push(emu, R_ECX); - Push(emu, R_EDX); - Push(emu, R_EBX); - Push(emu, tmp32u); - Push(emu, R_EBP); - Push(emu, R_ESI); - Push(emu, R_EDI); + Push32(emu, R_EAX); + Push32(emu, R_ECX); + Push32(emu, R_EDX); + Push32(emu, R_EBX); + Push32(emu, tmp32u); + Push32(emu, R_EBP); + Push32(emu, R_ESI); + Push32(emu, R_EDI); } else { unimp = 1; goto fini; @@ -348,14 +348,14 @@ x64emurun: break; case 0x61: /* POPAD */ if(rex.is32bits) { - R_EDI = Pop(emu); - R_ESI = Pop(emu); - R_EBP = Pop(emu); + R_EDI = Pop32(emu); + R_ESI = Pop32(emu); + R_EBP = Pop32(emu); R_ESP+=4; // POP ESP - R_EBX = Pop(emu); - R_EDX = Pop(emu); - R_ECX = Pop(emu); - R_EAX = Pop(emu); + R_EBX = Pop32(emu); + R_EDX = Pop32(emu); + R_ECX = Pop32(emu); + R_EAX = Pop32(emu); } else { unimp = 1; goto fini; @@ -446,7 +446,7 @@ x64emurun: if(rex.is32bits) Push32(emu, F32); else - Push(emu, F32S64); + Push64(emu, F32S64); break; case 0x69: /* IMUL Gd,Ed,Id */ nextop = F8; @@ -464,7 +464,7 @@ x64emurun: Push32(emu, (uint32_t)tmp32s); } else { tmp64s = F8S; - Push(emu, (uint64_t)tmp64s); + Push64(emu, (uint64_t)tmp64s); } break; case 0x6B: /* IMUL Gd,Ed,Ib */ @@ -771,7 +771,7 @@ x64emurun: case 0x8F: /* POP Ed */ nextop = F8; if(MODREG) { - emu->regs[(nextop&7)+(rex.b<<3)].q[0] = rex.is32bits?Pop32(emu):Pop(emu); + emu->regs[(nextop&7)+(rex.b<<3)].q[0] = rex.is32bits?Pop32(emu):Pop64(emu); } else { if(rex.is32bits) { tmp32u = Pop32(emu); // this order allows handling POP [ESP] and variant @@ -780,7 +780,7 @@ x64emurun: ED->dword[0] = tmp32u; R_ESP += 4; } else { - tmp64u = Pop(emu); // this order allows handling POP [ESP] and variant + tmp64u = Pop64(emu); // this order allows handling POP [ESP] and variant GETED(0); R_RSP -= sizeof(void*); // to prevent issue with SEGFAULT ED->q[0] = tmp64u; @@ -832,10 +832,10 @@ x64emurun: if(rex.is32bits) Push32(emu, emu->eflags.x64); else - Push(emu, emu->eflags.x64); + Push64(emu, emu->eflags.x64); break; case 0x9D: /* POPF */ - emu->eflags.x64 = (((rex.is32bits?Pop32(emu):Pop(emu)) & 0x3F7FD7)/* & (0xffff-40)*/ ) | 0x2; // mask off res2 and res3 and on res1 + emu->eflags.x64 = (((rex.is32bits?Pop32(emu):Pop64(emu)) & 0x3F7FD7)/* & (0xffff-40)*/ ) | 0x2; // mask off res2 and res3 and on res1 RESET_FLAGS(emu); #ifndef TEST_INTERPRETER if(ACCESS_FLAG(F_TF)) { @@ -1307,12 +1307,12 @@ x64emurun: break; case 0xC2: /* RETN Iw */ tmp16u = F16; - addr = rex.is32bits?Pop32(emu):Pop(emu); + addr = rex.is32bits?Pop32(emu):Pop64(emu); R_RSP += tmp16u; STEP2 break; case 0xC3: /* RET */ - addr = rex.is32bits?Pop32(emu):Pop(emu); + addr = rex.is32bits?Pop32(emu):Pop64(emu); STEP2 break; @@ -1348,21 +1348,21 @@ x64emurun: } } else { tmp64u = R_RBP; - Push(emu, R_RBP); + Push64(emu, R_RBP); R_RBP = R_RSP; if (tmp8u) { for (tmp8u2 = 1; tmp8u2 < tmp8u; tmp8u2++) { tmp64u -= sizeof(void*); - Push(emu, *((uintptr_t*)tmp64u)); + Push64(emu, *((uintptr_t*)tmp64u)); } - Push(emu, R_RBP); + Push64(emu, R_RBP); } } R_RSP -= tmp16u; break; case 0xC9: /* LEAVE */ R_RSP = R_RBP; - R_RBP = rex.is32bits?Pop32(emu):Pop(emu); + R_RBP = rex.is32bits?Pop32(emu):Pop64(emu); break; case 0xCC: /* INT 3 */ @@ -1399,12 +1399,12 @@ x64emurun: break; case 0xCF: /* IRET */ - addr = rex.is32bits?Pop32(emu):Pop(emu); - emu->segs[_CS] = (rex.is32bits?Pop32(emu):Pop(emu))&0xffff; + addr = rex.is32bits?Pop32(emu):Pop64(emu); + emu->segs[_CS] = (rex.is32bits?Pop32(emu):Pop64(emu))&0xffff; emu->segs_serial[_CS] = 0; - emu->eflags.x64 = (((rex.is32bits?Pop32(emu):Pop(emu)) & 0x3F7FD7)/* & (0xffff-40)*/ ) | 0x2; // mask off res2 and res3 and on res1 - tmp64u = rex.is32bits?Pop32(emu):Pop(emu); //RSP - emu->segs[_SS] = (rex.is32bits?Pop32(emu):Pop(emu))&0xffff; + emu->eflags.x64 = (((rex.is32bits?Pop32(emu):Pop64(emu)) & 0x3F7FD7)/* & (0xffff-40)*/ ) | 0x2; // mask off res2 and res3 and on res1 + tmp64u = rex.is32bits?Pop32(emu):Pop64(emu); //RSP + emu->segs[_SS] = (rex.is32bits?Pop32(emu):Pop64(emu))&0xffff; emu->segs_serial[_SS] = 0; R_RSP = tmp64u; RESET_FLAGS(emu); @@ -1637,7 +1637,7 @@ x64emurun: if(rex.is32bits) Push32(emu, addr); else - Push(emu, addr); + Push64(emu, addr); addr += tmp32s; STEP2 break; @@ -1862,7 +1862,7 @@ x64emurun: Push32(emu, addr); } else { tmp64u = (uintptr_t)getAlternate((void*)ED->q[0]); - Push(emu, addr); + Push64(emu, addr); } addr = tmp64u; STEP2 @@ -1881,8 +1881,8 @@ x64emurun: addr = (uintptr_t)getAlternate((void*)(uintptr_t)ED->dword[0]); R_CS = ED->word[2]; } else { - Push(emu, R_CS); - Push(emu, addr); + Push64(emu, R_CS); + Push64(emu, addr); addr = (uintptr_t)getAlternate((void*)ED->q[0]); R_CS = (ED+1)->word[0]; } @@ -1924,7 +1924,7 @@ x64emurun: Push32(emu, tmp32u); // avoid potential issue with push [esp+...] } else { tmp64u = ED->q[0]; // rex.w ignored - Push(emu, tmp64u); // avoid potential issue with push [esp+...] + Push64(emu, tmp64u); // avoid potential issue with push [esp+...] } break; default: diff --git a/src/emu/x64run64.c b/src/emu/x64run64.c index bf57954c..c8641e91 100644 --- a/src/emu/x64run64.c +++ b/src/emu/x64run64.c @@ -438,7 +438,7 @@ uintptr_t Run64(x64emu_t *emu, rex_t rex, int seg, uintptr_t addr) case 0x8F: /* POP FS:Ed */ nextop = F8; if(MODREG) { - emu->regs[(nextop&7)+(rex.b<<3)].q[0] = Pop(emu); + emu->regs[(nextop&7)+(rex.b<<3)].q[0] = Pop64(emu); } else { if(rex.is32bits) { tmp32u = Pop32(emu); // this order allows handling POP [ESP] and variant @@ -447,7 +447,7 @@ uintptr_t Run64(x64emu_t *emu, rex_t rex, int seg, uintptr_t addr) ED->dword[0] = tmp32u; R_ESP += 4; } else { - tmp64u = Pop(emu); // this order allows handling POP [ESP] and variant + tmp64u = Pop64(emu); // this order allows handling POP [ESP] and variant GETED_OFFS(0, tlsdata); R_RSP -= sizeof(void*); // to prevent issue with SEGFAULT ED->q[0] = tmp64u; @@ -642,7 +642,7 @@ uintptr_t Run64(x64emu_t *emu, rex_t rex, int seg, uintptr_t addr) Push32(emu, addr); } else { tmp64u = (uintptr_t)getAlternate((void*)ED->q[0]); - Push(emu, addr); + Push64(emu, addr); } addr = tmp64u; break; @@ -659,8 +659,8 @@ uintptr_t Run64(x64emu_t *emu, rex_t rex, int seg, uintptr_t addr) R_RIP = addr = ED->dword[0]; R_CS = ED->word[2]; } else { - Push(emu, R_CS); - Push(emu, addr); + Push64(emu, R_CS); + Push64(emu, addr); R_RIP = addr = ED->q[0]; R_CS = (ED+1)->word[0]; } @@ -695,7 +695,7 @@ uintptr_t Run64(x64emu_t *emu, rex_t rex, int seg, uintptr_t addr) Push32(emu, tmp32u); // avoid potential issue with push [esp+...] } else { tmp64u = ED->q[0]; // rex.w ignored - Push(emu, tmp64u); // avoid potential issue with push [esp+...] + Push64(emu, tmp64u); // avoid potential issue with push [esp+...] } break; default: diff --git a/src/emu/x64run66.c b/src/emu/x64run66.c index a5144852..4300bcb1 100644 --- a/src/emu/x64run66.c +++ b/src/emu/x64run66.c @@ -710,7 +710,7 @@ uintptr_t Run66(x64emu_t *emu, rex_t rex, int rep, uintptr_t addr) if(rex.is32bits) Push32(emu, addr); else - Push(emu, addr); + Push64(emu, addr); addr += tmp32s; break; @@ -803,7 +803,7 @@ uintptr_t Run66(x64emu_t *emu, rex_t rex, int rep, uintptr_t addr) Push32(emu, addr); } else { tmp64u = (uintptr_t)getAlternate((void*)ED->q[0]); - Push(emu, addr); + Push64(emu, addr); } addr = tmp64u; break; diff --git a/src/emu/x64run67.c b/src/emu/x64run67.c index 98d2df62..8b68d4c5 100644 --- a/src/emu/x64run67.c +++ b/src/emu/x64run67.c @@ -364,7 +364,7 @@ uintptr_t Run67(x64emu_t *emu, rex_t rex, int rep, uintptr_t addr) case 0xE8: /* CALL Id */ tmp32s = F32S; // call is relative - Push(emu, addr); + Push64(emu, addr); addr += tmp32s; break; diff --git a/src/emu/x64run_private.h b/src/emu/x64run_private.h index 5b3b30f7..ec91bdcc 100755 --- a/src/emu/x64run_private.h +++ b/src/emu/x64run_private.h @@ -23,24 +23,51 @@ typedef struct rex_s { static inline uint8_t Peek(x64emu_t *emu, int offset){return *(uint8_t*)(R_RIP + offset);} -static inline uint64_t Pop(x64emu_t *emu) -{ - uint64_t* st = ((uint64_t*)(R_RSP)); - R_RSP += 8; - return *st; -} - #ifdef TEST_INTERPRETER -#define Push(E, V) do{E->regs[_SP].q[0] -=8; test->memsize = 8; *(uint64_t*)test->mem = (V); test->memaddr = E->regs[_SP].q[0];}while(0) #define Push16(E, V) do{E->regs[_SP].q[0] -=2; test->memsize = 2; *(uint16_t*)test->mem = (V); test->memaddr = E->regs[_SP].q[0];}while(0) +#define Push32(E, V) do{E->regs[_SP].q[0] -=4; test->memsize = 4; *(uint32_t*)test->mem = (V); test->memaddr = E->regs[_SP].q[0];}while(0) +#define Push64(E, V) do{E->regs[_SP].q[0] -=8; test->memsize = 8; *(uint64_t*)test->mem = (V); test->memaddr = E->regs[_SP].q[0];}while(0) #else -static inline void Push(x64emu_t *emu, uint64_t v) +static inline void Push16(x64emu_t *emu, uint16_t v) +{ + R_RSP -= 2; + *((uint16_t*)R_RSP) = v; +} + +static inline void Push32(x64emu_t *emu, uint32_t v) +{ + R_RSP -= 4; + *((uint32_t*)R_RSP) = v; +} + +static inline void Push64(x64emu_t *emu, uint64_t v) { R_RSP -= 8; *((uint64_t*)R_RSP) = v; } #endif +static inline uint16_t Pop16(x64emu_t *emu) +{ + uint16_t* st = (uint16_t*)R_RSP; + R_RSP += 2; + return *st; +} + +static inline uint32_t Pop32(x64emu_t *emu) +{ + uint32_t* st = (uint32_t*)R_RSP; + R_RSP += 4; + return *st; +} + +static inline uint64_t Pop64(x64emu_t *emu) +{ + uint64_t* st = (uint64_t*)R_RSP; + R_RSP += 8; + return *st; +} + static inline void PushExit(x64emu_t* emu) { R_RSP -= 8; diff --git a/src/include/box64stack.h b/src/include/box64stack.h index 997e0646..0607f23f 100755 --- a/src/include/box64stack.h +++ b/src/include/box64stack.h @@ -9,11 +9,4 @@ typedef struct x64emu_s x64emu_t; int CalcStackSize(box64context_t *context); void SetupInitialStack(x64emu_t *emu); -uint16_t Pop16(x64emu_t *emu); -void Push16(x64emu_t *emu, uint16_t v); -uint32_t Pop32(x64emu_t *emu); -void Push32(x64emu_t *emu, uint32_t v); -uint64_t Pop64(x64emu_t *emu); -void Push64(x64emu_t *emu, uint64_t v); - -#endif //__BOX64_STACK_H_ \ No newline at end of file +#endif //__BOX64_STACK_H_ diff --git a/src/main.c b/src/main.c index 9fb48f7d..e06cd2ad 100755 --- a/src/main.c +++ b/src/main.c @@ -35,6 +35,7 @@ #include "x64run.h" #include "symbols.h" #include "rcfile.h" +#include "emu/x64run_private.h" box64context_t *my_context = NULL; int box64_quit = 0; diff --git a/src/tools/box64stack.c b/src/tools/box64stack.c index 97623261..44596b98 100755 --- a/src/tools/box64stack.c +++ b/src/tools/box64stack.c @@ -35,45 +35,6 @@ int CalcStackSize(box64context_t *context) return 0; } -uint16_t Pop16(x64emu_t *emu) -{ - uint16_t* st = ((uint16_t*)(R_RSP)); - R_RSP += 2; - return *st; -} - -void Push16(x64emu_t *emu, uint16_t v) -{ - R_RSP -= 2; - *((uint16_t*)R_RSP) = v; -} - -uint32_t Pop32(x64emu_t *emu) -{ - uint32_t* st = ((uint32_t*)(R_RSP)); - R_RSP += 4; - return *st; -} - -void Push32(x64emu_t *emu, uint32_t v) -{ - R_RSP -= 4; - *((uint32_t*)R_RSP) = v; -} - -uint64_t Pop64(x64emu_t *emu) -{ - uint64_t* st = ((uint64_t*)(R_RSP)); - R_RSP += 8; - return *st; -} - -void Push64(x64emu_t *emu, uint64_t v) -{ - R_RSP -= 8; - *((uint64_t*)R_RSP) = v; -} - void PushString(x64emu_t *emu, const char* s) { int sz = strlen(s) + 1; @@ -86,7 +47,7 @@ EXPORTDYN void SetupInitialStack(x64emu_t *emu) { // start with 0 - Push(emu, 0); + Push64(emu, 0); // push program executed PushString(emu, emu->context->argv[0]); uintptr_t p_arg0 = R_RSP; @@ -116,7 +77,7 @@ void SetupInitialStack(x64emu_t *emu) uintptr_t p_random = real_getauxval(25); if(!p_random) { for (int i=0; i<4; ++i) - Push(emu, random()); + Push64(emu, random()); p_random = R_RSP; } // align @@ -146,21 +107,21 @@ void SetupInitialStack(x64emu_t *emu) 31 0x7ffd5074efea 33 0x7ffd507e6000 */ - Push(emu, 0); Push(emu, 0); //AT_NULL(0)=0 - //Push(emu, ); Push(emu, 3); //AT_PHDR(3)=address of the PH of the executable - //Push(emu, ); Push(emu, 4); //AT_PHENT(4)=size of PH entry - //Push(emu, ); Push(emu, 5); //AT_PHNUM(5)=number of elf headers - Push(emu, box64_pagesize); Push(emu, 6); //AT_PAGESZ(6) - //Push(emu, real_getauxval(7)); Push(emu, 7); //AT_BASE(7)=ld-2.27.so start (in memory) - Push(emu, 0); Push(emu, 8); //AT_FLAGS(8)=0 - Push(emu, R_RIP); Push(emu, 9); //AT_ENTRY(9)=entrypoint - Push(emu, real_getauxval(11)); Push(emu, 11); //AT_UID(11) - Push(emu, real_getauxval(12)); Push(emu, 12); //AT_EUID(12) - Push(emu, real_getauxval(13)); Push(emu, 13); //AT_GID(13) - Push(emu, real_getauxval(14)); Push(emu, 14); //AT_EGID(14) - Push(emu, p_x86_64); Push(emu, 15); //AT_PLATFORM(15)=&"x86_64" - // Push HWCAP: same as CPUID 1.EDX - Push(emu, 1<<0 // fpu + Push64(emu, 0); Push64(emu, 0); //AT_NULL(0)=0 + //Push64(emu, ); Push64(emu, 3); //AT_PHDR(3)=address of the PH of the executable + //Push64(emu, ); Push64(emu, 4); //AT_PHENT(4)=size of PH entry + //Push64(emu, ); Push64(emu, 5); //AT_PHNUM(5)=number of elf headers + Push64(emu, box64_pagesize); Push64(emu, 6); //AT_PAGESZ(6) + //Push64(emu, real_getauxval(7)); Push64(emu, 7); //AT_BASE(7)=ld-2.27.so start (in memory) + Push64(emu, 0); Push64(emu, 8); //AT_FLAGS(8)=0 + Push64(emu, R_RIP); Push64(emu, 9); //AT_ENTRY(9)=entrypoint + Push64(emu, real_getauxval(11)); Push64(emu, 11); //AT_UID(11) + Push64(emu, real_getauxval(12)); Push64(emu, 12); //AT_EUID(12) + Push64(emu, real_getauxval(13)); Push64(emu, 13); //AT_GID(13) + Push64(emu, real_getauxval(14)); Push64(emu, 14); //AT_EGID(14) + Push64(emu, p_x86_64); Push64(emu, 15); //AT_PLATFORM(15)=&"x86_64" + // Push64 HWCAP: same as CPUID 1.EDX + Push64(emu, 1<<0 // fpu | 1<<4 // rdtsc | 1<<8 // cmpxchg8 | 1<<11 // sep (sysenter & sysexit) @@ -173,27 +134,27 @@ void SetupInitialStack(x64emu_t *emu) | 1<<28 // hyper threading | 1<<30 // ia64 ); - Push(emu, 16); //AT_HWCAP(16)=... - //Push(emu, sysconf(_SC_CLK_TCK)); Push(emu, 17); //AT_CLKTCK(17)=times() frequency - Push(emu, real_getauxval(23)); Push(emu, 23); //AT_SECURE(23) - Push(emu, p_random); Push(emu, 25); //AT_RANDOM(25)=p_random - Push(emu, 0); Push(emu, 26); //AT_HWCAP2(26)=0 - Push(emu, p_arg0); Push(emu, 31); //AT_EXECFN(31)=p_arg0 - Push(emu, emu->context->vsyscall); Push(emu, 32); //AT_SYSINFO(32)=vsyscall - //Push(emu, 0); Push(emu, 33); //AT_SYSINFO_EHDR(33)=address of vDSO + Push64(emu, 16); //AT_HWCAP(16)=... + //Push64(emu, sysconf(_SC_CLK_TCK)); Push64(emu, 17); //AT_CLKTCK(17)=times() frequency + Push64(emu, real_getauxval(23)); Push64(emu, 23); //AT_SECURE(23) + Push64(emu, p_random); Push64(emu, 25); //AT_RANDOM(25)=p_random + Push64(emu, 0); Push64(emu, 26); //AT_HWCAP2(26)=0 + Push64(emu, p_arg0); Push64(emu, 31); //AT_EXECFN(31)=p_arg0 + Push64(emu, emu->context->vsyscall); Push64(emu, 32); //AT_SYSINFO(32)=vsyscall + //Push64(emu, 0); Push64(emu, 33); //AT_SYSINFO_EHDR(33)=address of vDSO if(!emu->context->auxval_start) // store auxval start if needed emu->context->auxval_start = (uintptr_t*)R_RSP; // push nil / envs / nil / args / argc - Push(emu, 0); + Push64(emu, 0); for (int i=emu->context->envc-1; i>=0; --i) - Push(emu, p_envv[i]); + Push64(emu, p_envv[i]); box_free(emu->context->envv); emu->context->envv = (char**)R_RSP; - Push(emu, 0); + Push64(emu, 0); for (int i=emu->context->argc-1; i>=0; --i) - Push(emu, p_argv[i]); + Push64(emu, p_argv[i]); box_free(emu->context->argv); emu->context->argv = (char**)R_RSP; - Push(emu, emu->context->argc); + Push64(emu, emu->context->argc); } |