linker: Fix buggy R_X86_64_DTPMOD64
This commit is contained in:
parent
2bbe1349c2
commit
511595aca7
|
@ -4,6 +4,7 @@
|
|||
#include <chrono>
|
||||
#include <thread>
|
||||
#include "common/assert.h"
|
||||
#include "common/error.h"
|
||||
#include "common/logging/log.h"
|
||||
#include "common/singleton.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,
|
||||
struct OrbisTimesec* st, unsigned long* dst_sec) {
|
||||
return ORBIS_OK;
|
||||
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();
|
||||
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) {}
|
||||
|
||||
#if defined(_MSC_VER) || defined(_MSC_EXTENSIONS)
|
||||
#define DELTA_EPOCH_IN_MICROSECS 11644473600000000Ui64
|
||||
#else
|
||||
#define DELTA_EPOCH_IN_MICROSECS 11644473600000000ULL
|
||||
#endif
|
||||
#define FILETIME_1970 116444736000000000ull /* seconds between 1/1/1601 and 1/1/1970 */
|
||||
#define HECTONANOSEC_PER_SEC 10000000ull
|
||||
|
||||
struct timezone {
|
||||
int tz_minuteswest; /* minutes W of Greenwich */
|
||||
int tz_dsttime; /* type of dst correction */
|
||||
};
|
||||
int PS4_SYSV_ABI getntptimeofday(struct timespec *tp, struct timezone *z) {
|
||||
int res = 0;
|
||||
union {
|
||||
unsigned long long ns100; /*time since 1 Jan 1601 in 100ns units */
|
||||
FILETIME ft;
|
||||
} _now;
|
||||
TIME_ZONE_INFORMATION TimeZoneInformation;
|
||||
DWORD tzi;
|
||||
|
||||
struct timeval {
|
||||
long tv_sec;
|
||||
long tv_usec;
|
||||
};
|
||||
if (z != NULL)
|
||||
{
|
||||
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 */
|
||||
static const unsigned __int64 epoch = 116444736000000000ULL;
|
||||
if (tp != NULL) {
|
||||
typedef void (WINAPI * GetSystemTimeAsFileTime_t)(LPFILETIME);
|
||||
static GetSystemTimeAsFileTime_t GetSystemTimeAsFileTime_p /* = 0 */;
|
||||
|
||||
/*
|
||||
* FILETIME represents the number of 100-nanosecond intervals since
|
||||
* January 1, 1601 (UTC).
|
||||
*/
|
||||
#define FILETIME_UNITS_PER_SEC 10000000L
|
||||
#define FILETIME_UNITS_PER_USEC 10
|
||||
/* Set function pointer during first call */
|
||||
GetSystemTimeAsFileTime_t get_time =
|
||||
__atomic_load_n (&GetSystemTimeAsFileTime_p, __ATOMIC_RELAXED);
|
||||
if (get_time == NULL) {
|
||||
/* Use GetSystemTimePreciseAsFileTime() if available (Windows 8 or later) */
|
||||
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) {
|
||||
FILETIME file_time;
|
||||
ULARGE_INTEGER ularge;
|
||||
get_time (&_now.ft); /* 100 nano-seconds since 1-1-1601 */
|
||||
_now.ns100 -= FILETIME_1970; /* 100 nano-seconds since 1-1-1970 */
|
||||
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);
|
||||
ularge.LowPart = file_time.dwLowDateTime;
|
||||
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);
|
||||
int PS4_SYSV_ABI gettimeofday(struct timeval *p, struct timezone *z) {
|
||||
struct timespec tp;
|
||||
|
||||
if (getntptimeofday (&tp, z))
|
||||
return -1;
|
||||
p->tv_sec=tp.tv_sec;
|
||||
p->tv_usec=(tp.tv_nsec/1000);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -16,12 +16,23 @@ struct SceKernelTimeval {
|
|||
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 sceKernelGetProcessTime();
|
||||
u64 PS4_SYSV_ABI sceKernelGetProcessTimeCounter();
|
||||
u64 PS4_SYSV_ABI sceKernelGetProcessTimeCounterFrequency();
|
||||
u64 PS4_SYSV_ABI sceKernelReadTsc();
|
||||
int PS4_SYSV_ABI sceKernelGettimeofday(SceKernelTimeval* tp);
|
||||
int PS4_SYSV_ABI gettimeofday(struct timeval* tp, struct timezone* tzp);
|
||||
|
||||
void timeSymbolsRegister(Core::Loader::SymbolsResolver* sym);
|
||||
|
||||
|
|
|
@ -71,8 +71,8 @@ void Linker::Execute() {
|
|||
InitTlsForThread(true);
|
||||
|
||||
// Relocate all modules
|
||||
for (const auto& m : m_modules) {
|
||||
Relocate(m.get());
|
||||
for (u32 i = 1; const auto& m : m_modules) {
|
||||
Relocate(i, m.get());
|
||||
}
|
||||
|
||||
// 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();
|
||||
}
|
||||
|
||||
void Linker::Relocate(Module* module) {
|
||||
void Linker::Relocate(u32 index, Module* module) {
|
||||
module->ForEachRelocation([&](elf_relocation* rel, bool isJmpRel) {
|
||||
auto type = rel->GetType();
|
||||
auto symbol = rel->GetSymbol();
|
||||
|
@ -134,7 +134,7 @@ void Linker::Relocate(Module* module) {
|
|||
rel_is_resolved = true;
|
||||
break;
|
||||
case R_X86_64_DTPMOD64:
|
||||
rel_value = reinterpret_cast<uint64_t>(module);
|
||||
rel_value = static_cast<uint64_t>(index);
|
||||
rel_is_resolved = true;
|
||||
rel_sym_type = Loader::SymbolType::Tls;
|
||||
break;
|
||||
|
@ -257,7 +257,7 @@ void* Linker::TlsGetAddr(u64 module_index, u64 offset) {
|
|||
ASSERT_MSG(dtv_table[0].counter == dtv_generation_counter,
|
||||
"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");
|
||||
return module;
|
||||
}
|
||||
|
|
|
@ -54,7 +54,7 @@ public:
|
|||
|
||||
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,
|
||||
Module* module, Loader::SymbolRecord* return_info);
|
||||
void Execute();
|
||||
|
|
|
@ -321,6 +321,10 @@ void TextureCache::UntrackImage(Image& image, ImageId image_id) {
|
|||
void TextureCache::UpdatePagesCachedCount(VAddr addr, u64 size, s32 delta) {
|
||||
std::scoped_lock lk{mutex};
|
||||
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_end = page_start + num_pages;
|
||||
|
||||
|
|
Loading…
Reference in New Issue