diff options
Diffstat (limited to 'src/emu')
| -rw-r--r-- | src/emu/x64emu.c | 57 | ||||
| -rw-r--r-- | src/emu/x64emu_private.h | 6 | ||||
| -rw-r--r-- | src/emu/x64int3.c | 14 | ||||
| -rw-r--r-- | src/emu/x64run.c | 10 | ||||
| -rw-r--r-- | src/emu/x64run64.c | 10 | ||||
| -rw-r--r-- | src/emu/x64run_private.c | 53 | ||||
| -rw-r--r-- | src/emu/x64run_private.h | 21 | ||||
| -rw-r--r-- | src/emu/x64tls.c | 81 | ||||
| -rwxr-xr-x | src/emu/x86int3.c | 347 | ||||
| -rwxr-xr-x | src/emu/x86syscall.c | 2 | ||||
| -rw-r--r-- | src/emu/x86syscall_32.c | 447 | ||||
| -rw-r--r-- | src/emu/x87emu_private.c | 18 |
12 files changed, 1011 insertions, 55 deletions
diff --git a/src/emu/x64emu.c b/src/emu/x64emu.c index f0865299..ddfa0fc6 100644 --- a/src/emu/x64emu.c +++ b/src/emu/x64emu.c @@ -64,11 +64,29 @@ static void internalX64Setup(x64emu_t* emu, box64context_t *context, uintptr_t s // set default value R_RIP = start; R_RSP = (stack + stacksize) & ~7; // align stack start, always + #ifdef BOX32 + if(box64_is32bits) { + if(stack>=0x100000000LL) { + printf_log(LOG_NONE, "BOX32: Stack pointer too high (%p), aborting\n", (void*)stack); + abort(); + } + if(R_RSP>=0x100000000LL) { // special case, stack is just a bit too high + R_RSP = 0x100000000LL - 16; + } + } + #endif // fake init of segments... - emu->segs[_CS] = 0x33; - emu->segs[_DS] = emu->segs[_ES] = emu->segs[_SS] = 0x2b; - emu->segs[_FS] = 0x43; - emu->segs[_GS] = default_gs; + if(box64_is32bits) { + emu->segs[_CS] = 0x23; + emu->segs[_DS] = emu->segs[_ES] = emu->segs[_SS] = 0x2b; + emu->segs[_FS] = default_fs; + emu->segs[_GS] = 0x33; + } else { + emu->segs[_CS] = 0x33; + emu->segs[_DS] = emu->segs[_ES] = emu->segs[_SS] = 0x2b; + emu->segs[_FS] = 0x43; + emu->segs[_GS] = default_gs; + } // setup fpu regs reset_fpu(emu); emu->mxcsr.x32 = 0x1f80; @@ -77,7 +95,7 @@ static void internalX64Setup(x64emu_t* emu, box64context_t *context, uintptr_t s EXPORTDYN x64emu_t *NewX64Emu(box64context_t *context, uintptr_t start, uintptr_t stack, int stacksize, int ownstack) { - printf_log(LOG_DEBUG, "Allocate a new X86_64 Emu, with EIP=%p and Stack=%p/0x%X\n", (void*)start, (void*)stack, stacksize); + printf_log(LOG_DEBUG, "Allocate a new X86_64 Emu, with %cIP=%p and Stack=%p/0x%X\n", box64_is32bits?'E':'R', (void*)start, (void*)stack, stacksize); x64emu_t *emu = (x64emu_t*)box_calloc(1, sizeof(x64emu_t)); @@ -161,7 +179,7 @@ void CallCleanup(x64emu_t *emu, elfheader_t* h) if(!h) return; for(int i=h->clean_sz-1; i>=0; --i) { - printf_log(LOG_DEBUG, "Call cleanup #%d\n", i); + printf_log(LOG_DEBUG, "Call cleanup #%d (args:%d, arg:%p)\n", i, h->cleanups[i].arg, h->cleanups[i].a); RunFunctionWithEmu(emu, 0, (uintptr_t)(h->cleanups[i].f), h->cleanups[i].arg, h->cleanups[i].a ); // now remove the cleanup if(i!=h->clean_sz-1) @@ -325,10 +343,14 @@ void SetEBP(x64emu_t *emu, uint32_t v) { R_EBP = v; } -//void SetESP(x64emu_t *emu, uint32_t v) -//{ -// R_ESP = v; -//} +void SetESP(x64emu_t *emu, uint32_t v) +{ + R_ESP = v; +} +void SetEIP(x64emu_t *emu, uint32_t v) +{ + R_EIP = v; +} void SetRAX(x64emu_t *emu, uint64_t v) { R_RAX = v; @@ -373,7 +395,7 @@ uint64_t GetRBP(x64emu_t *emu) { return R_RBP; } -/*void SetFS(x64emu_t *emu, uint16_t v) +void SetFS(x64emu_t *emu, uint16_t v) { emu->segs[_FS] = v; emu->segs_serial[_FS] = 0; @@ -381,7 +403,7 @@ uint64_t GetRBP(x64emu_t *emu) uint16_t GetFS(x64emu_t *emu) { return emu->segs[_FS]; -}*/ +} void ResetFlags(x64emu_t *emu) @@ -572,9 +594,14 @@ void EmuCall(x64emu_t* emu, uintptr_t addr) uint64_t old_rip = R_RIP; //Push64(emu, GetRBP(emu)); // set frame pointer //SetRBP(emu, GetRSP(emu)); // save RSP - R_RSP -= 200; - R_RSP &= ~63LL; - PushExit(emu); + //R_RSP -= 200; + //R_RSP &= ~63LL; + #ifdef BOX32 + if(box64_is32bits) + PushExit_32(emu); + else + #endif + PushExit(emu); R_RIP = addr; emu->df = d_none; Run(emu, 0); diff --git a/src/emu/x64emu_private.h b/src/emu/x64emu_private.h index bef4a9a4..35bfd97e 100644 --- a/src/emu/x64emu_private.h +++ b/src/emu/x64emu_private.h @@ -5,6 +5,9 @@ typedef struct box64context_s box64context_t; typedef struct x64_ucontext_s x64_ucontext_t; +#ifdef BOX32 +typedef struct i386_ucontext_s i386_ucontext_t; +#endif #define ERR_UNIMPL 1 #define ERR_DIVBY0 2 @@ -116,6 +119,7 @@ typedef struct x64emu_s { uintptr_t prev2_ip; #endif // scratch stack, used for alignment of double and 64bits ints on arm. 200 elements should be enough + __int128_t dummy_align; // here to have scratch 128bits aligned uint64_t scratch[200]; // local stack, do be deleted when emu is freed void* stack2free; // this is the stack to free (can be NULL) @@ -126,7 +130,7 @@ typedef struct x64emu_s { uintptr_t old_savedsp; #endif - x64_ucontext_t *uc_link; // to handle setcontext + void* uc_link; // to handle setcontext (can be x64_ucontext_t or a i386_ucontext_t) int type; // EMUTYPE_xxx define } x64emu_t; diff --git a/src/emu/x64int3.c b/src/emu/x64int3.c index dd1b439c..b0f452a2 100644 --- a/src/emu/x64int3.c +++ b/src/emu/x64int3.c @@ -88,6 +88,10 @@ static uint8_t Peek8(uintptr_t addr, uintptr_t offset) void x64Int3(x64emu_t* emu, uintptr_t* addr) { + if(box64_is32bits) { + x86Int3(emu,addr); + return; + } onebridge_t* bridge = (onebridge_t*)(*addr-1); if(Peek8(*addr, 0)=='S' && Peek8(*addr, 1)=='C') // Signature for "Out of x86 door" { @@ -393,4 +397,12 @@ void print_cycle_log(int loglevel) { } } } -} \ No newline at end of file +} + +#ifndef BOX32 +void x86Int3(x64emu_t* emu, uintptr_t* addr) +{ + printf_log(LOG_NONE, "Error: Calling 32bits wrapped function without box32 support built in\n"); + abort(); +} +#endif \ No newline at end of file diff --git a/src/emu/x64run.c b/src/emu/x64run.c index 614bf91c..fbb92d1a 100644 --- a/src/emu/x64run.c +++ b/src/emu/x64run.c @@ -27,6 +27,9 @@ #include "modrm.h" int my_setcontext(x64emu_t* emu, void* ucp); +#ifdef BOX32 +int my32_setcontext(x64emu_t* emu, void* ucp); +#endif #ifdef TEST_INTERPRETER int RunTest(x64test_t *test) @@ -2232,7 +2235,12 @@ if(emu->segs[_CS]!=0x33 && emu->segs[_CS]!=0x23) printf_log(LOG_NONE, "Warning, // setcontext handling else if(emu->quit && emu->uc_link) { emu->quit = 0; - my_setcontext(emu, emu->uc_link); + #ifdef BOX32 + if(box64_is32bits) + my32_setcontext(emu, emu->uc_link); + else + #endif + my_setcontext(emu, emu->uc_link); addr = R_RIP; goto x64emurun; } diff --git a/src/emu/x64run64.c b/src/emu/x64run64.c index fe8da3e5..7ceef8ab 100644 --- a/src/emu/x64run64.c +++ b/src/emu/x64run64.c @@ -639,7 +639,15 @@ uintptr_t Run64(x64emu_t *emu, rex_t rex, int seg, uintptr_t addr) R_RAX = *(uint32_t*)(tlsdata+tmp64u); } break; - + case 0xA2: /* MOV Ob,AL */ + if(rex.is32bits) { + tmp32s = F32S; + *(uint8_t*)(uintptr_t)(tlsdata+tmp32s) = R_AL; + } else { + tmp64u = F64; + *(uint8_t*)(tlsdata+tmp64u) = R_AL; + } + break; case 0xA3: /* MOV FS:Od,EAX */ if(rex.is32bits) { tmp32s = F32S; diff --git a/src/emu/x64run_private.c b/src/emu/x64run_private.c index f94025ee..6055101a 100644 --- a/src/emu/x64run_private.c +++ b/src/emu/x64run_private.c @@ -24,6 +24,9 @@ #endif #include "x64tls.h" #include "bridge.h" +#ifdef BOX32 +#include "box32.h" +#endif #define PARITY(x) (((emu->x64emu_parity_tab[(x) / 32] >> ((x) % 32)) & 1) == 0) #define XOR2(x) (((x) ^ ((x)>>1)) & 0x1) @@ -53,7 +56,7 @@ void EXPORT my___libc_init(x64emu_t* emu, void* raw_args , void (*onexit)(void) emu->quit = 1; // finished! } #else -int32_t EXPORT my___libc_start_main(x64emu_t* emu, int (*main) (int, char * *, char * *), int argc, char * * ubp_av, void (*init) (void), void (*fini) (void), void (*rtld_fini) (void), void (* stack_end)) +EXPORT int32_t my___libc_start_main(x64emu_t* emu, int (*main) (int, char * *, char * *), int argc, char * * ubp_av, void (*init) (void), void (*fini) (void), void (*rtld_fini) (void), void (* stack_end)) { (void)argc; (void)ubp_av; (void)fini; (void)rtld_fini; (void)stack_end; @@ -106,6 +109,54 @@ int32_t EXPORT my___libc_start_main(x64emu_t* emu, int (*main) (int, char * *, c } return (int)GetEAX(emu); } +#ifdef BOX32 +#ifdef ANDROID +void EXPORT my32___libc_init(x64emu_t* emu, void* raw_args , void (*onexit)(void) , int (*main)(int, char**, char**), void const * const structors ) +{ + //TODO: register fini + // let's cheat and set all args... + Push_32(emu, (uint32_t)my_context->envv32); + Push_32(emu, (uint32_t)my_context->argv32); + Push_32(emu, (uint32_t)my_context->argc); + + printf_log(LOG_DEBUG, "Transfert to main(%d, %p, %p)=>%p from __libc_init\n", my_context->argc, my_context->argv, my_context->envv, main); + // should call structors->preinit_array and structors->init_array! + // call main and finish + PushExit_32(emu); + R_EIP=to_ptrv(main); + + DynaRun(emu); + + emu->quit = 1; // finished! +} +#else +int32_t EXPORT my32___libc_start_main(x64emu_t* emu, int *(main) (int, char * *, char * *), int argc, char * * ubp_av, void (*init) (void), void (*fini) (void), void (*rtld_fini) (void), void (* stack_end)) +{ + // let's cheat and set all args... + Push_32(emu, my_context->envv32); + Push_32(emu, my_context->argv32); + Push_32(emu, my_context->argc); + if(init) { + PushExit_32(emu); + R_EIP=to_ptrv(*init); + printf_log(LOG_DEBUG, "Calling init(%p) from __libc_start_main\n", *init); + DynaRun(emu); + if(emu->error) // any error, don't bother with more + return 0; + emu->quit = 0; + } + printf_log(LOG_DEBUG, "Transfert to main(%d, %p, %p)=>%p from __libc_start_main\n", my_context->argc, my_context->argv, my_context->envv, main); + // call main and finish + PushExit_32(emu); + R_EIP=to_ptrv(main); + + DynaRun(emu); + + emu->quit = 1; // finished! + return 0; +} +#endif +#endif #endif const char* GetNativeName(void* p) diff --git a/src/emu/x64run_private.h b/src/emu/x64run_private.h index 45a68659..925e14d5 100644 --- a/src/emu/x64run_private.h +++ b/src/emu/x64run_private.h @@ -50,6 +50,12 @@ static inline void Push16(x64emu_t *emu, uint16_t v) *((uint16_t*)R_RSP) = v; } +static inline void Push_32(x64emu_t *emu, uint32_t v) +{ + R_ESP -= 4; + *((uint32_t*)(uintptr_t)R_ESP) = v; +} + static inline void Push32(x64emu_t *emu, uint32_t v) { R_RSP -= 4; @@ -70,6 +76,13 @@ static inline uint16_t Pop16(x64emu_t *emu) return *st; } +static inline uint32_t Pop_32(x64emu_t *emu) +{ + uint32_t* st = (uint32_t*)(uintptr_t)R_RSP; + R_ESP += 4; + return *st; +} + static inline uint32_t Pop32(x64emu_t *emu) { uint32_t* st = (uint32_t*)R_RSP; @@ -90,6 +103,13 @@ static inline void PushExit(x64emu_t* emu) *((uint64_t*)R_RSP) = my_context->exit_bridge; } +#ifdef BOX32 +static inline void PushExit_32(x64emu_t* emu) +{ + R_ESP -= 4; + *((ptr_t*)(uintptr_t)R_ESP) = my_context->exit_bridge; +} +#endif // the op code definition can be found here: http://ref.x86asm.net/geek32.html reg64_t* GetECommon(x64emu_t* emu, uintptr_t* addr, rex_t rex, uint8_t m, uint8_t delta); @@ -232,6 +252,7 @@ void x64Syscall(x64emu_t *emu); void x64Int3(x64emu_t* emu, uintptr_t* addr); x64emu_t* x64emu_fork(x64emu_t* e, int forktype); void x86Syscall(x64emu_t *emu); //32bits syscall +void x86Int3(x64emu_t* emu, uintptr_t* addr); uintptr_t GetSegmentBaseEmu(x64emu_t* emu, int seg); #define GetGSBaseEmu(emu) GetSegmentBaseEmu(emu, _GS) diff --git a/src/emu/x64tls.c b/src/emu/x64tls.c index 78f83c74..99ae188c 100644 --- a/src/emu/x64tls.c +++ b/src/emu/x64tls.c @@ -11,6 +11,9 @@ #include "x64emu_private.h" #include "x64tls.h" #include "elfloader.h" +#ifdef BOX32 +#include "box32.h" +#endif typedef struct thread_area_s { @@ -118,12 +121,19 @@ uint32_t my_modify_ldt(x64emu_t* emu, int op, thread_area_t* td, int size) return (uint32_t)-1; } - /* - my_context->segtls[idx].base = td->base_addr; - my_context->segtls[idx].limit = td->limit; - pthread_setspecific(my_context->segtls[idx].key, (void*)my_context->segtls[idx].base); - */ - + if(box64_is32bits) { + emu->segs_serial[_GS] = 0; + my_context->segtls[idx].base = td->base_addr; + my_context->segtls[idx].limit = td->limit; + my_context->segtls[idx].present = 1; + if(idx>8 && !my_context->segtls[idx].key_init) { + pthread_key_create(&my_context->segtls[idx].key, NULL); + my_context->segtls[idx].key_init = 1; + } + if(my_context->segtls[idx].key_init) + pthread_setspecific(my_context->segtls[idx].key, (void*)my_context->segtls[idx].base); + } + ResetSegmentsCache(emu); return 0; @@ -220,6 +230,7 @@ int my_arch_prctl(x64emu_t *emu, int code, void* addr) #define POS_TLS 0x200 +#define POS_TLS_32 0x50 /* tls record should looks like: void* tcb 0x00 @@ -255,7 +266,7 @@ static tlsdatasize_t* setupTLSData(box64context_t* context) // Setup the GS segment: int dtssize = sizeDTS(context); int datasize = sizeTLSData(context->tlssize); - void *ptr_oversized = (char*)box_malloc(dtssize+POS_TLS+datasize); + void *ptr_oversized = (char*)box_malloc(dtssize+(box64_is32bits?POS_TLS_32:POS_TLS)+datasize); void *ptr = (void*)((uintptr_t)ptr_oversized + datasize); memcpy((void*)((uintptr_t)ptr-context->tlssize), context->tlsdata, context->tlssize); tlsdatasize_t *data = (tlsdatasize_t*)box_calloc(1, sizeof(tlsdatasize_t)); @@ -264,23 +275,45 @@ static tlsdatasize_t* setupTLSData(box64context_t* context) data->ptr = ptr_oversized; data->n_elfs = context->elfsize; pthread_setspecific(context->tlskey, data); - // copy canary... - memset((void*)((uintptr_t)ptr), 0, POS_TLS+dtssize); // set to 0 remining bytes - memcpy((void*)((uintptr_t)ptr+0x28), context->canary, sizeof(void*)); // put canary in place - uintptr_t tlsptr = (uintptr_t)ptr; - memcpy((void*)((uintptr_t)ptr+0x0), &tlsptr, sizeof(void*)); - memcpy((void*)((uintptr_t)ptr+0x10), &tlsptr, sizeof(void*)); // set tcb and self same address - uintptr_t dtp = (uintptr_t)ptr+POS_TLS; - memcpy((void*)(tlsptr+sizeof(void*)), &dtp, sizeof(void*)); - if(dtssize) { - for (int i=0; i<context->elfsize; ++i) { - // set pointer - dtp = (uintptr_t)ptr + GetTLSBase(context->elfs[i]); - *(uint64_t*)((uintptr_t)ptr+POS_TLS+i*16) = dtp; - *(uint64_t*)((uintptr_t)ptr+POS_TLS+i*16+8) = i; // index + #ifdef BOX32 + if(box64_is32bits) { + // copy canary... + memset((void*)((uintptr_t)ptr), 0, POS_TLS_32+dtssize); // set to 0 remining bytes + memcpy((void*)((uintptr_t)ptr+0x14), context->canary, 4); // put canary in place + ptr_t tlsptr = to_ptrv(ptr); + memcpy((void*)((uintptr_t)ptr+0x0), &tlsptr, 4); + ptr_t dtp = to_ptrv(ptr+POS_TLS_32); + memcpy(from_ptrv(tlsptr+0x4), &dtp, 4); + if(dtssize) { + for (int i=0; i<context->elfsize; ++i) { + // set pointer + dtp = to_ptrv(ptr + GetTLSBase(context->elfs[i])); + memcpy((void*)((uintptr_t)ptr+POS_TLS_32+i*8), &dtp, 4); + memcpy((void*)((uintptr_t)ptr+POS_TLS_32+i*8+4), &i, 4); // index + } } + memcpy((void*)((uintptr_t)ptr+0x10), &context->vsyscall, 4); // address of vsyscall + } else + #endif + { + // copy canary... + memset((void*)((uintptr_t)ptr), 0, POS_TLS+dtssize); // set to 0 remining bytes + memcpy((void*)((uintptr_t)ptr+0x28), context->canary, sizeof(void*)); // put canary in place + uintptr_t tlsptr = (uintptr_t)ptr; + memcpy((void*)((uintptr_t)ptr+0x0), &tlsptr, sizeof(void*)); + memcpy((void*)((uintptr_t)ptr+0x10), &tlsptr, sizeof(void*)); // set tcb and self same address + uintptr_t dtp = (uintptr_t)ptr+POS_TLS; + memcpy((void*)(tlsptr+sizeof(void*)), &dtp, sizeof(void*)); + if(dtssize) { + for (int i=0; i<context->elfsize; ++i) { + // set pointer + dtp = (uintptr_t)ptr + GetTLSBase(context->elfs[i]); + *(uint64_t*)((uintptr_t)ptr+POS_TLS+i*16) = dtp; + *(uint64_t*)((uintptr_t)ptr+POS_TLS+i*16+8) = i; // index + } + } + memcpy((void*)((uintptr_t)ptr+0x20), &context->vsyscall, sizeof(void*)); // address of vsyscall } - memcpy((void*)((uintptr_t)ptr+0x20), &context->vsyscall, sizeof(void*)); // address of vsyscall return data; } @@ -356,7 +389,9 @@ void* GetSegmentBase(uint32_t desc) return NULL; } int base = desc>>3; - if(base==0x8 && !my_context->segtls[base].key_init) + if(!box64_is32bits && base==0x8 && !my_context->segtls[base].key_init) + return GetSeg43Base(); + if(box64_is32bits && (base==0x6)) return GetSeg43Base(); if(base>15) { printf_log(LOG_NONE, "Warning, accessing segment unknown 0x%x or unset\n", desc); diff --git a/src/emu/x86int3.c b/src/emu/x86int3.c new file mode 100755 index 00000000..73f5b3ae --- /dev/null +++ b/src/emu/x86int3.c @@ -0,0 +1,347 @@ +#define _GNU_SOURCE /* See feature_test_macros(7) */ +#include <dlfcn.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <unistd.h> +#include <sys/syscall.h> +#include <sys/types.h> +#include <pthread.h> +#include <signal.h> + +#include "debug.h" +#include "box64stack.h" +#include "x64emu.h" +#include "x64run.h" +#include "x64emu_private.h" +#include "x64run_private.h" +#include "x87emu_private.h" +#include "x64primop.h" +#include "x64trace.h" +#include "wrapper32.h" +#include "box32context.h" +#include "librarian.h" +#include "signals.h" +#include "tools/bridge_private.h" + +#include <elf.h> +#include "elfloader.h" +#include "elfload_dump.h" +#include "elfs/elfloader_private.h" + +typedef int32_t (*iFpppp_t)(void*, void*, void*, void*); + +static uint64_t F64(uintptr_t* addr) { + uint64_t ret = *(uint64_t*)*addr; + *addr+=8; + return ret; +} +static uint8_t Peek8(uintptr_t addr, uintptr_t offset) +{ + return *(uint8_t*)(addr+offset); +} + +extern int errno; +void x86Int3(x64emu_t* emu, uintptr_t* addr) +{ + onebridge_t* bridge = (onebridge_t*)(*addr-1); + if(Peek8(*addr, 0)=='S' && Peek8(*addr, 1)=='C') // Signature for "Out of x86 door" + { + *addr += 2; + uintptr_t a = F64(addr); + if(a==0) { + R_RIP = *addr; + //printf_log(LOG_INFO, "%p:Exit x86 emu (emu=%p)\n", *(void**)(R_ESP), emu); + emu->quit=1; // normal quit + } else { + RESET_FLAGS(emu); + wrapper_t w = bridge->w; + a = F64(addr); + R_RIP = *addr; + /* This party can be used to trace only 1 specific lib (but it is quite slow) + elfheader_t *h = FindElfAddress(my_context, *(uintptr_t*)(R_ESP)); + int have_trace = 0; + if(h && strstr(ElfName(h), "libMiles")) have_trace = 1;*/ + if(box64_log>=LOG_DEBUG || cycle_log) { + int tid = GetTID(); + char t_buff[256] = "\0"; + char buff2[64] = "\0"; + char buff3[64] = "\0"; + int cycle_line = my_context->current_line; + if(cycle_log) { + my_context->current_line = (my_context->current_line+1)%cycle_log; + } + char* buff = cycle_log?my_context->log_call[cycle_line]:t_buff; + char* buffret = cycle_log?my_context->log_ret[cycle_line]:NULL; + if(buffret) buffret[0] = '\0'; + char *tmp; + int post = 0; + int perr = 0; + uint64_t *pu64 = NULL; + uint32_t *pu32 = NULL; + uint8_t *pu8 = NULL; + const char *s = bridge->name; + if(!s) + s = GetNativeName((void*)a); + if(a==(uintptr_t)PltResolver32) { + if(cycle_log) { + ptr_t addr = *((uint32_t*)from_ptrv(R_ESP)); + int slot = *((uint32_t*)from_ptrv(R_ESP+4)); + elfheader_t *h = (elfheader_t*)from_ptrv(addr); + Elf32_Rel * rel = (Elf32_Rel *)from_ptrv(h->jmprel + h->delta + slot); + Elf32_Sym *sym = &h->DynSym._32[ELF32_R_SYM(rel->r_info)]; + const char* symname = SymName32(h, sym); + snprintf(buff, 256, "%04d|PltResolver \"%s\"", tid, symname?symname:"???"); + } else { + snprintf(buff, 256, "%s", " ... "); + } + } else + if(strstr(s, "SDL_RWFromFile")==s || strstr(s, "SDL_RWFromFile")==s) { + snprintf(buff, 255, "%04d|%p: Calling %s(%s, %s)", tid, *(void**)from_ptr(R_ESP), s, from_ptrv(*(ptr_t*)from_ptr(R_ESP+4)), from_ptrv(*(ptr_t*)from_ptr(R_ESP+8))); + } else if(strstr(s, "glColor4f")==s) { + snprintf(buff, 255, "%04d|%p: Calling %s(%f, %f, %f, %f)", tid, *(void**)from_ptr(R_ESP), s, *(float*)from_ptr(R_ESP+4), *(float*)from_ptr(R_ESP+8), *(float*)from_ptr(R_ESP+12), *(float*)from_ptr(R_ESP+16)); + } else if(strstr(s, "glTexCoord2f")==s) { + snprintf(buff, 255, "%04d|%p: Calling %s(%f, %f)", tid, *(void**)from_ptr(R_ESP), s, *(float*)from_ptr(R_ESP+4), *(float*)from_ptr(R_ESP+8)); + } else if(strstr(s, "glVertex2f")==s) { + snprintf(buff, 255, "%04d|%p: Calling %s(%f, %f)", tid, *(void**)from_ptr(R_ESP), s, *(float*)from_ptr(R_ESP+4), *(float*)from_ptr(R_ESP+8)); + } else if(strstr(s, "glVertex3f")==s) { + snprintf(buff, 255, "%04d|%p: Calling %s(%f, %f, %f)", tid, *(void**)from_ptr(R_ESP), s, *(float*)from_ptr(R_ESP+4), *(float*)from_ptr(R_ESP+8), *(float*)from_ptr(R_ESP+12)); + } else if(strstr(s, "__open64")==s || strcmp(s, "open64")==0) { + snprintf(buff, 255, "%04d|%p: Calling %s(\"%s\", %d, %d)", tid, *(void**)from_ptr(R_ESP), s, from_ptrv(*(ptr_t*)from_ptr(R_ESP+4)), *(int*)from_ptr(R_ESP+8), *(int*)from_ptr(R_ESP+12)); + perr = 1; + } else if(!strcmp(s, "opendir")) { + snprintf(buff, 255, "%04d|%p: Calling %s(\"%s\")", tid, *(void**)from_ptr(R_ESP), s, from_ptrv(*(ptr_t*)from_ptr(R_ESP+4))); + perr = 1; + } else if(strstr(s, "__open")==s || !strcmp(s, "open") || !strcmp(s, "my_open64")) { + tmp = from_ptrv(*(ptr_t*)from_ptr(R_ESP+4)); + snprintf(buff, 255, "%04d|%p: Calling %s(\"%s\", %d (,%d))", tid, *(void**)from_ptr(R_ESP), s, (tmp)?tmp:"(nil)", *(int*)from_ptr(R_ESP+8), *(int*)from_ptr(R_ESP+12)); + perr = 1; + } else if(!strcmp(s, "shm_open")) { + tmp = from_ptrv(*(ptr_t*)from_ptr(R_ESP+4)); + snprintf(buff, 255, "%04d|%p: Calling %s(\"%s\", %d, %d)", tid, *(void**)from_ptr(R_ESP), s, (tmp)?tmp:"(nil)", *(int*)from_ptr(R_ESP+8), *(int*)from_ptr(R_ESP+12)); + perr = 1; + } else if(strcmp(s, "mkdir")==0) { + tmp = from_ptrv(*(ptr_t*)from_ptr(R_ESP+4)); + snprintf(buff, 255, "%04d|%p: Calling %s(\"%s\", %d)", tid, *(void**)from_ptr(R_ESP), s, (tmp)?tmp:"(nil)", *(int*)from_ptr(R_ESP+8)); + perr = 1; + } else if(!strcmp(s, "fopen")) { + snprintf(buff, 255, "%04d|%p: Calling %s(\"%s\", \"%s\")", tid, *(void**)from_ptr(R_ESP), s, from_ptrv(*(ptr_t*)from_ptr(R_ESP+4)), from_ptrv(*(ptr_t*)from_ptr(R_ESP+8))); + perr = 2; + } else if(!strcmp(s, "freopen")) { + snprintf(buff, 255, "%04d|%p: Calling %s(\"%s\", \"%s\", %p)", tid, *(void**)from_ptr(R_ESP), s, from_ptrv(*(ptr_t*)from_ptr(R_ESP+4)), from_ptrv(*(ptr_t*)from_ptr(R_ESP+8)), *(void**)from_ptr(R_ESP+12)); + perr = 2; + } else if(!strcmp(s, "fopen64")) { + snprintf(buff, 255, "%04d|%p: Calling %s(\"%s\", \"%s\")", tid, *(void**)from_ptr(R_ESP), s, from_ptrv(*(ptr_t*)from_ptr(R_ESP+4)), from_ptrv(*(ptr_t*)from_ptr(R_ESP+8))); + perr = 2; + } else if(!strcmp(s, "chdir")) { + pu32=*(uint32_t**)from_ptr(R_ESP+4); + snprintf(buff, 255, "%04d|%p: Calling %s(\"%s\")", tid, *(void**)from_ptr(R_ESP), s, pu32?((pu32==(uint32_t*)1)?"/1/":(char*)pu32):"/0/"); + } else if(strstr(s, "getenv")==s) { + snprintf(buff, 255, "%04d|%p: Calling %s(\"%s\")", tid, *(void**)from_ptr(R_ESP), s, from_ptrv(*(ptr_t*)from_ptr(R_ESP+4))); + post = 2; + } else if(strstr(s, "putenv")==s) { + snprintf(buff, 255, "%04d|%p: Calling %s(\"%s\")", tid, *(void**)from_ptr(R_ESP), s, from_ptrv(*(ptr_t*)from_ptr(R_ESP+4))); + } else if(strstr(s, "pread")==s) { + snprintf(buff, 255, "%04d|%p: Calling %s(%d, %p, %u, %d)", tid, *(void**)from_ptr(R_ESP), s, *(int32_t*)from_ptr(R_ESP+4), *(void**)from_ptr(R_ESP+8), *(uint32_t*)from_ptr(R_ESP+12), *(int32_t*)from_ptr(R_ESP+16)); + perr = 1; + } else if(!strcmp(s, "read")) { + snprintf(buff, 255, "%04d|%p: Calling %s(%d, %p, %u)", tid, *(void**)from_ptr(R_ESP), s, *(int32_t*)from_ptr(R_ESP+4), *(void**)from_ptr(R_ESP+8), *(uint32_t*)from_ptr(R_ESP+12)); + perr = 1; + } else if(strstr(s, "ioctl")==s) { + snprintf(buff, 255, "%04d|%p: Calling %s(%d, 0x%x, %p)", tid, *(void**)from_ptr(R_ESP), s, *(int32_t*)from_ptr(R_ESP+4), *(int32_t*)from_ptr(R_ESP+8), *(void**)from_ptr(R_ESP+12)); + perr = 1; + } else if(strstr(s, "statvfs64")==s) { + snprintf(buff, 255, "%04d|%p: Calling %s(%p(\"%s\"), %p)", tid, *(void**)from_ptr(R_ESP), s, *(void**)from_ptr(R_ESP+4), from_ptrv(*(ptr_t*)from_ptr(R_ESP+4)), *(void**)from_ptr(R_ESP+8)); + } else if(strstr(s, "index")==s) { + snprintf(buff, 255, "%04d|%p: Calling %s(%p(\"%s\"), %i(%c))", tid, *(void**)from_ptr(R_ESP), s, from_ptrv(*(ptr_t*)from_ptr(R_ESP+4)), from_ptrv(*(ptr_t*)from_ptr(R_ESP+4)), *(int32_t*)from_ptr(R_ESP+8), *(int32_t*)from_ptr(R_ESP+8)); + } else if(strstr(s, "rindex")==s) { + snprintf(buff, 255, "%04d|%p: Calling %s(%p(\"%s\"), %i(%c))", tid, *(void**)from_ptr(R_ESP), s, from_ptrv(*(ptr_t*)from_ptr(R_ESP+4)), from_ptrv(*(ptr_t*)from_ptr(R_ESP+4)), *(int32_t*)from_ptr(R_ESP+8), *(int32_t*)from_ptr(R_ESP+8)); + } else if(strstr(s, "__xstat64")==s) { + snprintf(buff, 255, "%04d|%p: Calling %s(%d, %p(\"%s\"), %p)", tid, *(void**)from_ptr(R_ESP), s, *(int32_t*)from_ptr(R_ESP+4), from_ptrv(*(ptr_t*)from_ptr(R_ESP+8)), from_ptrv(*(ptr_t*)from_ptr(R_ESP+8)), *(void**)from_ptr(R_ESP+12)); + perr = 1; + } else if(strcmp(s, "__xstat")==0) { + snprintf(buff, 255, "%04d|%p: Calling %s(%d, %p(\"%s\"), %p)", tid, *(void**)from_ptr(R_ESP), s, *(int32_t*)from_ptr(R_ESP+4), from_ptrv(*(ptr_t*)from_ptr(R_ESP+8)), from_ptrv(*(ptr_t*)from_ptr(R_ESP+8)), *(void**)from_ptr(R_ESP+12)); + perr = 1; + } else if(strstr(s, "__lxstat64")==s) { + snprintf(buff, 255, "%04d|%p: Calling %s(%d, %p(\"%s\"), %p)", tid, *(void**)from_ptr(R_ESP), s, *(int32_t*)from_ptr(R_ESP+4), from_ptrv(*(ptr_t*)from_ptr(R_ESP+8)), from_ptrv(*(ptr_t*)from_ptr(R_ESP+8)), *(void**)from_ptr(R_ESP+12)); + perr = 1; + } else if(strstr(s, "sem_timedwait")==s) { + pu32 = (uint32_t*)from_ptr(*(ptr_t*)from_ptr(R_ESP+8)); + snprintf(buff, 255, "%04d|%p: Calling %s(%p, %p[%d sec %d ns])", tid, *(void**)from_ptr(R_ESP), s, *(void**)from_ptr(R_ESP+4), *(void**)from_ptr(R_ESP+8), pu32?pu32[0]:-1, pu32?pu32[1]:-1); + perr = 1; + } else if(strstr(s, "waitpid")==s) { + snprintf(buff, 255, "%04d|%p: Calling %s(%d, %p, 0x%x)", tid, *(void**)from_ptr(R_ESP), s, *(int32_t*)from_ptr(R_ESP+4), *(void**)from_ptr(R_ESP+8), *(uint32_t*)from_ptr(R_ESP+12)); + perr = 1; + } else if(strstr(s, "clock_gettime")==s || strstr(s, "__clock_gettime")==s) { + snprintf(buff, 255, "%04d|%p: Calling %s(%d, %p)", tid, *(void**)from_ptr(R_ESP), s, *(uint32_t*)from_ptr(R_ESP+4), *(void**)from_ptr(R_ESP+8)); + post = 1; + pu32 = (uint32_t*)from_ptr(*(ptr_t*)from_ptr(R_ESP+8)); + } else if(strstr(s, "semop")==s) { + int16_t* p16 = *(int16_t**)from_ptr(R_ESP+8); + snprintf(buff, 255, "%04d|%p: Calling %s(%d, %p[%u/%d/0x%x], %d)", tid, *(void**)from_ptr(R_ESP), s, *(int*)from_ptr(R_ESP+4), p16, p16[0], p16[1], p16[2], *(int*)from_ptr(R_ESP+12)); + perr = 1; + } else if(!strcmp(s, "mmap64")) { + snprintf(buff, 255, "%04d|%p: Calling %s(%p, 0x%x, %d, 0x%x, %d, %ld)", tid, *(void**)from_ptr(R_ESP), s, *(void**)from_ptr(R_ESP+4), *(ulong_t*)from_ptr(R_ESP+8), *(int*)from_ptr(R_ESP+12), *(int*)from_ptr(R_ESP+16), *(int*)from_ptr(R_ESP+20), *(int64_t*)from_ptr(R_ESP+24)); + perr = 3; + } else if(!strcmp(s, "mmap")) { + snprintf(buff, 255, "%04d|%p: Calling %s(%p, 0x%x, %d, 0x%x, %d, %d)", tid, *(void**)from_ptr(R_ESP), s, *(void**)from_ptr(R_ESP+4), *(ulong_t*)from_ptr(R_ESP+8), *(int*)from_ptr(R_ESP+12), *(int*)from_ptr(R_ESP+16), *(int*)from_ptr(R_ESP+20), *(int*)from_ptr(R_ESP+24)); + perr = 3; + } else if(strstr(s, "strcasecmp")==s || strstr(s, "__strcasecmp")==s) { + snprintf(buff, 255, "%04d|%p: Calling %s(\"%s\", \"%s\")", tid, *(void**)from_ptr(R_ESP), s, from_ptrv(*(ptr_t*)from_ptr(R_ESP+4)), from_ptrv(*(ptr_t*)from_ptr(R_ESP+8))); + } else if(strstr(s, "gtk_signal_connect_full")) { + snprintf(buff, 255, "%04d|%p: Calling %s(%p, \"%s\", %p, %p, %p, %p, %d, %d)", tid, *(void**)from_ptr(R_ESP), "gtk_signal_connect_full", *(void**)from_ptr(R_ESP+4), from_ptrv(*(ptr_t*)from_ptr(R_ESP+8)), *(void**)from_ptr(R_ESP+12), *(void**)from_ptr(R_ESP+16), *(void**)from_ptr(R_ESP+20), *(void**)from_ptr(R_ESP+24), *(int32_t*)from_ptr(R_ESP+28), *(int32_t*)from_ptr(R_ESP+32)); + } else if(strstr(s, "strcmp")==s || strstr(s, "__strcmp")==s) { + snprintf(buff, 255, "%04d|%p: Calling %s(\"%s\", \"%s\")", tid, *(void**)from_ptr(R_ESP), s, from_ptrv(*(ptr_t*)from_ptr(R_ESP+4)), from_ptrv(*(ptr_t*)from_ptr(R_ESP+8))); + } else if(strstr(s, "strstr")==s) { + snprintf(buff, 255, "%04d|%p: Calling %s(\"%.127s\", \"%.127s\")", tid, *(void**)from_ptr(R_ESP), s, from_ptrv(*(ptr_t*)from_ptr(R_ESP+4)), from_ptrv(*(ptr_t*)from_ptr(R_ESP+8))); + } else if(strstr(s, "strlen")==s) { + snprintf(buff, 255, "%04d|%p: Calling %s(%p(\"%s\"))", tid, *(void**)from_ptr(R_ESP), s, from_ptrv(*(ptr_t*)from_ptr(R_ESP+4)), ((R_ESP+4))?((char*)from_ptrv(*(ptr_t*)from_ptr(R_ESP+4))):"nil"); + } else if(strstr(s, "vsnprintf")==s) { + snprintf(buff, 255, "%04d|%p: Calling %s(%08X, %u, %08X...)", tid, *(void**)from_ptr(R_ESP), s, *(uint32_t*)from_ptr(R_ESP+4), *(uint32_t*)from_ptr(R_ESP+8), *(uint32_t*)from_ptr(R_ESP+12)); + pu32 = (uint32_t*)from_ptr(*(ptr_t*)from_ptr(R_ESP+4)); + post = 3; + } else if(strstr(s, "vsprintf")==s) { + snprintf(buff, 255, "%04d|%p: Calling %s(%p, \"%s\", %p)", tid, *(void**)from_ptr(R_ESP), s, *(void**)from_ptr(R_ESP+4), from_ptrv(*(ptr_t*)from_ptr(R_ESP+8)), *(void**)from_ptr(R_ESP+12)); + pu32 = (uint32_t*)from_ptr(*(ptr_t*)from_ptr(R_ESP+4)); + post = 3; + } else if(strstr(s, "__vsprintf_chk")==s) { + snprintf(buff, 255, "%04d|%p: Calling %s(%p, %d, %zu, \"%s\", %p)", tid, *(void**)from_ptr(R_ESP), s, *(void**)from_ptr(R_ESP+4), *(int*)from_ptr(R_ESP+8), *(size_t*)from_ptr(R_ESP+12), from_ptrv(*(ptr_t*)from_ptr(R_ESP+16)), *(void**)from_ptr(R_ESP+20)); + pu32 = (uint32_t*)from_ptr(*(ptr_t*)from_ptr(R_ESP+4)); + post = 3; + } else if(strstr(s, "__snprintf_chk")==s) { + snprintf(buff, 255, "%04d|%p: Calling %s(%p, %zu, %d, %d, \"%s\", %p)", tid, *(void**)from_ptr(R_ESP), s, *(void**)from_ptr(R_ESP+4), *(size_t*)from_ptr(R_ESP+8), *(int*)from_ptr(R_ESP+12), *(int*)from_ptr(R_ESP+16), from_ptrv(*(ptr_t*)from_ptr(R_ESP+20)), *(void**)from_ptr(R_ESP+24)); + pu32 = (uint32_t*)from_ptr(*(ptr_t*)from_ptr(R_ESP+4)); + post = 3; + } else if(strstr(s, "snprintf")==s) { + snprintf(buff, 255, "%04d|%p: Calling %s(%p, %zu, \"%s\", ...)", tid, *(void**)from_ptr(R_ESP), s, *(void**)from_ptr(R_ESP+4), *(size_t*)from_ptr(R_ESP+8), from_ptrv(*(ptr_t*)from_ptr(R_ESP+12))); + pu32 = (uint32_t*)from_ptr(*(ptr_t*)from_ptr(R_ESP+4)); + post = 3; + } else if(strstr(s, "sprintf")==s) { + snprintf(buff, 255, "%04d|%p: Calling %s(%08X, %08X...)", tid, *(void**)from_ptr(R_ESP), s, *(uint32_t*)from_ptr(R_ESP+4), *(uint32_t*)from_ptr(R_ESP+8)); + pu32 = (uint32_t*)from_ptr(*(ptr_t*)from_ptr(R_ESP+4)); + post = 3; + } else if(strstr(s, "printf")==s) { + pu32 = (uint32_t*)from_ptr(*(ptr_t*)from_ptr(R_ESP+4)); + if(((uintptr_t)pu32)<0x5) // probably a _chk function + pu32 = (uint32_t*)from_ptr(*(ptr_t*)from_ptr(R_ESP+8)); + snprintf(buff, 255, "%04d|%p: Calling %s(\"%s\"...)", tid, *(void**)from_ptr(R_ESP), s, pu32?((char*)(pu32)):"nil"); + } else if(strstr(s, "__printf_chk")==s) { + pu32 = (uint32_t*)from_ptr(*(ptr_t*)from_ptr(R_ESP+8)); + snprintf(buff, 255, "%04d|%p: Calling %s(%d, \"%s\", ...)", tid, *(void**)from_ptr(R_ESP), s, from_ptri(int, R_ESP+4), pu32?((char*)(pu32)):"nil"); + } else if(strstr(s, "wprintf")==s) { + pu32 = (uint32_t*)from_ptr(*(ptr_t*)from_ptr(R_ESP+4)); + if(((uintptr_t)pu32)<0x5) // probably a _chk function + pu32 = (uint32_t*)from_ptr(*(ptr_t*)from_ptr(R_ESP+8)); + snprintf(buff, 255, "%04d|%p: Calling %s(\"%S\"...)", tid, *(void**)from_ptr(R_ESP), s, pu32?((wchar_t*)(pu32)):L"nil"); + } else if(strstr(s, "__vswprintf")==s) { + if(*(size_t*)from_ptr(R_ESP+12)<2) { + snprintf(buff, 255, "%04d|%p: Calling %s(%p, %u, %p, %p, %p)", tid, *(void**)from_ptr(R_ESP), s, *(void**)from_ptr(R_ESP+4), *(ulong_t*)from_ptr(R_ESP+8), *(void**)from_ptr(R_ESP+12), *(void**)from_ptr(R_ESP+16), *(void**)from_ptr(R_ESP+20)); + } else { + snprintf(buff, 255, "%04d|%p: Calling %s(%p, %u, \"%S\", %p)", tid, *(void**)from_ptr(R_ESP), s, *(void**)from_ptr(R_ESP+4), *(ulong_t*)from_ptr(R_ESP+8), *(wchar_t**)from_ptr(R_ESP+12), *(void**)from_ptr(R_ESP+16)); + pu32 = (uint32_t*)from_ptr(*(ptr_t*)from_ptr(R_ESP+4)); + post = 6; + } + } else if(strstr(s, "puts")==s) { + snprintf(buff, 255, "%04d|%p: Calling %s(\"%s\"...)", tid, *(void**)from_ptr(R_ESP), s, from_ptrv(*(ptr_t*)from_ptr(R_ESP+4))); + } else if(strstr(s, "fputs")==s) { + snprintf(buff, 255, "%04d|%p: Calling %s(\"%s\", %p...)", tid, *(void**)from_ptr(R_ESP), s, from_ptrv(*(ptr_t*)from_ptr(R_ESP+4)), *(void**)from_ptr(R_ESP+8)); + } else if(strstr(s, "fprintf")==s) { + pu32 = (uint32_t*)from_ptr(*(ptr_t*)from_ptr(R_ESP+8)); + if(((uintptr_t)pu32)<0x5) // probably a __fprint_chk + pu32 = (uint32_t*)from_ptr(*(ptr_t*)from_ptr(R_ESP+12)); + snprintf(buff, 255, "%04d|%p: Calling %s(%08X, \"%s\", ...)", tid, *(void**)from_ptr(R_ESP), s, *(uint32_t*)from_ptr(R_ESP+4), pu32?((char*)(pu32)):"nil"); + } else if(strstr(s, "vfprintf")==s) { + pu32 = (uint32_t*)from_ptr(*(ptr_t*)from_ptr(R_ESP+8)); + if(((uintptr_t)pu32)<0x5) // probably a _chk function + pu32 = (uint32_t*)from_ptr(*(ptr_t*)from_ptr(R_ESP+12)); + snprintf(buff, 255, "%04d|%p: Calling %s(%08X, \"%s\", ...)", tid, *(void**)from_ptr(R_ESP), s, *(uint32_t*)from_ptr(R_ESP+4), pu32?((char*)(pu32)):"nil"); + } else if(strstr(s, "vkGetInstanceProcAddr")==s) { + snprintf(buff, 255, "%04d|%p: Calling %s(%p, \"%s\")", tid, *(void**)from_ptr(R_ESP), s, *(void**)from_ptr(R_ESP+4), from_ptrv(*(ptr_t*)from_ptr(R_ESP+8))); + } else if(strstr(s, "vkGetDeviceProcAddr")==s) { + snprintf(buff, 255, "%04d|%p: Calling %s(%p, \"%s\")", tid, *(void**)from_ptr(R_ESP), s, *(void**)from_ptr(R_ESP+4), from_ptrv(*(ptr_t*)from_ptr(R_ESP+8))); + } else if(strstr(s, "glXGetProcAddress")==s) { + snprintf(buff, 255, "%04d|%p: Calling %s(\"%s\")", tid, *(void**)from_ptr(R_ESP), s, from_ptrv(*(ptr_t*)from_ptr(R_ESP+4))); + } else if(strstr(s, "sscanf")==s) { + snprintf(buff, 255, "%04d|%p: Calling %s(\"%s\", \"%s\", ...)", tid, *(void**)from_ptr(R_ESP), s, from_ptrv(*(ptr_t*)from_ptr(R_ESP+4)), from_ptrv(*(ptr_t*)from_ptr(R_ESP+8))); + } else if(!strcmp(s, "vsscanf")) { + snprintf(buff, 255, "%04d|%p: Calling %s(\"%s\", \"%s\", ...)", tid, *(void**)from_ptr(R_ESP), s, from_ptrv(*(ptr_t*)from_ptr(R_ESP+4)), from_ptrv(*(ptr_t*)from_ptr(R_ESP+8))); + } else if(strstr(s, "XCreateWindow")==s) { + snprintf(buff, 255, "%04d|%p: Calling %s(%p, %p, %d, %d, %u, %u, %u, %d, %u, %p, %u, %p)", tid, *(void**)from_ptr(R_ESP), s, *(void**)from_ptr(R_ESP+4), *(void**)from_ptr(R_ESP+8), *(int*)from_ptr(R_ESP+12), *(int*)from_ptr(R_ESP+16), *(uint32_t*)from_ptr(R_ESP+20), *(uint32_t*)from_ptr(R_ESP+24), *(uint32_t*)from_ptr(R_ESP+28), *(int32_t*)from_ptr(R_ESP+32), *(uint32_t*)from_ptr(R_ESP+36), *(void**)from_ptr(R_ESP+40), *(uint32_t*)from_ptr(R_ESP+44), *(void**)from_ptr(R_ESP+48)); + } else if(strstr(s, "XLoadQueryFont")==s) { + snprintf(buff, 255, "%04d|%p: Calling %s(%p, \"%s\")", tid, *(void**)from_ptr(R_ESP), s, *(void**)from_ptr(R_ESP+4), from_ptrv(*(ptr_t*)from_ptr(R_ESP+8))); + } else if(strstr(s, "pthread_mutex_lock")==s) { + snprintf(buff, 255, "%04d|%p: Calling %s(%p)", tid, *(void**)from_ptr(R_ESP), s, *(void**)from_ptr(R_ESP+4)); + } else if(!strcmp(s, "fmodf")) { + post = 4; + snprintf(buff, 255, "%04d|%p: Calling %s(%f, %f)", tid, *(void**)from_ptr(R_ESP), s, *(float*)from_ptr(R_ESP+4), *(float*)from_ptr(R_ESP+8)); + } else if(!strcmp(s, "fmod")) { + post = 4; + snprintf(buff, 255, "%04d|%p: Calling %s(%f, %f)", tid, *(void**)from_ptr(R_ESP), s, *(double*)from_ptr(R_ESP+4), *(double*)from_ptr(R_ESP+12)); + } else if(strstr(s, "SDL_GetWindowSurface")==s) { + post = 5; + snprintf(buff, 255, "%04d|%p: Calling %s(%p)", tid, *(void**)from_ptr(R_ESP), s, *(void**)from_ptr(R_ESP+4)); + } else if(strstr(s, "udev_monitor_new_from_netlink")==s) { + post = 5; + snprintf(buff, 255, "%04d|%p: Calling %s(%p, \"%s\")", tid, *(void**)from_ptr(R_ESP), s, *(void**)from_ptr(R_ESP+4), from_ptrv(*(ptr_t*)from_ptr(R_ESP+8))); + } else if(!strcmp(s, "syscall")) { + snprintf(buff, 255, "%04d|%p: Calling %s(%d, %p, %p, %p...)", tid, *(void**)from_ptr(R_ESP), s, *(int32_t*)from_ptr(R_ESP+4), *(void**)from_ptr(R_ESP+8), *(void**)from_ptr(R_ESP+12), *(void**)from_ptr(R_ESP+16)); + perr = 1; + } else { + snprintf(buff, 255, "%04d|%p: Calling %s (%08X, %08X, %08X...)", tid, *(void**)from_ptr(R_ESP), s, *(uint32_t*)from_ptr(R_ESP+4), *(uint32_t*)from_ptr(R_ESP+8), *(uint32_t*)from_ptr(R_ESP+12)); + } + if(!cycle_log) { + mutex_lock(&emu->context->mutex_trace); + printf_log(LOG_NONE, "%s =>", buff); + mutex_unlock(&emu->context->mutex_trace); + } + w(emu, a); // some function never come back, so unlock the mutex first! + if(post) + switch(post) { + case 1: snprintf(buff2, 63, " [%d sec %d nsec]", pu32?pu32[0]:-1, pu32?pu32[1]:-1); + break; + case 2: snprintf(buff2, 63, "(%s)", R_EAX?((char*)from_ptr(R_EAX)):"nil"); + break; + case 3: snprintf(buff2, 63, "(%s)", pu32?((char*)pu32):"nil"); + break; + case 4: snprintf(buff2, 63, " (%f)", ST0.d); + break; + case 5: { + uint32_t* p = (uint32_t*)from_ptrv(R_EAX); + if(p) + snprintf(buff2, 63, " size=%dx%d, pitch=%d, pixels=%p", p[2], p[3], p[4], p+5); + else + snprintf(buff2, 63, "NULL Surface"); + } + break; + case 6: snprintf(buff2, 63, "(%S)", pu32?((wchar_t*)pu32):L"nil"); + break; + } + if(perr==1 && ((int)R_EAX)<0) + snprintf(buff3, 63, " (errno=%d:\"%s\")", errno, strerror(errno)); + else if(perr==2 && R_EAX==0) + snprintf(buff3, 63, " (errno=%d:\"%s\")", errno, strerror(errno)); + else if(perr==3 && ((int)R_EAX)==-1) + snprintf(buff3, 63, " (errno=%d:\"%s\")", errno, strerror(errno)); + if(cycle_log) + snprintf(buffret, 128, "0x%lX%s%s", R_RAX, buff2, buff3); + else { + mutex_lock(&emu->context->mutex_trace); + printf_log(LOG_NONE, " return 0x%lX%s%s\n", R_RAX, buff2, buff3); + mutex_unlock(&emu->context->mutex_trace); + } + } else + w(emu, a); + } + return; + } + if(!box64_ignoreint3 && my_context->signals[SIGTRAP]) { + R_RIP = *addr; // update RIP + emit_signal(emu, SIGTRAP, NULL, 3); + } else { + printf_log(LOG_DEBUG, "%04d|Warning, ignoring unsupported Int 3 call @%p\n", GetTID(), (void*)R_RIP); + R_RIP = *addr; + } + //emu->quit = 1; +} diff --git a/src/emu/x86syscall.c b/src/emu/x86syscall.c index 1d28a989..5a76a505 100755 --- a/src/emu/x86syscall.c +++ b/src/emu/x86syscall.c @@ -266,7 +266,7 @@ void EXPORT x86Syscall(x64emu_t *emu) R_EAX = R_EBX; // faking the syscall here, we don't want to really terminate the thread now break; /*case 123: // SYS_modify_ldt - R_EAX = my_modify_ldt(emu, R_EBX, (thread_area_t*)(uintptr_t)R_ECX, R_EDX); + R_EAX = my32_modify_ldt(emu, R_EBX, (thread_area_t*)(uintptr_t)R_ECX, R_EDX); if(R_EAX==0xffffffff && errno>0) R_EAX = (uint32_t)-errno; break;*/ diff --git a/src/emu/x86syscall_32.c b/src/emu/x86syscall_32.c new file mode 100644 index 00000000..cae7b40b --- /dev/null +++ b/src/emu/x86syscall_32.c @@ -0,0 +1,447 @@ +#define _GNU_SOURCE /* See feature_test_macros(7) */ +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <sys/syscall.h> /* For SYS_xxx definitions */ +#include <unistd.h> +#include <time.h> +#include <sys/mman.h> +#include <sys/select.h> +#include <sys/types.h> +#include <sys/ioctl.h> +#include <asm/stat.h> +#include <errno.h> +#include <sched.h> +#include <sys/wait.h> +#include <sys/utsname.h> +#ifndef __NR_socketcall +#include <linux/net.h> +#include <sys/socket.h> +#endif +#include <sys/resource.h> +#include <poll.h> + +#include "debug.h" +#include "box64stack.h" +#include "x64emu.h" +#include "x64run.h" +#include "x64emu_private.h" +#include "x64trace.h" +#include "myalign32.h" +#include "box64context.h" +#include "callback.h" +#include "signals.h" +#include "x64tls.h" +#include "box32.h" + + +// Syscall table for x86_64 can be found +typedef struct scwrap_s { + uint32_t x86s; + int nats; + int nbpars; +} scwrap_t; + +static const scwrap_t syscallwrap[] = { + //{ 2, __NR_fork, 1 }, + //{ 3, __NR_read, 3 }, // wrapped so SA_RESTART can be handled by libc + //{ 4, __NR_write, 3 }, // same + //{ 5, __NR_open, 3 }, // flags need transformation + //{ 6, __NR_close, 1 }, // wrapped so SA_RESTART can be handled by libc + //{ 7, __NR_waitpid, 3 }, + //{ 10, __NR_unlink, 1 }, + //{ 12, __NR_chdir, 1 }, + //{ 13, __NR_time, 1 }, + //{ 15, __NR_chmod, 2 }, + //{ 19, __NR_lseek, 3 }, + //{ 20, __NR_getpid, 0 }, + //{ 24, __NR_getuid, 0 }, + //{ 33, __NR_access, 2 }, + //{ 37, __NR_kill, 2 }, + //{ 38, __NR_rename, 2 }, + //{ 39, __NR_mkdir, 2 }, + //{ 40, __NR_rmdir, 1 }, + //{ 41, __NR_dup, 1 }, + //{ 42, __NR_pipe, 1 }, + //{ 45, __NR_brk, 1 }, + //{ 47, __NR_getgid, 0 }, + //{ 49, __NR_geteuid, 0 }, + //{ 50, __NR_getegid, 0 }, + //{ 54, __NR_ioctl, 3 }, // should be wrapped to allow SA_RESTART handling by libc, but syscall is only 3 arguments, ioctl can be 5 + //{ 55, __NR_fcntl, 3 }, // wrapped to allow filter of F_SETFD + //{ 60, __NR_umask, 1 }, + //{ 63, __NR_dup2, 2 }, + //{ 64, __NR_getppid, 0 }, + //{ 66, __NR_setsid, 0 }, + //{ 75, __NR_setrlimit, 2 }, + //{ 76, __NR_getrlimit, 2 }, + //{ 77, __NR_getrusage, 2 }, + //{ 78, __NR_gettimeofday, 2 }, + //{ 83, __NR_symlink, 2 }, + //{ 82, __NR_select, 5 }, + //{ 85, __NR_readlink, 3 }, + //{ 91, __NR_munmap, 2 }, + //{ 94, __NR_fchmod, 2 }, + //{ 99, __NR_statfs, 2 }, + //{ 102, __NR_socketcall, 2 }, + //{ 104, __NR_setitimer, 3 }, + //{ 105, __NR_getitimer, 2 }, + //{ 106, __NR_newstat, 2 }, + //{ 106, __NR_stat, 2 }, + //{ 107, __NR_newlstat, 2 }, + //{ 107, __NR_lstat, 2 }, + //{ 108, __NR_newfstat, 2 }, + //{ 108, __NR_fstat, 2 }, + //{ 109, __NR_olduname, 1 }, + //{ 110, __NR_iopl, 1 }, + //{ 114, __NR_wait4, 4 }, //TODO: check struct rusage alignment + //{ 117, __NR_ipc, 6 }, + //{ 119, __NR_sigreturn, 0}, + //{ 120, __NR_clone, 5 }, // need works + //{ 122, __NR_uname, 1 }, + //{ 123, __NR_modify_ldt }, + //{ 125, __NR_mprotect, 3 }, + //{ 136, __NR_personality, 1 }, + //{ 140, __NR__llseek, 5 }, + //{ 141, __NR_getdents, 3 }, + //{ 142, __NR__newselect, 5 }, + //{ 143, __NR_flock, 2 }, + //{ 144, __NR_msync, 3 }, + //{ 145, __NR_readv, 3 }, + //{ 146, __NR_writev, 3 }, + //{ 148, __NR_fdatasync, 1 }, + //{ 149, __NR__sysctl, 1 }, // need wrapping? + //{ 156, __NR_sched_setscheduler, 3 }, + //{ 157, __NR_sched_getscheduler, 1 }, + //{ 158, __NR_sched_yield, 0 }, + //{ 162, __NR_nanosleep, 2 }, + //{ 164, __NR_setresuid, 3 }, + //{ 168, __NR_poll, 3 }, // wrapped to allow SA_RESTART wrapping by libc + //{ 172, __NR_prctl, 5 }, + //{ 173, __NR_rt_sigreturn, 0 }, + //{ 175, __NR_rt_sigprocmask, 4 }, + //{ 179, __NR_rt_sigsuspend, 2 }, + //{ 183, __NR_getcwd, 2 }, + //{ 184, __NR_capget, 2}, + //{ 185, __NR_capset, 2}, + //{ 186, __NR_sigaltstack, 2 }, // neeed wrap or something? + //{ 191, __NR_ugetrlimit, 2 }, +// { 192, __NR_mmap2, 6}, + //{ 195, __NR_stat64, 2 }, // need proprer wrap because of structure size change + //{ 196, __NR_lstat64, 2 }, // need proprer wrap because of structure size change + //{ 197, __NR_fstat64, 2 }, // need proprer wrap because of structure size change + //{ 199, __NR_getuid32, 0 }, + //{ 200, __NR_getgid32, 0 }, + //{ 201, __NR_geteuid32, 0 }, + //{ 202, __NR_getegid32, 0 }, + //{ 208, __NR_setresuid32, 3 }, + //{ 209, __NR_getresuid32, 3 }, + //{ 210, __NR_setresgid32, 3 }, + //{ 211, __NR_getresgid32, 3 }, + //{ 220, __NR_getdents64, 3 }, + //{ 221, __NR_fcntl64, 3 }, + { 224, __NR_gettid, 0 }, + //{ 240, __NR_futex, 6 }, + //{ 241, __NR_sched_setaffinity, 3 }, + //{ 242, __NR_sched_getaffinity, 3 }, + //{ 252, __NR_exit_group, 1 }, + //{ 254, __NR_epoll_create, 1 }, + //{ 255, __NR_epoll_ctl, 4 }, + //{ 256, __NR_epoll_wait, 4 }, + //{ 265, __NR_clock_gettime, 2 }, + //{ 266, __NR_clock_getres, 2 }, + //{ 270, __NR_tgkill, 3 }, + //{ 271, __NR_utimes, 2 }, + //{ 291, __NR_inotify_init, 0}, + //{ 292, __NR_inotify_add_watch, 3}, + //{ 293, __NR_inotify_rm_watch, 2}, + //{ 311, __NR_set_robust_list, 2 }, + //{ 312, __NR_get_robust_list, 4 }, + //{ 318, __NR_getcpu, 3}, + //{ 328, __NR_eventfd2, 2}, + //{ 329, __NR_epoll_create1, 1 }, + //{ 331, __NR_pipe2, 2}, + //{ 332, __NR_inotify_init1, 1}, + //{ 355, __NR_getrandom, 3 }, + //{ 356, __NR_memfd_create, 2}, + //{ 449, __NR_futex_waitv, 5}, +}; + +struct mmap_arg_struct { + unsigned long addr; + unsigned long len; + unsigned long prot; + unsigned long flags; + unsigned long fd; + unsigned long offset; +}; + +#undef st_atime +#undef st_ctime +#undef st_mtime + +struct x64_pt_regs { + long ebx; + long ecx; + long edx; + long esi; + long edi; + long ebp; + long eax; + int xds; + int xes; + int xfs; + int xgs; + long orig_eax; + long eip; + int xcs; + long eflags; + long esp; + int xss; +}; + +#ifndef __NR_olduname +struct oldold_utsname { + char sysname[9]; + char nodename[9]; + char release[9]; + char version[9]; + char machine[9]; +}; +#endif +struct old_utsname { + char sysname[65]; + char nodename[65]; + char release[65]; + char version[65]; + char machine[65]; +}; + +struct i386_user_desc { + unsigned int entry_number; + unsigned long base_addr; + unsigned int limit; + unsigned int seg_32bit:1; + unsigned int contents:2; + unsigned int read_exec_only:1; + unsigned int limit_in_pages:1; + unsigned int seg_not_present:1; + unsigned int useable:1; +}; + +int32_t my32_open(x64emu_t* emu, void* pathname, int32_t flags, uint32_t mode); +int32_t my32_execve(x64emu_t* emu, const char* path, char* const argv[], char* const envp[]); +int my32_munmap(x64emu_t* emu, void* addr, unsigned long length); + +void EXPORT x86Syscall(x64emu_t *emu) +{ + uint32_t s = R_EAX; + printf_log(LOG_DEBUG, "%p: Calling 32bits syscall 0x%02X (%d) %p %p %p %p %p", (void*)R_RIP, s, s, (void*)(uintptr_t)R_EBX, (void*)(uintptr_t)R_ECX, (void*)(uintptr_t)R_EDX, (void*)(uintptr_t)R_ESI, (void*)(uintptr_t)R_EDI); + // check wrapper first + int cnt = sizeof(syscallwrap) / sizeof(scwrap_t); + for (int i=0; i<cnt; i++) { + if(syscallwrap[i].x86s == s) { + int sc = syscallwrap[i].nats; + switch(syscallwrap[i].nbpars) { + case 0: *(int32_t*)&R_EAX = syscall(sc); break; + case 1: *(int32_t*)&R_EAX = syscall(sc, R_EBX); break; + case 2: *(int32_t*)&R_EAX = syscall(sc, R_EBX, R_ECX); break; + case 3: *(int32_t*)&R_EAX = syscall(sc, R_EBX, R_ECX, R_EDX); break; + case 4: *(int32_t*)&R_EAX = syscall(sc, R_EBX, R_ECX, R_EDX, R_ESI); break; + case 5: *(int32_t*)&R_EAX = syscall(sc, R_EBX, R_ECX, R_EDX, R_ESI, R_EDI); break; + case 6: *(int32_t*)&R_EAX = syscall(sc, R_EBX, R_ECX, R_EDX, R_ESI, R_EDI, R_EBP); break; + default: + printf_log(LOG_NONE, "ERROR, Unimplemented syscall wrapper (%d, %d)\n", s, syscallwrap[i].nbpars); + emu->quit = 1; + return; + } + if(R_EAX==0xffffffff && errno>0) + R_EAX = (uint32_t)-errno; + printf_log(LOG_DEBUG, " => 0x%x\n", R_EAX); + return; + } + } + switch (s) { + case 1: // sys_exit + emu->quit = 1; + emu->exit = 1; + //R_EAX = syscall(__NR_exit, R_EBX); // the syscall should exit only current thread + R_EAX = R_EBX; // faking the syscall here, we don't want to really terminate the thread now + break; + case 3: // sys_read + S_EAX = read((int)R_EBX, from_ptrv(R_ECX), from_ulong(R_EDX)); + break; + case 4: // sys_write + S_EAX = write((int)R_EBX, from_ptrv(R_ECX), from_ulong(R_EDX)); + break; + case 5: // sys_open + if(s==5) {printf_log(LOG_DEBUG, " => sys_open(\"%s\", %d, %d)", (char*)from_ptrv(R_EBX), of_convert32(R_ECX), R_EDX);}; + //S_EAX = open((void*)R_EBX, of_convert32(R_ECX), R_EDX); + S_EAX = my32_open(emu, from_ptrv(R_EBX), of_convert32(R_ECX), R_EDX); + break; + case 6: // sys_close + S_EAX = close((int)R_EBX); + break; + /*case 123: // SYS_modify_ldt + R_EAX = my32_modify_ldt(emu, R_EBX, (thread_area_t*)(uintptr_t)R_ECX, R_EDX); + if(R_EAX==0xffffffff && errno>0) + R_EAX = (uint32_t)-errno; + break;*/ + case 243: // set_thread_area + R_EAX = my_set_thread_area_32(emu, (thread_area_32_t*)(uintptr_t)R_EBX); + if(R_EAX==0xffffffff && errno>0) + R_EAX = (uint32_t)-errno; + break; + default: + printf_log(LOG_INFO, "Warning: Unsupported Syscall 0x%02Xh (%d)\n", s, s); + R_EAX = (uint32_t)-ENOSYS; + return; + } + printf_log(LOG_DEBUG, " => 0x%x\n", R_EAX); +} + +#ifdef BOX32 +#define stack(n) (b[(n)/4]) +#define i32(n) (int32_t)stack(n) +#define u32(n) (uint32_t)stack(n) +#define p(n) from_ptrv(stack(n)) + +uint32_t EXPORT my32_syscall(x64emu_t *emu, ptr_t* b) +{ + static uint32_t warned = 0; + uint32_t s = u32(0); + printf_log(LOG_DEBUG, "%p: Calling libc syscall 0x%02X (%d) %p %p %p %p %p\n", from_ptrv(R_EIP), s, s, from_ptrv(u32(4)), from_ptrv(u32(8)), from_ptrv(u32(12)), from_ptrv(u32(16)), from_ptrv(u32(20))); + // check wrapper first + int cnt = sizeof(syscallwrap) / sizeof(scwrap_t); + for (int i=0; i<cnt; i++) { + if(syscallwrap[i].x86s == s) { + int sc = syscallwrap[i].nats; + switch(syscallwrap[i].nbpars) { + case 0: return syscall(sc); + case 1: return syscall(sc, u32(4)); + case 2: return syscall(sc, u32(4), u32(8)); + case 3: return syscall(sc, u32(4), u32(8), u32(12)); + case 4: return syscall(sc, u32(4), u32(8), u32(12), u32(16)); + case 5: return syscall(sc, u32(4), u32(8), u32(12), u32(16), u32(20)); + case 6: return syscall(sc, u32(4), u32(8), u32(12), u32(16), u32(20), u32(24)); + default: + printf_log(LOG_NONE, "ERROR, Unimplemented syscall wrapper (%d, %d)\n", s, syscallwrap[i].nbpars); + emu->quit = 1; + return 0; + } + } + } + switch (s) { + case 1: // __NR_exit + emu->quit = 1; + return u32(4); // faking the syscall here, we don't want to really terminate the program now + case 3: // sys_read + return (uint32_t)read(i32(4), p(8), u32(12)); + case 4: // sys_write + return (uint32_t)write(i32(4), p(8), u32(12)); + case 5: // sys_open + return my32_open(emu, p(4), of_convert32(u32(8)), u32(12)); + case 6: // sys_close + return (uint32_t)close(i32(4)); + case 11: // execve + return (uint32_t)my32_execve(emu, p(4), p(8), p(12)); + case 91: // munmap + return (uint32_t)my32_munmap(emu, p(4), u32(8)); +#if 0 + case 120: // clone + // x86 raw syscall is long clone(unsigned long flags, void *stack, int *parent_tid, unsigned long tls, int *child_tid); + // so flags=u(4), stack=p(8), parent_tid=p(12), tls=p(16), child_tid=p(20) + if(p(8)) + { + void* stack_base = p(8); + int stack_size = 0; + if(!stack_base) { + // allocate a new stack... + int currstack = 0; + if((R_ESP>=(uintptr_t)emu->init_stack) && (R_ESP<=((uintptr_t)emu->init_stack+emu->size_stack))) + currstack = 1; + stack_size = (currstack)?emu->size_stack:(1024*1024); + stack_base = mmap(NULL, stack_size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_GROWSDOWN, -1, 0); + // copy value from old stack to new stack + if(currstack) + memcpy(stack_base, emu->init_stack, stack_size); + else { + int size_to_copy = (uintptr_t)emu->init_stack + emu->size_stack - (R_ESP); + memcpy(stack_base+stack_size-size_to_copy, (void*)R_ESP, size_to_copy); + } + } + x64emu_t * newemu = NewX86Emu(emu->context, R_EIP, (uintptr_t)stack_base, stack_size, (p(8))?0:1); + SetupX86Emu(newemu); + CloneEmu(newemu, emu); + Push32(newemu, 0); + PushExit(newemu); + void* mystack = NULL; + if(my32_context->stack_clone_used) { + mystack = malloc(1024*1024); // stack for own process... memory leak, but no practical way to remove it + } else { + if(!my32_context->stack_clone) + my32_context->stack_clone = malloc(1024*1024); + mystack = my32_context->stack_clone; + my32_context->stack_clone_used = 1; + } + // x86_64 raw clone is long clone(unsigned long flags, void *stack, int *parent_tid, int *child_tid, unsigned long tls); + long ret = clone(clone_fn, (void*)((uintptr_t)mystack+1024*1024), u32(4), newemu, p(12), p(16), p(20)); + return (uint32_t)ret; + } + else + return (uint32_t)syscall(__NR_clone, u32(4), p(8), p(12), p(16), p(20)); + break; + case 123: // SYS_modify_ldt + return my32_modify_ldt(emu, i32(4), (thread_area_t*)p(8), i32(12)); + case 125: // mprotect + return (uint32_t)my32_mprotect(emu, p(4), u32(8), i32(12)); + case 174: // sys_rt_sigaction + return (uint32_t)my32_sigaction(emu, i32(4), (x86_sigaction_t*)p(8), (x86_sigaction_t*)p(12)); + case 192: // mmap2 + return (uint32_t)my32_mmap64(emu, p(4), u32(8), i32(12), i32(16), i32(20), u32(24)); + case 243: // set_thread_area + return my32_set_thread_area((thread_area_t*)p(4)); +#ifndef NOALIGN + case 254: // epoll_create + return my32_epoll_create(emu, i32(4)); + case 255: // epoll_ctl + return my32_epoll_ctl(emu, i32(4), i32(8), i32(12), p(16)); + case 256: // epoll_wait + return my32_epoll_wait(emu, i32(4), p(8), i32(12), i32(16)); +#endif + case 270: //_NR_tgkill + /*if(!u32(12))*/ { + //printf("tgkill(%u, %u, %u) => ", u32(4), u32(8), u32(12)); + uint32_t ret = (uint32_t)syscall(__NR_tgkill, u32(4), u32(8), u32(12)); + //printf("%u (errno=%d)\n", ret, (ret==(uint32_t)-1)?errno:0); + return ret; + }/* else { + printf_log(LOG_INFO, "Warning: ignoring libc Syscall tgkill (%u, %u, %u)\n", u32(4), u32(8), u32(12)); + }*/ + return 0; +#ifndef NOALIGN + case 329: // epoll_create1 + return my32_epoll_create1(emu, of_convert32(i32(4))); +#endif +#ifndef __NR_getrandom + case 355: // getrandom + return (uint32_t)my32_getrandom(emu, p(4), u32(8), u32(12)); +#endif +#ifndef __NR_memfd_create + case 356: // memfd_create + return (uint32_t)my32_memfd_create(emu, (void*)R_EBX, R_ECX); +#endif +#endif + default: + if(!(warned&(1<<s))) { + printf_log(LOG_INFO, "Warning: Unsupported libc Syscall 0x%02X (%d)\n", s, s); + warned|=(1<<s); + } + errno = ENOSYS; + return -1; + } + return 0; +} +#endif //BOX32 \ No newline at end of file diff --git a/src/emu/x87emu_private.c b/src/emu/x87emu_private.c index 92c14268..c64f49cb 100644 --- a/src/emu/x87emu_private.c +++ b/src/emu/x87emu_private.c @@ -295,7 +295,6 @@ void fpu_savenv(x64emu_t* emu, char* p, int b16) // other stuff are not pushed.... } -// this is the 64bits version (slightly different than the 32bits!) typedef struct xsave32_s { uint16_t ControlWord; /* 000 */ uint16_t StatusWord; /* 002 */ @@ -311,9 +310,10 @@ typedef struct xsave32_s { uint32_t MxCsr; /* 018 */ uint32_t MxCsr_Mask; /* 01c */ sse_regs_t FloatRegisters[8];/* 020 */ // fpu/mmx are store in 128bits here - sse_regs_t XmmRegisters[16]; /* 0a0 */ - uint8_t Reserved4[96]; /* 1a0 */ + sse_regs_t XmmRegisters[8]; /* 0a0 */ + uint8_t Reserved4[56*4]; /* 1a0 */ } xsave32_t; +// this is the 64bits version (slightly different than the 32bits!) typedef struct xsave64_s { uint16_t ControlWord; /* 000 */ uint16_t StatusWord; /* 002 */ @@ -354,8 +354,7 @@ void fpu_fxsave32(x64emu_t* emu, void* ed) for(int i=0; i<8; ++i) memcpy(&p->FloatRegisters[i].q[0], (i<stack)?&ST(i):&emu->mmx[i], sizeof(mmx87_regs_t)); // copy SSE regs - for(int i=0; i<16; ++i) - memcpy(&p->XmmRegisters[i], &emu->xmm[i], 16); + memcpy(p->XmmRegisters, emu->xmm, 8*16); } void fpu_fxsave64(x64emu_t* emu, void* ed) @@ -381,8 +380,7 @@ void fpu_fxsave64(x64emu_t* emu, void* ed) for(int i=0; i<8; ++i) memcpy(&p->FloatRegisters[i].q[0], (i<stack)?&ST(i):&emu->mmx[i], sizeof(mmx87_regs_t)); // copy SSE regs - for(int i=0; i<16; ++i) - memcpy(&p->XmmRegisters[i], &emu->xmm[i], 16); + memcpy(p->XmmRegisters, emu->xmm, 16*16); } void fpu_fxrstor32(x64emu_t* emu, void* ed) @@ -406,8 +404,7 @@ void fpu_fxrstor32(x64emu_t* emu, void* ed) for(int i=0; i<8; ++i) memcpy((i<stack)?&ST(i):&emu->mmx[i], &p->FloatRegisters[i].q[0], sizeof(mmx87_regs_t)); // copy SSE regs - for(int i=0; i<16; ++i) - memcpy(&emu->xmm[i], &p->XmmRegisters[i], 16); + memcpy(emu->xmm, p->XmmRegisters, 8*16); } void fpu_fxrstor64(x64emu_t* emu, void* ed) @@ -431,8 +428,7 @@ void fpu_fxrstor64(x64emu_t* emu, void* ed) for(int i=0; i<8; ++i) memcpy((i<stack)?&ST(i):&emu->mmx[i], &p->FloatRegisters[i].q[0], sizeof(mmx87_regs_t)); // copy SSE regs - for(int i=0; i<16; ++i) - memcpy(&emu->xmm[i], &p->XmmRegisters[i], 16); + memcpy(emu->xmm, p->XmmRegisters, 16*16); } typedef struct xsaveheader_s { |