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

View File

@ -1,4 +1,4 @@
version: 0.1.2.build-{build}
version: 0.1.3.build-{build}
image: Visual Studio 2019
environment:
matrix:

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

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));
}
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

View File

@ -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));

View File

@ -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), &param, 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), &param2, 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;
}

View File

@ -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

View File

@ -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