about summary refs log tree commit diff stats
path: root/src/include
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2021-03-03 16:43:42 +0100
committerptitSeb <sebastien.chev@gmail.com>2021-03-03 16:43:42 +0100
commitf4829a8ce42b1abbcc8621802d6c6fad3a56cd5d (patch)
tree211276c3587721126ded00be46487bf23b605591 /src/include
parentf73fbd3cee38b4c0086c934d73972375c9c8c7d6 (diff)
downloadbox64-f4829a8ce42b1abbcc8621802d6c6fad3a56cd5d.tar.gz
box64-f4829a8ce42b1abbcc8621802d6c6fad3a56cd5d.zip
More infrastructure added to elf and x64 emu
Diffstat (limited to 'src/include')
-rwxr-xr-xsrc/include/box64context.h92
-rwxr-xr-xsrc/include/callback.h12
-rwxr-xr-xsrc/include/dynarec.h8
-rwxr-xr-xsrc/include/elfloader.h70
-rwxr-xr-xsrc/include/librarian.h51
-rwxr-xr-xsrc/include/library.h36
-rwxr-xr-xsrc/include/wrappedlibs.h21
-rwxr-xr-xsrc/include/x64emu.h4
-rwxr-xr-xsrc/include/x64run.h10
-rwxr-xr-xsrc/include/x64tls.h13
10 files changed, 273 insertions, 44 deletions
diff --git a/src/include/box64context.h b/src/include/box64context.h
index 9eca567e..c9c25bf3 100755
--- a/src/include/box64context.h
+++ b/src/include/box64context.h
@@ -11,7 +11,22 @@ 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 library_s library_t;
 typedef struct kh_threadstack_s kh_threadstack_t;
+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 dynablocklist_s  dynablocklist_t;
+typedef struct mmaplist_s       mmaplist_t;
+typedef struct kh_dynablocks_s  kh_dynablocks_t;
+#endif
 
 typedef void* (*procaddess_t)(const char* name);
 typedef void* (*vkprocaddess_t)(void* instance, const char* name);
@@ -25,6 +40,22 @@ typedef struct tlsdatasize_s {
 
 void free_tlsdatasize(void* p);
 
+typedef struct needed_libs_s {
+    int         cap;
+    int         size;
+    library_t   **libs;
+} needed_libs_t;
+
+void add_neededlib(needed_libs_t* needed, library_t* lib);
+void free_neededlib(needed_libs_t* needed);
+
+typedef struct base_segment_s {
+    uintptr_t       base;
+    uint64_t        limit;
+    int             present;
+    pthread_key_t   key;
+} base_segment_t;
+
 typedef struct box64context_s {
     path_collection_t   box64_path;     // PATH env. variable
     path_collection_t   box64_ld_lib;   // LD_LIBRARY_PATH env. variable
@@ -56,7 +87,8 @@ typedef struct box64context_s {
     int                 elfcap;
     int                 elfsize;        // number of elf loaded
 
-    int                 deferedInit;
+
+    needed_libs_t       neededlibs;     // needed libs for main elf
 
     uintptr_t           ep;             // entry point
 
@@ -66,12 +98,62 @@ typedef struct box64context_s {
     kh_threadstack_t    *stacksizes;    // stack sizes attributes for thread (temporary)
     bridge_t            *system;        // other bridges
     uintptr_t           vsyscall;       // vsyscall bridge value
-
+    dlprivate_t         *dlprivate;     // dlopen library map
+    kh_symbolmap_t      *glwrappers;    // the map of wrapper for glProcs (for GLX or SDL1/2)
+    kh_symbolmap_t      *glmymap;       // link to the mysymbolmap of libGL
+    procaddess_t        glxprocaddress;
+    kh_symbolmap_t      *alwrappers;    // the map of wrapper for alGetProcAddress
+    kh_symbolmap_t      *almymap;       // link to the mysymbolmap if libOpenAL
+    kh_symbolmap_t      *vkwrappers;    // the map of wrapper for VulkanProcs (TODO: check SDL2)
+    kh_symbolmap_t      *vkmymap;       // link to the mysymbolmap of libGL
+    vkprocaddess_t      vkprocaddress;
+
+    pthread_mutex_t     mutex_once;
+    pthread_mutex_t     mutex_once2;
+    pthread_mutex_t     mutex_trace;
+    #ifndef DYNAREC
+    pthread_mutex_t     mutex_lock;     // dynarec build will use their own mecanism
+    #else
+    pthread_mutex_t     mutex_dyndump;
+    int                 trace_dynarec;
+    #endif
+    pthread_mutex_t     mutex_tls;
     pthread_mutex_t     mutex_thread;
 
+    library_t           *libclib;       // shortcut to libc library (if loaded, so probably yes)
+    library_t           *sdl1lib;       // shortcut to SDL1 library (if loaded)
+    void*               sdl1allocrw;
+    void*               sdl1freerw;
+    library_t           *sdl1mixerlib;
+    library_t           *sdl2lib;       // shortcut to SDL2 library (if loaded)
+    void*               sdl2allocrw;
+    void*               sdl2freerw;
+    library_t           *sdl2mixerlib;
+    library_t           *x11lib;
+    library_t           *libxcb;
+    library_t           *libxcbxfixes;
+    library_t           *libxcbshape;
+    library_t           *libxcbshm;
+    library_t           *libxcbrandr;
+    library_t           *libxcbimage;
+    library_t           *libxcbkeysyms;
+    library_t           *libxcbxtest;
+    library_t           *zlib;
+    library_t           *vorbisfile;
+    library_t           *vorbis;
+    library_t           *asound;
+    library_t           *pulse;
+    library_t           *d3dadapter9;
+
+    int                 deferedInit;
+    elfheader_t         **deferedInitList;
+    int                 deferedInitSz;
+    int                 deferedInitCap;
+
     pthread_key_t       tlskey;     // then tls key to have actual tlsdata
     void*               tlsdata;    // the initial global tlsdata
     int32_t             tlssize;    // wanted size of tlsdata
+    base_segment_t      segtls[3];  // only handling 0/1/2 descriptors
 
     uintptr_t           *auxval_start;
 
@@ -81,6 +163,12 @@ typedef struct box64context_s {
 
     zydis_dec_t         *dec;           // trace
 
+    int                 forked;         //  how many forks... cleanup only when < 0
+
+    atfork_fnc_t        *atforks;       // fnc for atfork...
+    int                 atfork_sz;
+    int                 atfork_cap;
+
     uint8_t             canary[4];
 
     uintptr_t           signals[MAX_SIGNAL];
diff --git a/src/include/callback.h b/src/include/callback.h
new file mode 100755
index 00000000..b9482fc1
--- /dev/null
+++ b/src/include/callback.h
@@ -0,0 +1,12 @@
+#ifndef __CALLBACK_H__
+#define __CALLBACK_H__
+
+#include <stdint.h>
+
+typedef struct x64emu_s x64emu_t;
+
+uint64_t RunFunction(box64context_t *context, uintptr_t fnc, int nargs, ...);
+// use emu state to run function
+uint64_t RunFunctionWithEmu(x64emu_t *emu, int QuitOnLongJump, uintptr_t fnc, int nargs, ...);
+
+#endif //__CALLBACK_H__
\ No newline at end of file
diff --git a/src/include/dynarec.h b/src/include/dynarec.h
new file mode 100755
index 00000000..a68c6d6a
--- /dev/null
+++ b/src/include/dynarec.h
@@ -0,0 +1,8 @@
+#ifndef __DYNAREC_H_
+#define __DYNAREC_H_
+
+typedef struct x64emu_s x64emu_t;
+
+void DynaCall(x64emu_t* emu, uintptr_t addr); // try to use DynaRec... Fallback to EmuCall if no dynarec available
+
+#endif // __DYNAREC_H_
\ No newline at end of file
diff --git a/src/include/elfloader.h b/src/include/elfloader.h
index 28ce4844..a4d2cb6b 100755
--- a/src/include/elfloader.h
+++ b/src/include/elfloader.h
@@ -3,20 +3,20 @@
 #include <stdio.h>
 
 typedef struct elfheader_s elfheader_t;
-//typedef struct lib_s lib_t;
-//typedef struct library_s library_t;
-//typedef struct kh_mapsymbols_s kh_mapsymbols_t;
+typedef struct lib_s lib_t;
+typedef struct library_s library_t;
+typedef struct kh_mapsymbols_s kh_mapsymbols_t;
 typedef struct box64context_s box64context_t;
-//typedef struct x86emu_s x86emu_t;
-//typedef struct needed_libs_s needed_libs_t;
-//#ifdef DYNAREC
-//typedef struct dynablocklist_s dynablocklist_t;
-//#endif
+typedef struct x64emu_s x64emu_t;
+typedef struct needed_libs_s needed_libs_t;
+#ifdef DYNAREC
+typedef struct dynablocklist_s dynablocklist_t;
+#endif
 
 elfheader_t* LoadAndCheckElfHeader(FILE* f, const char* name, int exec); // exec : 0 = lib, 1 = exec
 void FreeElfHeader(elfheader_t** head);
 const char* ElfName(elfheader_t* head);
-//void ElfAttachLib(elfheader_t* head, library_t* lib);
+void ElfAttachLib(elfheader_t* head, library_t* lib);
 
 // return 0 if OK
 int CalcLoadAddr(elfheader_t* head);
@@ -24,34 +24,34 @@ int AllocElfMemory(box64context_t* context, elfheader_t* head, int mainbin);
 void FreeElfMemory(elfheader_t* head);
 int LoadElfMemory(FILE* f, box64context_t* context, elfheader_t* head);
 int ReloadElfMemory(FILE* f, box64context_t* context, elfheader_t* head);
-//int RelocateElf(lib_t *maplib, lib_t* local_maplib, elfheader_t* head);
-//int RelocateElfPlt(lib_t *maplib, lib_t* local_maplib, elfheader_t* head);
+int RelocateElf(lib_t *maplib, lib_t* local_maplib, elfheader_t* head);
+int RelocateElfPlt(lib_t *maplib, lib_t* local_maplib, elfheader_t* head);
 void CalcStack(elfheader_t* h, uint32_t* stacksz, int* stackalign);
-//uintptr_t GetEntryPoint(lib_t* maplib, elfheader_t* h);
+uintptr_t GetEntryPoint(lib_t* maplib, elfheader_t* h);
 uintptr_t GetLastByte(elfheader_t* h);
-//void AddSymbols(lib_t *maplib, kh_mapsymbols_t* mapsymbols, kh_mapsymbols_t* weaksymbols, kh_mapsymbols_t* localsymbols, elfheader_t* h);
-//int LoadNeededLibs(elfheader_t* h, lib_t *maplib, needed_libs_t* neededlibs, int local, box64context_t *box86, x86emu_t* emu);
-//uintptr_t GetElfInit(elfheader_t* h);
-//uintptr_t GetElfFini(elfheader_t* h);
-//void RunElfInit(elfheader_t* h, x86emu_t *emu);
-//void RunElfFini(elfheader_t* h, x86emu_t *emu);
-//void RunDeferedElfInit(x86emu_t *emu);
-//void* GetBaseAddress(elfheader_t* h);
-//void* GetElfDelta(elfheader_t* h);
-//uint32_t GetBaseSize(elfheader_t* h);
-//int IsAddressInElfSpace(elfheader_t* h, uintptr_t addr);
-//elfheader_t* FindElfAddress(box64context_t *context, uintptr_t addr);
-//const char* FindNearestSymbolName(elfheader_t* h, void* p, uintptr_t* start, uint32_t* sz);
-//int32_t GetTLSBase(elfheader_t* h);
-//uint32_t GetTLSSize(elfheader_t* h);
-//void* GetTLSPointer(box64context_t* context, elfheader_t* h);
-//void* GetDTatOffset(box64context_t* context, int index, int offset);
-//#ifdef DYNAREC
-//dynablocklist_t* GetDynablocksFromAddress(box64context_t *context, uintptr_t addr);
-//dynablocklist_t* GetDynablocksFromElf(elfheader_t* h);
-//#endif
-//void ResetSpecialCaseMainElf(elfheader_t* h);
-//void CreateMemorymapFile(box64context_t* context, int fd);
+void AddSymbols(lib_t *maplib, kh_mapsymbols_t* mapsymbols, kh_mapsymbols_t* weaksymbols, kh_mapsymbols_t* localsymbols, elfheader_t* h);
+int LoadNeededLibs(elfheader_t* h, lib_t *maplib, needed_libs_t* neededlibs, int local, box64context_t *box86, x64emu_t* emu);
+uintptr_t GetElfInit(elfheader_t* h);
+uintptr_t GetElfFini(elfheader_t* h);
+void RunElfInit(elfheader_t* h, x64emu_t *emu);
+void RunElfFini(elfheader_t* h, x64emu_t *emu);
+void RunDeferedElfInit(x64emu_t *emu);
+void* GetBaseAddress(elfheader_t* h);
+void* GetElfDelta(elfheader_t* h);
+uint32_t GetBaseSize(elfheader_t* h);
+int IsAddressInElfSpace(elfheader_t* h, uintptr_t addr);
+elfheader_t* FindElfAddress(box64context_t *context, uintptr_t addr);
+const char* FindNearestSymbolName(elfheader_t* h, void* p, uintptr_t* start, uint32_t* sz);
+int32_t GetTLSBase(elfheader_t* h);
+uint32_t GetTLSSize(elfheader_t* h);
+void* GetTLSPointer(box64context_t* context, elfheader_t* h);
+void* GetDTatOffset(box64context_t* context, int index, int offset);
+#ifdef DYNAREC
+dynablocklist_t* GetDynablocksFromAddress(box64context_t *context, uintptr_t addr);
+dynablocklist_t* GetDynablocksFromElf(elfheader_t* h);
+#endif
+void ResetSpecialCaseMainElf(elfheader_t* h);
+void CreateMemorymapFile(box64context_t* context, int fd);
 
 int ElfCheckIfUseTCMallocMinimal(elfheader_t* h);   // return 1 if tcmalloc is used
 
diff --git a/src/include/librarian.h b/src/include/librarian.h
new file mode 100755
index 00000000..a25fcd7b
--- /dev/null
+++ b/src/include/librarian.h
@@ -0,0 +1,51 @@
+#ifndef __LIBRARIAN_H_
+#define __LIBRARIAN_H_
+#include <stdint.h>
+
+typedef struct lib_s lib_t;
+typedef struct bridge_s bridge_t;
+typedef struct library_s library_t;
+typedef struct kh_mapsymbols_s kh_mapsymbols_t;
+typedef struct dlprivate_s dlprivate_t;
+typedef struct box64context_s  box64context_t;
+typedef struct x64emu_s x64emu_t;
+typedef struct elfheader_s elfheader_t;
+typedef struct needed_libs_s needed_libs_t;
+typedef struct kh_mapoffsets_s kh_mapoffsets_t;
+typedef char* cstr_t;
+
+lib_t *NewLibrarian(box64context_t* context, int ownlibs);
+void FreeLibrarian(lib_t **maplib);
+dlprivate_t *NewDLPrivate();
+void FreeDLPrivate(dlprivate_t **lib);
+
+box64context_t* GetLibrarianContext(lib_t* maplib);
+kh_mapsymbols_t* GetMapSymbol(lib_t* maplib);
+kh_mapsymbols_t* GetWeakSymbol(lib_t* maplib);
+kh_mapsymbols_t* GetLocalSymbol(lib_t* maplib);
+kh_mapsymbols_t* GetGlobalData(lib_t* maplib);
+int AddNeededLib(lib_t* maplib, needed_libs_t* neededlibs, int local, const char* path, box64context_t* box86, x64emu_t* emu); // 0=success, 1=error
+library_t* GetLibMapLib(lib_t* maplib, const char* name);
+library_t* GetLibInternal(const char* name);
+uintptr_t FindGlobalSymbol(lib_t *maplib, const char* name);
+int GetNoSelfSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, elfheader_t* self);
+int GetSelfSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, elfheader_t *self);
+int GetGlobalSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end);
+int GetGlobalNoWeakSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end);
+int GetLocalSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, elfheader_t *self);
+int GetNoWeakSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, elfheader_t *self);
+elfheader_t* GetGlobalSymbolElf(lib_t *maplib, const char* name);
+int IsGlobalNoWeakSymbolInNative(lib_t *maplib, const char* name);
+
+void AddSymbol(kh_mapsymbols_t *mapsymbols, const char* name, uintptr_t addr, uint32_t sz); // replace if already there
+uintptr_t FindSymbol(kh_mapsymbols_t *mapsymbols, const char* name);
+void AddWeakSymbol(kh_mapsymbols_t *mapsymbols, const char* name, uintptr_t addr, uint32_t sz); // don't add if already there
+int GetSymbolStartEnd(kh_mapsymbols_t* mapsymbols, const char* name, uintptr_t* start, uintptr_t* end);
+const char* GetSymbolName(kh_mapsymbols_t* mapsymbols, void* p, uintptr_t* offs, uint32_t* sz);
+
+const char* FindSymbolName(lib_t *maplib, void* p, void** start, uint32_t* sz, const char** libname, void** base);
+
+void AddOffsetSymbol(lib_t *maplib, void* offs, const char* name);
+const char* GetNameOffset(lib_t *maplib, void* offs);
+
+#endif //__LIBRARIAN_H_
\ No newline at end of file
diff --git a/src/include/library.h b/src/include/library.h
new file mode 100755
index 00000000..d33b1126
--- /dev/null
+++ b/src/include/library.h
@@ -0,0 +1,36 @@
+#ifndef __LIBRARY_H_
+#define __LIBRARY_H_
+#include <stdint.h>
+
+typedef struct library_s       library_t;
+typedef struct lib_s           lib_t;
+typedef struct kh_symbolmap_s  kh_symbolmap_t;
+typedef struct box64context_s  box64context_t;
+typedef struct x64emu_s        x64emu_t;
+typedef struct needed_libs_s   needed_libs_t;
+
+library_t *NewLibrary(const char* path, box64context_t* box86);
+int AddSymbolsLibrary(lib_t* maplib, library_t* lib, x64emu_t* emu);
+int FinalizeLibrary(library_t* lib, lib_t* local_maplib, x64emu_t* emu);
+int ReloadLibrary(library_t* lib, x64emu_t* emu);
+void InactiveLibrary(library_t* lib);
+void Free1Library(library_t **lib);
+
+char* GetNameLib(library_t *lib);
+int IsSameLib(library_t* lib, const char* path);    // check if lib is same (path -> name)
+int GetLibSymbolStartEnd(library_t* lib, const char* name, uintptr_t* start, uintptr_t* end);
+int GetLibNoWeakSymbolStartEnd(library_t* lib, const char* name, uintptr_t* start, uintptr_t* end);
+int GetLibLocalSymbolStartEnd(library_t* lib, const char* name, uintptr_t* start, uintptr_t* end);
+void fillGLProcWrapper(box64context_t* context);
+void freeGLProcWrapper(box64context_t* context);
+void fillALProcWrapper(box64context_t* context);
+void freeALProcWrapper(box64context_t* context);
+needed_libs_t* GetNeededLibs(library_t* lib);
+int GetNeededLibN(library_t* lib);
+library_t* GetNeededLib(library_t* lib, int idx);
+lib_t* GetMaplib(library_t* lib);
+
+int GetElfIndex(library_t* lib);    // -1 if no elf (i.e. native)
+void* GetHandle(library_t* lib);    // NULL if not native
+
+#endif //__LIBRARY_H_
\ No newline at end of file
diff --git a/src/include/wrappedlibs.h b/src/include/wrappedlibs.h
new file mode 100755
index 00000000..d8cf3a64
--- /dev/null
+++ b/src/include/wrappedlibs.h
@@ -0,0 +1,21 @@
+#ifndef __WRAPPEDLIBS_H__
+#define __WRAPPEDLIBS_H__
+#include <stdint.h>
+
+typedef struct library_s library_t;
+typedef struct box64context_s  box64context_t;
+
+typedef int (*wrappedlib_init_t)(library_t * lib, box64context_t* box64);  // 0 = success
+typedef void (*wrappedlib_fini_t)(library_t * lib);
+typedef int (*wrappedlib_get_t)(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz);
+
+typedef struct wrappedlib_s {
+    const char*         name;
+    wrappedlib_init_t   init;
+    wrappedlib_fini_t   fini;
+    wrappedlib_get_t    get;
+    wrappedlib_get_t    getnoweak;
+    wrappedlib_get_t    getlocal;
+} wrappedlib_t;
+
+#endif //__WRAPPEDLIBS_H__
\ No newline at end of file
diff --git a/src/include/x64emu.h b/src/include/x64emu.h
index ff19339b..f0ad24dd 100755
--- a/src/include/x64emu.h
+++ b/src/include/x64emu.h
@@ -42,8 +42,8 @@ void ResetSegmentsCache(x64emu_t *emu);
 const char* DumpCPURegs(x64emu_t* emu, uintptr_t ip);
 
 void StopEmu(x64emu_t* emu, const char* reason);
-//void PushExit(x64emu_t* emu);
-//void* GetExit();
+void PushExit(x64emu_t* emu);
+void* GetExit();
 void EmuCall(x64emu_t* emu, uintptr_t addr);
 void AddCleanup(x64emu_t *emu, void *p);
 void AddCleanup1Arg(x64emu_t *emu, void *p, void* a);
diff --git a/src/include/x64run.h b/src/include/x64run.h
index 6b7333f7..78903bbc 100755
--- a/src/include/x64run.h
+++ b/src/include/x64run.h
@@ -3,12 +3,12 @@
 #include <stdint.h>
 
 typedef struct x64emu_s x64emu_t;
-//int Run(x64emu_t *emu, int step); // 0 if run was successfull, 1 if error in x86 world
-//int DynaRun(x64emu_t *emu);
+int Run(x64emu_t *emu, int step); // 0 if run was successfull, 1 if error in x86 world
+int DynaRun(x64emu_t *emu);
 
-//uint32_t LibSyscall(x64emu_t *emu);
-//void PltResolver(x64emu_t* emu);
-//extern uintptr_t pltResolver;
+uint32_t LibSyscall(x64emu_t *emu);
+void PltResolver(x64emu_t* emu);
+extern uintptr_t pltResolver;
 int GetTID();
 
 #endif //__X64RUN_H_
\ No newline at end of file
diff --git a/src/include/x64tls.h b/src/include/x64tls.h
new file mode 100755
index 00000000..61f58887
--- /dev/null
+++ b/src/include/x64tls.h
@@ -0,0 +1,13 @@
+#ifndef __X64_TLS_H__
+#define __X64_TLS_H__
+
+typedef struct thread_area_s thread_area_t;
+
+uint32_t my_set_thread_area(thread_area_t* td);
+uint32_t my_modify_ldt(x64emu_t* emu, int op, thread_area_t* td, int size);
+
+void* fillTLSData(box64context_t *context);
+void* resizeTLSData(box64context_t *context, void* oldptr);
+void* GetSegmentBase(uint32_t desc);
+
+#endif //__X64_TLS_H__
\ No newline at end of file