fixup TLS for hello world sample

This commit is contained in:
Stefanos Kornilios Mitsis Poiitidis 2023-10-06 14:35:28 +03:00
parent 538276437a
commit c0249a6bc5
2 changed files with 50 additions and 4 deletions

View File

@ -123,7 +123,10 @@ PS4_SYSV_ABI void poll() { BREAKPOINT(); }
PS4_SYSV_ABI void munmap() { BREAKPOINT(); } PS4_SYSV_ABI void munmap() { BREAKPOINT(); }
PS4_SYSV_ABI void sceKernelUsleep() { BREAKPOINT(); } PS4_SYSV_ABI void sceKernelUsleep(unsigned int microseconds) {
std::this_thread::sleep_for(std::chrono::microseconds(microseconds));
//BREAKPOINT();
}
#define PROT_READ 0x1 #define PROT_READ 0x1
@ -174,7 +177,18 @@ PS4_SYSV_ABI void close() { BREAKPOINT(); }
PS4_SYSV_ABI void madvise() { BREAKPOINT(); } PS4_SYSV_ABI void madvise() { BREAKPOINT(); }
PS4_SYSV_ABI void _writev() { BREAKPOINT(); } struct iovec {
void* iov_base; /* Base address. */
size_t iov_len; /* Length. */
};
PS4_SYSV_ABI size_t _writev(int fd, const struct iovec* iov, int iovcn) {
size_t total_written = 0;
for (int i = 0; i < iovcn; i++) {
total_written += ::fwrite(iov[i].iov_base, 1, iov[i].iov_len, stdout);
}
return total_written;
}
PS4_SYSV_ABI void lseek() { BREAKPOINT(); } PS4_SYSV_ABI void lseek() { BREAKPOINT(); }
PS4_SYSV_ABI int* __error() { return _errno(); } PS4_SYSV_ABI int* __error() { return _errno(); }

View File

@ -169,6 +169,8 @@ void Linker::LoadModuleToMemory(Module* m)
LOG_ERROR_IF(debug_loader, "p_filesz==0 in type {}\n", m->elf->ElfPheaderTypeStr(elf_pheader[i].p_type)); LOG_ERROR_IF(debug_loader, "p_filesz==0 in type {}\n", m->elf->ElfPheaderTypeStr(elf_pheader[i].p_type));
} }
break; break;
case PT_TLS:
LOG_ERROR("TLS SIZE: memsz: {} filesz: {}\n", elf_pheader[i].p_memsz, elf_pheader[i].p_filesz);
default: default:
LOG_ERROR_IF(debug_loader, "Unimplemented type {}\n", m->elf->ElfPheaderTypeStr(elf_pheader[i].p_type)); LOG_ERROR_IF(debug_loader, "Unimplemented type {}\n", m->elf->ElfPheaderTypeStr(elf_pheader[i].p_type));
} }
@ -632,17 +634,47 @@ void Linker::Resolve(const std::string& name, int Symtype, Module* m, SymbolReco
} }
using exit_func_t = PS4_SYSV_ABI void (*)(); static thread_local void* tls_block_top;
// this assumes TLS will do mov rax|rcx, fs:[0] and
// that fs:[0] will be a nullptr in windows (seems to be so)
// and, that fs:[0] points to the top of the static TLS
static LONG CALLBACK ExceptionHandlerTLS(PEXCEPTION_POINTERS ExceptionInfo) {
static const uint8_t rax_fs0_deref[] = {0x64, 0x48, 0x8B, 0x04, 0x25, 0x00, 0x00, 0x00, 0x00};
static const uint8_t rcx_fs0_deref[] = {0x64, 0x48, 0x8B, 0x0C, 0x25, 0x00, 0x00, 0x00, 0x00};
if (memcmp((void*)ExceptionInfo->ContextRecord->Rip, rax_fs0_deref, sizeof(rax_fs0_deref)) == 0) {
ExceptionInfo->ContextRecord->Rip += sizeof(rax_fs0_deref);
ExceptionInfo->ContextRecord->Rax = *(DWORD64*)tls_block_top;
return EXCEPTION_CONTINUE_EXECUTION;
} else if (memcmp((void*)ExceptionInfo->ContextRecord->Rip, rcx_fs0_deref, sizeof(rcx_fs0_deref)) == 0) {
ExceptionInfo->ContextRecord->Rip += sizeof(rcx_fs0_deref);
ExceptionInfo->ContextRecord->Rcx = *(DWORD64*)tls_block_top;
return EXCEPTION_CONTINUE_EXECUTION;
}
return EXCEPTION_CONTINUE_SEARCH;
}
using exit_func_t = PS4_SYSV_ABI void (*)();
using entry_func_t = PS4_SYSV_ABI void (*)(EntryParams* params, exit_func_t atexit_func); using entry_func_t = PS4_SYSV_ABI void (*)(EntryParams* params, exit_func_t atexit_func);
static PS4_SYSV_ABI void ProgramExitFunc() { static PS4_SYSV_ABI void ProgramExitFunc() {
printf("exit function called\n"); printf("exit function called\n");
} }
static void run_main_entry(u64 addr, EntryParams* params, exit_func_t exit_func) { static void run_main_entry(u64 addr, EntryParams* params, exit_func_t exit_func) {
//reinterpret_cast<entry_func_t>(addr)(params, exit_func); // can't be used, stack has to have a specific layout //reinterpret_cast<entry_func_t>(addr)(params, exit_func); // can't be used, stack has to have a specific layout
void** tls_block = (void**)malloc(16); // this assumes 8 bytes of TLS storage, with the top of TLS pointing to itself
tls_block_top = tls_block[1] = &tls_block[1];
AddVectoredExceptionHandler(TRUE, ExceptionHandlerTLS);
asm volatile ( asm volatile (
"andq $-16, %%rsp\n"// Align to 16 bytes "andq $-16, %%rsp\n"// Align to 16 bytes
"subq $8, %%rsp\n" // videoout_basic expects the stack to be misaligned "subq $8, %%rsp\n" // videoout_basic expects the stack to be misaligned