Skip to content
Closed
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
58 changes: 58 additions & 0 deletions core/libs/prx/libSceAddressSanitizer/Allocator.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
#include "prx/libSceAddressSanitizer/include/Api.hpp"
#include "prx/libc/include/Api.hpp"

#include <cstddef>

extern "C" {

void* APS5_VABI __asan_malloc(std::size_t size) {
return malloc_nid_postfix(size);
}

void* APS5_VABI __asan_calloc(std::size_t count, std::size_t size) {
return calloc_nid_postfix(count, size);
}

void* APS5_VABI __asan_realloc(void* pointer, std::size_t size) {
return realloc_nid_postfix(pointer, size);
}

void* APS5_VABI __asan_reallocalign(void* pointer, std::size_t size, std::size_t alignment) {
return reallocalign_nid_postfix(pointer, size, alignment);
}

void APS5_VABI __asan_free(void* pointer) {
free_nid_postfix(pointer);
}

void* APS5_VABI __asan_memalign(std::size_t alignment, std::size_t size) {
return memalign_nid_postfix(alignment, size);
}

void* APS5_VABI __asan_aligned_alloc(std::size_t alignment, std::size_t size) {
return aligned_alloc_nid_postfix(alignment, size);
}

int APS5_VABI __asan_posix_memalign(void** pointer, std::size_t alignment, std::size_t size) {
return posix_memalign_nid_postfix(pointer, alignment, size);
}

std::size_t APS5_VABI __asan_malloc_usable_size(void* pointer) {
return pointer != nullptr ? malloc_usable_size_nid_postfix(pointer) : 0;
}

void APS5_VABI __asan_malloc_stats() {
}

void APS5_VABI __asan_print_accumulated_stats() {
}

std::size_t APS5_VABI __asan_load_cxx_array_cookie(void* pointer) {
return pointer != nullptr ? *static_cast<const std::size_t*>(pointer) : 0;
}

void* APS5_VABI __asan_poison_cxx_array_cookie(void* pointer) {
return pointer;
}

}
24 changes: 24 additions & 0 deletions core/libs/prx/libSceAddressSanitizer/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
add_library(libSceAddressSanitizer SHARED EXCLUDE_FROM_ALL
Allocator.cpp
Control.cpp
Export.cpp
Memory.cpp
Report.cpp
Shadow.cpp
Ubsan.cpp
)
target_include_directories(libSceAddressSanitizer PRIVATE ${LIBS_INCLUDE_DIR})
configure_windows_unwind(libSceAddressSanitizer)

if(BUILD_TESTING)
add_test_executable(guest_address_sanitizer_tests ${LIBS_INCLUDE_DIR}/tests/GuestAddressSanitizer.cpp)
target_include_directories(guest_address_sanitizer_tests PRIVATE ${LIBS_INCLUDE_DIR})
target_link_libraries(guest_address_sanitizer_tests PRIVATE libSceAddressSanitizer libc)
configure_windows_unwind(guest_address_sanitizer_tests)
add_test(NAME guest_address_sanitizer COMMAND guest_address_sanitizer_tests)
set_tests_properties(guest_address_sanitizer PROPERTIES TIMEOUT 30)
if(WIN32)
set_tests_properties(guest_address_sanitizer PROPERTIES ENVIRONMENT_MODIFICATION
"PATH=path_list_prepend:$<TARGET_FILE_DIR:libSceAddressSanitizer>")
endif()
endif()
198 changes: 198 additions & 0 deletions core/libs/prx/libSceAddressSanitizer/Control.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
#include "prx/libSceAddressSanitizer/include/Api.hpp"
#include "prx/libc/include/Api.hpp"

#include <atomic>
#include <cstddef>
#include <cstdint>
#include <cstring>

namespace {

std::atomic<bool> initialized{false};
std::atomic<std::size_t> registeredGlobals{0};
std::atomic<std::uint32_t> coverageGuard{0};
std::atomic<void (*)()> deathCallback{nullptr};
std::atomic<void*> reportDescriptor{nullptr};
std::atomic<bool> hasReportPath{false};
char reportPath[4096] = "";

const char* const noOptions = "";
const char* const noPath = "";

void Prepare(const char* name) {
if (!initialized.load(std::memory_order_acquire)) initialized.store(true, std::memory_order_release);
(void)name;
}

}

extern "C" {

void APS5_VABI __asan_init() {
Prepare(nullptr);
}

void APS5_VABI __asan_init_v5() {
Prepare(nullptr);
}

void APS5_VABI __asan_version_mismatch_check_v6() {
}

void APS5_VABI __asan_version_mismatch_check_v7() {
}

void APS5_VABI __asan_version_mismatch_check_v8() {
}

void APS5_VABI __asan_before_dynamic_init(const char* moduleName) {
Prepare(moduleName);
}

void APS5_VABI __asan_after_dynamic_init() {
Prepare(nullptr);
}

void APS5_VABI __asan_register_globals(const void*, std::size_t count) {
registeredGlobals.fetch_add(count, std::memory_order_relaxed);
}

void APS5_VABI __asan_unregister_globals(const void*, std::size_t count) {
auto current = registeredGlobals.load(std::memory_order_relaxed);
while (true) {
const auto next = current > count ? current - count : 0;
if (registeredGlobals.compare_exchange_weak(current, next, std::memory_order_relaxed)) return;
}
}

void APS5_VABI __asan_register_elf_globals(std::uintptr_t* flag, const void*, const void*) {
if (flag != nullptr) *flag = 1;
}

void APS5_VABI __asan_unregister_elf_globals(std::uintptr_t* flag, const void*, const void*) {
if (flag != nullptr) *flag = 0;
}

void APS5_VABI __asan_register_image_globals(std::uintptr_t* flag) {
if (flag != nullptr) *flag = 1;
}

void APS5_VABI __asan_unregister_image_globals(std::uintptr_t* flag) {
if (flag != nullptr) *flag = 0;
}

void APS5_VABI __asan_handle_no_return() {
}

void APS5_VABI __sanitizer_start_switch_fiber(void** fakeStackSave, const void*, std::size_t) {
if (fakeStackSave != nullptr) *fakeStackSave = nullptr;
}

void APS5_VABI __sanitizer_finish_switch_fiber(void*, const void** oldBottom, std::size_t* oldSize) {
if (oldBottom != nullptr) *oldBottom = nullptr;
if (oldSize != nullptr) *oldSize = 0;
}

void APS5_VABI __sanitizer_sandbox_on_notify(void*) {
}

void APS5_VABI __sanitizer_malloc_hook(const volatile void*, std::size_t) {
}

void APS5_VABI __sanitizer_free_hook(const volatile void*) {
}

void APS5_VABI __sanitizer_purge_allocator() {
}

int APS5_VABI __sanitizer_get_ownership(const void* pointer) {
return pointer != nullptr ? 1 : 0;
}

void* APS5_VABI __sanitizer_get_allocated_begin(const void* pointer) {
return const_cast<void*>(pointer);
}

std::size_t APS5_VABI __sanitizer_get_allocated_size(const void* pointer) {
if (pointer == nullptr) return 0;
return malloc_usable_size_nid_postfix(const_cast<void*>(pointer));
}

std::size_t APS5_VABI __sanitizer_get_allocated_size_fast(const void* pointer) {
return __sanitizer_get_allocated_size(pointer);
}

std::size_t APS5_VABI __sanitizer_get_estimated_allocated_size(std::size_t size) {
return size;
}

void APS5_VABI __sanitizer_set_death_callback(void (*callback)()) {
deathCallback.store(callback, std::memory_order_release);
}

void APS5_VABI __sanitizer_set_report_fd(void* descriptor) {
reportDescriptor.store(descriptor, std::memory_order_release);
}

void APS5_VABI __sanitizer_set_report_path(const char* path) {
if (path == nullptr) {
hasReportPath.store(false, std::memory_order_release);
reportPath[0] = '\0';
return;
}
std::strncpy(reportPath, path, sizeof(reportPath) - 1);
reportPath[sizeof(reportPath) - 1] = '\0';
hasReportPath.store(true, std::memory_order_release);
}

const char* APS5_VABI __sanitizer_get_report_path() {
return hasReportPath.load(std::memory_order_acquire) ? reportPath : noPath;
}

void APS5_VABI __sanitizer_print_stack_trace() {
}

void APS5_VABI __sanitizer_symbolize_pc(void*, const char*, char* output, std::size_t outputSize) {
if (output != nullptr && outputSize != 0) output[0] = '\0';
}

void APS5_VABI __sanitizer_symbolize_global(void*, const char*, char* output, std::size_t outputSize) {
if (output != nullptr && outputSize != 0) output[0] = '\0';
}

const char* APS5_VABI __sancov_default_options() {
return noOptions;
}

void APS5_VABI __sanitizer_cov_trace_pc_guard(std::uint32_t*) {
}

void APS5_VABI __sanitizer_cov_trace_pc_guard_init(std::uint32_t* start, std::uint32_t* stop) {
if (start == nullptr || stop == nullptr || start == stop || *start != 0) return;
for (auto* guard = start; guard < stop; ++guard) *guard = coverageGuard.fetch_add(1, std::memory_order_relaxed) + 1;
}

void APS5_VABI __sanitizer_cov_dump() {
}

void APS5_VABI __sanitizer_dump_coverage(const std::uintptr_t*, std::uintptr_t) {
}

void APS5_VABI __sanitizer_dump_trace_pc_guard_coverage() {
}

void APS5_VABI __sanitizer_annotate_contiguous_container(const void*, const void*, const void*, const void*) {
}

int APS5_VABI __sanitizer_verify_contiguous_container(const void* begin, const void* middle, const void* end) {
const auto first = reinterpret_cast<std::uintptr_t>(begin);
const auto second = reinterpret_cast<std::uintptr_t>(middle);
const auto third = reinterpret_cast<std::uintptr_t>(end);
return first <= second && second <= third ? 1 : 0;
}

const void* APS5_VABI __sanitizer_contiguous_container_find_bad_address(const void*, const void*, const void*) {
return nullptr;
}

}
Loading
Loading