linker: Fix buggy R_X86_64_DTPMOD64
This commit is contained in:
parent
2bbe1349c2
commit
511595aca7
|
@ -4,6 +4,7 @@
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
|
#include "common/error.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "common/singleton.h"
|
#include "common/singleton.h"
|
||||||
#include "core/libraries/error_codes.h"
|
#include "core/libraries/error_codes.h"
|
||||||
|
@ -165,7 +166,27 @@ s64 PS4_SYSV_ABI ps4__write(int d, const void* buf, std::size_t nbytes) {
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceKernelConvertUtcToLocaltime(time_t time, time_t* local_time,
|
int PS4_SYSV_ABI sceKernelConvertUtcToLocaltime(time_t time, time_t* local_time,
|
||||||
struct OrbisTimesec* st, unsigned long* dst_sec) {
|
struct OrbisTimesec* st, unsigned long* dst_sec) {
|
||||||
|
return ORBIS_OK;
|
||||||
LOG_TRACE(Kernel, "Called");
|
LOG_TRACE(Kernel, "Called");
|
||||||
|
timeval val;
|
||||||
|
timezone tmz;
|
||||||
|
gettimeofday(&val, &tmz);
|
||||||
|
|
||||||
|
if (local_time) {
|
||||||
|
*local_time = (tmz.tz_minuteswest + tmz.tz_dsttime) * 60 + time;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (st) {
|
||||||
|
st->t = time;
|
||||||
|
st->dst_sec = tmz.tz_dsttime * 60;
|
||||||
|
st->west_sec = tmz.tz_minuteswest * 60;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dst_sec) {
|
||||||
|
*dst_sec = tmz.tz_dsttime * 60;
|
||||||
|
}
|
||||||
|
return ORBIS_OK;
|
||||||
|
|
||||||
const auto* time_zone = std::chrono::current_zone();
|
const auto* time_zone = std::chrono::current_zone();
|
||||||
auto info = time_zone->get_info(std::chrono::system_clock::now());
|
auto info = time_zone->get_info(std::chrono::system_clock::now());
|
||||||
|
|
||||||
|
|
|
@ -39,44 +39,66 @@ u64 PS4_SYSV_ABI sceKernelReadTsc() {
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceKernelGettimeofday(SceKernelTimeval* tp) {}
|
int PS4_SYSV_ABI sceKernelGettimeofday(SceKernelTimeval* tp) {}
|
||||||
|
|
||||||
#if defined(_MSC_VER) || defined(_MSC_EXTENSIONS)
|
#define FILETIME_1970 116444736000000000ull /* seconds between 1/1/1601 and 1/1/1970 */
|
||||||
#define DELTA_EPOCH_IN_MICROSECS 11644473600000000Ui64
|
#define HECTONANOSEC_PER_SEC 10000000ull
|
||||||
#else
|
|
||||||
#define DELTA_EPOCH_IN_MICROSECS 11644473600000000ULL
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct timezone {
|
int PS4_SYSV_ABI getntptimeofday(struct timespec *tp, struct timezone *z) {
|
||||||
int tz_minuteswest; /* minutes W of Greenwich */
|
int res = 0;
|
||||||
int tz_dsttime; /* type of dst correction */
|
union {
|
||||||
};
|
unsigned long long ns100; /*time since 1 Jan 1601 in 100ns units */
|
||||||
|
FILETIME ft;
|
||||||
|
} _now;
|
||||||
|
TIME_ZONE_INFORMATION TimeZoneInformation;
|
||||||
|
DWORD tzi;
|
||||||
|
|
||||||
struct timeval {
|
if (z != NULL)
|
||||||
long tv_sec;
|
{
|
||||||
long tv_usec;
|
if ((tzi = GetTimeZoneInformation(&TimeZoneInformation)) != TIME_ZONE_ID_INVALID) {
|
||||||
};
|
z->tz_minuteswest = TimeZoneInformation.Bias;
|
||||||
|
if (tzi == TIME_ZONE_ID_DAYLIGHT)
|
||||||
|
z->tz_dsttime = 1;
|
||||||
|
else
|
||||||
|
z->tz_dsttime = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
z->tz_minuteswest = 0;
|
||||||
|
z->tz_dsttime = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* FILETIME of Jan 1 1970 00:00:00, the PostgreSQL epoch */
|
if (tp != NULL) {
|
||||||
static const unsigned __int64 epoch = 116444736000000000ULL;
|
typedef void (WINAPI * GetSystemTimeAsFileTime_t)(LPFILETIME);
|
||||||
|
static GetSystemTimeAsFileTime_t GetSystemTimeAsFileTime_p /* = 0 */;
|
||||||
|
|
||||||
/*
|
/* Set function pointer during first call */
|
||||||
* FILETIME represents the number of 100-nanosecond intervals since
|
GetSystemTimeAsFileTime_t get_time =
|
||||||
* January 1, 1601 (UTC).
|
__atomic_load_n (&GetSystemTimeAsFileTime_p, __ATOMIC_RELAXED);
|
||||||
*/
|
if (get_time == NULL) {
|
||||||
#define FILETIME_UNITS_PER_SEC 10000000L
|
/* Use GetSystemTimePreciseAsFileTime() if available (Windows 8 or later) */
|
||||||
#define FILETIME_UNITS_PER_USEC 10
|
get_time = (GetSystemTimeAsFileTime_t)(intptr_t) GetProcAddress (
|
||||||
|
GetModuleHandle ("kernel32.dll"),
|
||||||
|
"GetSystemTimePreciseAsFileTime"); /* <1us precision on Windows 10 */
|
||||||
|
if (get_time == NULL)
|
||||||
|
get_time = GetSystemTimeAsFileTime; /* >15ms precision on Windows 10 */
|
||||||
|
__atomic_store_n (&GetSystemTimeAsFileTime_p, get_time, __ATOMIC_RELAXED);
|
||||||
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI gettimeofday(struct timeval* tp, struct timezone* tzp) {
|
get_time (&_now.ft); /* 100 nano-seconds since 1-1-1601 */
|
||||||
FILETIME file_time;
|
_now.ns100 -= FILETIME_1970; /* 100 nano-seconds since 1-1-1970 */
|
||||||
ULARGE_INTEGER ularge;
|
tp->tv_sec = _now.ns100 / HECTONANOSEC_PER_SEC; /* seconds since 1-1-1970 */
|
||||||
|
tp->tv_nsec = (long) (_now.ns100 % HECTONANOSEC_PER_SEC) * 100; /* nanoseconds */
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
GetSystemTimePreciseAsFileTime(&file_time);
|
int PS4_SYSV_ABI gettimeofday(struct timeval *p, struct timezone *z) {
|
||||||
ularge.LowPart = file_time.dwLowDateTime;
|
struct timespec tp;
|
||||||
ularge.HighPart = file_time.dwHighDateTime;
|
|
||||||
|
|
||||||
tp->tv_sec = (long)((ularge.QuadPart - epoch) / FILETIME_UNITS_PER_SEC);
|
|
||||||
tp->tv_usec =
|
|
||||||
(long)(((ularge.QuadPart - epoch) % FILETIME_UNITS_PER_SEC) / FILETIME_UNITS_PER_USEC);
|
|
||||||
|
|
||||||
|
if (getntptimeofday (&tp, z))
|
||||||
|
return -1;
|
||||||
|
p->tv_sec=tp.tv_sec;
|
||||||
|
p->tv_usec=(tp.tv_nsec/1000);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,12 +16,23 @@ struct SceKernelTimeval {
|
||||||
s64 tv_usec;
|
s64 tv_usec;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct timezone {
|
||||||
|
int tz_minuteswest; /* minutes W of Greenwich */
|
||||||
|
int tz_dsttime; /* type of dst correction */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct timeval {
|
||||||
|
long tv_sec;
|
||||||
|
long tv_usec;
|
||||||
|
};
|
||||||
|
|
||||||
u64 PS4_SYSV_ABI sceKernelGetTscFrequency();
|
u64 PS4_SYSV_ABI sceKernelGetTscFrequency();
|
||||||
u64 PS4_SYSV_ABI sceKernelGetProcessTime();
|
u64 PS4_SYSV_ABI sceKernelGetProcessTime();
|
||||||
u64 PS4_SYSV_ABI sceKernelGetProcessTimeCounter();
|
u64 PS4_SYSV_ABI sceKernelGetProcessTimeCounter();
|
||||||
u64 PS4_SYSV_ABI sceKernelGetProcessTimeCounterFrequency();
|
u64 PS4_SYSV_ABI sceKernelGetProcessTimeCounterFrequency();
|
||||||
u64 PS4_SYSV_ABI sceKernelReadTsc();
|
u64 PS4_SYSV_ABI sceKernelReadTsc();
|
||||||
int PS4_SYSV_ABI sceKernelGettimeofday(SceKernelTimeval* tp);
|
int PS4_SYSV_ABI sceKernelGettimeofday(SceKernelTimeval* tp);
|
||||||
|
int PS4_SYSV_ABI gettimeofday(struct timeval* tp, struct timezone* tzp);
|
||||||
|
|
||||||
void timeSymbolsRegister(Core::Loader::SymbolsResolver* sym);
|
void timeSymbolsRegister(Core::Loader::SymbolsResolver* sym);
|
||||||
|
|
||||||
|
|
|
@ -71,8 +71,8 @@ void Linker::Execute() {
|
||||||
InitTlsForThread(true);
|
InitTlsForThread(true);
|
||||||
|
|
||||||
// Relocate all modules
|
// Relocate all modules
|
||||||
for (const auto& m : m_modules) {
|
for (u32 i = 1; const auto& m : m_modules) {
|
||||||
Relocate(m.get());
|
Relocate(i, m.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start shared library modules
|
// Start shared library modules
|
||||||
|
@ -113,7 +113,7 @@ Module* Linker::LoadModule(const std::filesystem::path& elf_name) {
|
||||||
return m_modules.emplace_back(std::move(module)).get();
|
return m_modules.emplace_back(std::move(module)).get();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Linker::Relocate(Module* module) {
|
void Linker::Relocate(u32 index, Module* module) {
|
||||||
module->ForEachRelocation([&](elf_relocation* rel, bool isJmpRel) {
|
module->ForEachRelocation([&](elf_relocation* rel, bool isJmpRel) {
|
||||||
auto type = rel->GetType();
|
auto type = rel->GetType();
|
||||||
auto symbol = rel->GetSymbol();
|
auto symbol = rel->GetSymbol();
|
||||||
|
@ -134,7 +134,7 @@ void Linker::Relocate(Module* module) {
|
||||||
rel_is_resolved = true;
|
rel_is_resolved = true;
|
||||||
break;
|
break;
|
||||||
case R_X86_64_DTPMOD64:
|
case R_X86_64_DTPMOD64:
|
||||||
rel_value = reinterpret_cast<uint64_t>(module);
|
rel_value = static_cast<uint64_t>(index);
|
||||||
rel_is_resolved = true;
|
rel_is_resolved = true;
|
||||||
rel_sym_type = Loader::SymbolType::Tls;
|
rel_sym_type = Loader::SymbolType::Tls;
|
||||||
break;
|
break;
|
||||||
|
@ -257,7 +257,7 @@ void* Linker::TlsGetAddr(u64 module_index, u64 offset) {
|
||||||
ASSERT_MSG(dtv_table[0].counter == dtv_generation_counter,
|
ASSERT_MSG(dtv_table[0].counter == dtv_generation_counter,
|
||||||
"Reallocation of DTV table is not supported");
|
"Reallocation of DTV table is not supported");
|
||||||
|
|
||||||
void* module = dtv_table[module_index - 1].pointer;
|
void* module = dtv_table[module_index + 1].pointer;
|
||||||
ASSERT_MSG(module, "DTV allocation is not supported");
|
ASSERT_MSG(module, "DTV allocation is not supported");
|
||||||
return module;
|
return module;
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,7 +54,7 @@ public:
|
||||||
|
|
||||||
Module* LoadModule(const std::filesystem::path& elf_name);
|
Module* LoadModule(const std::filesystem::path& elf_name);
|
||||||
|
|
||||||
void Relocate(Module* module);
|
void Relocate(u32 index, Module* module);
|
||||||
void Resolve(const std::string& name, Loader::SymbolType type,
|
void Resolve(const std::string& name, Loader::SymbolType type,
|
||||||
Module* module, Loader::SymbolRecord* return_info);
|
Module* module, Loader::SymbolRecord* return_info);
|
||||||
void Execute();
|
void Execute();
|
||||||
|
|
|
@ -321,6 +321,10 @@ void TextureCache::UntrackImage(Image& image, ImageId image_id) {
|
||||||
void TextureCache::UpdatePagesCachedCount(VAddr addr, u64 size, s32 delta) {
|
void TextureCache::UpdatePagesCachedCount(VAddr addr, u64 size, s32 delta) {
|
||||||
std::scoped_lock lk{mutex};
|
std::scoped_lock lk{mutex};
|
||||||
const u64 num_pages = ((addr + size - 1) >> PageShift) - (addr >> PageShift) + 1;
|
const u64 num_pages = ((addr + size - 1) >> PageShift) - (addr >> PageShift) + 1;
|
||||||
|
if (num_pages == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const u64 page_start = addr >> PageShift;
|
const u64 page_start = addr >> PageShift;
|
||||||
const u64 page_end = page_start + num_pages;
|
const u64 page_end = page_start + num_pages;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue