diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2021-07-12 13:43:00 -0500 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2021-07-12 13:43:00 -0500 |
| commit | a66bb7453b335975ae0f55a96e3f9665139d8024 (patch) | |
| tree | 55d579ac559eb10542e20e514fc7660d461d8df6 /src | |
| parent | 5406a040fbf51bec372612a147aea1f80acf97be (diff) | |
| download | box64-a66bb7453b335975ae0f55a96e3f9665139d8024.tar.gz box64-a66bb7453b335975ae0f55a96e3f9665139d8024.zip | |
Use box86 to launch x86 binary (if box86 is present in same folder as box64)
Diffstat (limited to 'src')
| -rwxr-xr-x | src/include/box64context.h | 1 | ||||
| -rwxr-xr-x | src/include/fileutils.h | 1 | ||||
| -rwxr-xr-x | src/main.c | 25 | ||||
| -rwxr-xr-x | src/tools/fileutils.c | 18 | ||||
| -rwxr-xr-x | src/wrapped/wrappedlibc.c | 58 |
5 files changed, 74 insertions, 29 deletions
diff --git a/src/include/box64context.h b/src/include/box64context.h index 0f99d1fe..1fe43d84 100755 --- a/src/include/box64context.h +++ b/src/include/box64context.h @@ -82,6 +82,7 @@ typedef struct box64context_s { char* fullpath; char* box64path; // path of current box64 executable + char* box86path; // path of box86 executable (if present) uint64_t stacksz; size_t stackalign; diff --git a/src/include/fileutils.h b/src/include/fileutils.h index 546ec9d9..8332681e 100755 --- a/src/include/fileutils.h +++ b/src/include/fileutils.h @@ -14,6 +14,7 @@ int FileExist(const char* filename, int flags); char* ResolveFile(const char* filename, path_collection_t* paths); // 1: if file is an x86 elf, 0: if not (or not found) +int FileIsX86ELF(const char* filename); int FileIsX64ELF(const char* filename); #if defined(RPI) || defined(RK3399) || defined(RK3326) diff --git a/src/main.c b/src/main.c index 266fa96b..10a505c7 100755 --- a/src/main.c +++ b/src/main.c @@ -817,7 +817,16 @@ int main(int argc, const char **argv, const char **env) { my_context->argv[0] = strdup(prog); else my_context->argv[0] = ResolveFile(prog, &my_context->box64_path); - + // check if box86 is present + { + my_context->box86path = strdup(my_context->box64path); + char* p = strrchr(my_context->box86path, '6'); // get the 8 of box86 + p[0] = '8'; p[1] = '6'; // change 64 to 86 + if(!FileExist(my_context->box86path, IS_FILE)) { + free(my_context->box86path); + my_context->box86path = NULL; + } + } const char* prgname = strrchr(prog, '/'); if(!prgname) prgname = prog; @@ -894,12 +903,22 @@ int main(int argc, const char **argv, const char **env) { } elfheader_t *elf_header = LoadAndCheckElfHeader(f, my_context->argv[0], 1); if(!elf_header) { - printf_log(LOG_NONE, "Error: reading elf header of %s, try to launch natively instead\n", my_context->argv[0]); + int x86 = my_context->box86path?FileIsX86ELF(my_context->argv[0]):0; + printf_log(LOG_NONE, "Error: reading elf header of %s, try to launch %s instead\n", my_context->argv[0], x86?"using box86":"natively"); fclose(f); free_contextargv(); FreeBox64Context(&my_context); FreeCollection(&ld_preload); - return execvp(argv[1], (char * const*)(argv+1)); + if(x86) { + // duplicate the array to change 1st arg as box86 + const char** newargv = (const char**)calloc(argc+1, sizeof(char*)); + newargv[0] = my_context->box86path; + for(int i=1; i<argc; ++i) + newargv[i] = argv[i]; + return execvp(newargv[0], (char * const*)newargv); + } else + return execvp(argv[1], (char * const*)(argv+1)); + printf_log(LOG_NONE, "Failed to execvp: error is %s\n", strerror(errno)); } AddElfHeader(my_context, elf_header); diff --git a/src/tools/fileutils.c b/src/tools/fileutils.c index 18b8dc4d..fa57cd69 100755 --- a/src/tools/fileutils.c +++ b/src/tools/fileutils.c @@ -15,6 +15,7 @@ #include "debug.h" #include "fileutils.h" +static const char* x86sign = "\x7f" "ELF" "\x01" "\x01" "\x01" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x02" "\x00" "\x03" "\x00"; static const char* x64sign = "\x7f" "ELF" "\x02" "\x01" "\x01" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x02" "\x00" "\x3e" "\x00"; int FileExist(const char* filename, int flags) @@ -77,6 +78,23 @@ int FileIsX64ELF(const char* filename) return 0; } +int FileIsX86ELF(const char* filename) +{ + FILE *f = fopen(filename, "rb"); + if(!f) + return 0; + char head[sizeof(*x86sign)] = {0}; + int sz = fread(head, sizeof(*x86sign), 1, f); + if(sz!=1) { + fclose(f); + return 0; + } + fclose(f); + if(memcmp(head, x86sign, sizeof(*x86sign))==0) + return 1; + return 0; +} + #if defined(RPI) || defined(RK3399) || defined(RK3326) void sanitize_mojosetup_gtk_background() { diff --git a/src/wrapped/wrappedlibc.c b/src/wrapped/wrappedlibc.c index b4bfe2d1..c11a27e3 100755 --- a/src/wrapped/wrappedlibc.c +++ b/src/wrapped/wrappedlibc.c @@ -1539,10 +1539,11 @@ EXPORT int32_t my_nftw64(x64emu_t* emu, void* pathname, void* B, int32_t nopenfd EXPORT int32_t my_execv(x64emu_t* emu, const char* path, char* const argv[]) { int self = isProcSelf(path, "exe"); - int x86 = FileIsX64ELF(path); - printf_log(LOG_DEBUG, "execv(\"%s\", %p) is x86=%d\n", path, argv, x86); + int x64 = FileIsX64ELF(path); + int x86 = my_context->box86path?FileIsX86ELF(path):0; + printf_log(LOG_DEBUG, "execv(\"%s\", %p) is x64=%d\n", path, argv, x64); #if 1 - if (x86 || self) { + if (x64 || x86 || self) { int skip_first = 0; if(strlen(path)>=strlen("wine64-preloader") && strcmp(path+strlen(path)-strlen("wine64-preloader"), "wine64-preloader")==0) skip_first++; @@ -1550,7 +1551,7 @@ EXPORT int32_t my_execv(x64emu_t* emu, const char* path, char* const argv[]) int n=skip_first; while(argv[n]) ++n; const char** newargv = (const char**)calloc(n+2, sizeof(char*)); - newargv[0] = emu->context->box64path; + newargv[0] = x86?emu->context->box86path:emu->context->box64path; memcpy(newargv+1, argv+skip_first, sizeof(char*)*(n+1)); if(self) newargv[1] = emu->context->fullpath; printf_log(LOG_DEBUG, " => execv(\"%s\", %p [\"%s\", \"%s\", \"%s\"...:%d])\n", emu->context->box64path, newargv, newargv[0], n?newargv[1]:"", (n>1)?newargv[2]:"",n); @@ -1565,10 +1566,11 @@ EXPORT int32_t my_execv(x64emu_t* emu, const char* path, char* const argv[]) EXPORT int32_t my_execve(x64emu_t* emu, const char* path, char* const argv[], char* const envp[]) { int self = isProcSelf(path, "exe"); - int x86 = FileIsX64ELF(path); - printf_log(LOG_DEBUG, "execv(\"%s\", %p) is x86=%d\n", path, argv, x86); + int x64 = FileIsX64ELF(path); + int x86 = my_context->box86path?FileIsX86ELF(path):0; + printf_log(LOG_DEBUG, "execv(\"%s\", %p) is x64=%d\n", path, argv, x64); #if 1 - if (x86 || self) { + if (x64 || x86 || self) { int skip_first = 0; if(strlen(path)>=strlen("wine64-preloader") && strcmp(path+strlen(path)-strlen("wine64-preloader"), "wine64-preloader")==0) skip_first++; @@ -1576,7 +1578,7 @@ EXPORT int32_t my_execve(x64emu_t* emu, const char* path, char* const argv[], ch int n=skip_first; while(argv[n]) ++n; const char** newargv = (const char**)calloc(n+2, sizeof(char*)); - newargv[0] = emu->context->box64path; + newargv[0] = x86?emu->context->box86path:emu->context->box64path; memcpy(newargv+1, argv+skip_first, sizeof(char*)*(n+1)); if(self) newargv[1] = emu->context->fullpath; printf_log(LOG_DEBUG, " => execv(\"%s\", %p [\"%s\", \"%s\", \"%s\"...:%d])\n", emu->context->box64path, newargv, newargv[0], n?newargv[1]:"", (n>1)?newargv[2]:"",n); @@ -1597,15 +1599,16 @@ EXPORT int32_t my_execvp(x64emu_t* emu, const char* path, char* const argv[]) fullpath = strdup(path); // use fullpath... int self = isProcSelf(fullpath, "exe"); - int x86 = FileIsX64ELF(fullpath); - printf_log(LOG_DEBUG, "execvp(\"%s\", %p), IsX86=%d / fullpath=\"%s\"\n", path, argv, x86, fullpath); + int x64 = FileIsX64ELF(fullpath); + int x86 = my_context->box86path?FileIsX86ELF(path):0; + printf_log(LOG_DEBUG, "execvp(\"%s\", %p), IsX86=%d / fullpath=\"%s\"\n", path, argv, x64, fullpath); free(fullpath); - if (x86 || self) { + if (x64 || x86 || self) { // count argv... int i=0; while(argv[i]) ++i; char** newargv = (char**)calloc(i+2, sizeof(char*)); - newargv[0] = emu->context->box64path; + newargv[0] = x86?emu->context->box86path:emu->context->box64path; for (int j=0; j<i; ++j) newargv[j+1] = argv[j]; if(self) newargv[1] = emu->context->fullpath; @@ -1621,15 +1624,16 @@ EXPORT int32_t my_execvp(x64emu_t* emu, const char* path, char* const argv[]) EXPORT int32_t my_execl(x64emu_t* emu, const char* path) { int self = isProcSelf(path, "exe"); - int x86 = FileIsX64ELF(path); - printf_log(LOG_DEBUG, "execl(\"%s\", ...), IsX86=%d, self=%d\n", path, x86, self); + int x64 = FileIsX64ELF(path); + int x86 = my_context->box86path?FileIsX86ELF(path):0; + printf_log(LOG_DEBUG, "execl(\"%s\", ...), IsX86=%d, self=%d\n", path, x64, self); // count argv... int i=0; while(getVargN(emu, i+1)) ++i; - char** newargv = (char**)calloc(i+((x86 || self)?2:1), sizeof(char*)); + char** newargv = (char**)calloc(i+((x64 || self)?2:1), sizeof(char*)); int j=0; - if ((x86 || self)) - newargv[j++] = emu->context->box64path; + if ((x64 || x86 || self)) + newargv[j++] = x86?emu->context->box86path:emu->context->box64path; for (int k=0; k<i; ++k) newargv[j++] = getVargN(emu, k+1); if(self) newargv[1] = emu->context->fullpath; @@ -1647,16 +1651,17 @@ EXPORT int32_t my_execlp(x64emu_t* emu, const char* path) fullpath = strdup(path); // use fullpath... int self = isProcSelf(fullpath, "exe"); - int x86 = FileIsX64ELF(fullpath); - printf_log(LOG_DEBUG, "execlp(\"%s\", ...), IsX86=%d / fullpath=\"%s\"\n", path, x86, fullpath); + int x64 = FileIsX64ELF(fullpath); + int x86 = my_context->box86path?FileIsX86ELF(path):0; + printf_log(LOG_DEBUG, "execlp(\"%s\", ...), IsX86=%d / fullpath=\"%s\"\n", path, x64, fullpath); free(fullpath); // count argv... int i=0; while(getVargN(emu, i+1)) ++i; - char** newargv = (char**)calloc(i+((x86 || self)?2:1), sizeof(char*)); + char** newargv = (char**)calloc(i+((x64 || self)?2:1), sizeof(char*)); int j=0; - if ((x86 || self)) - newargv[j++] = emu->context->box64path; + if ((x64 || x86 || self)) + newargv[j++] = x86?emu->context->box86path:emu->context->box64path; for (int k=0; k<i; ++k) newargv[j++] = getVargN(emu, k+1); if(self) newargv[1] = emu->context->fullpath; @@ -1675,15 +1680,16 @@ EXPORT int32_t my_posix_spawnp(x64emu_t* emu, pid_t* pid, const char* path, char* fullpath = ResolveFile(path, &my_context->box64_path); // use fullpath... int self = isProcSelf(fullpath, "exe"); - int x86 = FileIsX64ELF(fullpath); - printf_log(LOG_DEBUG, "posix_spawnp(%p, \"%s\", %p, %p, %p, %p), IsX86=%d / fullpath=\"%s\"\n", pid, path, actions, attrp, argv, envp, x86, fullpath); + int x64 = FileIsX64ELF(fullpath); + int x86 = my_context->box86path?FileIsX86ELF(path):0; + printf_log(LOG_DEBUG, "posix_spawnp(%p, \"%s\", %p, %p, %p, %p), IsX86=%d / fullpath=\"%s\"\n", pid, path, actions, attrp, argv, envp, x64, fullpath); free(fullpath); - if ((x86 || self)) { + if (x64 || x86 || self) { // count argv... int i=0; while(argv[i]) ++i; char** newargv = (char**)calloc(i+2, sizeof(char*)); - newargv[0] = emu->context->box64path; + newargv[0] = x86?emu->context->box86path:emu->context->box64path; for (int j=0; j<i; ++j) newargv[j+1] = argv[j]; if(self) newargv[1] = emu->context->fullpath; |