mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-25 12:26:51 +01:00
Linux: port the emulator to a working state on Linux (#117)
Linux: port the emulator to a working state
This commit is contained in:
@@ -8,6 +8,8 @@
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <execinfo.h>
|
||||
#include <pthread.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
@@ -15,8 +17,48 @@
|
||||
#include <libgen.h> // POSIX basename() lives here on macOS, not in <cstring>
|
||||
#endif
|
||||
|
||||
void SysStackWalk(void** /*stack*/, int* depth) {
|
||||
*depth = 0;
|
||||
// Avoid unwinding a guest-owned stack.
|
||||
static bool OnOwnStack() {
|
||||
const char* probe = reinterpret_cast<const char*>(&probe);
|
||||
|
||||
pthread_attr_t attr {};
|
||||
#if defined(__APPLE__)
|
||||
const auto* top = static_cast<const char*>(pthread_get_stackaddr_np(pthread_self()));
|
||||
const auto size = pthread_get_stacksize_np(pthread_self());
|
||||
(void)attr;
|
||||
return top != nullptr && size != 0 && probe < top && probe >= top - size;
|
||||
#else
|
||||
if (pthread_getattr_np(pthread_self(), &attr) != 0) {
|
||||
return false;
|
||||
}
|
||||
void* base = nullptr;
|
||||
size_t size = 0;
|
||||
const bool ok =
|
||||
pthread_attr_getstack(&attr, &base, &size) == 0 && base != nullptr && size != 0;
|
||||
pthread_attr_destroy(&attr);
|
||||
if (!ok) {
|
||||
return false;
|
||||
}
|
||||
const auto* low = static_cast<const char*>(base);
|
||||
return probe >= low && probe < low + size;
|
||||
#endif
|
||||
}
|
||||
|
||||
void SysStackWalk(void** stack, int* depth) {
|
||||
if (stack == nullptr || depth == nullptr || *depth <= 0) {
|
||||
if (depth != nullptr) {
|
||||
*depth = 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!OnOwnStack()) {
|
||||
*depth = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
const int n = ::backtrace(stack, *depth);
|
||||
*depth = (n < 0 ? 0 : n);
|
||||
}
|
||||
|
||||
void SysStackUsagePrint(sys_dbg_stack_info_t& stack) {
|
||||
@@ -33,6 +75,33 @@ void SysStackUsage(sys_dbg_stack_info_t& s) {
|
||||
|
||||
[[maybe_unused]] int result = 0;
|
||||
|
||||
memset(&s, 0, sizeof(sys_dbg_stack_info_t));
|
||||
|
||||
// Record the reservation before the Linux /proc walk.
|
||||
{
|
||||
pthread_attr_t self_attr {};
|
||||
#if defined(__APPLE__)
|
||||
void* stack_top = pthread_get_stackaddr_np(pthread_self());
|
||||
const size_t stack_size = pthread_get_stacksize_np(pthread_self());
|
||||
if (stack_top != nullptr && stack_size != 0) {
|
||||
s.reserved_addr = reinterpret_cast<uintptr_t>(stack_top) - stack_size;
|
||||
s.reserved_size = stack_size;
|
||||
}
|
||||
(void)self_attr;
|
||||
#else
|
||||
if (pthread_getattr_np(pthread_self(), &self_attr) == 0) {
|
||||
void* stack_base = nullptr;
|
||||
size_t stack_size = 0;
|
||||
if (pthread_attr_getstack(&self_attr, &stack_base, &stack_size) == 0 &&
|
||||
stack_base != nullptr && stack_size != 0) {
|
||||
s.reserved_addr = reinterpret_cast<uintptr_t>(stack_base);
|
||||
s.reserved_size = stack_size;
|
||||
}
|
||||
pthread_attr_destroy(&self_attr);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
char str[1024];
|
||||
char str2[1024];
|
||||
result = sprintf(str, "/proc/%d/exe", static_cast<int>(pid));
|
||||
@@ -46,8 +115,6 @@ void SysStackUsage(sys_dbg_stack_info_t& s) {
|
||||
|
||||
result = sprintf(str, "/proc/%d/maps", static_cast<int>(pid));
|
||||
|
||||
memset(&s, 0, sizeof(sys_dbg_stack_info_t));
|
||||
|
||||
FILE* f = fopen(str, "r");
|
||||
|
||||
if (f == nullptr) {
|
||||
@@ -121,6 +188,11 @@ void SysStackUsage(sys_dbg_stack_info_t& s) {
|
||||
}
|
||||
|
||||
result = fclose(f);
|
||||
|
||||
if (s.reserved_addr == 0) {
|
||||
s.reserved_addr = s.addr;
|
||||
s.reserved_size = s.total_size;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user