mirror of https://github.com/InoriRus/Kyty.git
fix memory alloc issue
This commit is contained in:
parent
11f472acc6
commit
50b54b2607
|
@ -1,4 +1,4 @@
|
|||
version: 0.1.2.build-{build}
|
||||
version: 0.1.3.build-{build}
|
||||
image: Visual Studio 2019
|
||||
environment:
|
||||
matrix:
|
||||
|
|
|
@ -82,7 +82,7 @@ if (KYTY_LINKER STREQUAL LD)
|
|||
set(KYTY_LD_OPTIONS "-Wl,--image-base=0x100000000000")
|
||||
endif()
|
||||
|
||||
project(Kyty${KYTY_PROJECT_NAME}${CMAKE_BUILD_TYPE}${KYTY_COMPILER} VERSION 0.1.2)
|
||||
project(Kyty${KYTY_PROJECT_NAME}${CMAKE_BUILD_TYPE}${KYTY_COMPILER} VERSION 0.1.3)
|
||||
|
||||
include(src_script.cmake)
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@ namespace Kyty::Libs::LibKernel::Memory {
|
|||
KYTY_SUBSYSTEM_DEFINE(Memory);
|
||||
|
||||
int KYTY_SYSV_ABI KernelMapNamedFlexibleMemory(void** addr_in_out, size_t len, int prot, int flags, const char* name);
|
||||
int KYTY_SYSV_ABI KernelMapFlexibleMemory(void** addr_in_out, size_t len, int prot, int flags);
|
||||
int KYTY_SYSV_ABI KernelMunmap(uint64_t vaddr, size_t len);
|
||||
size_t KYTY_SYSV_ABI KernelGetDirectMemorySize();
|
||||
int KYTY_SYSV_ABI KernelAllocateDirectMemory(int64_t search_start, int64_t search_end, size_t len, size_t alignment, int memory_type,
|
||||
|
@ -21,6 +22,7 @@ int KYTY_SYSV_ABI KernelReleaseDirectMemory(int64_t start, size_t len);
|
|||
int KYTY_SYSV_ABI KernelMapDirectMemory(void** addr, size_t len, int prot, int flags, int64_t direct_memory_start, size_t alignment);
|
||||
int KYTY_SYSV_ABI KernelQueryMemoryProtection(void* addr, void** start, void** end, int* prot);
|
||||
int KYTY_SYSV_ABI KernelDirectMemoryQuery(int64_t offset, int flags, void* info, size_t info_size);
|
||||
int KYTY_SYSV_ABI KernelAvailableFlexibleMemorySize(size_t* size);
|
||||
|
||||
} // namespace Kyty::Libs::LibKernel::Memory
|
||||
|
||||
|
|
|
@ -177,6 +177,9 @@ int KYTY_SYSV_ABI pthread_setspecific(LibKernel::PthreadKey key, void* value);
|
|||
void* KYTY_SYSV_ABI pthread_getspecific(LibKernel::PthreadKey key);
|
||||
int KYTY_SYSV_ABI pthread_mutex_destroy(LibKernel::PthreadMutex* mutex);
|
||||
int KYTY_SYSV_ABI pthread_mutex_init(LibKernel::PthreadMutex* mutex, const LibKernel::PthreadMutexattr* attr);
|
||||
int KYTY_SYSV_ABI pthread_mutexattr_init(LibKernel::PthreadMutexattr* attr);
|
||||
int KYTY_SYSV_ABI pthread_mutexattr_settype(LibKernel::PthreadMutexattr* attr, int type);
|
||||
int KYTY_SYSV_ABI pthread_mutexattr_destroy(LibKernel::PthreadMutexattr* attr);
|
||||
|
||||
} // namespace Posix
|
||||
|
||||
|
|
|
@ -74,12 +74,16 @@ public:
|
|||
|
||||
KYTY_CLASS_NO_COPY(FlexibleMemory);
|
||||
|
||||
static uint64_t Size() { return static_cast<uint64_t>(448) * 1024 * 1024; }
|
||||
uint64_t Available();
|
||||
|
||||
bool Map(uint64_t vaddr, size_t len, int prot, VirtualMemory::Mode mode, Graphics::GpuMemoryMode gpu_mode);
|
||||
bool Unmap(uint64_t vaddr, uint64_t size, Graphics::GpuMemoryMode* gpu_mode);
|
||||
bool Find(uint64_t vaddr, uint64_t* base_addr, size_t* len, int* prot, VirtualMemory::Mode* mode, Graphics::GpuMemoryMode* gpu_mode);
|
||||
|
||||
private:
|
||||
Vector<AllocatedBlock> m_allocated;
|
||||
uint64_t m_allocated_total = 0;
|
||||
Core::Mutex m_mutex;
|
||||
};
|
||||
|
||||
|
@ -311,6 +315,7 @@ bool FlexibleMemory::Map(uint64_t vaddr, size_t len, int prot, VirtualMemory::Mo
|
|||
b.gpu_mode = gpu_mode;
|
||||
|
||||
m_allocated.Add(b);
|
||||
m_allocated_total += len;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -329,6 +334,7 @@ bool FlexibleMemory::Unmap(uint64_t vaddr, uint64_t size, Graphics::GpuMemoryMod
|
|||
*gpu_mode = b.gpu_mode;
|
||||
|
||||
m_allocated.RemoveAt(index);
|
||||
m_allocated_total -= size;
|
||||
return true;
|
||||
}
|
||||
index++;
|
||||
|
@ -374,6 +380,13 @@ bool FlexibleMemory::Find(uint64_t vaddr, uint64_t* base_addr, size_t* len, int*
|
|||
});
|
||||
}
|
||||
|
||||
uint64_t FlexibleMemory::Available()
|
||||
{
|
||||
Core::LockGuard lock(m_mutex);
|
||||
|
||||
return Size() - m_allocated_total;
|
||||
}
|
||||
|
||||
int32_t KYTY_SYSV_ABI KernelMapNamedFlexibleMemory(void** addr_in_out, size_t len, int prot, int flags, const char* name)
|
||||
{
|
||||
PRINT_NAME();
|
||||
|
@ -396,6 +409,11 @@ int32_t KYTY_SYSV_ABI KernelMapNamedFlexibleMemory(void** addr_in_out, size_t le
|
|||
case 5: mode = VirtualMemory::Mode::ExecuteRead; break;
|
||||
case 6:
|
||||
case 7: mode = VirtualMemory::Mode::ExecuteReadWrite; break;
|
||||
case 0x32:
|
||||
case 0x33:
|
||||
mode = VirtualMemory::Mode::ReadWrite;
|
||||
gpu_mode = Graphics::GpuMemoryMode::ReadWrite;
|
||||
break;
|
||||
default: EXIT("unknown prot: %d\n", prot);
|
||||
}
|
||||
|
||||
|
@ -405,25 +423,36 @@ int32_t KYTY_SYSV_ABI KernelMapNamedFlexibleMemory(void** addr_in_out, size_t le
|
|||
|
||||
if (!g_flexible_memory->Map(out_addr, len, prot, mode, gpu_mode))
|
||||
{
|
||||
printf(FG_RED "\t[Fail]\n" FG_DEFAULT);
|
||||
printf(FG_RED "\t [Fail]\n" FG_DEFAULT);
|
||||
VirtualMemory::Free(out_addr);
|
||||
return KERNEL_ERROR_ENOMEM;
|
||||
}
|
||||
|
||||
printf("\tin_addr = 0x%016" PRIx64 "\n", in_addr);
|
||||
printf("\tout_addr = 0x%016" PRIx64 "\n", out_addr);
|
||||
printf("\tsize = %" PRIu64 "\n", len);
|
||||
printf("\tmode = %s\n", Core::EnumName(mode).C_Str());
|
||||
printf("\tname = %s\n", name);
|
||||
printf("\t in_addr = 0x%016" PRIx64 "\n", in_addr);
|
||||
printf("\t out_addr = 0x%016" PRIx64 "\n", out_addr);
|
||||
printf("\t size = %" PRIu64 "\n", len);
|
||||
printf("\t mode = %s\n", Core::EnumName(mode).C_Str());
|
||||
printf("\t name = %s\n", name);
|
||||
printf("\t gpu_mode = %s\n", Core::EnumName(gpu_mode).C_Str());
|
||||
|
||||
if (out_addr == 0)
|
||||
{
|
||||
return KERNEL_ERROR_ENOMEM;
|
||||
}
|
||||
|
||||
if (gpu_mode != Graphics::GpuMemoryMode::NoAccess)
|
||||
{
|
||||
Graphics::GpuMemorySetAllocatedRange(out_addr, len);
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int KYTY_SYSV_ABI KernelMapFlexibleMemory(void** addr_in_out, size_t len, int prot, int flags)
|
||||
{
|
||||
return KernelMapNamedFlexibleMemory(addr_in_out, len, prot, flags, "");
|
||||
}
|
||||
|
||||
int KYTY_SYSV_ABI KernelMunmap(uint64_t vaddr, size_t len)
|
||||
{
|
||||
PRINT_NAME();
|
||||
|
@ -688,6 +717,21 @@ int KYTY_SYSV_ABI KernelQueryMemoryProtection(void* addr, void** start, void** e
|
|||
return OK;
|
||||
}
|
||||
|
||||
int KYTY_SYSV_ABI KernelAvailableFlexibleMemorySize(size_t* size)
|
||||
{
|
||||
PRINT_NAME();
|
||||
|
||||
EXIT_IF(g_flexible_memory == nullptr);
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(size == nullptr);
|
||||
|
||||
*size = g_flexible_memory->Available();
|
||||
|
||||
printf("\t *size = 0x%016" PRIx64 "\n", *size);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
} // namespace Kyty::Libs::LibKernel::Memory
|
||||
|
||||
#endif // KYTY_EMU_ENABLED
|
||||
|
|
|
@ -631,6 +631,8 @@ int KYTY_SYSV_ABI PthreadMutexattrInit(PthreadMutexattr* attr)
|
|||
{
|
||||
// PRINT_NAME();
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(attr == nullptr);
|
||||
|
||||
*attr = new PthreadMutexattrPrivate {};
|
||||
|
||||
int result = pthread_mutexattr_init(&(*attr)->p);
|
||||
|
@ -669,6 +671,8 @@ int KYTY_SYSV_ABI PthreadMutexattrSettype(PthreadMutexattr* attr, int type)
|
|||
{
|
||||
// PRINT_NAME();
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(attr == nullptr || *attr == nullptr);
|
||||
|
||||
int ptype = PTHREAD_MUTEX_DEFAULT;
|
||||
switch (type)
|
||||
{
|
||||
|
@ -693,6 +697,8 @@ int KYTY_SYSV_ABI PthreadMutexattrSetprotocol([[maybe_unused]] PthreadMutexattr*
|
|||
{
|
||||
// PRINT_NAME();
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(attr == nullptr || *attr == nullptr);
|
||||
|
||||
[[maybe_unused]] int pprotocol = PTHREAD_PRIO_NONE;
|
||||
switch (protocol)
|
||||
{
|
||||
|
@ -2656,6 +2662,27 @@ int KYTY_SYSV_ABI pthread_mutex_init(LibKernel::PthreadMutex* mutex, const LibKe
|
|||
return POSIX_PTHREAD_CALL(LibKernel::PthreadMutexInit(mutex, attr, nullptr));
|
||||
}
|
||||
|
||||
int KYTY_SYSV_ABI pthread_mutexattr_init(LibKernel::PthreadMutexattr* attr)
|
||||
{
|
||||
PRINT_NAME();
|
||||
|
||||
return POSIX_PTHREAD_CALL(LibKernel::PthreadMutexattrInit(attr));
|
||||
}
|
||||
|
||||
int KYTY_SYSV_ABI pthread_mutexattr_settype(LibKernel::PthreadMutexattr* attr, int type)
|
||||
{
|
||||
PRINT_NAME();
|
||||
|
||||
return POSIX_PTHREAD_CALL(LibKernel::PthreadMutexattrSettype(attr, type));
|
||||
}
|
||||
|
||||
int KYTY_SYSV_ABI pthread_mutexattr_destroy(LibKernel::PthreadMutexattr* attr)
|
||||
{
|
||||
PRINT_NAME();
|
||||
|
||||
return POSIX_PTHREAD_CALL(LibKernel::PthreadMutexattrDestroy(attr));
|
||||
}
|
||||
|
||||
} // namespace Posix
|
||||
|
||||
} // namespace Kyty::Libs
|
||||
|
|
|
@ -417,6 +417,13 @@ int KYTY_SYSV_ABI clock_gettime(int clock_id, LibKernel::KernelTimespec* time)
|
|||
return POSIX_CALL(LibKernel::KernelClockGettime(clock_id, time));
|
||||
}
|
||||
|
||||
void KYTY_SYSV_ABI KernelSetGPO(uint32_t bits)
|
||||
{
|
||||
PRINT_NAME();
|
||||
|
||||
printf("\t bits = %08" PRIx32 "\n", bits);
|
||||
}
|
||||
|
||||
} // namespace LibKernel
|
||||
|
||||
namespace Posix {
|
||||
|
@ -455,6 +462,9 @@ LIB_DEFINE(InitLibKernel_1_Posix)
|
|||
LIB_FUNC("7H0iTOciTLo", Posix::pthread_mutex_lock);
|
||||
LIB_FUNC("2Z+PpY6CaJg", Posix::pthread_mutex_unlock);
|
||||
LIB_FUNC("ttHNfU+qDBU", Posix::pthread_mutex_init);
|
||||
LIB_FUNC("dQHWEsJtoE4", Posix::pthread_mutexattr_init);
|
||||
LIB_FUNC("mDmgMOGVUqg", Posix::pthread_mutexattr_settype);
|
||||
LIB_FUNC("HF7lK46xzjY", Posix::pthread_mutexattr_destroy);
|
||||
LIB_FUNC("ltCfaGr2JGE", Posix::pthread_mutex_destroy);
|
||||
LIB_FUNC("mkx2fVhNMsg", Posix::pthread_cond_broadcast);
|
||||
LIB_FUNC("Op8TBGY5KHg", Posix::pthread_cond_wait);
|
||||
|
@ -492,6 +502,7 @@ LIB_DEFINE(InitLibKernel_1_FS)
|
|||
LIB_DEFINE(InitLibKernel_1_Mem)
|
||||
{
|
||||
LIB_FUNC("mL8NDH86iQI", Memory::KernelMapNamedFlexibleMemory);
|
||||
LIB_FUNC("IWIBBdTHit4", Memory::KernelMapFlexibleMemory);
|
||||
LIB_FUNC("cQke9UuBQOk", Memory::KernelMunmap);
|
||||
LIB_FUNC("pO96TwzOm5E", Memory::KernelGetDirectMemorySize);
|
||||
LIB_FUNC("rTXw65xmLIA", Memory::KernelAllocateDirectMemory);
|
||||
|
@ -499,6 +510,7 @@ LIB_DEFINE(InitLibKernel_1_Mem)
|
|||
LIB_FUNC("MBuItvba6z8", Memory::KernelReleaseDirectMemory);
|
||||
LIB_FUNC("WFcfL2lzido", Memory::KernelQueryMemoryProtection);
|
||||
LIB_FUNC("BHouLQzh0X0", Memory::KernelDirectMemoryQuery);
|
||||
LIB_FUNC("aNz11fnnzi4", Memory::KernelAvailableFlexibleMemorySize);
|
||||
}
|
||||
|
||||
LIB_DEFINE(InitLibKernel_1_Equeue)
|
||||
|
@ -600,34 +612,34 @@ LIB_DEFINE(InitLibKernel_1)
|
|||
LIB_OBJECT("f7uOxY9mM1U", &LibKernel::g_stack_chk_guard);
|
||||
LIB_OBJECT("djxxOmW6-aw", &LibKernel::g_progname);
|
||||
|
||||
LIB_FUNC("Ou3iL1abvng", LibKernel::stack_chk_fail);
|
||||
LIB_FUNC("wzvqT4UqKX8", LibKernel::KernelLoadStartModule);
|
||||
LIB_FUNC("QKd0qM58Qes", LibKernel::KernelStopUnloadModule);
|
||||
LIB_FUNC("vNe1w4diLCs", LibKernel::tls_get_addr);
|
||||
LIB_FUNC("1jfXLRVzisc", LibKernel::KernelUsleep);
|
||||
LIB_FUNC("6xVpy0Fdq+I", LibKernel::sigprocmask);
|
||||
LIB_FUNC("6Z83sYWFlA8", LibKernel::exit);
|
||||
LIB_FUNC("8OnWXlgQlvo", LibKernel::KernelRtldThreadAtexitDecrement);
|
||||
LIB_FUNC("959qrazPIrg", LibKernel::KernelGetProcParam);
|
||||
LIB_FUNC("p5EcQeEeJAE", LibKernel::KernelRtldSetApplicationHeapAPI);
|
||||
LIB_FUNC("FxVZqBAA7ks", LibKernel::write);
|
||||
LIB_FUNC("9BcDykPmo1I", LibKernel::get_error_addr);
|
||||
LIB_FUNC("bnZxYgAFeA0", LibKernel::KernelGetSanitizerNewReplaceExternal);
|
||||
LIB_FUNC("ca7v6Cxulzs", LibKernel::KernelSetGPO);
|
||||
LIB_FUNC("DRuBt2pvICk", LibKernel::read);
|
||||
LIB_FUNC("f7KBOafysXo", LibKernel::KernelGetModuleInfoFromAddr);
|
||||
LIB_FUNC("zE-wXIZjLoM", LibKernel::KernelDebugRaiseExceptionOnReleaseMode);
|
||||
LIB_FUNC("OMDRKKAZ8I4", LibKernel::KernelDebugRaiseException);
|
||||
LIB_FUNC("6Z83sYWFlA8", LibKernel::exit);
|
||||
LIB_FUNC("py6L8jiVAN8", LibKernel::KernelGetSanitizerMallocReplaceExternal);
|
||||
LIB_FUNC("bnZxYgAFeA0", LibKernel::KernelGetSanitizerNewReplaceExternal);
|
||||
LIB_FUNC("Fjc4-n1+y2g", LibKernel::elf_phdr_match_addr);
|
||||
LIB_FUNC("FxVZqBAA7ks", LibKernel::write);
|
||||
LIB_FUNC("kbw4UHHSYy0", LibKernel::pthread_cxa_finalize);
|
||||
LIB_FUNC("Xjoosiw+XPI", LibKernel::KernelUuidCreate);
|
||||
LIB_FUNC("WslcK1FQcGI", LibKernel::KernelIsNeoMode);
|
||||
LIB_FUNC("9BcDykPmo1I", LibKernel::get_error_addr);
|
||||
LIB_FUNC("6xVpy0Fdq+I", LibKernel::sigprocmask);
|
||||
LIB_FUNC("lLMT9vJAck0", LibKernel::clock_gettime);
|
||||
|
||||
LIB_FUNC("1jfXLRVzisc", LibKernel::KernelUsleep);
|
||||
LIB_FUNC("rNhWz+lvOMU", LibKernel::KernelSetThreadDtors);
|
||||
LIB_FUNC("WhCc1w3EhSI", LibKernel::KernelSetThreadAtexitReport);
|
||||
LIB_FUNC("OMDRKKAZ8I4", LibKernel::KernelDebugRaiseException);
|
||||
LIB_FUNC("Ou3iL1abvng", LibKernel::stack_chk_fail);
|
||||
LIB_FUNC("p5EcQeEeJAE", LibKernel::KernelRtldSetApplicationHeapAPI);
|
||||
LIB_FUNC("pB-yGZ2nQ9o", LibKernel::KernelSetThreadAtexitCount);
|
||||
LIB_FUNC("py6L8jiVAN8", LibKernel::KernelGetSanitizerMallocReplaceExternal);
|
||||
LIB_FUNC("QKd0qM58Qes", LibKernel::KernelStopUnloadModule);
|
||||
LIB_FUNC("rNhWz+lvOMU", LibKernel::KernelSetThreadDtors);
|
||||
LIB_FUNC("Tz4RNUCBbGI", LibKernel::KernelRtldThreadAtexitIncrement);
|
||||
LIB_FUNC("8OnWXlgQlvo", LibKernel::KernelRtldThreadAtexitDecrement);
|
||||
LIB_FUNC("vNe1w4diLCs", LibKernel::tls_get_addr);
|
||||
LIB_FUNC("WhCc1w3EhSI", LibKernel::KernelSetThreadAtexitReport);
|
||||
LIB_FUNC("WslcK1FQcGI", LibKernel::KernelIsNeoMode);
|
||||
LIB_FUNC("wzvqT4UqKX8", LibKernel::KernelLoadStartModule);
|
||||
LIB_FUNC("Xjoosiw+XPI", LibKernel::KernelUuidCreate);
|
||||
LIB_FUNC("zE-wXIZjLoM", LibKernel::KernelDebugRaiseExceptionOnReleaseMode);
|
||||
}
|
||||
|
||||
} // namespace Kyty::Libs
|
||||
|
|
|
@ -68,13 +68,17 @@ struct RelocateHandlerStack
|
|||
uint64_t stack[3];
|
||||
};
|
||||
|
||||
constexpr uint64_t INVALID_MEMORY = 0x840000000;
|
||||
constexpr uint64_t DESIRED_BASE_ADDR = 0x010000000;
|
||||
constexpr uint64_t SYSTEM_RESERVED = 0x800000000u;
|
||||
constexpr uint64_t CODE_BASE_INCR = 0x010000000u;
|
||||
constexpr uint64_t INVALID_OFFSET = 0x040000000u;
|
||||
constexpr uint64_t CODE_BASE_OFFSET = 0x100000000u;
|
||||
constexpr uint64_t INVALID_MEMORY = SYSTEM_RESERVED + INVALID_OFFSET;
|
||||
|
||||
constexpr size_t XSAVE_BUFFER_SIZE = 2688;
|
||||
constexpr uint64_t XSAVE_CHK_GUARD = 0xDeadBeef5533CCAA;
|
||||
constexpr uint64_t XSAVE_CHK_GUARD = 0xDeadBeef5533CCAAu;
|
||||
|
||||
static uint64_t g_desired_base_addr = DESIRED_BASE_ADDR;
|
||||
static uint64_t g_desired_base_addr = SYSTEM_RESERVED + CODE_BASE_OFFSET;
|
||||
static uint64_t g_invalid_memory = 0;
|
||||
|
||||
static Program* g_tls_main_program = nullptr;
|
||||
alignas(64) static uint8_t g_tls_reg_save_area[XSAVE_BUFFER_SIZE + sizeof(XSAVE_CHK_GUARD)];
|
||||
|
@ -191,7 +195,8 @@ static void KYTY_SYSV_ABI stackwalk_x86(uint64_t rbp, void** stack, int* depth,
|
|||
|
||||
void KYTY_SYSV_ABI sys_stack_walk_x86(uint64_t rbp, void** stack, int* depth)
|
||||
{
|
||||
stackwalk_x86(rbp, stack, depth, 0, UINT64_MAX, DESIRED_BASE_ADDR, g_desired_base_addr - DESIRED_BASE_ADDR);
|
||||
stackwalk_x86(rbp, stack, depth, 0, UINT64_MAX, SYSTEM_RESERVED + CODE_BASE_OFFSET,
|
||||
g_desired_base_addr - (SYSTEM_RESERVED + CODE_BASE_OFFSET));
|
||||
}
|
||||
|
||||
static void kyty_exception_handler(const VirtualMemory::ExceptionHandler::ExceptionInfo* info)
|
||||
|
@ -209,7 +214,7 @@ static void kyty_exception_handler(const VirtualMemory::ExceptionHandler::Except
|
|||
Core::Singleton<Loader::RuntimeLinker>::Instance()->StackTrace(info->rbp);
|
||||
|
||||
EXIT("Access violation: %s [%016" PRIx64 "] %s\n", Core::EnumName(info->access_violation_type).C_Str(),
|
||||
info->access_violation_vaddr, (info->access_violation_vaddr == INVALID_MEMORY ? "(Unpatched object)" : ""));
|
||||
info->access_violation_vaddr, (info->access_violation_vaddr == g_invalid_memory ? "(Unpatched object)" : ""));
|
||||
}
|
||||
|
||||
EXIT("Unknown exception!!!");
|
||||
|
@ -426,7 +431,7 @@ static void relocate(uint32_t index, Elf64_Rela* r, Program* program, bool jmpre
|
|||
bool weak = (ri.bind == BindType::Weak || !program->fail_if_global_not_resolved);
|
||||
if (ri.type == SymbolType::Object && weak)
|
||||
{
|
||||
value = INVALID_MEMORY;
|
||||
value = g_invalid_memory;
|
||||
} else if (ri.type == SymbolType::Func && jmprela_table && weak)
|
||||
{
|
||||
if (program->custom_call_plt_vaddr != 0)
|
||||
|
@ -722,7 +727,7 @@ Program* RuntimeLinker::LoadProgram(const String& elf_name)
|
|||
|
||||
if (elf_name.FilenameWithoutExtension().EndsWith(U"libc") || elf_name.FilenameWithoutExtension().EndsWith(U"Fios2") ||
|
||||
elf_name.FilenameWithoutExtension().EndsWith(U"Fios2_debug") || elf_name.FilenameWithoutExtension().EndsWith(U"NpToolkit") ||
|
||||
elf_name.FilenameWithoutExtension().EndsWith(U"NpToolkit2"))
|
||||
elf_name.FilenameWithoutExtension().EndsWith(U"NpToolkit2") || elf_name.FilenameWithoutExtension().EndsWith(U"JobManager"))
|
||||
{
|
||||
program->fail_if_global_not_resolved = false;
|
||||
}
|
||||
|
@ -1130,7 +1135,7 @@ void RuntimeLinker::LoadProgramToMemory(Program* program)
|
|||
program->tls.handler_vaddr = program->base_vaddr + program->base_size_aligned + exception_handler_size;
|
||||
}
|
||||
|
||||
g_desired_base_addr += DESIRED_BASE_ADDR * (1 + alloc_size / DESIRED_BASE_ADDR);
|
||||
g_desired_base_addr += CODE_BASE_INCR * (1 + alloc_size / CODE_BASE_INCR);
|
||||
|
||||
EXIT_IF(program->base_vaddr == 0);
|
||||
EXIT_IF(program->base_size_aligned < program->base_size);
|
||||
|
@ -1152,8 +1157,9 @@ void RuntimeLinker::LoadProgramToMemory(Program* program)
|
|||
program->base_size_aligned + exception_handler_size + tls_handler_size, kyty_exception_handler);
|
||||
} else
|
||||
{
|
||||
program->exception_handler->Install(0, program->base_vaddr + program->base_size_aligned,
|
||||
program->base_vaddr + program->base_size_aligned + exception_handler_size + tls_handler_size,
|
||||
program->exception_handler->Install(SYSTEM_RESERVED, program->base_vaddr + program->base_size_aligned,
|
||||
program->base_vaddr + program->base_size_aligned + exception_handler_size + tls_handler_size -
|
||||
SYSTEM_RESERVED,
|
||||
kyty_exception_handler);
|
||||
|
||||
if (Libs::Graphics::GpuMemoryWatcherEnabled())
|
||||
|
@ -1381,7 +1387,8 @@ static void InstallRelocateHandler(Program* program)
|
|||
{
|
||||
program->custom_call_plt_num = program->dynamic_info->jmprela_table_size / sizeof(Elf64_Rela);
|
||||
auto size = Jit::CallPlt::GetSize(program->custom_call_plt_num);
|
||||
program->custom_call_plt_vaddr = VirtualMemory::Alloc(0, size, VirtualMemory::Mode::Write);
|
||||
program->custom_call_plt_vaddr = VirtualMemory::Alloc(SYSTEM_RESERVED, size, VirtualMemory::Mode::Write);
|
||||
EXIT_NOT_IMPLEMENTED(program->custom_call_plt_vaddr == 0);
|
||||
auto* code = new (reinterpret_cast<void*>(program->custom_call_plt_vaddr)) Jit::CallPlt(program->custom_call_plt_num);
|
||||
code->SetPltGot(pltgot_vaddr);
|
||||
VirtualMemory::Protect(program->custom_call_plt_vaddr, size, VirtualMemory::Mode::Execute);
|
||||
|
@ -1395,6 +1402,12 @@ void RuntimeLinker::Relocate(Program* program)
|
|||
|
||||
EXIT_IF(program == nullptr);
|
||||
|
||||
if (g_invalid_memory == 0)
|
||||
{
|
||||
g_invalid_memory = VirtualMemory::Alloc(INVALID_MEMORY, 4096, VirtualMemory::Mode::NoAccess);
|
||||
EXIT_NOT_IMPLEMENTED(g_invalid_memory == 0);
|
||||
}
|
||||
|
||||
printf("--- Relocate program: " FG_WHITE BOLD "%s" DEFAULT " ---\n", program->file_name.C_Str());
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(program->dynamic_info->symbol_table_entry_size != sizeof(Elf64_Sym));
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
// IWYU pragma: no_include <minwinbase.h>
|
||||
// IWYU pragma: no_include <apisetcconv.h>
|
||||
// IWYU pragma: no_include <winbase.h>
|
||||
// IWYU pragma: no_include <winerror.h>
|
||||
|
||||
//#include <memoryapi.h>
|
||||
|
||||
|
@ -299,12 +300,21 @@ void Init()
|
|||
|
||||
uint64_t Alloc(uint64_t address, uint64_t size, Mode mode)
|
||||
{
|
||||
auto ptr = reinterpret_cast<uintptr_t>(VirtualAlloc(reinterpret_cast<LPVOID>(static_cast<uintptr_t>(address)), size,
|
||||
static_cast<DWORD>(MEM_COMMIT) | static_cast<DWORD>(MEM_RESERVE),
|
||||
get_protection_flag(mode)));
|
||||
auto ptr = (address == 0 ? AllocAligned(address, size, mode, 1)
|
||||
: reinterpret_cast<uintptr_t>(VirtualAlloc(reinterpret_cast<LPVOID>(static_cast<uintptr_t>(address)), size,
|
||||
static_cast<DWORD>(MEM_COMMIT) | static_cast<DWORD>(MEM_RESERVE),
|
||||
get_protection_flag(mode))));
|
||||
if (ptr == 0)
|
||||
{
|
||||
printf("VirtualAlloc() failed: 0x%08" PRIx32 "\n", static_cast<uint32_t>(GetLastError()));
|
||||
auto err = static_cast<uint32_t>(GetLastError());
|
||||
|
||||
if (err != ERROR_INVALID_ADDRESS)
|
||||
{
|
||||
printf("VirtualAlloc() failed: 0x%08" PRIx32 "\n", err);
|
||||
} else
|
||||
{
|
||||
return AllocAligned(address, size, mode, 1);
|
||||
}
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
@ -325,16 +335,30 @@ uint64_t AllocAligned(uint64_t address, uint64_t size, Mode mode, uint64_t align
|
|||
{
|
||||
if (alignment == 0)
|
||||
{
|
||||
printf("VirtualAlloc2 failed: 0x%08" PRIx32 "\n", static_cast<uint32_t>(GetLastError()));
|
||||
return 0;
|
||||
}
|
||||
|
||||
MEM_ADDRESS_REQUIREMENTS req2 {};
|
||||
static constexpr uint64_t SYSTEM_MANAGED_MIN = 0x0000040000u;
|
||||
static constexpr uint64_t SYSTEM_MANAGED_MAX = 0x07FFFFBFFFu;
|
||||
static constexpr uint64_t USER_MIN = 0x1000000000u;
|
||||
static constexpr uint64_t USER_MAX = 0xFBFFFFFFFFu;
|
||||
|
||||
MEM_ADDRESS_REQUIREMENTS req {};
|
||||
MEM_EXTENDED_PARAMETER param {};
|
||||
req2.LowestStartingAddress = nullptr;
|
||||
req2.HighestEndingAddress = reinterpret_cast<PVOID>(0xffffffffffu); // nullptr;
|
||||
req.LowestStartingAddress = (address == 0 ? reinterpret_cast<PVOID>(SYSTEM_MANAGED_MIN) : reinterpret_cast<PVOID>(address));
|
||||
req.HighestEndingAddress = (address == 0 ? reinterpret_cast<PVOID>(SYSTEM_MANAGED_MAX) : reinterpret_cast<PVOID>(USER_MAX));
|
||||
req.Alignment = alignment;
|
||||
param.Type = MemExtendedParameterAddressRequirements;
|
||||
param.Pointer = &req;
|
||||
|
||||
MEM_ADDRESS_REQUIREMENTS req2 {};
|
||||
MEM_EXTENDED_PARAMETER param2 {};
|
||||
req2.LowestStartingAddress = (address == 0 ? reinterpret_cast<PVOID>(USER_MIN) : reinterpret_cast<PVOID>(address));
|
||||
req2.HighestEndingAddress = reinterpret_cast<PVOID>(USER_MAX);
|
||||
req2.Alignment = alignment;
|
||||
param.Type = MemExtendedParameterAddressRequirements;
|
||||
param.Pointer = &req2;
|
||||
param2.Type = MemExtendedParameterAddressRequirements;
|
||||
param2.Pointer = &req2;
|
||||
|
||||
static auto virtual_alloc2 = ResolveVirtualAlloc2();
|
||||
|
||||
|
@ -343,11 +367,24 @@ uint64_t AllocAligned(uint64_t address, uint64_t size, Mode mode, uint64_t align
|
|||
auto ptr = reinterpret_cast<uintptr_t>(virtual_alloc2(GetCurrentProcess(), nullptr, size,
|
||||
static_cast<DWORD>(MEM_COMMIT) | static_cast<DWORD>(MEM_RESERVE),
|
||||
get_protection_flag(mode), ¶m, 1));
|
||||
|
||||
if (ptr == 0)
|
||||
{
|
||||
printf("VirtualAlloc2(alignment = 0x%016" PRIx64 ") failed: 0x%08" PRIx32 "\n", alignment, static_cast<uint32_t>(GetLastError()));
|
||||
ptr = reinterpret_cast<uintptr_t>(virtual_alloc2(GetCurrentProcess(), nullptr, size,
|
||||
static_cast<DWORD>(MEM_COMMIT) | static_cast<DWORD>(MEM_RESERVE),
|
||||
get_protection_flag(mode), ¶m2, 1));
|
||||
}
|
||||
|
||||
return AllocAligned(address, size, mode, alignment << 1u);
|
||||
if (ptr == 0)
|
||||
{
|
||||
auto err = static_cast<uint32_t>(GetLastError());
|
||||
if (err != ERROR_INVALID_PARAMETER)
|
||||
{
|
||||
printf("VirtualAlloc2(alignment = 0x%016" PRIx64 ") failed: 0x%08" PRIx32 "\n", alignment, err);
|
||||
} else
|
||||
{
|
||||
return AllocAligned(address, size, mode, alignment << 1u);
|
||||
}
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
|
|
@ -12,15 +12,17 @@
|
|||
namespace Kyty::Core {
|
||||
|
||||
#ifdef __clang__
|
||||
int dbg_exit_handler(char const* file, int line, const char* f, ...) KYTY_FORMAT_PRINTF(3, 4) __attribute__((analyzer_noreturn));
|
||||
int dbg_assert_handler(char const* expr, char const* file, int line) __attribute__((analyzer_noreturn));
|
||||
int dbg_exit_if_handler(char const* expr, char const* file, int line) __attribute__((analyzer_noreturn));
|
||||
int dbg_not_implemented_handler(char const* expr, char const* file, int line) __attribute__((analyzer_noreturn));
|
||||
int dbg_exit_handler(char const* file, int line, const char* f, ...) KYTY_FORMAT_PRINTF(3, 4) __attribute__((analyzer_noreturn));
|
||||
int dbg_assert_handler(char const* expr, char const* file, int line) __attribute__((analyzer_noreturn));
|
||||
int dbg_exit_if_handler(char const* expr, char const* file, int line) __attribute__((analyzer_noreturn));
|
||||
int dbg_not_implemented_handler(char const* expr, char const* file, int line) __attribute__((analyzer_noreturn));
|
||||
void dbg_exit(int status) __attribute__((analyzer_noreturn));
|
||||
#else
|
||||
int dbg_exit_handler(char const* file, int line, const char* f, ...) KYTY_FORMAT_PRINTF(3, 4);
|
||||
int dbg_assert_handler(char const* expr, char const* file, int line);
|
||||
int dbg_exit_if_handler(char const* expr, char const* file, int line);
|
||||
int dbg_not_implemented_handler(char const* expr, char const* file, int line);
|
||||
int dbg_exit_handler(char const* file, int line, const char* f, ...) KYTY_FORMAT_PRINTF(3, 4);
|
||||
int dbg_assert_handler(char const* expr, char const* file, int line);
|
||||
int dbg_exit_if_handler(char const* expr, char const* file, int line);
|
||||
int dbg_not_implemented_handler(char const* expr, char const* file, int line);
|
||||
void dbg_exit(int status);
|
||||
#endif
|
||||
|
||||
bool dbg_is_debugger_present();
|
||||
|
@ -33,7 +35,8 @@ bool dbg_is_debugger_present();
|
|||
|
||||
#if KYTY_PLATFORM == KYTY_PLATFORM_WINDOWS
|
||||
#define ASSERT_HALT() \
|
||||
(Kyty::Core::dbg_is_debugger_present() ? (::fflush(nullptr), *(reinterpret_cast<volatile int*>(1)) = 0) : (std::_Exit(321), 1))
|
||||
(Kyty::Core::dbg_is_debugger_present() ? (::fflush(nullptr), *(reinterpret_cast<volatile int*>(1)) = 0) \
|
||||
: (Kyty::Core::dbg_exit(321), 1))
|
||||
#else
|
||||
#define ASSERT_HALT() (std::_Exit(321), 1)
|
||||
#endif
|
||||
|
|
|
@ -73,6 +73,11 @@ int dbg_exit_handler(char const* file, int line, const char* f, ...)
|
|||
return 1;
|
||||
}
|
||||
|
||||
void dbg_exit(int status)
|
||||
{
|
||||
std::_Exit(status);
|
||||
}
|
||||
|
||||
bool dbg_is_debugger_present()
|
||||
{
|
||||
#if KYTY_PLATFORM == KYTY_PLATFORM_WINDOWS
|
||||
|
|
Loading…
Reference in New Issue