fix memory alloc issue

This commit is contained in:
InoriRus
2022-05-28 10:38:01 +10:00
parent 11f472acc6
commit 50b54b2607
11 changed files with 206 additions and 60 deletions
+1 -1
View File
@@ -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:
+1 -1
View File
@@ -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
+44
View File
@@ -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);
} }
@@ -415,15 +433,26 @@ int32_t KYTY_SYSV_ABI KernelMapNamedFlexibleMemory(void** addr_in_out, size_t le
printf("\t size = %" PRIu64 "\n", len); printf("\t size = %" PRIu64 "\n", len);
printf("\t mode = %s\n", Core::EnumName(mode).C_Str()); printf("\t mode = %s\n", Core::EnumName(mode).C_Str());
printf("\t name = %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
+27
View File
@@ -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
+32 -20
View File
@@ -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
+25 -12
View File
@@ -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));
+46 -9
View File
@@ -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)
: reinterpret_cast<uintptr_t>(VirtualAlloc(reinterpret_cast<LPVOID>(static_cast<uintptr_t>(address)), 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))); 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));
req2.Alignment = alignment; req.Alignment = alignment;
param.Type = MemExtendedParameterAddressRequirements; param.Type = MemExtendedParameterAddressRequirements;
param.Pointer = &req2; 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;
param2.Type = MemExtendedParameterAddressRequirements;
param2.Pointer = &req2;
static auto virtual_alloc2 = ResolveVirtualAlloc2(); static auto virtual_alloc2 = ResolveVirtualAlloc2();
@@ -343,12 +367,25 @@ 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), &param, 1)); get_protection_flag(mode), &param, 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), &param2, 1));
}
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 AllocAligned(address, size, mode, alignment << 1u);
} }
}
return ptr; return ptr;
} }
+4 -1
View File
@@ -16,11 +16,13 @@ int dbg_exit_handler(char const* file, int line, const char* f, ...) KYTY_FORMAT
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
+5
View File
@@ -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