about summary refs log tree commit diff stats
path: root/src/tools/box32stack.c
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2024-08-26 17:45:13 +0200
committerGitHub <noreply@github.com>2024-08-26 17:45:13 +0200
commitb5105a1e57bba3305d5dce93ab4d2f7faab6b34a (patch)
treeab26b700d3c48f2c8e32a1084ae7c2e7a8448b06 /src/tools/box32stack.c
parent9beb745765e9c99bad6410094a97bf0bf9ebc1eb (diff)
downloadbox64-b5105a1e57bba3305d5dce93ab4d2f7faab6b34a.tar.gz
box64-b5105a1e57bba3305d5dce93ab4d2f7faab6b34a.zip
Added preliminary Box32 support (#1760)
* Improve the ReserveHigMemory helper function

* [BOX32] Added some wrapping infrastructure

* [BOX32] More wrapped 32bits lib infrastructure

* [BOX32] Added callback and tls 32bits handling

* [BOX32] Added more 32bits, around wrappers and elfs

* [BOX32] Added the 32bits version of myalign

* [BOX32] More wrapped libs and 32bits fixes and imrpovments

* [BOX32] Added some 32bits tests

* [BOX32] Try to enable some Box32 build and test on the CI

* [BOX32] Disable Box32 testing on CI platform that use qemu

* [BOX32] Another attempt to disable Box32 testing on CI platform that use qemu

* [BOX32] Small fix for another attempt to disable Box32 testing on CI platform that use qemu

* [BOX32] Yet another fix for another attempt to disable Box32 testing on CI platform that use qemu

* [BOX32] Fixed a typo in CI script

* [BOX32] Better scratch alighnment and enabled more tests

* [BOX32] Added (partial) wrapped 32bits librt

* [BOX32] Added mention of Box32 in README

* [BOX32] Added phtread handling, and numerous fixes to 32bits handling. [ARM64_DYNAREC] Fixed access to segment with negative offset

* [BOX32] Added system libs and cpp testing, plus some more fixes

* [BOX32] Fix previous commit

* [BOX32] Better stack adjustment for 32bits processes

* [BOX32] Added getenv wrapped 32bits function and friends

* [BOX32] Don't look for box86 for a Box32 build

* [BOX32] Don't do 32bits cppThreads test for now on CI

* [BOX32] Enabled a few more 32bits tests

* [BOX32] For ld_lib_path for both CppThreads tests

* [BOX32] [ANDROID] Some Fixes for Android Build

* [BOX32] Still need to disable cppThread_32bits test on CI for some reason

* [BOX32] [ANDROID] Don't show PreInit Array Warning (#1751)

* [BOX32] [ANDROID] One More Fix for Android Build That I forgotten to … (#1752)

* [BOX32] [ANDROID] One More Fix for Android Build That I forgotten to push before

* [BOX32] [ANDROID] Try to Create __libc_init

* [BOX32] [ANDROID] Try to disable NEEDED_LIBS for now (libdl is not wrapped)

* [BOX32] Updated generated files

* [BOX32] Added 32bits context functions

* [BOX32] Added 32bits signal handling

* [BOX32] Added some missing 32bits elfloader functions

* [BOX32] Fix build on x86_64 machine

* [BOX32] Better fix for x86_64 build

* [BOX32] Actually added missing libs, and re-enabled cppThreads_32bits test

* [BOX32] Added wrapped 32bits libdl

* [BOX32] Try to re-enabled Box32 test on CI for ARM64 builds

* [BOX32] fine-tuning Box32 test on CI for ARM64 builds

* [BOX32] More fine-tuning to Box32 test on CI for ARM64 builds

* [BOX32] Enabled Box32 test on CI for LA64 and RV64 builds too

* [BOX32] re-Disabled Box32 test on CI for LA64 and RV64 builds, not working for now

* [BOX32] Temporarily disabled cppThreads_32bits test on CI

---------

Co-authored-by: KreitinnSoftware <pablopro5051@gmail.com>
Co-authored-by: KreitinnSoftware <80591934+KreitinnSoftware@users.noreply.github.com>
Diffstat (limited to 'src/tools/box32stack.c')
-rw-r--r--src/tools/box32stack.c137
1 files changed, 137 insertions, 0 deletions
diff --git a/src/tools/box32stack.c b/src/tools/box32stack.c
new file mode 100644
index 00000000..441b27ab
--- /dev/null
+++ b/src/tools/box32stack.c
@@ -0,0 +1,137 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <sys/mman.h>
+
+#include "box64stack.h"
+#include "box64context.h"
+#include "elfloader.h"
+#include "debug.h"
+#include "emu/x64emu_private.h"
+#include "emu/x64run_private.h"
+#include "auxval.h"
+#include "custommem.h"
+#include "box32.h"
+
+static void PushString32(x64emu_t *emu, const char* s)
+{
+    int sz = strlen(s) + 1;
+    // round to 4 bytes boundary
+    R_ESP -= sz;
+    memcpy(from_ptrv(R_ESP), s, sz);
+}
+
+static void Push32_32(x64emu_t *emu, uint32_t v)
+{
+    R_ESP -= 4;
+    *((uint32_t*)from_ptr(R_ESP)) = v;
+}
+
+
+EXPORTDYN
+void SetupInitialStack32(x64emu_t *emu)
+{
+    // start with 0
+    Push32_32(emu, 0);
+    // push program executed
+    PushString32(emu, emu->context->argv[0]);
+    uintptr_t p_arg0 = from_ptr(R_ESP);
+    // push envs
+    uintptr_t p_envv[emu->context->envc];
+    for (int i=emu->context->envc-1; i>=0; --i) {
+        PushString32(emu, emu->context->envv[i]);
+        p_envv[i] = from_ptr(R_ESP);
+    }
+    // push args, also, free the argv[] string and point to the one in the main stack
+    uintptr_t p_argv[emu->context->argc];
+    for (int i=emu->context->argc-1; i>=0; --i) {
+        PushString32(emu, emu->context->argv[i]);
+        p_argv[i] = R_ESP;
+        free(emu->context->argv[i]);
+        emu->context->argv[i] = (char*)p_argv[i];
+    }
+    // align
+    uintptr_t tmp = from_ptr(R_ESP)&~(emu->context->stackalign-1);
+    memset((void*)tmp, 0, from_ptr(R_ESP)-tmp);
+    R_ESP=to_ptr(tmp);
+
+    // push some AuxVector stuffs
+    PushString32(emu, "i686");
+    uintptr_t p_i686 = from_ptr(R_ESP);
+    uintptr_t p_random = real_getauxval(25);
+    if(!p_random) {
+        for (int i=0; i<4; ++i)
+            Push32_32(emu, random());
+        p_random = from_ptr(R_ESP);
+    }
+    // align
+    tmp = (R_ESP)&~(emu->context->stackalign-1);
+    memset((void*)tmp, 0, from_ptr(R_ESP)-tmp);
+    R_ESP=tmp;
+
+    // push the AuxVector themselves
+    /*
+    00: 00000000
+    03: 08048034
+    04: 00000020
+    05: 0000000b
+    06: 00001000
+    07: f7fc0000
+    08: 00000000
+    09: 08049060
+    11: 000003e8
+    12: 000003e8
+    13: 000003e8
+    14: 000003e8
+    15: ffd8aa5b/i686
+    16: bfebfbff
+    17: 00000064
+    23: 00000000
+    25: ffd8aa4b
+    26: 00000000
+    31: ffd8bfeb/./testAuxVec
+    32: f7fbfb40
+    33: f7fbf000
+    */
+    Push32_32(emu, 0); Push32_32(emu, 0);                            //AT_NULL(0)=0
+    //Push32_32(emu, ); Push32_32(emu, 3);                             //AT_PHDR(3)=address of the PH of the executable
+    //Push32_32(emu, ); Push32_32(emu, 4);                             //AT_PHENT(4)=size of PH entry
+    //Push32_32(emu, ); Push32_32(emu, 5);                             //AT_PHNUM(5)=number of elf headers
+    Push32_32(emu, box64_pagesize); Push32_32(emu, 6);               //AT_PAGESZ(6)
+    //Push32_32(emu, real_getauxval(7)); Push32_32(emu, 7);            //AT_BASE(7)=ld-2.27.so start (in memory)
+    Push32_32(emu, 0); Push32_32(emu, 8);                            //AT_FLAGS(8)=0
+    Push32_32(emu, R_EIP); Push32_32(emu, 9);                        //AT_ENTRY(9)=entrypoint
+    Push32_32(emu, from_ulong(real_getauxval(11))); Push32_32(emu, 11);          //AT_UID(11)
+    Push32_32(emu, from_ulong(real_getauxval(12))); Push32_32(emu, 12);          //AT_EUID(12)
+    Push32_32(emu, from_ulong(real_getauxval(13))); Push32_32(emu, 13);          //AT_GID(13)
+    Push32_32(emu, from_ulong(real_getauxval(14))); Push32_32(emu, 14);          //AT_EGID(14)
+    Push32_32(emu, p_i686); Push32_32(emu, 15);                      //AT_PLATFORM(15)=&"i686"
+    // Push HWCAP:
+    //  FPU: 1<<0 ; VME: 1<<1 ; DE : 1<<2 ; PSE: 1<<3 ; TSC: 1<<4 ; MSR: 1<<5 ; PAE: 1<<6 ; MCE: 1<<7
+    //  CX8: 1<<8 ; APIC:1<<9 ;             SEP: 1<<11; MTRR:1<<12; PGE: 1<<13; MCA: 1<<14; CMOV:1<<15
+    // FCMOV:1<<16;                                                                         MMX: 1<<23
+    // OSFXR:1<<24; XMM: 1<<25;XMM2: 1<<26;                                                AMD3D:1<<31
+    Push32_32(emu, (1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<4) | (1<<8)  | (1<<15) | (1<<16) | (1<<23) | (1<<25) | (1<<26));
+    Push32_32(emu, 16);                                         //AT_HWCAP(16)=...
+    //Push32_32(emu, sysconf(_SC_CLK_TCK)); Push32_32(emu, 17);        //AT_CLKTCK(17)=times() frequency
+    Push32_32(emu, from_ulong(real_getauxval(23))); Push32_32(emu, 23);          //AT_SECURE(23)
+    Push32_32(emu, p_random); Push32_32(emu, 25);                    //AT_RANDOM(25)=p_random
+    Push32_32(emu, 0); Push32_32(emu, 26);                           //AT_HWCAP2(26)=0
+    Push32_32(emu, p_arg0); Push32_32(emu, 31);                      //AT_EXECFN(31)=p_arg0
+    Push32_32(emu, emu->context->vsyscall); Push32_32(emu, 32); //AT_SYSINFO(32)=vsyscall
+    //Push32_32(emu, ); Push32_32(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*)from_ptr(R_ESP);
+
+    // push nil / envs / nil / args / argc
+    Push32_32(emu, 0);
+    for (int i=emu->context->envc-1; i>=0; --i)
+        Push32_32(emu, to_ptr(p_envv[i]));
+    emu->context->envv32 = R_ESP;
+    Push32_32(emu, 0);
+    for (int i=emu->context->argc-1; i>=0; --i)
+        Push32_32(emu, to_ptr(p_argv[i]));
+    emu->context->argv32 = R_ESP;
+    Push32_32(emu, emu->context->argc);
+}