diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2021-06-07 20:06:02 +0200 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2021-06-07 20:06:02 +0200 |
| commit | 508545aa874ac7c8de5fb589bc03e3f45c70adb5 (patch) | |
| tree | 9bde8c750dbd39210a7012d884b05ae33a213c4f /src/emu | |
| parent | 52d86177c5d7e70df4018ec8c9ef7a7da5bf030a (diff) | |
| download | box64-508545aa874ac7c8de5fb589bc03e3f45c70adb5.tar.gz box64-508545aa874ac7c8de5fb589bc03e3f45c70adb5.zip | |
Added suport for arch_prctl syscall, and GL segment handling ([DYNAREC] too)
Diffstat (limited to 'src/emu')
| -rwxr-xr-x | src/emu/x64run.c | 11 | ||||
| -rw-r--r-- | src/emu/x64run64.c | 4 | ||||
| -rwxr-xr-x | src/emu/x64run_private.h | 2 | ||||
| -rwxr-xr-x | src/emu/x64syscall.c | 6 | ||||
| -rwxr-xr-x | src/emu/x64tls.c | 34 |
5 files changed, 51 insertions, 6 deletions
diff --git a/src/emu/x64run.c b/src/emu/x64run.c index d56b3aa2..0ef1e84e 100755 --- a/src/emu/x64run.c +++ b/src/emu/x64run.c @@ -241,14 +241,21 @@ x64emurun: GD->sdword[0] = ED->sdword[0]; // meh? break; case 0x64: /* FS: prefix */ - if(Run64(emu, rex)) { + if(Run64(emu, rex, _FS)) { + unimp = 1; + goto fini; + } + if(emu->quit) + goto fini; + break; + case 0x65: /* GS: prefix */ + if(Run64(emu, rex, _GS)) { unimp = 1; goto fini; } if(emu->quit) goto fini; break; - case 0x66: /* 16bits prefix */ if(Run66(emu, rex, rep)) { unimp = 1; diff --git a/src/emu/x64run64.c b/src/emu/x64run64.c index 1708bb79..c7f2fbec 100644 --- a/src/emu/x64run64.c +++ b/src/emu/x64run64.c @@ -22,7 +22,7 @@ #include "modrm.h" -int Run64(x64emu_t *emu, rex_t rex) +int Run64(x64emu_t *emu, rex_t rex, int seg) { uint8_t opcode; uint8_t nextop; @@ -35,7 +35,7 @@ int Run64(x64emu_t *emu, rex_t rex) reg64_t *oped, *opgd; sse_regs_t *opex, *opgx; int rep; - uintptr_t tlsdata = GetFSBaseEmu(emu); + uintptr_t tlsdata = GetSegmentBaseEmu(emu, seg); opcode = F8; // REX prefix before the F0 are ignored diff --git a/src/emu/x64run_private.h b/src/emu/x64run_private.h index 7f4089fc..bcaea031 100755 --- a/src/emu/x64run_private.h +++ b/src/emu/x64run_private.h @@ -102,7 +102,7 @@ void UpdateFlags(x64emu_t *emu); #define RESET_FLAGS(emu) emu->df = d_none int Run0F(x64emu_t *emu, rex_t rex); -int Run64(x64emu_t *emu, rex_t rex); +int Run64(x64emu_t *emu, rex_t rex, int seg); int Run66(x64emu_t *emu, rex_t rex, int rep); int Run660F(x64emu_t *emu, rex_t rex); int Run6664(x64emu_t *emu, rex_t rex); diff --git a/src/emu/x64syscall.c b/src/emu/x64syscall.c index c43e1407..126dfb82 100755 --- a/src/emu/x64syscall.c +++ b/src/emu/x64syscall.c @@ -116,6 +116,7 @@ scwrap_t syscallwrap[] = { { 127, __NR_rt_sigpending, 2}, //{ 131, __NR_sigaltstack, 2}, // wrapped to use my_sigaltstack { 157, __NR_prctl, 5 }, // needs wrapping? + //{ 158, __NR_arch_prctl, 2}, //need wrapping { 186, __NR_gettid, 0 }, //0xBA { 200, __NR_tkill, 2 }, #ifdef __NR_time @@ -324,6 +325,9 @@ void EXPORT x64Syscall(x64emu_t *emu) case 131: // sys_sigaltstack R_EAX = (uint32_t)my_sigaltstack(emu, (void*)R_RDI, (void*)R_RSI); break; + case 158: // sys_arch_prctl + R_EAX = (uint32_t)my_arch_prctl(emu, (int)R_EDI, (void*)R_RSI); + break; #ifndef __NR_time case 201: // sys_time R_RAX = (uintptr_t)time((void*)R_RDI); @@ -433,6 +437,8 @@ uintptr_t EXPORT my_syscall(x64emu_t *emu) return (uintptr_t)my_readlink(emu,(void*)R_RSI, (void*)R_RDX, (size_t)R_RCX); case 131: // sys_sigaltstack return (uint32_t)my_sigaltstack(emu, (void*)R_RSI, (void*)R_RDX); + case 158: // sys_arch_prctl + return (uint32_t)my_arch_prctl(emu, (int)R_ESI, (void*)R_RDX); #ifndef __NR_time case 201: // sys_time return (uintptr_t)time((void*)R_RSI); diff --git a/src/emu/x64tls.c b/src/emu/x64tls.c index de573a45..59af88fb 100755 --- a/src/emu/x64tls.c +++ b/src/emu/x64tls.c @@ -8,6 +8,7 @@ #include "debug.h" #include "box64context.h" #include "x64emu.h" +#include "x64emu_private.h" #include "x64tls.h" #include "elfloader.h" @@ -27,6 +28,7 @@ typedef struct thread_area_s static pthread_once_t thread_key_once0 = PTHREAD_ONCE_INIT; static pthread_once_t thread_key_once1 = PTHREAD_ONCE_INIT; static pthread_once_t thread_key_once2 = PTHREAD_ONCE_INIT; +static pthread_once_t thread_key_once3 = PTHREAD_ONCE_INIT; static void thread_key_alloc0() { pthread_key_create(&my_context->segtls[0].key, NULL); @@ -37,6 +39,9 @@ static void thread_key_alloc1() { static void thread_key_alloc2() { pthread_key_create(&my_context->segtls[2].key, NULL); } +static void thread_key_alloc3() { + pthread_key_create(&my_context->segtls[3].key, NULL); +} uint32_t my_set_thread_area(thread_area_t* td) { @@ -128,6 +133,33 @@ uint32_t my_modify_ldt(x64emu_t* emu, int op, thread_area_t* td, int size) return 0; } +int my_arch_prctl(x64emu_t *emu, int code, void* addr) +{ + #define ARCH_SET_GS 0x1001 + #define ARCH_GET_GS 0x1004 + switch(code) { + case ARCH_GET_GS: + *(void**)addr = GetSegmentBase(emu->segs[_GS]); + return 0; + case ARCH_SET_GS: + if(emu->segs[_GS]!=(0xa<<3)) { + pthread_once(&thread_key_once3, thread_key_alloc3); + emu->segs[_GS] = 0xa<<3; + if(!default_gs) + default_gs = 0xa<<3; + } + my_context->segtls[3].base = (uintptr_t)addr; + my_context->segtls[3].limit = 0; + my_context->segtls[3].present = 1; + pthread_setspecific(my_context->segtls[3].key, (void*)my_context->segtls[3].base); + return 0; + } + // other are unsupported + printf_log(LOG_INFO, "warning, call to unsupported arch_prctl(0x%x, %p)\n", code, addr); + return -1; +} + + #define POS_TLS 0x200 /* tls record should looks like: @@ -222,7 +254,7 @@ void* GetSegmentBase(uint32_t desc) if(base==0x6) return GetSeg33Base(); - if(base>6 && base<10 && my_context->segtls[base-7].present) { + if(base>6 && base<11 && my_context->segtls[base-7].present) { void* ptr = pthread_getspecific(my_context->segtls[base-7].key); return ptr; } |