mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-07-23 18:45:36 +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 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(); }
|
||||||
|
|
||||||
|
@ -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
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 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
|
||||||
|
Loading…
Reference in New Issue
Block a user