#ifndef __BOX64CONTEXT_H_
#define __BOX64CONTEXT_H_
#include <stdint.h>
#include <pthread.h>
#include "pathcoll.h"
#include "dictionnary.h"
#ifdef DYNAREC
#include "dynarec/native_lock.h"
#endif
#ifdef DYNAREC
#endif
typedef struct elfheader_s elfheader_t;
typedef struct cleanup_s cleanup_t;
typedef struct x64emu_s x64emu_t;
typedef struct zydis_s zydis_t;
typedef struct zydis_dec_s zydis_dec_t;
typedef struct lib_s lib_t;
typedef struct bridge_s bridge_t;
typedef struct dlprivate_s dlprivate_t;
typedef struct kh_symbolmap_s kh_symbolmap_t;
typedef struct kh_defaultversion_s kh_defaultversion_t;
typedef struct kh_mapsymbols_s kh_mapsymbols_t;
typedef struct library_s library_t;
typedef struct linkmap_s linkmap_t;
typedef struct kh_threadstack_s kh_threadstack_t;
typedef struct rbtree rbtree;
typedef struct atfork_fnc_s {
uintptr_t prepare;
uintptr_t parent;
uintptr_t child;
void* handle;
} atfork_fnc_t;
#ifdef DYNAREC
typedef struct dynablock_s dynablock_t;
typedef struct mmaplist_s mmaplist_t;
typedef struct kh_dynablocks_s kh_dynablocks_t;
#endif
#define DYNAMAP_SHIFT 16
typedef void* (*procaddress_t)(const char* name);
typedef void* (*vkprocaddess_t)(void* instance, const char* name);
#define MAX_SIGNAL 64
typedef struct tlsdatasize_s {
int tlssize;
int n_elfs;
void* data;
void* ptr;
} tlsdatasize_t;
void free_tlsdatasize(void* p);
typedef struct needed_libs_s {
int cap;
int size;
int init_size;
char** names;
library_t** libs;
int nb_done;
} needed_libs_t;
void free_neededlib(needed_libs_t* needed);
needed_libs_t* new_neededlib(int n);
needed_libs_t* copy_neededlib(needed_libs_t* needed);
void add1_neededlib(needed_libs_t* needed);
void add1lib_neededlib(needed_libs_t* needed, library_t* lib, const char* name);
void add1lib_neededlib_name(needed_libs_t* needed, library_t* lib, const char* name);
void add1libref_neededlib(needed_libs_t* needed, library_t* lib);
typedef struct base_segment_s {
uintptr_t base;
uint64_t limit;
pthread_key_t key;
uint8_t present;
uint8_t is32bits;
uint8_t key_init;
} base_segment_t;
typedef struct box64context_s {
path_collection_t box64_path;
path_collection_t box64_ld_lib;
path_collection_t box64_emulated_libs;
int x64trace;
int trace_tid;
uint32_t sel_serial;
zydis_t *zydis;
void* box64lib;
int argc;
char** argv;
int envc;
char** envv;
int orig_argc;
char** orig_argv;
char* fullpath;
char* box64path;
char* box86path;
char* bashpath;
uint64_t stacksz;
size_t stackalign;
void* stack;
elfheader_t **elfs;
int elfcap;
int elfsize;
needed_libs_t *neededlibs;
needed_libs_t *preload;
uintptr_t ep;
lib_t *maplib;
lib_t *local_maplib;
dic_t *versym;
kh_mapsymbols_t *globdata;
kh_mapsymbols_t *uniques;
kh_threadstack_t *stacksizes;
bridge_t *system;
uintptr_t exit_bridge;
uintptr_t vsyscall;
uintptr_t vsyscalls[3];
dlprivate_t *dlprivate;
kh_symbolmap_t *alwrappers;
kh_symbolmap_t *almymap;
kh_symbolmap_t *vkwrappers;
kh_symbolmap_t *vkmymap;
vkprocaddess_t vkprocaddress;
#ifndef DYNAREC
pthread_mutex_t mutex_lock;
pthread_mutex_t mutex_trace;
pthread_mutex_t mutex_tls;
pthread_mutex_t mutex_thread;
pthread_mutex_t mutex_bridge;
#else
#ifdef USE_CUSTOM_MUTEX
uint32_t mutex_dyndump;
uint32_t mutex_trace;
uint32_t mutex_tls;
uint32_t mutex_thread;
uint32_t mutex_bridge;
#else
pthread_mutex_t mutex_dyndump;
pthread_mutex_t mutex_trace;
pthread_mutex_t mutex_tls;
pthread_mutex_t mutex_thread;
pthread_mutex_t mutex_bridge;
#endif
uintptr_t max_db_size;
rbtree* db_sizes;
int trace_dynarec;
pthread_mutex_t mutex_lock;
#if defined(__riscv) || defined(__loongarch64)
uint32_t mutex_16b;
#endif
#endif
library_t *libclib;
library_t *sdl1mixerlib;
library_t *sdl2lib;
library_t *sdl2mixerlib;
linkmap_t *linkmap;
void* sdl1allocrw;
void* sdl1freerw;
void* sdl2allocrw;
void* sdl2freerw;
int deferredInit;
elfheader_t **deferredInitList;
int deferredInitSz;
int deferredInitCap;
pthread_key_t tlskey;
void* tlsdata;
int64_t tlssize;
base_segment_t segtls[16];
uintptr_t *auxval_start;
cleanup_t *cleanups;
int clean_sz;
int clean_cap;
zydis_dec_t *dec;
zydis_dec_t *dec32;
int forked;
atfork_fnc_t *atforks;
int atfork_sz;
int atfork_cap;
uint8_t canary[8];
uintptr_t signals[MAX_SIGNAL+1];
uintptr_t restorer[MAX_SIGNAL+1];
int onstack[MAX_SIGNAL+1];
int is_sigaction[MAX_SIGNAL+1];
x64emu_t *emu_sig;
int no_sigsegv;
int no_sigill;
void* stack_clone;
int stack_clone_used;
char* *log_call;
char* *log_ret;
int current_line;
} box64context_t;
#ifndef USE_CUSTOM_MUTEX
#define mutex_lock(A) pthread_mutex_lock(A)
#define mutex_trylock(A) pthread_mutex_trylock(A)
#define mutex_unlock(A) pthread_mutex_unlock(A)
#else
int GetTID(void);
#define mutex_lock(A) {uint32_t tid = (uint32_t)GetTID(); while(native_lock_storeifnull_d(A, tid)) sched_yield();}
#define mutex_trylock(A) native_lock_storeifnull_d(A, (uint32_t)GetTID())
#define mutex_unlock(A) native_lock_storeifref_d(A, 0, (uint32_t)GetTID())
#endif
extern box64context_t *my_context;
box64context_t *NewBox64Context(int argc);
void FreeBox64Context(box64context_t** context);
void freeCycleLog(box64context_t* ctx);
void initCycleLog(box64context_t* context);
void print_cycle_log(int loglevel);
int AddElfHeader(box64context_t* ctx, elfheader_t* head);
void RemoveElfHeader(box64context_t* ctx, elfheader_t* head);
int AddTLSPartition(box64context_t* context, int tlssize);
void thread_set_emu(x64emu_t* emu);
x64emu_t* thread_get_emu(void);
int unlockMutex(void);
void relockMutex(int locks);
#endif