mirror of
https://github.com/InoriRus/Kyty.git
synced 2026-08-28 05:06:40 +00:00
fix memory alloc issue
This commit is contained in:
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
version: 0.1.2.build-{build}
|
version: 0.1.3.build-{build}
|
||||||
image: Visual Studio 2019
|
image: Visual Studio 2019
|
||||||
environment:
|
environment:
|
||||||
matrix:
|
matrix:
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ if (KYTY_LINKER STREQUAL LD)
|
|||||||
set(KYTY_LD_OPTIONS "-Wl,--image-base=0x100000000000")
|
set(KYTY_LD_OPTIONS "-Wl,--image-base=0x100000000000")
|
||||||
endif()
|
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)
|
include(src_script.cmake)
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ namespace Kyty::Libs::LibKernel::Memory {
|
|||||||
KYTY_SUBSYSTEM_DEFINE(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 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);
|
int KYTY_SYSV_ABI KernelMunmap(uint64_t vaddr, size_t len);
|
||||||
size_t KYTY_SYSV_ABI KernelGetDirectMemorySize();
|
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,
|
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 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 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 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
|
} // 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);
|
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_destroy(LibKernel::PthreadMutex* mutex);
|
||||||
int KYTY_SYSV_ABI pthread_mutex_init(LibKernel::PthreadMutex* mutex, const LibKernel::PthreadMutexattr* attr);
|
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
|
} // namespace Posix
|
||||||
|
|
||||||
|
|||||||
@@ -74,12 +74,16 @@ public:
|
|||||||
|
|
||||||
KYTY_CLASS_NO_COPY(FlexibleMemory);
|
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 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 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);
|
bool Find(uint64_t vaddr, uint64_t* base_addr, size_t* len, int* prot, VirtualMemory::Mode* mode, Graphics::GpuMemoryMode* gpu_mode);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Vector<AllocatedBlock> m_allocated;
|
Vector<AllocatedBlock> m_allocated;
|
||||||
|
uint64_t m_allocated_total = 0;
|
||||||
Core::Mutex m_mutex;
|
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;
|
b.gpu_mode = gpu_mode;
|
||||||
|
|
||||||
m_allocated.Add(b);
|
m_allocated.Add(b);
|
||||||
|
m_allocated_total += len;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -329,6 +334,7 @@ bool FlexibleMemory::Unmap(uint64_t vaddr, uint64_t size, Graphics::GpuMemoryMod
|
|||||||
*gpu_mode = b.gpu_mode;
|
*gpu_mode = b.gpu_mode;
|
||||||
|
|
||||||
m_allocated.RemoveAt(index);
|
m_allocated.RemoveAt(index);
|
||||||
|
m_allocated_total -= size;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
index++;
|
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)
|
int32_t KYTY_SYSV_ABI KernelMapNamedFlexibleMemory(void** addr_in_out, size_t len, int prot, int flags, const char* name)
|
||||||
{
|
{
|
||||||
PRINT_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 5: mode = VirtualMemory::Mode::ExecuteRead; break;
|
||||||
case 6:
|
case 6:
|
||||||
case 7: mode = VirtualMemory::Mode::ExecuteReadWrite; break;
|
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);
|
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))
|
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);
|
VirtualMemory::Free(out_addr);
|
||||||
return KERNEL_ERROR_ENOMEM;
|
return KERNEL_ERROR_ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("\tin_addr = 0x%016" PRIx64 "\n", in_addr);
|
printf("\t in_addr = 0x%016" PRIx64 "\n", in_addr);
|
||||||
printf("\tout_addr = 0x%016" PRIx64 "\n", out_addr);
|
printf("\t out_addr = 0x%016" PRIx64 "\n", out_addr);
|
||||||
printf("\tsize = %" PRIu64 "\n", len);
|
printf("\t size = %" PRIu64 "\n", len);
|
||||||
printf("\tmode = %s\n", Core::EnumName(mode).C_Str());
|
printf("\t mode = %s\n", Core::EnumName(mode).C_Str());
|
||||||
printf("\tname = %s\n", name);
|
printf("\t name = %s\n", name);
|
||||||
|
printf("\t gpu_mode = %s\n", Core::EnumName(gpu_mode).C_Str());
|
||||||
|
|
||||||
if (out_addr == 0)
|
if (out_addr == 0)
|
||||||
{
|
{
|
||||||
return KERNEL_ERROR_ENOMEM;
|
return KERNEL_ERROR_ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (gpu_mode != Graphics::GpuMemoryMode::NoAccess)
|
||||||
|
{
|
||||||
|
Graphics::GpuMemorySetAllocatedRange(out_addr, len);
|
||||||
|
}
|
||||||
|
|
||||||
return OK;
|
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)
|
int KYTY_SYSV_ABI KernelMunmap(uint64_t vaddr, size_t len)
|
||||||
{
|
{
|
||||||
PRINT_NAME();
|
PRINT_NAME();
|
||||||
@@ -688,6 +717,21 @@ int KYTY_SYSV_ABI KernelQueryMemoryProtection(void* addr, void** start, void** e
|
|||||||
return OK;
|
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
|
} // namespace Kyty::Libs::LibKernel::Memory
|
||||||
|
|
||||||
#endif // KYTY_EMU_ENABLED
|
#endif // KYTY_EMU_ENABLED
|
||||||
|
|||||||
@@ -631,6 +631,8 @@ int KYTY_SYSV_ABI PthreadMutexattrInit(PthreadMutexattr* attr)
|
|||||||
{
|
{
|
||||||
// PRINT_NAME();
|
// PRINT_NAME();
|
||||||
|
|
||||||
|
EXIT_NOT_IMPLEMENTED(attr == nullptr);
|
||||||
|
|
||||||
*attr = new PthreadMutexattrPrivate {};
|
*attr = new PthreadMutexattrPrivate {};
|
||||||
|
|
||||||
int result = pthread_mutexattr_init(&(*attr)->p);
|
int result = pthread_mutexattr_init(&(*attr)->p);
|
||||||
@@ -669,6 +671,8 @@ int KYTY_SYSV_ABI PthreadMutexattrSettype(PthreadMutexattr* attr, int type)
|
|||||||
{
|
{
|
||||||
// PRINT_NAME();
|
// PRINT_NAME();
|
||||||
|
|
||||||
|
EXIT_NOT_IMPLEMENTED(attr == nullptr || *attr == nullptr);
|
||||||
|
|
||||||
int ptype = PTHREAD_MUTEX_DEFAULT;
|
int ptype = PTHREAD_MUTEX_DEFAULT;
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
@@ -693,6 +697,8 @@ int KYTY_SYSV_ABI PthreadMutexattrSetprotocol([[maybe_unused]] PthreadMutexattr*
|
|||||||
{
|
{
|
||||||
// PRINT_NAME();
|
// PRINT_NAME();
|
||||||
|
|
||||||
|
EXIT_NOT_IMPLEMENTED(attr == nullptr || *attr == nullptr);
|
||||||
|
|
||||||
[[maybe_unused]] int pprotocol = PTHREAD_PRIO_NONE;
|
[[maybe_unused]] int pprotocol = PTHREAD_PRIO_NONE;
|
||||||
switch (protocol)
|
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));
|
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 Posix
|
||||||
|
|
||||||
} // namespace Kyty::Libs
|
} // 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));
|
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 LibKernel
|
||||||
|
|
||||||
namespace Posix {
|
namespace Posix {
|
||||||
@@ -455,6 +462,9 @@ LIB_DEFINE(InitLibKernel_1_Posix)
|
|||||||
LIB_FUNC("7H0iTOciTLo", Posix::pthread_mutex_lock);
|
LIB_FUNC("7H0iTOciTLo", Posix::pthread_mutex_lock);
|
||||||
LIB_FUNC("2Z+PpY6CaJg", Posix::pthread_mutex_unlock);
|
LIB_FUNC("2Z+PpY6CaJg", Posix::pthread_mutex_unlock);
|
||||||
LIB_FUNC("ttHNfU+qDBU", Posix::pthread_mutex_init);
|
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("ltCfaGr2JGE", Posix::pthread_mutex_destroy);
|
||||||
LIB_FUNC("mkx2fVhNMsg", Posix::pthread_cond_broadcast);
|
LIB_FUNC("mkx2fVhNMsg", Posix::pthread_cond_broadcast);
|
||||||
LIB_FUNC("Op8TBGY5KHg", Posix::pthread_cond_wait);
|
LIB_FUNC("Op8TBGY5KHg", Posix::pthread_cond_wait);
|
||||||
@@ -492,6 +502,7 @@ LIB_DEFINE(InitLibKernel_1_FS)
|
|||||||
LIB_DEFINE(InitLibKernel_1_Mem)
|
LIB_DEFINE(InitLibKernel_1_Mem)
|
||||||
{
|
{
|
||||||
LIB_FUNC("mL8NDH86iQI", Memory::KernelMapNamedFlexibleMemory);
|
LIB_FUNC("mL8NDH86iQI", Memory::KernelMapNamedFlexibleMemory);
|
||||||
|
LIB_FUNC("IWIBBdTHit4", Memory::KernelMapFlexibleMemory);
|
||||||
LIB_FUNC("cQke9UuBQOk", Memory::KernelMunmap);
|
LIB_FUNC("cQke9UuBQOk", Memory::KernelMunmap);
|
||||||
LIB_FUNC("pO96TwzOm5E", Memory::KernelGetDirectMemorySize);
|
LIB_FUNC("pO96TwzOm5E", Memory::KernelGetDirectMemorySize);
|
||||||
LIB_FUNC("rTXw65xmLIA", Memory::KernelAllocateDirectMemory);
|
LIB_FUNC("rTXw65xmLIA", Memory::KernelAllocateDirectMemory);
|
||||||
@@ -499,6 +510,7 @@ LIB_DEFINE(InitLibKernel_1_Mem)
|
|||||||
LIB_FUNC("MBuItvba6z8", Memory::KernelReleaseDirectMemory);
|
LIB_FUNC("MBuItvba6z8", Memory::KernelReleaseDirectMemory);
|
||||||
LIB_FUNC("WFcfL2lzido", Memory::KernelQueryMemoryProtection);
|
LIB_FUNC("WFcfL2lzido", Memory::KernelQueryMemoryProtection);
|
||||||
LIB_FUNC("BHouLQzh0X0", Memory::KernelDirectMemoryQuery);
|
LIB_FUNC("BHouLQzh0X0", Memory::KernelDirectMemoryQuery);
|
||||||
|
LIB_FUNC("aNz11fnnzi4", Memory::KernelAvailableFlexibleMemorySize);
|
||||||
}
|
}
|
||||||
|
|
||||||
LIB_DEFINE(InitLibKernel_1_Equeue)
|
LIB_DEFINE(InitLibKernel_1_Equeue)
|
||||||
@@ -600,34 +612,34 @@ LIB_DEFINE(InitLibKernel_1)
|
|||||||
LIB_OBJECT("f7uOxY9mM1U", &LibKernel::g_stack_chk_guard);
|
LIB_OBJECT("f7uOxY9mM1U", &LibKernel::g_stack_chk_guard);
|
||||||
LIB_OBJECT("djxxOmW6-aw", &LibKernel::g_progname);
|
LIB_OBJECT("djxxOmW6-aw", &LibKernel::g_progname);
|
||||||
|
|
||||||
LIB_FUNC("Ou3iL1abvng", LibKernel::stack_chk_fail);
|
LIB_FUNC("1jfXLRVzisc", LibKernel::KernelUsleep);
|
||||||
LIB_FUNC("wzvqT4UqKX8", LibKernel::KernelLoadStartModule);
|
LIB_FUNC("6xVpy0Fdq+I", LibKernel::sigprocmask);
|
||||||
LIB_FUNC("QKd0qM58Qes", LibKernel::KernelStopUnloadModule);
|
LIB_FUNC("6Z83sYWFlA8", LibKernel::exit);
|
||||||
LIB_FUNC("vNe1w4diLCs", LibKernel::tls_get_addr);
|
LIB_FUNC("8OnWXlgQlvo", LibKernel::KernelRtldThreadAtexitDecrement);
|
||||||
LIB_FUNC("959qrazPIrg", LibKernel::KernelGetProcParam);
|
LIB_FUNC("959qrazPIrg", LibKernel::KernelGetProcParam);
|
||||||
LIB_FUNC("p5EcQeEeJAE", LibKernel::KernelRtldSetApplicationHeapAPI);
|
LIB_FUNC("9BcDykPmo1I", LibKernel::get_error_addr);
|
||||||
LIB_FUNC("FxVZqBAA7ks", LibKernel::write);
|
LIB_FUNC("bnZxYgAFeA0", LibKernel::KernelGetSanitizerNewReplaceExternal);
|
||||||
|
LIB_FUNC("ca7v6Cxulzs", LibKernel::KernelSetGPO);
|
||||||
LIB_FUNC("DRuBt2pvICk", LibKernel::read);
|
LIB_FUNC("DRuBt2pvICk", LibKernel::read);
|
||||||
LIB_FUNC("f7KBOafysXo", LibKernel::KernelGetModuleInfoFromAddr);
|
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("Fjc4-n1+y2g", LibKernel::elf_phdr_match_addr);
|
||||||
|
LIB_FUNC("FxVZqBAA7ks", LibKernel::write);
|
||||||
LIB_FUNC("kbw4UHHSYy0", LibKernel::pthread_cxa_finalize);
|
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("lLMT9vJAck0", LibKernel::clock_gettime);
|
||||||
|
LIB_FUNC("OMDRKKAZ8I4", LibKernel::KernelDebugRaiseException);
|
||||||
LIB_FUNC("1jfXLRVzisc", LibKernel::KernelUsleep);
|
LIB_FUNC("Ou3iL1abvng", LibKernel::stack_chk_fail);
|
||||||
LIB_FUNC("rNhWz+lvOMU", LibKernel::KernelSetThreadDtors);
|
LIB_FUNC("p5EcQeEeJAE", LibKernel::KernelRtldSetApplicationHeapAPI);
|
||||||
LIB_FUNC("WhCc1w3EhSI", LibKernel::KernelSetThreadAtexitReport);
|
|
||||||
LIB_FUNC("pB-yGZ2nQ9o", LibKernel::KernelSetThreadAtexitCount);
|
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("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
|
} // namespace Kyty::Libs
|
||||||
|
|||||||
@@ -68,13 +68,17 @@ struct RelocateHandlerStack
|
|||||||
uint64_t stack[3];
|
uint64_t stack[3];
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr uint64_t INVALID_MEMORY = 0x840000000;
|
constexpr uint64_t SYSTEM_RESERVED = 0x800000000u;
|
||||||
constexpr uint64_t DESIRED_BASE_ADDR = 0x010000000;
|
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 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;
|
static Program* g_tls_main_program = nullptr;
|
||||||
alignas(64) static uint8_t g_tls_reg_save_area[XSAVE_BUFFER_SIZE + sizeof(XSAVE_CHK_GUARD)];
|
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)
|
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)
|
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);
|
Core::Singleton<Loader::RuntimeLinker>::Instance()->StackTrace(info->rbp);
|
||||||
|
|
||||||
EXIT("Access violation: %s [%016" PRIx64 "] %s\n", Core::EnumName(info->access_violation_type).C_Str(),
|
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!!!");
|
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);
|
bool weak = (ri.bind == BindType::Weak || !program->fail_if_global_not_resolved);
|
||||||
if (ri.type == SymbolType::Object && weak)
|
if (ri.type == SymbolType::Object && weak)
|
||||||
{
|
{
|
||||||
value = INVALID_MEMORY;
|
value = g_invalid_memory;
|
||||||
} else if (ri.type == SymbolType::Func && jmprela_table && weak)
|
} else if (ri.type == SymbolType::Func && jmprela_table && weak)
|
||||||
{
|
{
|
||||||
if (program->custom_call_plt_vaddr != 0)
|
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") ||
|
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"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;
|
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;
|
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_vaddr == 0);
|
||||||
EXIT_IF(program->base_size_aligned < program->base_size);
|
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);
|
program->base_size_aligned + exception_handler_size + tls_handler_size, kyty_exception_handler);
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
program->exception_handler->Install(0, program->base_vaddr + program->base_size_aligned,
|
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,
|
program->base_vaddr + program->base_size_aligned + exception_handler_size + tls_handler_size -
|
||||||
|
SYSTEM_RESERVED,
|
||||||
kyty_exception_handler);
|
kyty_exception_handler);
|
||||||
|
|
||||||
if (Libs::Graphics::GpuMemoryWatcherEnabled())
|
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);
|
program->custom_call_plt_num = program->dynamic_info->jmprela_table_size / sizeof(Elf64_Rela);
|
||||||
auto size = Jit::CallPlt::GetSize(program->custom_call_plt_num);
|
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);
|
auto* code = new (reinterpret_cast<void*>(program->custom_call_plt_vaddr)) Jit::CallPlt(program->custom_call_plt_num);
|
||||||
code->SetPltGot(pltgot_vaddr);
|
code->SetPltGot(pltgot_vaddr);
|
||||||
VirtualMemory::Protect(program->custom_call_plt_vaddr, size, VirtualMemory::Mode::Execute);
|
VirtualMemory::Protect(program->custom_call_plt_vaddr, size, VirtualMemory::Mode::Execute);
|
||||||
@@ -1395,6 +1402,12 @@ void RuntimeLinker::Relocate(Program* program)
|
|||||||
|
|
||||||
EXIT_IF(program == nullptr);
|
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());
|
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));
|
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 <minwinbase.h>
|
||||||
// IWYU pragma: no_include <apisetcconv.h>
|
// IWYU pragma: no_include <apisetcconv.h>
|
||||||
// IWYU pragma: no_include <winbase.h>
|
// IWYU pragma: no_include <winbase.h>
|
||||||
|
// IWYU pragma: no_include <winerror.h>
|
||||||
|
|
||||||
//#include <memoryapi.h>
|
//#include <memoryapi.h>
|
||||||
|
|
||||||
@@ -299,12 +300,21 @@ void Init()
|
|||||||
|
|
||||||
uint64_t Alloc(uint64_t address, uint64_t size, Mode mode)
|
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,
|
auto ptr = (address == 0 ? AllocAligned(address, size, mode, 1)
|
||||||
static_cast<DWORD>(MEM_COMMIT) | static_cast<DWORD>(MEM_RESERVE),
|
: reinterpret_cast<uintptr_t>(VirtualAlloc(reinterpret_cast<LPVOID>(static_cast<uintptr_t>(address)), size,
|
||||||
get_protection_flag(mode)));
|
static_cast<DWORD>(MEM_COMMIT) | static_cast<DWORD>(MEM_RESERVE),
|
||||||
|
get_protection_flag(mode))));
|
||||||
if (ptr == 0)
|
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;
|
return ptr;
|
||||||
}
|
}
|
||||||
@@ -325,16 +335,30 @@ uint64_t AllocAligned(uint64_t address, uint64_t size, Mode mode, uint64_t align
|
|||||||
{
|
{
|
||||||
if (alignment == 0)
|
if (alignment == 0)
|
||||||
{
|
{
|
||||||
|
printf("VirtualAlloc2 failed: 0x%08" PRIx32 "\n", static_cast<uint32_t>(GetLastError()));
|
||||||
return 0;
|
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 {};
|
MEM_EXTENDED_PARAMETER param {};
|
||||||
req2.LowestStartingAddress = nullptr;
|
req.LowestStartingAddress = (address == 0 ? reinterpret_cast<PVOID>(SYSTEM_MANAGED_MIN) : reinterpret_cast<PVOID>(address));
|
||||||
req2.HighestEndingAddress = reinterpret_cast<PVOID>(0xffffffffffu); // nullptr;
|
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;
|
req2.Alignment = alignment;
|
||||||
param.Type = MemExtendedParameterAddressRequirements;
|
param2.Type = MemExtendedParameterAddressRequirements;
|
||||||
param.Pointer = &req2;
|
param2.Pointer = &req2;
|
||||||
|
|
||||||
static auto virtual_alloc2 = ResolveVirtualAlloc2();
|
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,
|
auto ptr = reinterpret_cast<uintptr_t>(virtual_alloc2(GetCurrentProcess(), nullptr, size,
|
||||||
static_cast<DWORD>(MEM_COMMIT) | static_cast<DWORD>(MEM_RESERVE),
|
static_cast<DWORD>(MEM_COMMIT) | static_cast<DWORD>(MEM_RESERVE),
|
||||||
get_protection_flag(mode), ¶m, 1));
|
get_protection_flag(mode), ¶m, 1));
|
||||||
|
|
||||||
if (ptr == 0)
|
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;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,15 +12,17 @@
|
|||||||
namespace Kyty::Core {
|
namespace Kyty::Core {
|
||||||
|
|
||||||
#ifdef __clang__
|
#ifdef __clang__
|
||||||
int dbg_exit_handler(char const* file, int line, const char* f, ...) KYTY_FORMAT_PRINTF(3, 4) __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_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_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_not_implemented_handler(char const* expr, char const* file, int line) __attribute__((analyzer_noreturn));
|
||||||
|
void dbg_exit(int status) __attribute__((analyzer_noreturn));
|
||||||
#else
|
#else
|
||||||
int dbg_exit_handler(char const* file, int line, const char* f, ...) KYTY_FORMAT_PRINTF(3, 4);
|
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_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_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_not_implemented_handler(char const* expr, char const* file, int line);
|
||||||
|
void dbg_exit(int status);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool dbg_is_debugger_present();
|
bool dbg_is_debugger_present();
|
||||||
@@ -33,7 +35,8 @@ bool dbg_is_debugger_present();
|
|||||||
|
|
||||||
#if KYTY_PLATFORM == KYTY_PLATFORM_WINDOWS
|
#if KYTY_PLATFORM == KYTY_PLATFORM_WINDOWS
|
||||||
#define ASSERT_HALT() \
|
#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
|
#else
|
||||||
#define ASSERT_HALT() (std::_Exit(321), 1)
|
#define ASSERT_HALT() (std::_Exit(321), 1)
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -73,6 +73,11 @@ int dbg_exit_handler(char const* file, int line, const char* f, ...)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void dbg_exit(int status)
|
||||||
|
{
|
||||||
|
std::_Exit(status);
|
||||||
|
}
|
||||||
|
|
||||||
bool dbg_is_debugger_present()
|
bool dbg_is_debugger_present()
|
||||||
{
|
{
|
||||||
#if KYTY_PLATFORM == KYTY_PLATFORM_WINDOWS
|
#if KYTY_PLATFORM == KYTY_PLATFORM_WINDOWS
|
||||||
|
|||||||
Reference in New Issue
Block a user