mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-28 22:06:59 +01:00
libc: isolate guest tm from host ABI
This commit is contained in:
+56
-21
@@ -360,75 +360,110 @@ static KYTY_SYSV_ABI double libc_difftime(int64_t time1, int64_t time0) {
|
|||||||
return std::difftime(static_cast<std::time_t>(time1), static_cast<std::time_t>(time0));
|
return std::difftime(static_cast<std::time_t>(time1), static_cast<std::time_t>(time0));
|
||||||
}
|
}
|
||||||
|
|
||||||
static KYTY_SYSV_ABI std::tm* libc_gmtime(const int64_t* timer) {
|
struct GuestTm {
|
||||||
|
int tm_sec;
|
||||||
|
int tm_min;
|
||||||
|
int tm_hour;
|
||||||
|
int tm_mday;
|
||||||
|
int tm_mon;
|
||||||
|
int tm_year;
|
||||||
|
int tm_wday;
|
||||||
|
int tm_yday;
|
||||||
|
int tm_isdst;
|
||||||
|
};
|
||||||
|
|
||||||
|
static_assert(sizeof(GuestTm) == 36);
|
||||||
|
|
||||||
|
static GuestTm ToGuestTm(const std::tm& time) {
|
||||||
|
return {time.tm_sec, time.tm_min, time.tm_hour, time.tm_mday, time.tm_mon,
|
||||||
|
time.tm_year, time.tm_wday, time.tm_yday, time.tm_isdst};
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::tm ToHostTm(const GuestTm& time) {
|
||||||
|
std::tm result {};
|
||||||
|
result.tm_sec = time.tm_sec;
|
||||||
|
result.tm_min = time.tm_min;
|
||||||
|
result.tm_hour = time.tm_hour;
|
||||||
|
result.tm_mday = time.tm_mday;
|
||||||
|
result.tm_mon = time.tm_mon;
|
||||||
|
result.tm_year = time.tm_year;
|
||||||
|
result.tm_wday = time.tm_wday;
|
||||||
|
result.tm_yday = time.tm_yday;
|
||||||
|
result.tm_isdst = time.tm_isdst;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static KYTY_SYSV_ABI GuestTm* libc_gmtime(const int64_t* timer) {
|
||||||
if (timer == nullptr) {
|
if (timer == nullptr) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
thread_local std::tm result {};
|
thread_local GuestTm result {};
|
||||||
|
std::tm host_result {};
|
||||||
const auto t = static_cast<std::time_t>(*timer);
|
const auto t = static_cast<std::time_t>(*timer);
|
||||||
|
|
||||||
#if KYTY_PLATFORM == KYTY_PLATFORM_WINDOWS
|
#if KYTY_PLATFORM == KYTY_PLATFORM_WINDOWS
|
||||||
if (_gmtime64_s(&result, &t) != 0) {
|
if (_gmtime64_s(&host_result, &t) != 0) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
if (gmtime_r(&t, &result) == nullptr) {
|
if (gmtime_r(&t, &host_result) == nullptr) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
result = ToGuestTm(host_result);
|
||||||
return &result;
|
return &result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static KYTY_SYSV_ABI std::tm* libc_localtime(const int64_t* timer) {
|
static KYTY_SYSV_ABI GuestTm* libc_localtime(const int64_t* timer) {
|
||||||
if (timer == nullptr) {
|
if (timer == nullptr) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
thread_local std::tm result {};
|
thread_local GuestTm result {};
|
||||||
|
std::tm host_result {};
|
||||||
const auto t = static_cast<std::time_t>(*timer);
|
const auto t = static_cast<std::time_t>(*timer);
|
||||||
|
|
||||||
#if KYTY_PLATFORM == KYTY_PLATFORM_WINDOWS
|
#if KYTY_PLATFORM == KYTY_PLATFORM_WINDOWS
|
||||||
if (_localtime64_s(&result, &t) != 0) {
|
if (_localtime64_s(&host_result, &t) != 0) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
if (localtime_r(&t, &result) == nullptr) {
|
if (localtime_r(&t, &host_result) == nullptr) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
result = ToGuestTm(host_result);
|
||||||
return &result;
|
return &result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static KYTY_SYSV_ABI int64_t libc_mktime(std::tm* timeptr) {
|
static KYTY_SYSV_ABI int64_t libc_mktime(GuestTm* timeptr) {
|
||||||
if (timeptr == nullptr) {
|
if (timeptr == nullptr) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto host_time = ToHostTm(*timeptr);
|
||||||
|
|
||||||
#if KYTY_PLATFORM == KYTY_PLATFORM_WINDOWS
|
#if KYTY_PLATFORM == KYTY_PLATFORM_WINDOWS
|
||||||
return static_cast<int64_t>(_mktime64(timeptr));
|
const auto result = static_cast<int64_t>(_mktime64(&host_time));
|
||||||
#else
|
#else
|
||||||
return static_cast<int64_t>(std::mktime(timeptr));
|
const auto result = static_cast<int64_t>(std::mktime(&host_time));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
*timeptr = ToGuestTm(host_time);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static KYTY_SYSV_ABI size_t libc_strftime(char* str, size_t count, const char* format,
|
static KYTY_SYSV_ABI size_t libc_strftime(char* str, size_t count, const char* format,
|
||||||
const std::tm* timeptr) {
|
const GuestTm* timeptr) {
|
||||||
if (str == nullptr || format == nullptr || timeptr == nullptr) {
|
if (str == nullptr || format == nullptr || timeptr == nullptr) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if KYTY_PLATFORM == KYTY_PLATFORM_LINUX && !defined(__APPLE__)
|
const auto host_time = ToHostTm(*timeptr);
|
||||||
// Guest-created tm values do not initialize glibc's tm_zone pointer.
|
return std::strftime(str, count, format, &host_time);
|
||||||
std::tm sanitized = *timeptr;
|
|
||||||
sanitized.tm_zone = nullptr;
|
|
||||||
|
|
||||||
return std::strftime(str, count, format, &sanitized);
|
|
||||||
#else
|
|
||||||
return std::strftime(str, count, format, timeptr);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static KYTY_SYSV_ABI void catchReturnFromMain(int status) {
|
static KYTY_SYSV_ABI void catchReturnFromMain(int status) {
|
||||||
|
|||||||
Reference in New Issue
Block a user