Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions core/libs/prx/libc/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -938,6 +938,15 @@ if(BUILD_TESTING)
set_tests_properties(guest_underflow_error PROPERTIES ENVIRONMENT_MODIFICATION
"PATH=path_list_prepend:$<TARGET_FILE_DIR:libc>")
endif()
if(WIN32)
add_test_executable(exception_personality_tests ${LIBS_INCLUDE_DIR}/tests/ExceptionPersonality.cpp)
target_include_directories(exception_personality_tests PRIVATE ${LIBS_INCLUDE_DIR})
target_link_libraries(exception_personality_tests PRIVATE libc)
configure_windows_unwind(exception_personality_tests)
add_test(NAME exception_personality COMMAND exception_personality_tests)
set_tests_properties(exception_personality PROPERTIES ENVIRONMENT_MODIFICATION
"PATH=path_list_prepend:$<TARGET_FILE_DIR:libc>")
endif()
if(UNIX)
add_test_executable(exception_personality_tests ${LIBS_INCLUDE_DIR}/tests/ExceptionPersonality.cpp)
target_include_directories(exception_personality_tests PRIVATE ${LIBS_INCLUDE_DIR})
Expand Down
15 changes: 13 additions & 2 deletions core/libs/prx/libc/src/exception/Unwind.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,12 +107,23 @@ extern "C" void _Unwind_DeleteException(_Unwind_Exception*);

namespace LibcUnwind {
#ifdef _WIN32
static bool Readable(Word address, std::size_t size) {
for (Word cursor = address; cursor - address < size;) {
MEMORY_BASIC_INFORMATION memory{};
if (VirtualQuery(reinterpret_cast<const void*>(cursor), &memory, sizeof(memory)) != sizeof(memory)) return false;
if (memory.RegionSize == 0 || memory.State != MEM_COMMIT || (memory.Protect & (PAGE_NOACCESS | PAGE_GUARD)) != 0 || (memory.Protect & 0xff) == PAGE_EXECUTE) return false;
cursor = reinterpret_cast<Word>(memory.BaseAddress) + memory.RegionSize;
}
return true;
}

static Word ResolveImport(Word address) {
const auto* code = reinterpret_cast<const Byte*>(address);
if (code[0] == 0xff && code[1] == 0x25) {
if (Readable(address, 6) && code[0] == 0xff && code[1] == 0x25) {
std::int32_t displacement;
std::memcpy(&displacement, code + 2, sizeof(displacement));
std::memcpy(&address, code + 6 + displacement, sizeof(address));
const Word slot = address + 6 + displacement;
if (Readable(slot, sizeof(address))) std::memcpy(&address, reinterpret_cast<const void*>(slot), sizeof(address));
}
return address;
}
Expand Down
Loading