mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-07-23 10:35:03 +00:00
fixup TLS for hello world sample
This commit is contained in:
parent
538276437a
commit
c0249a6bc5
@ -123,7 +123,10 @@ PS4_SYSV_ABI void poll() { 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
|
||||
@ -174,7 +177,18 @@ PS4_SYSV_ABI void close() { 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 int* __error() { return _errno(); }
|
||||
|
||||
|
@ -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));
|
||||
}
|
||||
break;
|
||||
case PT_TLS:
|
||||
LOG_ERROR("TLS SIZE: memsz: {} filesz: {}\n", elf_pheader[i].p_memsz, elf_pheader[i].p_filesz);
|
||||
default:
|
||||
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);
|
||||
|
||||
static PS4_SYSV_ABI void ProgramExitFunc() {
|
||||
|
||||
printf("exit function called\n");
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
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 (
|
||||
"andq $-16, %%rsp\n"// Align to 16 bytes
|
||||
"subq $8, %%rsp\n" // videoout_basic expects the stack to be misaligned
|
||||
|
Loading…
Reference in New Issue
Block a user