about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorAlexandre Julliard <julliard@winehq.org>2023-07-03 21:54:37 +0200
committerGitHub <noreply@github.com>2023-07-03 21:54:37 +0200
commita450806dd2da14cf29b6b01dc8e7e385e65f8dcb (patch)
tree813f68ac9f6b2f5214460ca1d3bef1407edfedf7 /src
parentcf6048419baf5c7a29ddf5a2463d7ae744832463 (diff)
downloadbox64-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-xsrc/elfs/elfloader.c1
-rwxr-xr-xsrc/emu/x64run.c82
-rw-r--r--src/emu/x64run64.c12
-rw-r--r--src/emu/x64run66.c4
-rw-r--r--src/emu/x64run67.c2
-rwxr-xr-xsrc/emu/x64run_private.h45
-rwxr-xr-xsrc/include/box64stack.h9
-rwxr-xr-xsrc/main.c1
-rwxr-xr-xsrc/tools/box64stack.c99
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);
 }