diff --git a/CMakeLists.txt b/CMakeLists.txt index 12dc810b..00fd4a01 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -37,6 +37,7 @@ SET(ELFLOADER_SRC src/elfload_dump.c src/librarian.c src/stack.c + src/threads.c src/wrapper.c src/x86emu.c src/x86run.c @@ -50,7 +51,7 @@ SET(ELFLOADER_SRC ) add_executable(box86 ${ELFLOADER_SRC}) -target_link_libraries(box86 m dl rt) +target_link_libraries(box86 m dl rt pthread) add_test(test01 ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/box86 -D TEST_ARGS=${CMAKE_SOURCE_DIR}/tests/test01 -D TEST_OUTPUT=tmpfile.txt @@ -75,4 +76,9 @@ add_test(test04 ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/box86 add_test(test05 ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/box86 -D TEST_ARGS=${CMAKE_SOURCE_DIR}/tests/test05 -D TEST_ARGS2=7 -D TEST_OUTPUT=tmpfile.txt -D TEST_REFERENCE=${CMAKE_SOURCE_DIR}/tests/ref05.txt + -P ${CMAKE_SOURCE_DIR}/runTest.cmake ) + +add_test(test06 ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/box86 + -D TEST_ARGS=${CMAKE_SOURCE_DIR}/tests/test06 -D TEST_OUTPUT=tmpfile.txt + -D TEST_REFERENCE=${CMAKE_SOURCE_DIR}/tests/ref06.txt -P ${CMAKE_SOURCE_DIR}/runTest.cmake ) \ No newline at end of file diff --git a/src/box86context.h b/src/box86context.h index 2c51a286..632eb869 100755 --- a/src/box86context.h +++ b/src/box86context.h @@ -8,6 +8,7 @@ typedef struct elfheader_s elfheader_t; typedef struct x86emu_s x86emu_t; typedef struct zydis_s zydis_t; typedef struct lib_s lib_t; +typedef struct bridge_s bridge_t; typedef struct box86context_s { path_collection_t box86_path; // PATH env. variable @@ -36,6 +37,8 @@ typedef struct box86context_s { lib_t *maplib; // lib and symbols handling + bridge_t *threads; // threads + } box86context_t; box86context_t *NewBox86Context(int argc); diff --git a/src/bridge.c b/src/bridge.c index 0f8b5d67..95b28282 100755 --- a/src/bridge.c +++ b/src/bridge.c @@ -3,18 +3,9 @@ #include #include "bridge.h" +#include "bridge_private.h" #include "wrapper.h" -#pragma pack(push, 1) -typedef struct onebridge_s { - uint8_t CC; // CC int 0x3 - uint8_t S, C; // 'S' 'C', just a signature - wrapper_t w; // wrapper - uintptr_t f; // the function for the wrapper - uint8_t C3; // C3 ret -} onebridge_t; -#pragma pack(pop) - #define NBRICK 16 typedef struct brick_s brick_t; typedef struct brick_s { diff --git a/src/bridge_private.h b/src/bridge_private.h new file mode 100755 index 00000000..4db190a5 --- /dev/null +++ b/src/bridge_private.h @@ -0,0 +1,17 @@ +#ifndef __BRIDGE_PRIVATE_H_ +#define __BRIDGE_PRIVATE_H_ +#include + +#include "wrapper.h" + +#pragma pack(push, 1) +typedef struct onebridge_s { + uint8_t CC; // CC int 0x3 + uint8_t S, C; // 'S' 'C', just a signature + wrapper_t w; // wrapper + uintptr_t f; // the function for the wrapper + uint8_t C3; // C3 ret +} onebridge_t; +#pragma pack(pop) + +#endif //__BRIDGE_PRIVATE_H_ \ No newline at end of file diff --git a/src/elfloader.c b/src/elfloader.c index 8eefb77f..b5ec6b73 100755 --- a/src/elfloader.c +++ b/src/elfloader.c @@ -301,8 +301,9 @@ void AddGlobalsSymbols(lib_t* maplib, elfheader_t* h) if(((h->SymTab[i].st_info == 18) || h->SymTab[i].st_info == 17) && (h->SymTab[i].st_other==0) && (h->SymTab[i].st_shndx!=0)) { const char * symname = h->StrTab+h->SymTab[i].st_name; uintptr_t offs = h->SymTab[i].st_value + h->delta; - printf_log(LOG_DUMP, "Adding Symbol \"%s\" with offset=%p\n", symname, offs); - AddSymbol(maplib, symname, offs); + uint32_t sz = h->SymTab[i].st_size; + printf_log(LOG_DUMP, "Adding Symbol \"%s\" with offset=%p sz=%d\n", symname, offs, sz); + AddSymbol(maplib, symname, offs, sz); } } } diff --git a/src/librarian.c b/src/librarian.c index a4bfd672..0b9d73aa 100755 --- a/src/librarian.c +++ b/src/librarian.c @@ -1,6 +1,8 @@ #include #include +#include + #include "debug.h" #include "librarian.h" #include "librarian_private.h" @@ -39,11 +41,13 @@ int32_t my__libc_start_main(x86emu_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)); // implemented in x86run_private.c uint32_t LibSyscall(x86emu_t *emu); // implemented in x86syscall.c +int my_pthread_create(x86emu_t *emu, void* t, void* attr, void* start_routine, void* arg); //implemented in thread.c uintptr_t CreateSymbol(lib_t *maplib, const char* name) { // look for symbols that can be created uintptr_t addr = 0; + // libc if(strcmp(name, "__stack_chk_fail")==0) { addr = AddBridge(maplib->bridge, vFE, my__stack_chk_fail); } else if(strcmp(name, "__libc_start_main")==0) { @@ -64,17 +68,30 @@ uintptr_t CreateSymbol(lib_t *maplib, const char* name) addr = AddBridge(maplib->bridge, iFi, putchar); } else if(strcmp(name, "strtol")==0) { addr = AddBridge(maplib->bridge, iFppi, strtol); + } else if(strcmp(name, "strerror")==0) { + addr = AddBridge(maplib->bridge, pFv, strerror); + } //pthread + else if(strcmp(name, "pthread_self")==0) { + addr = AddBridge(maplib->bridge, uFv, pthread_self); + } else if(strcmp(name, "pthread_create")==0) { + addr = AddBridge(maplib->bridge, iFEpppp, my_pthread_create); + } else if(strcmp(name, "pthread_equal")==0) { + addr = AddBridge(maplib->bridge, iFuu, pthread_equal); + } else if(strcmp(name, "pthread_join")==0) { + addr = AddBridge(maplib->bridge, iFup, pthread_join); } + if(addr) - AddSymbol(maplib, name, addr); + AddSymbol(maplib, name, addr, 12); return addr; } -void AddSymbol(lib_t *maplib, const char* name, uintptr_t addr) +void AddSymbol(lib_t *maplib, const char* name, uintptr_t addr, uint32_t sz) { int ret; khint_t k = kh_put(maplib_t, maplib->maplib, name, &ret); kh_value(maplib->maplib, k).offs = addr; + kh_value(maplib->maplib, k).sz = sz; } uintptr_t FindSymbol(lib_t *maplib, const char* name) { @@ -83,3 +100,13 @@ uintptr_t FindSymbol(lib_t *maplib, const char* name) return CreateSymbol(maplib, name); return kh_val(maplib->maplib, k).offs; } + +int GetSymbolStartEnd(lib_t* maplib, const char* name, uintptr_t* start, uintptr_t* end) +{ + khint_t k = kh_get(maplib_t, maplib->maplib, name); + if(k==kh_end(maplib->maplib)) + return 0; + *start = kh_val(maplib->maplib, k).offs; + *end = *start + kh_val(maplib->maplib, k).sz; + return 1; +} \ No newline at end of file diff --git a/src/librarian.h b/src/librarian.h index 1b5ae421..61394bb4 100755 --- a/src/librarian.h +++ b/src/librarian.h @@ -8,7 +8,8 @@ typedef struct bridge_s bridge_t; lib_t *NewLibrarian(); void FreeLibrarian(lib_t **maplib); -void AddSymbol(lib_t *maplib, const char* name, uintptr_t addr); +void AddSymbol(lib_t *maplib, const char* name, uintptr_t addr, uint32_t sz); uintptr_t FindSymbol(lib_t *maplib, const char* name); +int GetSymbolStartEnd(lib_t* maplib, const char* name, uintptr_t* start, uintptr_t* end); #endif //__LIBRARIAN_H_ \ No newline at end of file diff --git a/src/librarian_private.h b/src/librarian_private.h index 9a046ac7..b5543408 100755 --- a/src/librarian_private.h +++ b/src/librarian_private.h @@ -5,6 +5,7 @@ typedef struct { uintptr_t offs; + uint32_t sz; // need to track type of symbol? // need to track origin? } onelib_t; diff --git a/src/main.c b/src/main.c index 82f77dc3..3484bf82 100755 --- a/src/main.c +++ b/src/main.c @@ -129,7 +129,7 @@ int main(int argc, const char **argv, const char **env) { // init random seed srandom(time(NULL)); - // check BOX86_loG debug level + // check BOX86_LOG debug level LoadLogEnv(); // Create a new context @@ -153,8 +153,7 @@ int main(int argc, const char **argv, const char **env) { p = getenv("BOX86_TRACE"); if(p) { - setbuf(stdout, NULL); - if (strcmp(p, "1")==0) + if (strcmp(p, "0")) context->x86trace = 1; } if(context->x86trace) { @@ -243,9 +242,20 @@ int main(int argc, const char **argv, const char **env) { // setup the stack... Push(context->emu, (uint32_t)context->argv); Push(context->emu, context->argc); - SetupX86Emu(context->emu); + SetupX86Emu(context->emu, NULL, NULL); SetEAX(context->emu, context->argc); SetEBX(context->emu, (uint32_t)context->argv); + + p = getenv("BOX86_TRACE"); + if(p) { + setbuf(stdout, NULL); + uintptr_t trace_start, trace_end; + if (strcmp(p, "1")==0) + SetTraceEmu(context->emu, 0, 0); + else if (GetSymbolStartEnd(context->maplib, p, &trace_start, &trace_end)) + SetTraceEmu(context->emu, trace_start, trace_end); + } + // emulate! printf_log(LOG_DEBUG, "Start x86emu on Main\n"); Run(context->emu); diff --git a/src/threads.c b/src/threads.c new file mode 100755 index 00000000..c918a301 --- /dev/null +++ b/src/threads.c @@ -0,0 +1,57 @@ +#include +#include +#include + +#include "box86context.h" +#include "threads.h" +#include "x86emu_private.h" +#include "bridge_private.h" +#include "x86run.h" +#include "x86emu.h" +#include "stack.h" + +// memory handling to be perfected... +// keep a hash thread_t -> emu to set emu->quit to 1 on pthread_cancel + +typedef struct emuthread_s { + x86emu_t *emu; + onebridge_t routine; + int stacksize; + void *stack; +} emuthread_t; + +void* pthread_routine(void* p) +{ + emuthread_t *et = (emuthread_t*)p; + Run(et->emu); + void* r = (void*)GetEAX(et->emu); + FreeX86Emu(&et->emu); + free(et->stack); + free(et); + return r; +} + +int my_pthread_create(x86emu_t *emu, void* t, void* attr, void* start_routine, void* arg) +{ + emuthread_t *emuthread = (emuthread_t*)calloc(1, sizeof(emuthread_t)); + emuthread->routine.CC = 0xCC; + emuthread->routine.S = 'S'; emuthread->routine.C = 'C'; + emuthread->routine.w = pFp; + emuthread->routine.f = (uintptr_t)start_routine; + emuthread->routine.C3 = 0xC3; + + emuthread->stacksize = 2*1024*1024; //default stack size is 2Mo + // TODO: get stack size inside attr + emuthread->stack = calloc(1, emuthread->stacksize); + emuthread->emu = NewX86Emu(emu->context, (uintptr_t)start_routine, (uintptr_t)emuthread->stack, + emuthread->stacksize); + SetupX86Emu(emuthread->emu, emu->shared_global, emu->globals); + emuthread->emu->trace_start = emu->trace_start; + emuthread->emu->trace_end = emu->trace_end; + Push(emuthread->emu, (uintptr_t)arg); + PushExit(emuthread->emu); + + // create thread + return pthread_create((pthread_t*)t, (const pthread_attr_t *)attr, + pthread_routine, emuthread); +} \ No newline at end of file diff --git a/src/threads.h b/src/threads.h new file mode 100755 index 00000000..08357ea3 --- /dev/null +++ b/src/threads.h @@ -0,0 +1,7 @@ +#ifndef _THREADS_H_ +#define _THREADS_H_ + +#include "bridge.h" + + +#endif //_THREADS_H_ \ No newline at end of file diff --git a/src/wrapper.c b/src/wrapper.c index 0af9d80c..53a2a716 100755 --- a/src/wrapper.c +++ b/src/wrapper.c @@ -23,15 +23,23 @@ typedef void (*vFv_t)(); typedef void (*vFp_t)(void*); typedef void (*vFE_t)(x86emu_t*); typedef int32_t (*iFv_t)(); +typedef uint32_t (*uFv_t)(); +typedef void* (*pFv_t)(); typedef uint32_t (*uFE_t)(x86emu_t*); typedef void (*vFi_t)(int32_t); typedef int32_t (*iFi_t)(int32_t); typedef int32_t (*iFp_t)(void*); +typedef void* (*pFp_t)(void*); typedef int32_t (*iFpp_t)(void*, void*); +typedef int32_t (*iFii_t)(int32_t, int32_t); +typedef int32_t (*iFip_t)(int32_t, void*); +typedef int32_t (*iFuu_t)(uint32_t, uint32_t); +typedef int32_t (*iFup_t)(uint32_t, void*); typedef int32_t (*iFppi_t)(void*, void*, int32_t); typedef void* (*pFuu_t)(uint32_t, uint32_t); typedef int32_t (*iFipp_t)(int, void*, void*); typedef int32_t (*iFppp_t)(void*, void*, void*); +typedef int32_t (*iFEpppp_t)(x86emu_t*, void*, void*, void*, void*); typedef int32_t (*iFEpippppp_t)(x86emu_t*, void*, int32_t, void*, void*, void*, void*, void*); #define DEF(A) A f = (A)fnc @@ -54,7 +62,12 @@ void vFE(x86emu_t *emu, uintptr_t fnc) void iFv(x86emu_t *emu, uintptr_t fnc) { DEF(iFv_t); - *(int32_t*)&R_EAX = f(); + R_EAX = *(uint32_t*)f(); +} +void uFv(x86emu_t *emu, uintptr_t fnc) +{ + DEF(uFv_t); + R_EAX = f(); } void uFE(x86emu_t *emu, uintptr_t fnc) { @@ -66,6 +79,11 @@ void vFi(x86emu_t *emu, uintptr_t fnc) DEF(vFi_t); f(i32(0)); } +void pFv(x86emu_t *emu, uintptr_t fnc) +{ + DEF(pFv_t); + R_EAX = *(uint32_t*)f(); +} void iFi(x86emu_t *emu, uintptr_t fnc) { DEF(iFi_t); @@ -76,6 +94,11 @@ void iFp(x86emu_t *emu, uintptr_t fnc) DEF(iFp_t); R_EAX = (uint32_t)f(p(0)); } +void pFp(x86emu_t *emu, uintptr_t fnc) +{ + DEF(pFp_t); + R_EAX = (uint32_t)f(p(0)); +} void iFpp(x86emu_t *emu, uintptr_t fnc) { DEF(iFpp_t); @@ -91,6 +114,26 @@ void pFuu(x86emu_t *emu, uintptr_t fnc) DEF(pFuu_t); R_EAX = (uintptr_t)f(u32(0), u32(4)); } +void iFii(x86emu_t *emu, uintptr_t fnc) +{ + DEF(iFii_t); + R_EAX = (uint32_t)f(i32(0), i32(4)); +} +void iFip(x86emu_t *emu, uintptr_t fnc) +{ + DEF(iFip_t); + R_EAX = (uint32_t)f(i32(0), p(4)); +} +void iFuu(x86emu_t *emu, uintptr_t fnc) +{ + DEF(iFuu_t); + R_EAX = (uint32_t)f(u32(0), u32(4)); +} +void iFup(x86emu_t *emu, uintptr_t fnc) +{ + DEF(iFup_t); + R_EAX = (uint32_t)f(u32(0), p(4)); +} void iFpV(x86emu_t *emu, uintptr_t fnc) { DEF(iFpp_t); @@ -111,6 +154,11 @@ void iFvopV(x86emu_t *emu, uintptr_t fnc) DEF(iFppp_t); R_EAX = (uint32_t)f((void*)stdout, p(4), (void*)stack(8)); } +void iFEpppp(x86emu_t *emu, uintptr_t fnc) +{ + DEF(iFEpppp_t); + R_EAX = (uint32_t)f(emu, p(0), p(4), p(8), p(12)); +} void iFEpippppp(x86emu_t *emu, uintptr_t fnc) { DEF(iFEpippppp_t); diff --git a/src/wrapper.h b/src/wrapper.h index 89e1860c..d30f555a 100755 --- a/src/wrapper.h +++ b/src/wrapper.h @@ -20,16 +20,24 @@ void vFp(x86emu_t *emu, uintptr_t fnc); void vFE(x86emu_t *emu, uintptr_t fnc); void uFE(x86emu_t *emu, uintptr_t fnc); void iFv(x86emu_t *emu, uintptr_t fnc); +void uFv(x86emu_t *emu, uintptr_t fnc); +void pFv(x86emu_t *emu, uintptr_t fnc); void vFi(x86emu_t *emu, uintptr_t fnc); void iFi(x86emu_t *emu, uintptr_t fnc); void iFp(x86emu_t *emu, uintptr_t fnc); +void pFp(x86emu_t *emu, uintptr_t fnc); void iFpp(x86emu_t *emu, uintptr_t fnc); void iFppi(x86emu_t *emu, uintptr_t fnc); void pFuu(x86emu_t *emu, uintptr_t fnc); +void iFii(x86emu_t *emu, uintptr_t fnc); +void iFip(x86emu_t *emu, uintptr_t fnc); +void iFuu(x86emu_t *emu, uintptr_t fnc); +void iFup(x86emu_t *emu, uintptr_t fnc); void iFpv(x86emu_t *emu, uintptr_t fnc); void iF1pV(x86emu_t *emu, uintptr_t fnc); void iFopV(x86emu_t *emu, uintptr_t fnc); void iFvopV(x86emu_t *emu, uintptr_t fnc); +void iFEpppp(x86emu_t *emu, uintptr_t fnc); void iFEpippppp(x86emu_t *emu, uintptr_t fnc); // this is __libc_start_main basically diff --git a/src/x86emu.c b/src/x86emu.c index 4d6a0463..ee016af7 100755 --- a/src/x86emu.c +++ b/src/x86emu.c @@ -51,20 +51,34 @@ x86emu_t *NewX86Emu(box86context_t *context, uintptr_t start, uintptr_t stack, i return emu; } -void SetupX86Emu(x86emu_t *emu) +void SetupX86Emu(x86emu_t *emu, int* shared_global, void* globals) { printf_log(LOG_DEBUG, "Setup X86 Emu\n"); // push "end emu" marker address PushExit(emu); // Setup the GS segment: - emu->globals = calloc(1, 256); // arbitrary 256 byte size? - // calc canary... - uint8_t canary[4]; - for (int i=0; i<4; ++i) canary[i] = 1 + getrand(255); - canary[getrand(4)] = 0; - memcpy(emu->globals+0x14, canary, sizeof(canary)); // put canary in place - printf_log(LOG_DEBUG, "Setting up canary (for Stack protector) at GS:0x14, value:%08X\n", *(uint32_t*)canary); + if(shared_global) { + emu->globals = globals; + emu->shared_global = shared_global; + } else { + emu->globals = calloc(1, 256); // arbitrary 256 byte size? + // calc canary... + uint8_t canary[4]; + for (int i=0; i<4; ++i) canary[i] = 1 + getrand(255); + canary[getrand(4)] = 0; + memcpy(emu->globals+0x14, canary, sizeof(canary)); // put canary in place + printf_log(LOG_DEBUG, "Setting up canary (for Stack protector) at GS:0x14, value:%08X\n", *(uint32_t*)canary); + emu->shared_global = (int*)calloc(1, sizeof(int)); + } + (*emu->shared_global)++; +} + +void SetTraceEmu(x86emu_t *emu, uintptr_t trace_start, uintptr_t trace_end) +{ + printf_log(LOG_INFO, "Setting trace only between %p and %p\n", trace_start, trace_end); + emu->trace_start = trace_start; + emu->trace_end = trace_end; } void FreeX86Emu(x86emu_t **x86emu) @@ -74,8 +88,11 @@ void FreeX86Emu(x86emu_t **x86emu) printf_log(LOG_DEBUG, "Free a X86 Emu (%p)\n", *x86emu); if((*x86emu)->dec) DeleteX86TraceDecoder(&(*x86emu)->dec); - if((*x86emu)->globals) - free((*x86emu)->globals); + if((*x86emu)->shared_global && !(*(*x86emu)->shared_global)--) { + if((*x86emu)->globals) + free((*x86emu)->globals); + free((*x86emu)->shared_global); + } free(*x86emu); *x86emu = NULL; } diff --git a/src/x86emu.h b/src/x86emu.h index 7641b6d8..c23e003e 100755 --- a/src/x86emu.h +++ b/src/x86emu.h @@ -5,7 +5,8 @@ typedef struct x86emu_s x86emu_t; typedef struct box86context_s box86context_t; x86emu_t *NewX86Emu(box86context_t *context, uintptr_t start, uintptr_t stack, int stacksize); -void SetupX86Emu(x86emu_t *emu); +void SetupX86Emu(x86emu_t *emu, int* shared_gloabl, void* globals); +void SetTraceEmu(x86emu_t *emu, uintptr_t trace_start, uintptr_t trace_end); void FreeX86Emu(x86emu_t **x86emu); uint32_t GetEAX(x86emu_t *emu); diff --git a/src/x86emu_private.h b/src/x86emu_private.h index e335aa22..7a239d25 100755 --- a/src/x86emu_private.h +++ b/src/x86emu_private.h @@ -34,8 +34,10 @@ typedef struct x86emu_s { int error; // trace zydis_dec_t *dec; + uintptr_t trace_start, trace_end; // global stuffs, pointed with GS: segment void *globals; + int *shared_global; // parent context box86context_t *context; } x86emu_t; diff --git a/src/x86run.c b/src/x86run.c index bfe832fa..026a145b 100755 --- a/src/x86run.c +++ b/src/x86run.c @@ -13,10 +13,13 @@ int Run(x86emu_t *emu) { + printf_log(LOG_DEBUG, "Run X86, EIP=%p\n", emu, R_EIP); emu->quit = 0; while (!emu->quit) { - if(emu->dec) { + if(emu->dec && ( + (emu->trace_end == 0) + || ((R_EIP >= emu->trace_start) && (R_EIP < emu->trace_end))) ) { printf_log(LOG_NONE, "%s", DumpCPURegs(emu)); if(Peek(emu, 0)==0xcc && Peek(emu, 1)=='S' && Peek(emu, 2)=='C') { uint32_t a = *(uint32_t*)(R_EIP+3); @@ -26,7 +29,7 @@ int Run(x86emu_t *emu) printf_log(LOG_NONE, "%08p: Native call to %p\n", R_EIP, a); } } else { - printf_log(LOG_NONE, "%08p: %s\n", R_EIP, DecodeX86Trace(emu->dec, R_EIP)); + printf_log(LOG_NONE, "%s\n", DecodeX86Trace(emu->dec, R_EIP)); } } uint8_t opcode = Fetch8(emu); @@ -242,6 +245,16 @@ int Run(x86emu_t *emu) if(!ACCESS_FLAG(F_ZF)) R_EIP += tmp8s; break; + case 0x76: /* JBE Ib */ + tmp8s = Fetch8s(emu); + if((ACCESS_FLAG(F_ZF) || ACCESS_FLAG(F_CF))) + R_EIP += tmp8s; + break; + case 0x77: /* JNBE Ib */ + tmp8s = Fetch8s(emu); + if(!(ACCESS_FLAG(F_ZF) || ACCESS_FLAG(F_CF))) + R_EIP += tmp8s; + break; case 0x7C: /* JL Ib */ tmp8s = Fetch8s(emu); if(ACCESS_FLAG(F_SF) != ACCESS_FLAG(F_OF)) @@ -326,6 +339,9 @@ int Run(x86emu_t *emu) GetG(emu, &op2, nextop); op2->dword[0] = (uint32_t)&op1->dword[0]; break; + + case 0x90: /* NOP */ + break; case 0xA1: /* MOV EAX, Od */ R_EAX = *(uint32_t*)Fetch32(emu); diff --git a/tests/ref06.txt b/tests/ref06.txt new file mode 100755 index 00000000..8fca60ff --- /dev/null +++ b/tests/ref06.txt @@ -0,0 +1,4 @@ +[02] Second thread executing +[02] Thread done. + +[00] Done. diff --git a/tests/test06 b/tests/test06 new file mode 100755 index 00000000..46e3858d Binary files /dev/null and b/tests/test06 differ diff --git a/tests/test06.c b/tests/test06.c new file mode 100755 index 00000000..5a2e0ba0 --- /dev/null +++ b/tests/test06.c @@ -0,0 +1,55 @@ +#include +#include +#include +#include + +const int thread_count = 2; +pthread_t tid[2]; +const char *thread_messages[2] = { + "First thread executing", + "Second thread executing" +}; + +void *doSomething(void *arg) +{ + pthread_t id = pthread_self(); + int num = -1; + + for (int i = 0 ; i < thread_count ; ++i) + { + if (pthread_equal(id, tid[i])) + { + num = i + 1; + if (num == 2) printf("[%02d] %s\n", num, thread_messages[i]); + break; + } + } + + for (unsigned int i = 0 ; i < 0x10000 ; ++i); + if (num == 2) printf("[%02d] Thread done.\n", num); + + return NULL; +} + +int main(int argc, char const *argv[]) +{ + int err; + + for (int i = 0 ; i < thread_count ; ++i) + { + //printf("[00] Thread %d starting\n", i + 1); + err = pthread_create(&tid[i], NULL, doSomething, NULL); + if (err) + { + printf("[00] Couldn't create thread %d: %s\n", i + 1, strerror(err)); + } + for (unsigned int i = 0 ; i < 0x1000 ; ++i); + } + + //printf("[00] Waiting for all threads to end...\n"); + for (int i = 0 ; i < thread_count ; ++i) + pthread_join(tid[i], NULL); + printf("\n[00] Done.\n"); + + return 0; +}