diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2021-03-02 10:47:22 +0100 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2021-03-02 10:47:22 +0100 |
| commit | 26201d7e705714cd8ecca3fa28f51e819f9eb520 (patch) | |
| tree | a53914e9b6b28285ed5ee1f22d7d2900f608faec /src | |
| parent | 542a2a0775e5fe2921ce7893a9c1d77915a87bc4 (diff) | |
| download | box64-26201d7e705714cd8ecca3fa28f51e819f9eb520.tar.gz box64-26201d7e705714cd8ecca3fa28f51e819f9eb520.zip | |
More elf loader and parsing and stack preparing
Diffstat (limited to 'src')
| -rwxr-xr-x | src/elfs/elfloader.c | 62 | ||||
| -rwxr-xr-x | src/include/box64stack.h | 17 | ||||
| -rwxr-xr-x | src/include/elfloader.h | 4 | ||||
| -rwxr-xr-x | src/main.c | 9 | ||||
| -rwxr-xr-x | src/tools/box64stack.c | 138 |
5 files changed, 197 insertions, 33 deletions
diff --git a/src/elfs/elfloader.c b/src/elfs/elfloader.c index f1d4cf39..c107ca6a 100755 --- a/src/elfs/elfloader.c +++ b/src/elfs/elfloader.c @@ -23,10 +23,10 @@ #include "box64context.h" //#include "library.h" //#include "x86emu.h" -//#include "box86stack.h" +//#include "box64stack.h" //#include "callback.h" //#include "dynarec.h" -//#include "box86stack.h" +//#include "box64stack.h" #include "custommem.h" #include "wine_tools.h" //#ifdef DYNAREC @@ -359,8 +359,8 @@ int FindR386COPYRel(elfheader_t* h, const char* name, uintptr_t *offs, uint32_t* return 0; int cnt = h->relsz / h->relent; for (int i=0; i<cnt; ++i) { - int t = ELF32_R_TYPE(rel[i].r_info); - Elf64_Sym *sym = &h->DynSym[ELF32_R_SYM(rel[i].r_info)]; + int t = ELF64_R_TYPE(rel[i].r_info); + Elf64_Sym *sym = &h->DynSym[ELF64_R_SYM(rel[i].r_info)]; const char* symname = SymName(h, sym); if(!strcmp(symname, name) && t==R_386_COPY) { *offs = sym->st_value + h->delta; @@ -374,9 +374,9 @@ int FindR386COPYRel(elfheader_t* h, const char* name, uintptr_t *offs, uint32_t* int RelocateElfREL(lib_t *maplib, lib_t *local_maplib, elfheader_t* head, int cnt, Elf64_Rel *rel) { for (int i=0; i<cnt; ++i) { - int t = ELF32_R_TYPE(rel[i].r_info); - Elf64_Sym *sym = &head->DynSym[ELF32_R_SYM(rel[i].r_info)]; - int bind = ELF32_ST_BIND(sym->st_info); + int t = ELF64_R_TYPE(rel[i].r_info); + Elf64_Sym *sym = &head->DynSym[ELF64_R_SYM(rel[i].r_info)]; + int bind = ELF64_ST_BIND(sym->st_info); const char* symname = SymName(head, sym); uint32_t ndx = sym->st_shndx; uint32_t *p = (uint32_t*)(rel[i].r_offset + head->delta); @@ -481,7 +481,7 @@ int RelocateElfREL(lib_t *maplib, lib_t *local_maplib, elfheader_t* head, int cn } printf_log(LOG_DUMP, "Apply %s R_386_COPY @%p with sym=%s, @%p size=%d (", (bind==STB_LOCAL)?"Local":"Global", p, symname, (void*)offs, sym->st_size); memmove(p, (void*)offs, sym->st_size); - if(LOG_DUMP<=box86_log) { + if(LOG_DUMP<=box64_log) { uint32_t*k = (uint32_t*)p; for (int i=0; i<((sym->st_size>128)?128:sym->st_size); i+=4, ++k) printf_log(LOG_DUMP, "%s0x%08X", i?" ":"", *k); @@ -574,7 +574,7 @@ int RelocateElfREL(lib_t *maplib, lib_t *local_maplib, elfheader_t* head, int cn } break; default: - printf_log(LOG_INFO, "Warning, don't know of to handle rel #%d %s (%p)\n", i, DumpRelType(ELF32_R_TYPE(rel[i].r_info)), p); + printf_log(LOG_INFO, "Warning, don't know of to handle rel #%d %s (%p)\n", i, DumpRelType(ELF64_R_TYPE(rel[i].r_info)), p); } } return 0; @@ -583,12 +583,12 @@ int RelocateElfREL(lib_t *maplib, lib_t *local_maplib, elfheader_t* head, int cn int RelocateElfRELA(lib_t *maplib, lib_t *local_maplib, elfheader_t* head, int cnt, Elf64_Rela *rela) { for (int i=0; i<cnt; ++i) { - Elf64_Sym *sym = &head->DynSym[ELF32_R_SYM(rela[i].r_info)]; + Elf64_Sym *sym = &head->DynSym[ELF64_R_SYM(rela[i].r_info)]; const char* symname = SymName(head, sym); uint32_t *p = (uint32_t*)(rela[i].r_offset + head->delta); uintptr_t offs = 0; uintptr_t end = 0; - switch(ELF32_R_TYPE(rela[i].r_info)) { + switch(ELF64_R_TYPE(rela[i].r_info)) { case R_386_NONE: case R_386_PC32: // can be ignored @@ -607,7 +607,7 @@ int RelocateElfRELA(lib_t *maplib, lib_t *local_maplib, elfheader_t* head, int c } break; default: - printf_log(LOG_INFO, "Warning, don't know of to handle rela #%d %s on %s\n", i, DumpRelType(ELF32_R_TYPE(rela[i].r_info)), symname); + printf_log(LOG_INFO, "Warning, don't know of to handle rela #%d %s on %s\n", i, DumpRelType(ELF64_R_TYPE(rela[i].r_info)), symname); } } return 0; @@ -663,7 +663,7 @@ int RelocateElfPlt(lib_t *maplib, lib_t *local_maplib, elfheader_t* head) return 0; } - +#endif void CalcStack(elfheader_t* elf, uint32_t* stacksz, int* stackalign) { if(*stacksz < elf->stacksz) @@ -676,7 +676,7 @@ Elf64_Sym* GetFunction(elfheader_t* h, const char* name) { // TODO: create a hash on named to avoid this loop for (int i=0; i<h->numSymTab; ++i) { - int type = ELF32_ST_TYPE(h->SymTab[i].st_info); + int type = ELF64_ST_TYPE(h->SymTab[i].st_info); if(/*h->SymTab[i].st_info == 18*/type==STT_FUNC) { // TODO: this "18" is probably defined somewhere const char * symname = h->StrTab+h->SymTab[i].st_name; if(strcmp(symname, name)==0) { @@ -690,7 +690,7 @@ Elf64_Sym* GetFunction(elfheader_t* h, const char* name) Elf64_Sym* GetElfObject(elfheader_t* h, const char* name) { for (int i=0; i<h->numSymTab; ++i) { - int type = ELF32_ST_TYPE(h->SymTab[i].st_info); + int type = ELF64_ST_TYPE(h->SymTab[i].st_info); if(/*h->SymTab[i].st_info == 16*/type==STT_OBJECT) { const char * symname = h->StrTab+h->SymTab[i].st_name; if(strcmp(symname, name)==0) { @@ -708,12 +708,12 @@ uintptr_t GetFunctionAddress(elfheader_t* h, const char* name) if(sym) return sym->st_value; return 0; } - +#if 0 uintptr_t GetEntryPoint(lib_t* maplib, elfheader_t* h) { uintptr_t ep = h->entrypoint + h->delta; printf_log(LOG_DEBUG, "Entry Point is %p\n", (void*)ep); - if(box86_log>=LOG_DUMP) { + if(box64_log>=LOG_DUMP) { printf_log(LOG_DUMP, "(short) Dump of Entry point\n"); int sz = 64; uintptr_t lastbyte = GetLastByte(h); @@ -727,7 +727,7 @@ uintptr_t GetEntryPoint(lib_t* maplib, elfheader_t* h) if(m) { ep = m; printf_log(LOG_DEBUG, "Using \"main\" as Entry Point @%p\n", ep); - if(box86_log>=LOG_DUMP) { + if(box64_log>=LOG_DUMP) { printf_log(LOG_DUMP, "(short) Dump of Entry point\n"); int sz = 64; uintptr_t lastbyte = GetLastByte(h); @@ -739,19 +739,19 @@ uintptr_t GetEntryPoint(lib_t* maplib, elfheader_t* h) */ return ep; } - +#endif uintptr_t GetLastByte(elfheader_t* h) { return (uintptr_t)h->memory/* + h->delta*/ + h->memsz; } - +#if 0 void AddSymbols(lib_t *maplib, kh_mapsymbols_t* mapsymbols, kh_mapsymbols_t* weaksymbols, kh_mapsymbols_t* localsymbols, elfheader_t* h) { printf_log(LOG_DUMP, "Will look for Symbol to add in SymTable(%d)\n", h->numSymTab); for (int i=0; i<h->numSymTab; ++i) { const char * symname = h->StrTab+h->SymTab[i].st_name; - int bind = ELF32_ST_BIND(h->SymTab[i].st_info); - int type = ELF32_ST_TYPE(h->SymTab[i].st_info); + int bind = ELF64_ST_BIND(h->SymTab[i].st_info); + int type = ELF64_ST_TYPE(h->SymTab[i].st_info); int vis = h->SymTab[i].st_other&0x3; if((type==STT_OBJECT || type==STT_FUNC || type==STT_COMMON || type==STT_TLS || type==STT_NOTYPE) && (vis==STV_DEFAULT || vis==STV_PROTECTED) && (h->SymTab[i].st_shndx!=0)) { @@ -774,8 +774,8 @@ void AddSymbols(lib_t *maplib, kh_mapsymbols_t* mapsymbols, kh_mapsymbols_t* wea printf_log(LOG_DUMP, "Will look for Symbol to add in DynSym (%d)\n", h->numDynSym); for (int i=0; i<h->numDynSym; ++i) { const char * symname = h->DynStr+h->DynSym[i].st_name; - int bind = ELF32_ST_BIND(h->DynSym[i].st_info); - int type = ELF32_ST_TYPE(h->DynSym[i].st_info); + int bind = ELF64_ST_BIND(h->DynSym[i].st_info); + int type = ELF64_ST_TYPE(h->DynSym[i].st_info); int vis = h->DynSym[i].st_other&0x3; //st_shndx==65521 means ABS value if((type==STT_OBJECT || type==STT_FUNC || type==STT_COMMON || type==STT_TLS || type==STT_NOTYPE) @@ -812,7 +812,7 @@ $PLATFORM – Expands to the processor type of the current machine (see the uname(1) man page description of the -i option). For more details of this token expansion, see “System Specific Shared Objects” */ -int LoadNeededLibs(elfheader_t* h, lib_t *maplib, needed_libs_t* neededlibs, int local, box64context_t *box86, x86emu_t* emu) +int LoadNeededLibs(elfheader_t* h, lib_t *maplib, needed_libs_t* neededlibs, int local, box64context_t *box64, x86emu_t* emu) { DumpDynamicRPath(h); // update RPATH first @@ -852,7 +852,7 @@ int LoadNeededLibs(elfheader_t* h, lib_t *maplib, needed_libs_t* neededlibs, int printf_log(LOG_INFO, "BOX86: Warning, RPATH with $ variable not supported yet (%s)\n", rpath); } else { printf_log(LOG_DEBUG, "Prepending path \"%s\" to BOX86_LD_LIBRARY_PATH\n", rpath); - PrependList(&box86->box86_ld_lib, rpath, 1); + PrependList(&box64->box64_ld_lib, rpath, 1); } if(rpath!=rpathref) free(rpath); @@ -866,7 +866,7 @@ int LoadNeededLibs(elfheader_t* h, lib_t *maplib, needed_libs_t* neededlibs, int if(h->Dynamic[i].d_tag==DT_NEEDED) { char *needed = h->DynStrTab+h->delta+h->Dynamic[i].d_un.d_val; // TODO: Add LD_LIBRARY_PATH and RPATH Handling - if(AddNeededLib(maplib, neededlibs, local, needed, box86, emu)) { + if(AddNeededLib(maplib, neededlibs, local, needed, box64, emu)) { printf_log(LOG_INFO, "Error loading needed lib: \"%s\"\n", needed); if(!allow_missing_libs) return 1; //error... @@ -1088,7 +1088,7 @@ dynablocklist_t* GetDynablocksFromAddress(box64context_t *context, uintptr_t add if(ret) { return ret; }*/ - if(box86_dynarec_forced) { + if(box64_dynarec_forced) { addDBFromAddressRange(addr, 1); return getDB(addr>>DYNAMAP_SHIFT); } @@ -1130,7 +1130,7 @@ static int my_dl_iterate_phdr_##A(struct dl_phdr_info* a, size_t b, void* c)\ { \ if(!a->dlpi_name) \ return 0; \ - if(!a->dlpi_name[0]) /*don't send informations about box86 itself*/ \ + if(!a->dlpi_name[0]) /*don't send informations about box64 itself*/ \ return 0; \ return RunFunction(my_context, my_dl_iterate_phdr_fct_##A, 3, a, b, c); \ } @@ -1245,8 +1245,8 @@ EXPORT void PltResolver(x86emu_t* emu) Elf64_Rel * rel = (Elf64_Rel *)(h->jmprel + h->delta + slot); - Elf64_Sym *sym = &h->DynSym[ELF32_R_SYM(rel->r_info)]; - int bind = ELF32_ST_BIND(sym->st_info); + Elf64_Sym *sym = &h->DynSym[ELF64_R_SYM(rel->r_info)]; + int bind = ELF64_ST_BIND(sym->st_info); const char* symname = SymName(h, sym); uint32_t *p = (uint32_t*)(rel->r_offset + h->delta); uintptr_t offs = 0; diff --git a/src/include/box64stack.h b/src/include/box64stack.h new file mode 100755 index 00000000..a6b00fea --- /dev/null +++ b/src/include/box64stack.h @@ -0,0 +1,17 @@ +#ifndef __BOX64_STACK_H_ +#define __BOX64_STACK_H_ + +#include <stdint.h> + +typedef struct box64context_s box64context_t; +//typedef struct x64emu_s x64emu_t; + +int CalcStackSize(box64context_t *context); +//void SetupInitialStack(x64emu_t *emu); + +//uint16_t Pop16(x64emu_t *emu); +//void Push16(x64emu_t *emu, uint16_t v); +//uint32_t Pop32(x64emu_t *emu); +//void Push32(x64emu_t *emu, uint32_t v); + +#endif //__BOX64_STACK_H_ \ No newline at end of file diff --git a/src/include/elfloader.h b/src/include/elfloader.h index 2046865d..28ce4844 100755 --- a/src/include/elfloader.h +++ b/src/include/elfloader.h @@ -26,9 +26,9 @@ 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); -//void CalcStack(elfheader_t* h, uint32_t* stacksz, int* stackalign); +void CalcStack(elfheader_t* h, uint32_t* stacksz, int* stackalign); //uintptr_t GetEntryPoint(lib_t* maplib, elfheader_t* h); -//uintptr_t GetLastByte(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); diff --git a/src/main.c b/src/main.c index 90f513fd..4d5b7fe8 100755 --- a/src/main.c +++ b/src/main.c @@ -16,6 +16,7 @@ #include "wine_tools.h" #include "elfloader.h" #include "custommem.h" +#include "box64stack.h" box64context_t *my_context = NULL; int box64_log = LOG_NONE; @@ -807,6 +808,14 @@ int main(int argc, const char **argv, const char **env) { printf_log(LOG_INFO, "BOX86: Using tcmalloc_minimal.so.4, and it's in the LD_PRELOAD command\n"); } } + // get and alloc stack size and align + if(CalcStackSize(my_context)) { + printf_log(LOG_NONE, "Error: allocating stack\n"); + free_contextargv(); + FreeBox64Context(&my_context); + FreeCollection(&ld_preload); + return -1; + } return 0; } diff --git a/src/tools/box64stack.c b/src/tools/box64stack.c new file mode 100755 index 00000000..12be1b7d --- /dev/null +++ b/src/tools/box64stack.c @@ -0,0 +1,138 @@ +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include <string.h> + +#include "box64stack.h" +#include "box64context.h" +#include "elfloader.h" +#include "debug.h" +//#include "emu/x64emu_private.h" +//#include "emu/x86run_private.h" +//#include "auxval.h" + +EXPORTDYN +int CalcStackSize(box64context_t *context) +{ + printf_log(LOG_DEBUG, "Calc stack size, based on %d elf(s)\n", context->elfsize); + context->stacksz = 8*1024*1024; context->stackalign=4; + for (int i=0; i<context->elfsize; ++i) + CalcStack(context->elfs[i], &context->stacksz, &context->stackalign); + + if (posix_memalign((void**)&context->stack, context->stackalign, context->stacksz)) { + printf_log(LOG_NONE, "Cannot allocate aligned memory (0x%x/0x%x) for stack\n", context->stacksz, context->stackalign); + return 1; + } + memset(context->stack, 0, context->stacksz); + printf_log(LOG_DEBUG, "Stack is @%p size=0x%x align=0x%x\n", context->stack, context->stacksz, context->stackalign); + + return 0; +} + +//uint16_t Pop16(x64emu_t *emu) +//{ +// uint16_t* st = ((uint16_t*)(R_ESP)); +// R_ESP += 2; +// return *st; +//} + +//void Push16(x64emu_t *emu, uint16_t v) +//{ +// R_ESP -= 2; +// *((uint16_t*)R_ESP) = v; +//} +//uint32_t Pop32(x64emu_t *emu) +//{ +// uint32_t* st = ((uint32_t*)(R_ESP)); +// R_ESP += 4; +// return *st; +//} + +//void Push32(x64emu_t *emu, uint32_t v) +//{ +// R_ESP -= 4; +// *((uint32_t*)R_ESP) = v; +//} + +//void PushString(x64emu_t *emu, const char* s) +//{ +// int sz = strlen(s) + 1; +// // round to 4 bytes boundary +// R_ESP -= sz; +// memcpy((void*)R_ESP, s, sz); +//} + +//EXPORTDYN +//void SetupInitialStack(x64emu_t *emu) +//{ +// // start with 0 +// Push(emu, 0); +// // push program executed +// PushString(emu, emu->context->argv[0]); +// uintptr_t p_arg0 = R_ESP; +// // push envs +// uintptr_t p_envv[emu->context->envc]; +// for (int i=emu->context->envc-1; i>=0; --i) { +// PushString(emu, emu->context->envv[i]); +// p_envv[i] = R_ESP; +// } +// // push args, also, free the argv[] string and point to the one in the main stack +// uintptr_t p_argv[emu->context->argc]; +// for (int i=emu->context->argc-1; i>=0; --i) { +// PushString(emu, emu->context->argv[i]); +// p_argv[i] = R_ESP; +// free(emu->context->argv[i]); +// emu->context->argv[i] = (char*)p_argv[i]; +// } +// // align +// uintptr_t tmp = (R_ESP)&~(emu->context->stackalign-1); +// memset((void*)tmp, 0, R_ESP-tmp); +// R_ESP=tmp; +// +// // push some AuxVector stuffs +// PushString(emu, "i686"); +// uintptr_t p_386 = R_ESP; +// uintptr_t p_random = real_getauxval(25); +// if(!p_random) { +// for (int i=0; i<4; ++i) +// Push(emu, random()); +// p_random = R_ESP; +// } +// // align +// tmp = (R_ESP)&~(emu->context->stackalign-1); +// memset((void*)tmp, 0, R_ESP-tmp); +// R_ESP=tmp; +// +// // push the AuxVector themselves +// Push(emu, 0); Push(emu, 0); //AT_NULL(0)=0 +// Push(emu, p_386); Push(emu, 15); //AT_PLATFORM(15)=p_386* +// Push(emu, 0); Push(emu, 66); //AT_HWCAP2(26)=0 +// // Push HWCAP: +// // FPU: 1<<0 ; VME: 1<<1 ; DE : 1<<2 ; PSE: 1<<3 ; TSC: 1<<4 +// // MSR: 1<<5 : PAE: 1<<6 : MCE: 1<<7 ; CX8: 1<<8 : APIC:1<<9 +// // SEP: 1<<11: MTRR:1<<12: PGE: 1<<13: MCA: 1<<14; CMOV:1<<15; FCMOV: 1<<16 +// // MMX: 1<<23:OSFXR:1<<24: XMM: 1<<25:XMM2: 1<<26;AMD3D:1<<31 +// Push(emu, (1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<4) | (1<<8) | (1<<15) | (1<<16) | (1<<23) | (1<<25) | (1<<26)); +// Push(emu, 16); //AT_HWCAP(16)=... +// Push(emu, p_arg0); Push(emu, 31); //AT_EXECFN(31)=p_arg0 +// Push(emu, p_random); Push(emu, 25); //AT_RANDOM(25)=p_random +// Push(emu, real_getauxval(23)); Push(emu, 23); //AT_SECURE(23)=0 +// Push(emu, real_getauxval(14)); Push(emu, 14); //AT_EGID(14) +// Push(emu, real_getauxval(13)); Push(emu, 13); //AT_GID(13) +// Push(emu, real_getauxval(12)); Push(emu, 12); //AT_EUID(12) +// Push(emu, real_getauxval(11)); Push(emu, 11); //AT_UID(11) +// Push(emu, R_EIP); Push(emu, 9); //AT_ENTRY(9)=entrypoint +// Push(emu, 0/*emu->context->vsyscall*/); Push(emu, 32); //AT_SYSINFO(32)=vsyscall +// if(!emu->context->auxval_start) // store auxval start if needed +// emu->context->auxval_start = (uintptr_t*)R_ESP; +// // TODO: continue +// +// // push nil / envs / nil / args / argc +// Push(emu, 0); +// for (int i=emu->context->envc-1; i>=0; --i) +// Push(emu, p_envv[i]); +// Push(emu, 0); +// for (int i=emu->context->argc-1; i>=0; --i) +// Push(emu, p_argv[i]); +// Push(emu, emu->context->argc); +//} \ No newline at end of file |