diff --git a/.gitmodules b/.gitmodules index f05248d4084f..8e275d96e6ea 100644 --- a/.gitmodules +++ b/.gitmodules @@ -67,6 +67,10 @@ [submodule "3rdparty/nghttp2"] path = 3rdparty/nghttp2 url = https://github.com/nghttp2/nghttp2.git +[submodule "3rdparty/compiler-rt"] + path = 3rdparty/compiler-rt + url = https://github.com/PrivacyOnion/compiler-rt.git + shallow = true [submodule "3rdparty/quickjs"] path = 3rdparty/quickjs url = https://github.com/quickjs-ng/quickjs.git diff --git a/3rdparty/compiler-rt b/3rdparty/compiler-rt new file mode 160000 index 000000000000..040178683306 --- /dev/null +++ b/3rdparty/compiler-rt @@ -0,0 +1 @@ +Subproject commit 040178683306fd2f85820a9e85ad47251c86b401 diff --git a/core/libs/prx/libSceAddressSanitizer/CMakeLists.txt b/core/libs/prx/libSceAddressSanitizer/CMakeLists.txt new file mode 100644 index 000000000000..6823c26a866e --- /dev/null +++ b/core/libs/prx/libSceAddressSanitizer/CMakeLists.txt @@ -0,0 +1,282 @@ +set(ANYPS5_LIBS_INCLUDE_DIR ${LIBS_INCLUDE_DIR}) +add_subdirectory(${CMAKE_SOURCE_DIR}/3rdparty/compiler-rt/lib/asan_anyps5 ${CMAKE_CURRENT_BINARY_DIR}/compiler-rt-anyps5 EXCLUDE_FROM_ALL) +add_library(libSceAddressSanitizer SHARED EXCLUDE_FROM_ALL Export.cpp) +target_link_libraries(libSceAddressSanitizer PRIVATE compiler_rt_anyps5) +target_include_directories(libSceAddressSanitizer PUBLIC ${CMAKE_SOURCE_DIR}/3rdparty/compiler-rt/lib) +target_include_directories(libSceAddressSanitizer PRIVATE ${LIBS_INCLUDE_DIR}) +configure_windows_unwind(libSceAddressSanitizer) + +if(BUILD_TESTING AND (WIN32 OR CMAKE_SYSTEM_NAME STREQUAL "Linux")) + add_test_executable(guest_addresssanitizer_shadow_tests ${LIBS_INCLUDE_DIR}/tests/GuestAddressSanitizerShadow.cpp) + target_include_directories(guest_addresssanitizer_shadow_tests PRIVATE ${LIBS_INCLUDE_DIR}) + target_link_libraries(guest_addresssanitizer_shadow_tests PRIVATE libSceAddressSanitizer libc) + configure_windows_unwind(guest_addresssanitizer_shadow_tests) + add_test(NAME guest_addresssanitizer_shadow COMMAND guest_addresssanitizer_shadow_tests) + set_tests_properties(guest_addresssanitizer_shadow PROPERTIES TIMEOUT 20) + add_test_executable(guest_addresssanitizer_runtime_tests ${LIBS_INCLUDE_DIR}/tests/GuestAddressSanitizerRuntime.cpp) + target_include_directories(guest_addresssanitizer_runtime_tests PRIVATE ${LIBS_INCLUDE_DIR}) + target_link_libraries(guest_addresssanitizer_runtime_tests PRIVATE libSceAddressSanitizer libc) + configure_windows_unwind(guest_addresssanitizer_runtime_tests) + add_test(NAME guest_addresssanitizer_fake_stack_option COMMAND guest_addresssanitizer_runtime_tests fake_stack_option) + set_tests_properties(guest_addresssanitizer_fake_stack_option PROPERTIES TIMEOUT 20) + add_test(NAME guest_addresssanitizer_vptr_cache_data COMMAND guest_addresssanitizer_runtime_tests vptr_cache_data) + set_tests_properties(guest_addresssanitizer_vptr_cache_data PROPERTIES TIMEOUT 20) + add_test(NAME guest_addresssanitizer_globals_invalid_array COMMAND guest_addresssanitizer_runtime_tests globals_invalid_array) + set_tests_properties(guest_addresssanitizer_globals_invalid_array PROPERTIES TIMEOUT 20) + if(WIN32) + set_tests_properties(guest_addresssanitizer_fake_stack_option PROPERTIES ENVIRONMENT_MODIFICATION + "PATH=path_list_prepend:$") + set_tests_properties(guest_addresssanitizer_vptr_cache_data PROPERTIES ENVIRONMENT_MODIFICATION + "PATH=path_list_prepend:$") + set_tests_properties(guest_addresssanitizer_globals_invalid_array PROPERTIES ENVIRONMENT_MODIFICATION + "PATH=path_list_prepend:$") + endif() + if(Python3_Interpreter_FOUND) + add_test(NAME guest_addresssanitizer_legacy_ubsan COMMAND ${Python3_EXECUTABLE} + ${LIBS_INCLUDE_DIR}/tests/test_addresssanitizer_legacy.py $) + set_tests_properties(guest_addresssanitizer_legacy_ubsan PROPERTIES TIMEOUT 20) + if(WIN32) + set_tests_properties(guest_addresssanitizer_legacy_ubsan PROPERTIES ENVIRONMENT_MODIFICATION + "PATH=path_list_prepend:$") + endif() + endif() + foreach(mode clean contiguous double_ended memory heap wrapper_call_sites heap_aligned fake_stack no_return globals globals_elf fibers locate init sandbox_notify) + add_test(NAME guest_addresssanitizer_runtime_${mode} COMMAND guest_addresssanitizer_runtime_tests ${mode}) + set_tests_properties(guest_addresssanitizer_runtime_${mode} PROPERTIES TIMEOUT 20) + if(WIN32) + set_tests_properties(guest_addresssanitizer_runtime_${mode} PROPERTIES ENVIRONMENT_MODIFICATION + "PATH=path_list_prepend:$") + endif() + endforeach() + add_test(NAME guest_addresssanitizer_runtime_exp_load4 COMMAND ${CMAKE_COMMAND} + -DEXECUTABLE=$ -DMODE=exp_load4 -DSTATUS=1 + "-DPATTERN=ERROR: AddressSanitizer: use-after-poison on address 0x[0-9a-f]+ at pc 0x[0-9a-f]+ bp 0x[0-9a-f]+ sp 0x[0-9a-f]+.READ of size 4 at 0x[0-9a-f]+ thread T-1.*ABORTING" + -P ${LIBS_INCLUDE_DIR}/tests/AddressSanitizerDiagnostic.cmake) + add_test(NAME guest_addresssanitizer_runtime_exp_store16_noabort COMMAND ${CMAKE_COMMAND} + -DEXECUTABLE=$ -DMODE=exp_store16_noabort -DSTATUS=1 + "-DPATTERN=ERROR: AddressSanitizer: use-after-poison on address 0x[0-9a-f]+ at pc 0x[0-9a-f]+ bp 0x[0-9a-f]+ sp 0x[0-9a-f]+.WRITE of size 16 at .*ABORTING" + -P ${LIBS_INCLUDE_DIR}/tests/AddressSanitizerDiagnostic.cmake) + add_test(NAME guest_addresssanitizer_runtime_exp_loadN COMMAND ${CMAKE_COMMAND} + -DEXECUTABLE=$ -DMODE=exp_loadN -DSTATUS=1 + "-DPATTERN=ERROR: AddressSanitizer: use-after-poison on address 0x[0-9a-f]+ at pc 0x[0-9a-f]+ bp 0x[0-9a-f]+ sp 0x[0-9a-f]+.READ of size 16 at .*ABORTING" + -P ${LIBS_INCLUDE_DIR}/tests/AddressSanitizerDiagnostic.cmake) + add_test(NAME guest_addresssanitizer_runtime_report_exp_store2 COMMAND ${CMAKE_COMMAND} + -DEXECUTABLE=$ -DMODE=report_exp_store2 -DSTATUS=1 + "-DPATTERN=ERROR: AddressSanitizer: use-after-poison on address 0x[0-9a-f]+ at pc 0x[0-9a-f]+ bp 0x[0-9a-f]+ sp 0x[0-9a-f]+.WRITE of size 2 at .*ABORTING" + -P ${LIBS_INCLUDE_DIR}/tests/AddressSanitizerDiagnostic.cmake) + add_test(NAME guest_addresssanitizer_runtime_report_exp_load_n COMMAND ${CMAKE_COMMAND} + -DEXECUTABLE=$ -DMODE=report_exp_load_n -DSTATUS=1 + "-DPATTERN=ERROR: AddressSanitizer: use-after-poison on address 0x[0-9a-f]+ at pc 0x[0-9a-f]+ bp 0x[0-9a-f]+ sp 0x[0-9a-f]+.READ of size 6 at .*ABORTING" + -P ${LIBS_INCLUDE_DIR}/tests/AddressSanitizerDiagnostic.cmake) + add_test(NAME guest_addresssanitizer_runtime_memcpy_source COMMAND ${CMAKE_COMMAND} + -DEXECUTABLE=$ -DMODE=memcpy_source -DSTATUS=1 + "-DPATTERN=ERROR: AddressSanitizer: use-after-poison on address 0x[0-9a-f]+ at pc 0x[0-9a-f]+ bp 0x[0-9a-f]+ sp 0x[0-9a-f]+.READ of size 16 at .*ABORTING" + -P ${LIBS_INCLUDE_DIR}/tests/AddressSanitizerDiagnostic.cmake) + add_test(NAME guest_addresssanitizer_runtime_memset_poison COMMAND ${CMAKE_COMMAND} + -DEXECUTABLE=$ -DMODE=memset_poison -DSTATUS=1 + "-DPATTERN=ERROR: AddressSanitizer: use-after-poison on address 0x[0-9a-f]+ at pc 0x[0-9a-f]+ bp 0x[0-9a-f]+ sp 0x[0-9a-f]+.WRITE of size 16 at .*ABORTING" + -P ${LIBS_INCLUDE_DIR}/tests/AddressSanitizerDiagnostic.cmake) + add_test(NAME guest_addresssanitizer_runtime_memmove_poison COMMAND ${CMAKE_COMMAND} + -DEXECUTABLE=$ -DMODE=memmove_poison -DSTATUS=1 + "-DPATTERN=ERROR: AddressSanitizer: use-after-poison on address 0x[0-9a-f]+ at pc 0x[0-9a-f]+ bp 0x[0-9a-f]+ sp 0x[0-9a-f]+.WRITE of size 8 at .*ABORTING" + -P ${LIBS_INCLUDE_DIR}/tests/AddressSanitizerDiagnostic.cmake) + add_test(NAME guest_addresssanitizer_runtime_memcpy_overlap COMMAND ${CMAKE_COMMAND} + -DEXECUTABLE=$ -DMODE=memcpy_overlap -DSTATUS=1 + "-DPATTERN=ERROR: AddressSanitizer: memcpy-param-overlap: memory ranges [[]0x[0-9a-f]+,0x[0-9a-f]+[)] and [[]0x[0-9a-f]+, 0x[0-9a-f]+[)] overlap.*ABORTING" + -P ${LIBS_INCLUDE_DIR}/tests/AddressSanitizerDiagnostic.cmake) + add_test(NAME guest_addresssanitizer_runtime_memset_negative COMMAND ${CMAKE_COMMAND} + -DEXECUTABLE=$ -DMODE=memset_negative -DSTATUS=1 + "-DPATTERN=ERROR: AddressSanitizer: negative-size-param: [(]size=-1[)].*ABORTING" + -P ${LIBS_INCLUDE_DIR}/tests/AddressSanitizerDiagnostic.cmake) + add_test(NAME guest_addresssanitizer_runtime_container_params COMMAND ${CMAKE_COMMAND} + -DEXECUTABLE=$ -DMODE=container_params -DSTATUS=1 + "-DPATTERN=ERROR: AddressSanitizer: bad parameters to __sanitizer_annotate_contiguous_container:.*beg : 0x[0-9a-f]+.*new_mid : 0x[0-9a-f]+.ERROR: beg is not aligned by 8.*ABORTING" + -P ${LIBS_INCLUDE_DIR}/tests/AddressSanitizerDiagnostic.cmake) + add_test(NAME guest_addresssanitizer_runtime_double_ended_params COMMAND ${CMAKE_COMMAND} + -DEXECUTABLE=$ -DMODE=double_ended_params -DSTATUS=1 + "-DPATTERN=ERROR: AddressSanitizer: bad parameters to __sanitizer_annotate_double_ended_contiguous_container:.*storage_beg : 0x[0-9a-f]+.*new_container_end : 0x[0-9a-f]+.ERROR: storage_beg is not aligned by 8.*ABORTING" + -P ${LIBS_INCLUDE_DIR}/tests/AddressSanitizerDiagnostic.cmake) + add_test(NAME guest_addresssanitizer_runtime_ubsan_arithmetic COMMAND ${CMAKE_COMMAND} + -DEXECUTABLE=$ -DMODE=ubsan_arithmetic -DSTATUS=0 + "-DPATTERN=test.cpp:10:5: runtime error: signed integer overflow: 2147483647 [+] 1 cannot be represented in type 'int'.SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior test.cpp:10:5.test.cpp:11:6: runtime error: unsigned integer overflow: 0 - 1 cannot be represented in type 'unsigned int'.SUMMARY: .*test.cpp:12:7: runtime error: signed integer overflow: 65536 [*] 65536 cannot be represented in type 'int'.*test.cpp:13:8: runtime error: negation of -2147483648 cannot be represented in type 'int'. cast to an unsigned type to negate this value to itself.*test.cpp:14:9: runtime error: division by zero.*test.cpp:15:10: runtime error: division of -2147483648 by -1 cannot be represented in type 'int'.*test.cpp:16:11: runtime error: shift exponent 40 is too large for 32-bit type 'int'.*test.cpp:17:12: runtime error: shift exponent -1 is negative.*test.cpp:18:13: runtime error: left shift of negative value -1.*test.cpp:19:14: runtime error: left shift of 1073741824 by 2 places cannot be represented in type 'int'.*test.cpp:20:15: runtime error: index 4 out of bounds for type 'int .4.'.*test.cpp:21:16: runtime error: variable length array bound evaluates to non-positive value -3" + -P ${LIBS_INCLUDE_DIR}/tests/AddressSanitizerDiagnostic.cmake) + add_test(NAME guest_addresssanitizer_runtime_ubsan_misc COMMAND ${CMAKE_COMMAND} + -DEXECUTABLE=$ -DMODE=ubsan_misc -DSTATUS=0 + "-DPATTERN=test.cpp:30:3: runtime error: load of null pointer of type 'int'.SUMMARY.*test.cpp:31:4: runtime error: store to misaligned address 0x[0-9a-f]+ for type 'int', which requires 4 byte alignment.*0x[0-9a-f]+: note: pointer points here. 00 00 00 00.*test.cpp:32:5: runtime error: load of address 0x[0-9a-f]+ with insufficient space for an object of type 'int'.*test.cpp:33:6: runtime error: null pointer passed as argument 2, which is declared to never be null.decl.h:5:1: note: nonnull attribute specified here.*test.cpp:34:7: runtime error: null pointer passed as argument 1, which is declared to never be null.decl.h:6:2: note: _Nonnull type annotation specified here.*test.cpp:35:8: runtime error: applying zero offset to null pointer.*test.cpp:36:9: runtime error: applying non-zero offset 16 to null pointer.*test.cpp:37:10: runtime error: applying non-zero offset to non-null pointer 0x000000001000 produced null pointer.*test.cpp:38:11: runtime error: addition of unsigned offset to 0x000000001000 overflowed to 0x000000000800.*test.cpp:39:12: runtime error: load of value 5, which is not a valid value for type 'bool'.*test.cpp:40:13: runtime error: implicit conversion from type 'int' of value 300 [(]32-bit, signed[)] to type 'unsigned char' changed the value to 44 [(]8-bit, unsigned[)].*test.cpp:41:14: runtime error: 1e[+]10 is outside the range of representable values of type 'int'.*test.cpp:42:15: runtime error: passing zero to ctz[(][)], which is not a valid argument.*test.cpp:43:16: runtime error: assumption of 8 byte alignment for pointer of type 'char [*]' failed.test.cpp:44:17: note: alignment assumption was specified here.*0x[0-9a-f]+: note: address is 1 aligned, misalignment offset is 3 bytes.*test.cpp:45:18: runtime error: null pointer returned from function declared to never return null.decl.h:9:2: note: _Nonnull return type annotation specified here.*test.cpp:46:19: runtime error: call to function [(]unknown[)] through pointer to incorrect function type 'void [(][*][)][(]int[)]'.*note: [(]unknown[)] defined here" + -P ${LIBS_INCLUDE_DIR}/tests/AddressSanitizerDiagnostic.cmake) + add_test(NAME guest_addresssanitizer_runtime_ubsan_data COMMAND ${CMAKE_COMMAND} + -DEXECUTABLE=$ -DMODE=ubsan_data -DSTATUS=0 + "-DPATTERN=data kind=signed-integer-overflow file=test.cpp line=50 column=4 memory=[^ ]+ message=Signed integer overflow: 2147483647 [+] 1 cannot be represented in type 'int'" + -P ${LIBS_INCLUDE_DIR}/tests/AddressSanitizerDiagnostic.cmake) + add_test(NAME guest_addresssanitizer_runtime_ubsan_dedup COMMAND ${CMAKE_COMMAND} + -DEXECUTABLE=$ -DMODE=ubsan_dedup -DSTATUS=0 + "-DPATTERN=dedup count=1" + -P ${LIBS_INCLUDE_DIR}/tests/AddressSanitizerDiagnostic.cmake) + add_test(NAME guest_addresssanitizer_runtime_ubsan_abort COMMAND ${CMAKE_COMMAND} + -DEXECUTABLE=$ -DMODE=ubsan_abort -DSTATUS=1 + "-DPATTERN=test.cpp:70:2: runtime error: unsigned integer overflow: 0 - 1 cannot be represented in type 'unsigned int'.SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior test.cpp:70:2.death callback" + -P ${LIBS_INCLUDE_DIR}/tests/AddressSanitizerDiagnostic.cmake) + add_test(NAME guest_addresssanitizer_runtime_ubsan_unreachable COMMAND ${CMAKE_COMMAND} + -DEXECUTABLE=$ -DMODE=ubsan_unreachable -DSTATUS=1 + "-DPATTERN=test.cpp:71:3: runtime error: execution reached an unreachable program point.SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior test.cpp:71:3.death callback" + -P ${LIBS_INCLUDE_DIR}/tests/AddressSanitizerDiagnostic.cmake) + add_test(NAME guest_addresssanitizer_runtime_heap_stats COMMAND ${CMAKE_COMMAND} + -DEXECUTABLE=$ -DMODE=heap_stats -DSTATUS=0 + "-DPATTERN=Stats: [0-9]+M malloced [(][0-9]+M for red zones[)] by [0-9]+ calls.Stats: [0-9]+M realloced by [0-9]+ calls.Stats: [0-9]+M freed by [0-9]+ calls.Stats: [0-9]+M really freed by [0-9]+ calls.Stats: [0-9]+M [(][0-9]+M-[0-9]+M[)] mmaped.*mallocs by size class: .*Stats: malloc large: [0-9]+" + -P ${LIBS_INCLUDE_DIR}/tests/AddressSanitizerDiagnostic.cmake) + add_test(NAME guest_addresssanitizer_runtime_heap_double_free COMMAND ${CMAKE_COMMAND} + -DEXECUTABLE=$ -DMODE=heap_double_free -DSTATUS=1 + "-DPATTERN=ERROR: AddressSanitizer: attempting double-free on 0x[0-9a-f]+ in thread T[0-9]+:.0x[0-9a-f]+ is located 0 bytes inside of 10-byte region.*freed by thread T[0-9]+ here:.*previously allocated by thread T[0-9]+ here:.*SUMMARY: AddressSanitizer: double-free.*ABORTING" + -P ${LIBS_INCLUDE_DIR}/tests/AddressSanitizerDiagnostic.cmake) + add_test(NAME guest_addresssanitizer_runtime_heap_bad_free COMMAND ${CMAKE_COMMAND} + -DEXECUTABLE=$ -DMODE=heap_bad_free -DSTATUS=1 + "-DPATTERN=ERROR: AddressSanitizer: attempting free on address which was not malloc[(][)]-ed: 0x[0-9a-f]+ in thread T[0-9]+.*SUMMARY: AddressSanitizer: bad-free.*ABORTING" + -P ${LIBS_INCLUDE_DIR}/tests/AddressSanitizerDiagnostic.cmake) + add_test(NAME guest_addresssanitizer_runtime_heap_interior_free COMMAND ${CMAKE_COMMAND} + -DEXECUTABLE=$ -DMODE=heap_interior_free -DSTATUS=1 + "-DPATTERN=ERROR: AddressSanitizer: attempting free on address which was not malloc[(][)]-ed: 0x[0-9a-f]+ in thread T[0-9]+.0x[0-9a-f]+ is located 1 bytes inside of 32-byte region.*SUMMARY: AddressSanitizer: bad-free" + -P ${LIBS_INCLUDE_DIR}/tests/AddressSanitizerDiagnostic.cmake) + add_test(NAME guest_addresssanitizer_runtime_heap_usable_size_unowned COMMAND ${CMAKE_COMMAND} + -DEXECUTABLE=$ -DMODE=heap_usable_size_unowned -DSTATUS=1 + "-DPATTERN=ERROR: AddressSanitizer: attempting to call malloc_usable_size[(][)] for pointer which is not owned: 0x[0-9a-f]+.*SUMMARY: AddressSanitizer: bad-malloc_usable_size" + -P ${LIBS_INCLUDE_DIR}/tests/AddressSanitizerDiagnostic.cmake) + add_test(NAME guest_addresssanitizer_runtime_heap_allocated_size_unowned COMMAND ${CMAKE_COMMAND} + -DEXECUTABLE=$ -DMODE=heap_allocated_size_unowned -DSTATUS=1 + "-DPATTERN=ERROR: AddressSanitizer: attempting to call __sanitizer_get_allocated_size[(][)] for pointer which is not owned: 0x[0-9a-f]+.*SUMMARY: AddressSanitizer: bad-__sanitizer_get_allocated_size" + -P ${LIBS_INCLUDE_DIR}/tests/AddressSanitizerDiagnostic.cmake) + add_test(NAME guest_addresssanitizer_runtime_heap_calloc_overflow COMMAND ${CMAKE_COMMAND} + -DEXECUTABLE=$ -DMODE=heap_calloc_overflow -DSTATUS=1 + "-DPATTERN=ERROR: AddressSanitizer: calloc parameters overflow: count [*] size [(]1099511627776 [*] 1099511627776[)] cannot be represented in type size_t [(]thread T[0-9]+[)].HINT: if you don't care about these errors you may set allocator_may_return_null=1.SUMMARY: AddressSanitizer: calloc-overflow" + -P ${LIBS_INCLUDE_DIR}/tests/AddressSanitizerDiagnostic.cmake) + add_test(NAME guest_addresssanitizer_runtime_heap_aligned_alloc_bad COMMAND ${CMAKE_COMMAND} + -DEXECUTABLE=$ -DMODE=heap_aligned_alloc_bad -DSTATUS=1 + "-DPATTERN=ERROR: AddressSanitizer: invalid alignment requested in aligned_alloc: 24, alignment must be a power of two and the requested size 0x30 must be a multiple of alignment [(]thread T[0-9]+[)].*SUMMARY: AddressSanitizer: invalid-aligned-alloc-alignment" + -P ${LIBS_INCLUDE_DIR}/tests/AddressSanitizerDiagnostic.cmake) + add_test(NAME guest_addresssanitizer_runtime_heap_posix_memalign_bad COMMAND ${CMAKE_COMMAND} + -DEXECUTABLE=$ -DMODE=heap_posix_memalign_bad -DSTATUS=1 + "-DPATTERN=ERROR: AddressSanitizer: invalid alignment requested in posix_memalign: 12, alignment must be a power of two and a multiple of sizeof[(]void[*][)] == 8 [(]thread T[0-9]+[)].*SUMMARY: AddressSanitizer: invalid-posix-memalign-alignment" + -P ${LIBS_INCLUDE_DIR}/tests/AddressSanitizerDiagnostic.cmake) + add_test(NAME guest_addresssanitizer_runtime_heap_memalign_bad COMMAND ${CMAKE_COMMAND} + -DEXECUTABLE=$ -DMODE=heap_memalign_bad -DSTATUS=1 + "-DPATTERN=ERROR: AddressSanitizer: invalid allocation alignment: 24, alignment must be a power of two [(]thread T[0-9]+[)].*SUMMARY: AddressSanitizer: invalid-allocation-alignment" + -P ${LIBS_INCLUDE_DIR}/tests/AddressSanitizerDiagnostic.cmake) + add_test(NAME guest_addresssanitizer_runtime_heap_too_big COMMAND ${CMAKE_COMMAND} + -DEXECUTABLE=$ -DMODE=heap_too_big -DSTATUS=1 + "-DPATTERN=ERROR: AddressSanitizer: requested allocation size 0x20000000000 [(]0x[0-9a-f]+ after adjustments for alignment, red zones etc.[)] exceeds maximum supported size of 0x10000000000 [(]thread T[0-9]+[)].*SUMMARY: AddressSanitizer: allocation-size-too-big" + -P ${LIBS_INCLUDE_DIR}/tests/AddressSanitizerDiagnostic.cmake) + add_test(NAME guest_addresssanitizer_runtime_heap_realloc_freed COMMAND ${CMAKE_COMMAND} + -DEXECUTABLE=$ -DMODE=heap_realloc_freed -DSTATUS=1 + "-DPATTERN=ERROR: AddressSanitizer: attempting double-free on 0x[0-9a-f]+ in thread T[0-9]+:.*is located 0 bytes inside of 10-byte region.*SUMMARY: AddressSanitizer: double-free" + -P ${LIBS_INCLUDE_DIR}/tests/AddressSanitizerDiagnostic.cmake) + add_test(NAME guest_addresssanitizer_runtime_globals_odr_indicator COMMAND ${CMAKE_COMMAND} + -DEXECUTABLE=$ -DMODE=globals_odr_indicator -DSTATUS=1 + "-DPATTERN=ERROR: AddressSanitizer: odr-violation [(]0x[0-9a-f]+[)]:. [[]1[]] size=24 'newer' test.cpp:5:6. [[]2[]] size=13 'older' test.cpp:5:6.HINT: if you don't care about these errors you may set ASAN_OPTIONS=detect_odr_violation=0.SUMMARY: AddressSanitizer: odr-violation: global 'newer' at test.cpp:5:6.*ABORTING" + -P ${LIBS_INCLUDE_DIR}/tests/AddressSanitizerDiagnostic.cmake) + add_test(NAME guest_addresssanitizer_runtime_globals_odr_poison COMMAND ${CMAKE_COMMAND} + -DEXECUTABLE=$ -DMODE=globals_odr_poison -DSTATUS=1 + "-DPATTERN=ERROR: AddressSanitizer: odr-violation [(]0x[0-9a-f]+[)]:. [[]1[]] size=24 'newer' test.cpp:5:6. [[]2[]] size=13 'older' test.cpp:5:6.*ABORTING" + -P ${LIBS_INCLUDE_DIR}/tests/AddressSanitizerDiagnostic.cmake) + add_test(NAME guest_addresssanitizer_runtime_globals_describe COMMAND ${CMAKE_COMMAND} + -DEXECUTABLE=$ -DMODE=globals_describe -DSTATUS=0 + "-DPATTERN=0x[0-9a-f]+ is located 2 bytes inside of global variable 'g2' defined in 'test.cpp:5:6' [(]0x[0-9a-f]+[)] of size 5. 'g2' is ascii string 'text'.0x[0-9a-f]+ is located 1 bytes after global variable 'g2' defined in 'test.cpp:5:6' [(]0x[0-9a-f]+[)] of size 5.*Address 0x[0-9a-f]+ is a wild pointer inside of access range of size 0x000000000001" + -P ${LIBS_INCLUDE_DIR}/tests/AddressSanitizerDiagnostic.cmake) + add_test(NAME guest_addresssanitizer_runtime_describe_heap COMMAND ${CMAKE_COMMAND} + -DEXECUTABLE=$ -DMODE=describe_heap -DSTATUS=0 + "-DPATTERN=0x[0-9a-f]+ is located 3 bytes inside of 10-byte region [[]0x[0-9a-f]+,0x[0-9a-f]+[)].allocated by thread T[0-9]+ here:. #0 0x[0-9a-f]+.0x[0-9a-f]+ is located 2 bytes after 10-byte region.*0x[0-9a-f]+ is located 4 bytes before 10-byte region.*freed by thread T[0-9]+ here:. #0 0x[0-9a-f]+.previously allocated by thread T[0-9]+ here:.*Address 0x000000001000 is a wild pointer inside of access range of size 0x000000000001[.].Address 0x010000000000 is located in the low shadow area" + -P ${LIBS_INCLUDE_DIR}/tests/AddressSanitizerDiagnostic.cmake) + add_test(NAME guest_addresssanitizer_runtime_fiber_unstarted COMMAND ${CMAKE_COMMAND} + -DEXECUTABLE=$ -DMODE=fiber_unstarted -DSTATUS=1 + "-DPATTERN=ERROR: finishing a fiber switch that has not started" + -P ${LIBS_INCLUDE_DIR}/tests/AddressSanitizerDiagnostic.cmake) + add_test(NAME guest_addresssanitizer_runtime_fiber_double_start COMMAND ${CMAKE_COMMAND} + -DEXECUTABLE=$ -DMODE=fiber_double_start -DSTATUS=1 + "-DPATTERN=ERROR: starting fiber switch while in fiber switch" + -P ${LIBS_INCLUDE_DIR}/tests/AddressSanitizerDiagnostic.cmake) + add_test(NAME guest_addresssanitizer_runtime_report_path COMMAND ${CMAKE_COMMAND} + -DEXECUTABLE=$ -DMODE=report_path -DSTATUS=0 + "-DPATTERN=report path ok" + -P ${LIBS_INCLUDE_DIR}/tests/AddressSanitizerDiagnostic.cmake) + add_test(NAME guest_addresssanitizer_runtime_report_stdout COMMAND ${CMAKE_COMMAND} + -DEXECUTABLE=$ -DMODE=report_stdout -DSTATUS=0 + "-DPATTERN=Address 0x000000003000 is a wild pointer inside of access range of size 0x000000000001" + -P ${LIBS_INCLUDE_DIR}/tests/AddressSanitizerDiagnostic.cmake) + add_test(NAME guest_addresssanitizer_runtime_report_descriptor COMMAND ${CMAKE_COMMAND} + -DEXECUTABLE=$ -DMODE=report_descriptor -DSTATUS=0 + "-DPATTERN=Address 0x000000004000 is a wild pointer inside of access range of size 0x000000000001" + -P ${LIBS_INCLUDE_DIR}/tests/AddressSanitizerDiagnostic.cmake) + add_test(NAME guest_addresssanitizer_runtime_stack_trace COMMAND ${CMAKE_COMMAND} + -DEXECUTABLE=$ -DMODE=stack_trace -DSTATUS=0 + "-DPATTERN= #0 0x[0-9a-f]+ [(].*guest_addresssanitizer_runtime_tests.*[+]0x[0-9a-f]+[)]" + -P ${LIBS_INCLUDE_DIR}/tests/AddressSanitizerDiagnostic.cmake) + add_test(NAME guest_addresssanitizer_runtime_symbolize COMMAND ${CMAKE_COMMAND} + -DEXECUTABLE=$ -DMODE=symbolize -DSTATUS=0 + "-DPATTERN=symbolized=[(]guest_addresssanitizer_runtime_tests[^+]*[+]0x[0-9a-f]+[)].literal=[%][|]0[|][|][<]null[>][|][|]0x0[|]0[|]0.short=0x[0-9a-f][0-9a-f].global=<>" + -P ${LIBS_INCLUDE_DIR}/tests/AddressSanitizerDiagnostic.cmake) + add_test(NAME guest_addresssanitizer_runtime_symbolize_bad COMMAND ${CMAKE_COMMAND} + -DEXECUTABLE=$ -DMODE=symbolize_bad -DSTATUS=1 + "-DPATTERN=Unsupported specifier in stack frame format: z" + -P ${LIBS_INCLUDE_DIR}/tests/AddressSanitizerDiagnostic.cmake) + add_test(NAME guest_addresssanitizer_runtime_coverage COMMAND ${CMAKE_COMMAND} + -DEXECUTABLE=$ -DMODE=coverage -DSTATUS=0 + "-DPATTERN=SanitizerCoverage: ./guest_addresssanitizer_runtime_tests[^ ]*[.][0-9]+[.]sancov: 2 PCs written" + -P ${LIBS_INCLUDE_DIR}/tests/AddressSanitizerDiagnostic.cmake) + add_test(NAME guest_addresssanitizer_runtime_fatal_control COMMAND ${CMAKE_COMMAND} + -DEXECUTABLE=$ -DMODE=fatal_control -DSTATUS=1 + "-DPATTERN=ERROR: AddressSanitizer: use-after-poison on address 0x[0-9a-f]+ at pc 0x[0-9a-f]+ bp 0x[0-9a-f]+ sp 0x[0-9a-f]+.READ of size 4 at 0x[0-9a-f]+ thread T-1.*ABORTING" + -P ${LIBS_INCLUDE_DIR}/tests/AddressSanitizerDiagnostic.cmake) + set_tests_properties(guest_addresssanitizer_runtime_fatal_control PROPERTIES WILL_FAIL TRUE) + foreach(mode exp_load4 exp_store16_noabort exp_loadN report_exp_store2 report_exp_load_n memcpy_source memset_poison memmove_poison memcpy_overlap memset_negative container_params double_ended_params ubsan_arithmetic ubsan_misc ubsan_data ubsan_dedup ubsan_abort ubsan_unreachable heap_stats heap_double_free heap_bad_free heap_interior_free heap_usable_size_unowned heap_allocated_size_unowned heap_calloc_overflow heap_aligned_alloc_bad heap_posix_memalign_bad heap_memalign_bad heap_too_big heap_realloc_freed globals_odr_indicator globals_odr_poison globals_describe describe_heap fiber_unstarted fiber_double_start report_path report_stdout report_descriptor stack_trace symbolize symbolize_bad coverage fatal_control) + set_tests_properties(guest_addresssanitizer_runtime_${mode} PROPERTIES TIMEOUT 20) + if(WIN32) + set_tests_properties(guest_addresssanitizer_runtime_${mode} PROPERTIES ENVIRONMENT_MODIFICATION + "PATH=path_list_prepend:$") + endif() + endforeach() + if(WIN32) + add_test_executable(guest_addresssanitizer_backing_tests ${LIBS_INCLUDE_DIR}/tests/GuestAddressSanitizerBacking.cpp) + target_include_directories(guest_addresssanitizer_backing_tests PRIVATE ${LIBS_INCLUDE_DIR}) + target_link_libraries(guest_addresssanitizer_backing_tests PRIVATE libSceAddressSanitizer libc) + configure_windows_unwind(guest_addresssanitizer_backing_tests) + add_test(NAME guest_addresssanitizer_backing_layout COMMAND guest_addresssanitizer_backing_tests) + set_tests_properties(guest_addresssanitizer_backing_layout PROPERTIES TIMEOUT 20 ENVIRONMENT_MODIFICATION + "PATH=path_list_prepend:$") + add_test_executable(guest_addresssanitizer_mapping_tests ${LIBS_INCLUDE_DIR}/tests/GuestAddressSanitizerMapping.cpp) + target_include_directories(guest_addresssanitizer_mapping_tests PRIVATE ${LIBS_INCLUDE_DIR}) + target_link_libraries(guest_addresssanitizer_mapping_tests PRIVATE libSceAddressSanitizer libc) + configure_windows_unwind(guest_addresssanitizer_mapping_tests) + add_test(NAME guest_addresssanitizer_mapping COMMAND guest_addresssanitizer_mapping_tests) + add_test(NAME guest_addresssanitizer_mapping_collision COMMAND guest_addresssanitizer_mapping_tests collision) + set_tests_properties(guest_addresssanitizer_mapping guest_addresssanitizer_mapping_collision PROPERTIES TIMEOUT 20 ENVIRONMENT_MODIFICATION + "PATH=path_list_prepend:$") + add_test(NAME guest_addresssanitizer_report_load4 COMMAND ${CMAKE_COMMAND} + -DEXECUTABLE=$ -DMODE=report -DARGUMENT=load4 -DSTATUS=1 + "-DPATTERN=ERROR: AddressSanitizer: use-after-poison on address 0x[0-9a-f]+ at pc 0x[0-9a-f]+ bp 0x[0-9a-f]+ sp 0x[0-9a-f]+.READ of size 4 at 0x[0-9a-f]+ thread T-1.Shadow bytes around the buggy address:.*=>0x[0-9a-f]+:.*f7.*Shadow byte legend.*callback present=1 type=0 size=4 desc=use-after-poison address=ok text=ok.ABORTING.death callback" + -P ${LIBS_INCLUDE_DIR}/tests/AddressSanitizerDiagnostic.cmake) + add_test(NAME guest_addresssanitizer_report_load16 COMMAND ${CMAKE_COMMAND} + -DEXECUTABLE=$ -DMODE=report -DARGUMENT=load16 -DSTATUS=1 + "-DPATTERN=ERROR: AddressSanitizer: use-after-poison on address .*READ of size 16 at .*callback present=1 type=0 size=16 desc=use-after-poison address=ok text=ok.ABORTING.death callback" + -P ${LIBS_INCLUDE_DIR}/tests/AddressSanitizerDiagnostic.cmake) + add_test(NAME guest_addresssanitizer_report_storeN COMMAND ${CMAKE_COMMAND} + -DEXECUTABLE=$ -DMODE=report -DARGUMENT=storeN -DSTATUS=1 + "-DPATTERN=ERROR: AddressSanitizer: use-after-poison on address .*WRITE of size 16 at .*callback present=1 type=1 size=16 desc=use-after-poison address=ok text=ok.ABORTING.death callback" + -P ${LIBS_INCLUDE_DIR}/tests/AddressSanitizerDiagnostic.cmake) + add_test(NAME guest_addresssanitizer_report_unaligned COMMAND ${CMAKE_COMMAND} + -DEXECUTABLE=$ -DMODE=report -DARGUMENT=unaligned -DSTATUS=1 + "-DPATTERN=ERROR: AddressSanitizer: use-after-poison on address .*WRITE of size 4 at .*callback present=1 type=1 size=4 desc=use-after-poison address=ok text=ok.ABORTING.death callback" + -P ${LIBS_INCLUDE_DIR}/tests/AddressSanitizerDiagnostic.cmake) + add_test(NAME guest_addresssanitizer_report_partial COMMAND ${CMAKE_COMMAND} + -DEXECUTABLE=$ -DMODE=report -DARGUMENT=partial -DSTATUS=1 + "-DPATTERN=ERROR: AddressSanitizer: use-after-poison on address .*READ of size 1 at .*callback present=1 type=0 size=1 desc=use-after-poison address=ok text=ok.ABORTING.death callback" + -P ${LIBS_INCLUDE_DIR}/tests/AddressSanitizerDiagnostic.cmake) + add_test(NAME guest_addresssanitizer_report_report_error COMMAND ${CMAKE_COMMAND} + -DEXECUTABLE=$ -DMODE=report -DARGUMENT=report_error -DSTATUS=1 + "-DPATTERN=ERROR: AddressSanitizer: use-after-poison on address 0x[0-9a-f]+ at pc 0x000000001000 bp 0x000000002000 sp 0x000000003000.WRITE of size 2 at .*callback present=1 type=1 size=2 desc=use-after-poison address=ok text=ok.ABORTING.death callback" + -P ${LIBS_INCLUDE_DIR}/tests/AddressSanitizerDiagnostic.cmake) + foreach(mode load4 load16 storeN unaligned partial report_error) + set_tests_properties(guest_addresssanitizer_report_${mode} PROPERTIES TIMEOUT 20 ENVIRONMENT_MODIFICATION + "PATH=path_list_prepend:$") + endforeach() + set_tests_properties(guest_addresssanitizer_shadow PROPERTIES ENVIRONMENT_MODIFICATION + "PATH=path_list_prepend:$") + endif() +endif() diff --git a/core/libs/prx/libSceAddressSanitizer/Export.cpp b/core/libs/prx/libSceAddressSanitizer/Export.cpp index fd4263f4dbf1..53945ce2b4ec 100644 --- a/core/libs/prx/libSceAddressSanitizer/Export.cpp +++ b/core/libs/prx/libSceAddressSanitizer/Export.cpp @@ -1,49 +1,42 @@ #include "prx/libSceAddressSanitizer/include/Api.hpp" -#include -#include -#include "SceTypes.hpp" #include "prx/libc/include/General.hpp" +#include "asan_anyps5/Interface.hpp" extern "C" { -int APS5_VABI __asan_addr_is_in_fake_stack() { - NotImplemented_nid_no_patch(__func__); - return 0; +int __asan_option_detect_stack_use_after_return = 0; +std::uintptr_t __ubsan_vptr_type_cache[128] = {}; + +void* APS5_VABI __asan_addr_is_in_fake_stack(void* fakeStack, void* address, void** begin, void** end) { + return AsanRuntime::Impl::__asan_addr_is_in_fake_stack_nid_no_patch(fakeStack, address, begin, end, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_address_is_poisoned() { - NotImplemented_nid_no_patch(__func__); - return 0; +int APS5_VABI __asan_address_is_poisoned(const volatile void* address) { + return AsanRuntime::Impl::__asan_address_is_poisoned_nid_no_patch(address, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_after_dynamic_init() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_after_dynamic_init() { + return; } -int APS5_VABI __asan_aligned_alloc() { - NotImplemented_nid_no_patch(__func__); - return 0; +void* APS5_VABI __asan_aligned_alloc(std::size_t alignment, std::size_t size) { + return AsanRuntime::Impl::__asan_aligned_alloc_nid_no_patch(alignment, size, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_alloca_poison() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_alloca_poison(std::uintptr_t addr, std::uintptr_t size) { + return AsanRuntime::Impl::__asan_alloca_poison_nid_no_patch(addr, size, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_allocas_unpoison() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_allocas_unpoison(std::uintptr_t top, std::uintptr_t bottom) { + return AsanRuntime::Impl::__asan_allocas_unpoison_nid_no_patch(top, bottom, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_before_dynamic_init() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_before_dynamic_init(const char* moduleName) { + return AsanRuntime::Impl::__asan_before_dynamic_init_nid_no_patch(moduleName, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_calloc() { - NotImplemented_nid_no_patch(__func__); - return 0; +void* APS5_VABI __asan_calloc(std::size_t count, std::size_t size) { + return AsanRuntime::Impl::__asan_calloc_nid_no_patch(count, size, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } int APS5_VABI __asan_current_error_report() { @@ -56,9 +49,8 @@ int APS5_VABI __asan_current_error_report_size() { return 0; } -int APS5_VABI __asan_describe_address() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_describe_address(std::uintptr_t address) { + return AsanRuntime::Impl::__asan_describe_address_nid_no_patch(address, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } int APS5_VABI __asan_destroy_fake_stack() { @@ -66,194 +58,156 @@ int APS5_VABI __asan_destroy_fake_stack() { return 0; } -int APS5_VABI __asan_exp_load1() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_exp_load1(std::uintptr_t address, std::uint32_t experiment) { + return AsanRuntime::Impl::__asan_exp_load1_nid_no_patch(address, experiment, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_exp_load16() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_exp_load16(std::uintptr_t address, std::uint32_t experiment) { + return AsanRuntime::Impl::__asan_exp_load16_nid_no_patch(address, experiment, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_exp_load16_noabort() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_exp_load16_noabort(std::uintptr_t address, std::uint32_t experiment) { + return AsanRuntime::Impl::__asan_exp_load16_noabort_nid_no_patch(address, experiment, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_exp_load1_noabort() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_exp_load1_noabort(std::uintptr_t address, std::uint32_t experiment) { + return AsanRuntime::Impl::__asan_exp_load1_noabort_nid_no_patch(address, experiment, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_exp_load2() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_exp_load2(std::uintptr_t address, std::uint32_t experiment) { + return AsanRuntime::Impl::__asan_exp_load2_nid_no_patch(address, experiment, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_exp_load2_noabort() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_exp_load2_noabort(std::uintptr_t address, std::uint32_t experiment) { + return AsanRuntime::Impl::__asan_exp_load2_noabort_nid_no_patch(address, experiment, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_exp_load4() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_exp_load4(std::uintptr_t address, std::uint32_t experiment) { + return AsanRuntime::Impl::__asan_exp_load4_nid_no_patch(address, experiment, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_exp_load4_noabort() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_exp_load4_noabort(std::uintptr_t address, std::uint32_t experiment) { + return AsanRuntime::Impl::__asan_exp_load4_noabort_nid_no_patch(address, experiment, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_exp_load8() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_exp_load8(std::uintptr_t address, std::uint32_t experiment) { + return AsanRuntime::Impl::__asan_exp_load8_nid_no_patch(address, experiment, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_exp_load8_noabort() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_exp_load8_noabort(std::uintptr_t address, std::uint32_t experiment) { + return AsanRuntime::Impl::__asan_exp_load8_noabort_nid_no_patch(address, experiment, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_exp_loadN() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_exp_loadN(std::uintptr_t address, std::uintptr_t size, std::uint32_t experiment) { + return AsanRuntime::Impl::__asan_exp_loadN_nid_no_patch(address, size, experiment, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_exp_loadN_noabort() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_exp_loadN_noabort(std::uintptr_t address, std::uintptr_t size, std::uint32_t experiment) { + return AsanRuntime::Impl::__asan_exp_loadN_noabort_nid_no_patch(address, size, experiment, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_exp_store1() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_exp_store1(std::uintptr_t address, std::uint32_t experiment) { + return AsanRuntime::Impl::__asan_exp_store1_nid_no_patch(address, experiment, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_exp_store16() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_exp_store16(std::uintptr_t address, std::uint32_t experiment) { + return AsanRuntime::Impl::__asan_exp_store16_nid_no_patch(address, experiment, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_exp_store16_noabort() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_exp_store16_noabort(std::uintptr_t address, std::uint32_t experiment) { + return AsanRuntime::Impl::__asan_exp_store16_noabort_nid_no_patch(address, experiment, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_exp_store1_noabort() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_exp_store1_noabort(std::uintptr_t address, std::uint32_t experiment) { + return AsanRuntime::Impl::__asan_exp_store1_noabort_nid_no_patch(address, experiment, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_exp_store2() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_exp_store2(std::uintptr_t address, std::uint32_t experiment) { + return AsanRuntime::Impl::__asan_exp_store2_nid_no_patch(address, experiment, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_exp_store2_noabort() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_exp_store2_noabort(std::uintptr_t address, std::uint32_t experiment) { + return AsanRuntime::Impl::__asan_exp_store2_noabort_nid_no_patch(address, experiment, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_exp_store4() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_exp_store4(std::uintptr_t address, std::uint32_t experiment) { + return AsanRuntime::Impl::__asan_exp_store4_nid_no_patch(address, experiment, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_exp_store4_noabort() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_exp_store4_noabort(std::uintptr_t address, std::uint32_t experiment) { + return AsanRuntime::Impl::__asan_exp_store4_noabort_nid_no_patch(address, experiment, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_exp_store8() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_exp_store8(std::uintptr_t address, std::uint32_t experiment) { + return AsanRuntime::Impl::__asan_exp_store8_nid_no_patch(address, experiment, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_exp_store8_noabort() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_exp_store8_noabort(std::uintptr_t address, std::uint32_t experiment) { + return AsanRuntime::Impl::__asan_exp_store8_noabort_nid_no_patch(address, experiment, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_exp_storeN() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_exp_storeN(std::uintptr_t address, std::uintptr_t size, std::uint32_t experiment) { + return AsanRuntime::Impl::__asan_exp_storeN_nid_no_patch(address, size, experiment, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_exp_storeN_noabort() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_exp_storeN_noabort(std::uintptr_t address, std::uintptr_t size, std::uint32_t experiment) { + return AsanRuntime::Impl::__asan_exp_storeN_noabort_nid_no_patch(address, size, experiment, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_free() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_free(void* pointer) { + return AsanRuntime::Impl::__asan_free_nid_no_patch(pointer, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_get_alloc_stack() { - NotImplemented_nid_no_patch(__func__); - return 0; +std::uintptr_t APS5_VABI __asan_get_alloc_stack(std::uintptr_t address, std::uintptr_t* trace, std::uintptr_t size, std::uint32_t* threadId) { + return AsanRuntime::Impl::__asan_get_alloc_stack_nid_no_patch(address, trace, size, threadId, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_get_current_fake_stack() { - NotImplemented_nid_no_patch(__func__); - return 0; +void* APS5_VABI __asan_get_current_fake_stack() { + return AsanRuntime::Impl::__asan_get_current_fake_stack_nid_no_patch({reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_get_free_stack() { - NotImplemented_nid_no_patch(__func__); - return 0; +std::uintptr_t APS5_VABI __asan_get_free_stack(std::uintptr_t address, std::uintptr_t* trace, std::uintptr_t size, std::uint32_t* threadId) { + return AsanRuntime::Impl::__asan_get_free_stack_nid_no_patch(address, trace, size, threadId, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_get_report_access_size() { - NotImplemented_nid_no_patch(__func__); - return 0; +std::size_t APS5_VABI __asan_get_report_access_size() { + return AsanRuntime::Impl::__asan_get_report_access_size_nid_no_patch({reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } int APS5_VABI __asan_get_report_access_type() { - NotImplemented_nid_no_patch(__func__); - return 0; + return AsanRuntime::Impl::__asan_get_report_access_type_nid_no_patch({reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_get_report_address() { - NotImplemented_nid_no_patch(__func__); - return 0; +void* APS5_VABI __asan_get_report_address() { + return AsanRuntime::Impl::__asan_get_report_address_nid_no_patch({reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_get_report_bp() { - NotImplemented_nid_no_patch(__func__); - return 0; +void* APS5_VABI __asan_get_report_bp() { + return AsanRuntime::Impl::__asan_get_report_bp_nid_no_patch({reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_get_report_description() { - NotImplemented_nid_no_patch(__func__); - return 0; +const char* APS5_VABI __asan_get_report_description() { + return AsanRuntime::Impl::__asan_get_report_description_nid_no_patch({reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_get_report_pc() { - NotImplemented_nid_no_patch(__func__); - return 0; +void* APS5_VABI __asan_get_report_pc() { + return AsanRuntime::Impl::__asan_get_report_pc_nid_no_patch({reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_get_report_sp() { - NotImplemented_nid_no_patch(__func__); - return 0; +void* APS5_VABI __asan_get_report_sp() { + return AsanRuntime::Impl::__asan_get_report_sp_nid_no_patch({reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_get_shadow_mapping() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_get_shadow_mapping(std::size_t* scale, std::size_t* offset) { + return AsanRuntime::Impl::__asan_get_shadow_mapping_nid_no_patch(scale, offset, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_handle_no_return() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_handle_no_return() { + return AsanRuntime::Impl::__asan_handle_no_return_nid_no_patch({reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_init() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_init() { + return AsanRuntime::Impl::__asan_init_nid_no_patch({reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } int APS5_VABI __asan_init_v5() { @@ -261,79 +215,64 @@ int APS5_VABI __asan_init_v5() { return 0; } -int APS5_VABI __asan_load1() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_load1(std::uintptr_t address) { + return AsanRuntime::Impl::__asan_load1_nid_no_patch(address, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_load16() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_load16(std::uintptr_t address) { + return AsanRuntime::Impl::__asan_load16_nid_no_patch(address, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_load16_noabort() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_load16_noabort(std::uintptr_t address) { + return AsanRuntime::Impl::__asan_load16_noabort_nid_no_patch(address, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_load1_noabort() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_load1_noabort(std::uintptr_t address) { + return AsanRuntime::Impl::__asan_load1_noabort_nid_no_patch(address, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_load2() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_load2(std::uintptr_t address) { + return AsanRuntime::Impl::__asan_load2_nid_no_patch(address, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_load2_noabort() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_load2_noabort(std::uintptr_t address) { + return AsanRuntime::Impl::__asan_load2_noabort_nid_no_patch(address, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_load4() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_load4(std::uintptr_t address) { + return AsanRuntime::Impl::__asan_load4_nid_no_patch(address, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_load4_noabort() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_load4_noabort(std::uintptr_t address) { + return AsanRuntime::Impl::__asan_load4_noabort_nid_no_patch(address, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_load8() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_load8(std::uintptr_t address) { + return AsanRuntime::Impl::__asan_load8_nid_no_patch(address, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_load8_noabort() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_load8_noabort(std::uintptr_t address) { + return AsanRuntime::Impl::__asan_load8_noabort_nid_no_patch(address, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_loadN() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_loadN(std::uintptr_t address, std::uintptr_t size) { + return AsanRuntime::Impl::__asan_loadN_nid_no_patch(address, size, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_loadN_noabort() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_loadN_noabort(std::uintptr_t address, std::uintptr_t size) { + return AsanRuntime::Impl::__asan_loadN_noabort_nid_no_patch(address, size, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_load_cxx_array_cookie() { - NotImplemented_nid_no_patch(__func__); - return 0; +std::uintptr_t APS5_VABI __asan_load_cxx_array_cookie(std::uintptr_t* p) { + return AsanRuntime::Impl::__asan_load_cxx_array_cookie_nid_no_patch(p, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_locate_address() { - NotImplemented_nid_no_patch(__func__); - return 0; +const char* APS5_VABI __asan_locate_address(std::uintptr_t address, char* name, std::uintptr_t nameSize, std::uintptr_t* regionAddress, std::uintptr_t* regionSize) { + return AsanRuntime::Impl::__asan_locate_address_nid_no_patch(address, name, nameSize, regionAddress, regionSize, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_malloc() { - NotImplemented_nid_no_patch(__func__); - return 0; +void* APS5_VABI __asan_malloc(std::size_t size) { + return AsanRuntime::Impl::__asan_malloc_nid_no_patch(size, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } int APS5_VABI __asan_malloc_stats() { @@ -341,69 +280,52 @@ int APS5_VABI __asan_malloc_stats() { return 0; } -int APS5_VABI __asan_malloc_usable_size() { - NotImplemented_nid_no_patch(__func__); - return 0; -} - -int APS5_VABI __asan_memalign() { - NotImplemented_nid_no_patch(__func__); - return 0; +std::size_t APS5_VABI __asan_malloc_usable_size(const void* pointer) { + return AsanRuntime::Impl::__asan_malloc_usable_size_nid_no_patch(pointer, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_memcpy() { - NotImplemented_nid_no_patch(__func__); - return 0; +void* APS5_VABI __asan_memalign(std::size_t alignment, std::size_t size) { + return AsanRuntime::Impl::__asan_memalign_nid_no_patch(alignment, size, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_memmove() { - NotImplemented_nid_no_patch(__func__); - return 0; +void* APS5_VABI __asan_memcpy(void* to, const void* from, std::uintptr_t size) { + return AsanRuntime::Impl::__asan_memcpy_nid_no_patch(to, from, size, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_memset() { - NotImplemented_nid_no_patch(__func__); - return 0; +void* APS5_VABI __asan_memmove(void* to, const void* from, std::uintptr_t size) { + return AsanRuntime::Impl::__asan_memmove_nid_no_patch(to, from, size, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_option_detect_stack_use_after_return() { - NotImplemented_nid_no_patch(__func__); - return 0; +void* APS5_VABI __asan_memset(void* block, int value, std::uintptr_t size) { + return AsanRuntime::Impl::__asan_memset_nid_no_patch(block, value, size, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_poison_cxx_array_cookie() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_poison_cxx_array_cookie(std::uintptr_t p) { + return AsanRuntime::Impl::__asan_poison_cxx_array_cookie_nid_no_patch(p, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_poison_intra_object_redzone() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_poison_intra_object_redzone(std::uintptr_t address, std::uintptr_t size) { + return AsanRuntime::Impl::__asan_poison_intra_object_redzone_nid_no_patch(address, size, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_poison_memory_region() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_poison_memory_region(const volatile void* addr, std::uintptr_t size) { + return AsanRuntime::Impl::__asan_poison_memory_region_nid_no_patch(addr, size, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_poison_stack_memory() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_poison_stack_memory(std::uintptr_t address, std::uintptr_t size) { + return AsanRuntime::Impl::__asan_poison_stack_memory_nid_no_patch(address, size, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_posix_memalign() { - NotImplemented_nid_no_patch(__func__); - return 0; +int APS5_VABI __asan_posix_memalign(void** memptr, std::size_t alignment, std::size_t size) { + return AsanRuntime::Impl::__asan_posix_memalign_nid_no_patch(memptr, alignment, size, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_print_accumulated_stats() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_print_accumulated_stats() { + return AsanRuntime::Impl::__asan_print_accumulated_stats_nid_no_patch({reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_realloc() { - NotImplemented_nid_no_patch(__func__); - return 0; +void* APS5_VABI __asan_realloc(void* pointer, std::size_t size) { + return AsanRuntime::Impl::__asan_realloc_nid_no_patch(pointer, size, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } int APS5_VABI __asan_reallocalign() { @@ -411,19 +333,16 @@ int APS5_VABI __asan_reallocalign() { return 0; } -int APS5_VABI __asan_region_is_poisoned() { - NotImplemented_nid_no_patch(__func__); - return 0; +std::uintptr_t APS5_VABI __asan_region_is_poisoned(std::uintptr_t address, std::uintptr_t size) { + return AsanRuntime::Impl::__asan_region_is_poisoned_nid_no_patch(address, size, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_register_elf_globals() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_register_elf_globals(std::uintptr_t* flag, void* start, void* stop) { + return AsanRuntime::Impl::__asan_register_elf_globals_nid_no_patch(flag, start, stop, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_register_globals() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_register_globals(void* globals, std::uintptr_t count) { + return AsanRuntime::Impl::__asan_register_globals_nid_no_patch(globals, count, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } int APS5_VABI __asan_register_image_globals() { @@ -431,574 +350,460 @@ int APS5_VABI __asan_register_image_globals() { return 0; } -int APS5_VABI __asan_report_error() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_report_error(void* pc, void* bp, void* sp, void* address, int isWrite, std::size_t accessSize, std::uint32_t experiment) { + return AsanRuntime::Impl::__asan_report_error_nid_no_patch(pc, bp, sp, address, isWrite, accessSize, experiment, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_report_exp_load1() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_report_exp_load1(std::uintptr_t address, std::uint32_t experiment) { + return AsanRuntime::Impl::__asan_report_exp_load1_nid_no_patch(address, experiment, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_report_exp_load16() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_report_exp_load16(std::uintptr_t address, std::uint32_t experiment) { + return AsanRuntime::Impl::__asan_report_exp_load16_nid_no_patch(address, experiment, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_report_exp_load16_noabort() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_report_exp_load16_noabort(std::uintptr_t address, std::uint32_t experiment) { + return AsanRuntime::Impl::__asan_report_exp_load16_noabort_nid_no_patch(address, experiment, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_report_exp_load1_noabort() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_report_exp_load1_noabort(std::uintptr_t address, std::uint32_t experiment) { + return AsanRuntime::Impl::__asan_report_exp_load1_noabort_nid_no_patch(address, experiment, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_report_exp_load2() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_report_exp_load2(std::uintptr_t address, std::uint32_t experiment) { + return AsanRuntime::Impl::__asan_report_exp_load2_nid_no_patch(address, experiment, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_report_exp_load2_noabort() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_report_exp_load2_noabort(std::uintptr_t address, std::uint32_t experiment) { + return AsanRuntime::Impl::__asan_report_exp_load2_noabort_nid_no_patch(address, experiment, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_report_exp_load4() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_report_exp_load4(std::uintptr_t address, std::uint32_t experiment) { + return AsanRuntime::Impl::__asan_report_exp_load4_nid_no_patch(address, experiment, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_report_exp_load4_noabort() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_report_exp_load4_noabort(std::uintptr_t address, std::uint32_t experiment) { + return AsanRuntime::Impl::__asan_report_exp_load4_noabort_nid_no_patch(address, experiment, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_report_exp_load8() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_report_exp_load8(std::uintptr_t address, std::uint32_t experiment) { + return AsanRuntime::Impl::__asan_report_exp_load8_nid_no_patch(address, experiment, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_report_exp_load8_noabort() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_report_exp_load8_noabort(std::uintptr_t address, std::uint32_t experiment) { + return AsanRuntime::Impl::__asan_report_exp_load8_noabort_nid_no_patch(address, experiment, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_report_exp_load_n() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_report_exp_load_n(std::uintptr_t address, std::uintptr_t size, std::uint32_t experiment) { + return AsanRuntime::Impl::__asan_report_exp_load_n_nid_no_patch(address, size, experiment, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_report_exp_load_n_noabort() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_report_exp_load_n_noabort(std::uintptr_t address, std::uintptr_t size, std::uint32_t experiment) { + return AsanRuntime::Impl::__asan_report_exp_load_n_noabort_nid_no_patch(address, size, experiment, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_report_exp_store1() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_report_exp_store1(std::uintptr_t address, std::uint32_t experiment) { + return AsanRuntime::Impl::__asan_report_exp_store1_nid_no_patch(address, experiment, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_report_exp_store16() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_report_exp_store16(std::uintptr_t address, std::uint32_t experiment) { + return AsanRuntime::Impl::__asan_report_exp_store16_nid_no_patch(address, experiment, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_report_exp_store16_noabort() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_report_exp_store16_noabort(std::uintptr_t address, std::uint32_t experiment) { + return AsanRuntime::Impl::__asan_report_exp_store16_noabort_nid_no_patch(address, experiment, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_report_exp_store1_noabort() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_report_exp_store1_noabort(std::uintptr_t address, std::uint32_t experiment) { + return AsanRuntime::Impl::__asan_report_exp_store1_noabort_nid_no_patch(address, experiment, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_report_exp_store2() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_report_exp_store2(std::uintptr_t address, std::uint32_t experiment) { + return AsanRuntime::Impl::__asan_report_exp_store2_nid_no_patch(address, experiment, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_report_exp_store2_noabort() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_report_exp_store2_noabort(std::uintptr_t address, std::uint32_t experiment) { + return AsanRuntime::Impl::__asan_report_exp_store2_noabort_nid_no_patch(address, experiment, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_report_exp_store4() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_report_exp_store4(std::uintptr_t address, std::uint32_t experiment) { + return AsanRuntime::Impl::__asan_report_exp_store4_nid_no_patch(address, experiment, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_report_exp_store4_noabort() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_report_exp_store4_noabort(std::uintptr_t address, std::uint32_t experiment) { + return AsanRuntime::Impl::__asan_report_exp_store4_noabort_nid_no_patch(address, experiment, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_report_exp_store8() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_report_exp_store8(std::uintptr_t address, std::uint32_t experiment) { + return AsanRuntime::Impl::__asan_report_exp_store8_nid_no_patch(address, experiment, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_report_exp_store8_noabort() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_report_exp_store8_noabort(std::uintptr_t address, std::uint32_t experiment) { + return AsanRuntime::Impl::__asan_report_exp_store8_noabort_nid_no_patch(address, experiment, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_report_exp_store_n() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_report_exp_store_n(std::uintptr_t address, std::uintptr_t size, std::uint32_t experiment) { + return AsanRuntime::Impl::__asan_report_exp_store_n_nid_no_patch(address, size, experiment, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_report_exp_store_n_noabort() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_report_exp_store_n_noabort(std::uintptr_t address, std::uintptr_t size, std::uint32_t experiment) { + return AsanRuntime::Impl::__asan_report_exp_store_n_noabort_nid_no_patch(address, size, experiment, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_report_load1() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_report_load1(std::uintptr_t address) { + return AsanRuntime::Impl::__asan_report_load1_nid_no_patch(address, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_report_load16() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_report_load16(std::uintptr_t address) { + return AsanRuntime::Impl::__asan_report_load16_nid_no_patch(address, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_report_load16_noabort() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_report_load16_noabort(std::uintptr_t address) { + return AsanRuntime::Impl::__asan_report_load16_noabort_nid_no_patch(address, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_report_load1_noabort() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_report_load1_noabort(std::uintptr_t address) { + return AsanRuntime::Impl::__asan_report_load1_noabort_nid_no_patch(address, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_report_load2() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_report_load2(std::uintptr_t address) { + return AsanRuntime::Impl::__asan_report_load2_nid_no_patch(address, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_report_load2_noabort() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_report_load2_noabort(std::uintptr_t address) { + return AsanRuntime::Impl::__asan_report_load2_noabort_nid_no_patch(address, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_report_load4() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_report_load4(std::uintptr_t address) { + return AsanRuntime::Impl::__asan_report_load4_nid_no_patch(address, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_report_load4_noabort() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_report_load4_noabort(std::uintptr_t address) { + return AsanRuntime::Impl::__asan_report_load4_noabort_nid_no_patch(address, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_report_load8() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_report_load8(std::uintptr_t address) { + return AsanRuntime::Impl::__asan_report_load8_nid_no_patch(address, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_report_load8_noabort() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_report_load8_noabort(std::uintptr_t address) { + return AsanRuntime::Impl::__asan_report_load8_noabort_nid_no_patch(address, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_report_load_n() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_report_load_n(std::uintptr_t address, std::uintptr_t size) { + return AsanRuntime::Impl::__asan_report_load_n_nid_no_patch(address, size, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_report_load_n_noabort() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_report_load_n_noabort(std::uintptr_t address, std::uintptr_t size) { + return AsanRuntime::Impl::__asan_report_load_n_noabort_nid_no_patch(address, size, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } int APS5_VABI __asan_report_present() { - NotImplemented_nid_no_patch(__func__); - return 0; + return AsanRuntime::Impl::__asan_report_present_nid_no_patch({reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_report_store1() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_report_store1(std::uintptr_t address) { + return AsanRuntime::Impl::__asan_report_store1_nid_no_patch(address, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_report_store16() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_report_store16(std::uintptr_t address) { + return AsanRuntime::Impl::__asan_report_store16_nid_no_patch(address, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_report_store16_noabort() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_report_store16_noabort(std::uintptr_t address) { + return AsanRuntime::Impl::__asan_report_store16_noabort_nid_no_patch(address, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_report_store1_noabort() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_report_store1_noabort(std::uintptr_t address) { + return AsanRuntime::Impl::__asan_report_store1_noabort_nid_no_patch(address, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_report_store2() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_report_store2(std::uintptr_t address) { + return AsanRuntime::Impl::__asan_report_store2_nid_no_patch(address, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_report_store2_noabort() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_report_store2_noabort(std::uintptr_t address) { + return AsanRuntime::Impl::__asan_report_store2_noabort_nid_no_patch(address, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_report_store4() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_report_store4(std::uintptr_t address) { + return AsanRuntime::Impl::__asan_report_store4_nid_no_patch(address, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_report_store4_noabort() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_report_store4_noabort(std::uintptr_t address) { + return AsanRuntime::Impl::__asan_report_store4_noabort_nid_no_patch(address, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_report_store8() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_report_store8(std::uintptr_t address) { + return AsanRuntime::Impl::__asan_report_store8_nid_no_patch(address, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_report_store8_noabort() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_report_store8_noabort(std::uintptr_t address) { + return AsanRuntime::Impl::__asan_report_store8_noabort_nid_no_patch(address, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_report_store_n() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_report_store_n(std::uintptr_t address, std::uintptr_t size) { + return AsanRuntime::Impl::__asan_report_store_n_nid_no_patch(address, size, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_report_store_n_noabort() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_report_store_n_noabort(std::uintptr_t address, std::uintptr_t size) { + return AsanRuntime::Impl::__asan_report_store_n_noabort_nid_no_patch(address, size, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_set_error_report_callback() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_set_error_report_callback(void (APS5_VABI* callback)(const char*)) { + return AsanRuntime::Impl::__asan_set_error_report_callback_nid_no_patch(callback, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_set_shadow_00() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_set_shadow_00(std::uintptr_t address, std::uintptr_t size) { + return AsanRuntime::Impl::__asan_set_shadow_00_nid_no_patch(address, size, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_set_shadow_01() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_set_shadow_01(std::uintptr_t address, std::uintptr_t size) { + return AsanRuntime::Impl::__asan_set_shadow_01_nid_no_patch(address, size, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_set_shadow_02() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_set_shadow_02(std::uintptr_t address, std::uintptr_t size) { + return AsanRuntime::Impl::__asan_set_shadow_02_nid_no_patch(address, size, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_set_shadow_03() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_set_shadow_03(std::uintptr_t address, std::uintptr_t size) { + return AsanRuntime::Impl::__asan_set_shadow_03_nid_no_patch(address, size, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_set_shadow_04() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_set_shadow_04(std::uintptr_t address, std::uintptr_t size) { + return AsanRuntime::Impl::__asan_set_shadow_04_nid_no_patch(address, size, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_set_shadow_05() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_set_shadow_05(std::uintptr_t address, std::uintptr_t size) { + return AsanRuntime::Impl::__asan_set_shadow_05_nid_no_patch(address, size, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_set_shadow_06() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_set_shadow_06(std::uintptr_t address, std::uintptr_t size) { + return AsanRuntime::Impl::__asan_set_shadow_06_nid_no_patch(address, size, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_set_shadow_07() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_set_shadow_07(std::uintptr_t address, std::uintptr_t size) { + return AsanRuntime::Impl::__asan_set_shadow_07_nid_no_patch(address, size, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_set_shadow_f1() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_set_shadow_f1(std::uintptr_t address, std::uintptr_t size) { + return AsanRuntime::Impl::__asan_set_shadow_f1_nid_no_patch(address, size, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_set_shadow_f2() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_set_shadow_f2(std::uintptr_t address, std::uintptr_t size) { + return AsanRuntime::Impl::__asan_set_shadow_f2_nid_no_patch(address, size, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_set_shadow_f3() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_set_shadow_f3(std::uintptr_t address, std::uintptr_t size) { + return AsanRuntime::Impl::__asan_set_shadow_f3_nid_no_patch(address, size, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_set_shadow_f5() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_set_shadow_f5(std::uintptr_t address, std::uintptr_t size) { + return AsanRuntime::Impl::__asan_set_shadow_f5_nid_no_patch(address, size, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_set_shadow_f8() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_set_shadow_f8(std::uintptr_t address, std::uintptr_t size) { + return AsanRuntime::Impl::__asan_set_shadow_f8_nid_no_patch(address, size, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_stack_free_0() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_stack_free_0(std::uintptr_t pointer, std::uintptr_t size) { + return AsanRuntime::Impl::__asan_stack_free_0_nid_no_patch(pointer, size, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_stack_free_1() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_stack_free_1(std::uintptr_t pointer, std::uintptr_t size) { + return AsanRuntime::Impl::__asan_stack_free_1_nid_no_patch(pointer, size, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_stack_free_10() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_stack_free_10(std::uintptr_t pointer, std::uintptr_t size) { + return AsanRuntime::Impl::__asan_stack_free_10_nid_no_patch(pointer, size, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_stack_free_2() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_stack_free_2(std::uintptr_t pointer, std::uintptr_t size) { + return AsanRuntime::Impl::__asan_stack_free_2_nid_no_patch(pointer, size, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_stack_free_3() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_stack_free_3(std::uintptr_t pointer, std::uintptr_t size) { + return AsanRuntime::Impl::__asan_stack_free_3_nid_no_patch(pointer, size, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_stack_free_4() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_stack_free_4(std::uintptr_t pointer, std::uintptr_t size) { + return AsanRuntime::Impl::__asan_stack_free_4_nid_no_patch(pointer, size, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_stack_free_5() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_stack_free_5(std::uintptr_t pointer, std::uintptr_t size) { + return AsanRuntime::Impl::__asan_stack_free_5_nid_no_patch(pointer, size, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_stack_free_6() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_stack_free_6(std::uintptr_t pointer, std::uintptr_t size) { + return AsanRuntime::Impl::__asan_stack_free_6_nid_no_patch(pointer, size, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_stack_free_7() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_stack_free_7(std::uintptr_t pointer, std::uintptr_t size) { + return AsanRuntime::Impl::__asan_stack_free_7_nid_no_patch(pointer, size, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_stack_free_8() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_stack_free_8(std::uintptr_t pointer, std::uintptr_t size) { + return AsanRuntime::Impl::__asan_stack_free_8_nid_no_patch(pointer, size, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_stack_free_9() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_stack_free_9(std::uintptr_t pointer, std::uintptr_t size) { + return AsanRuntime::Impl::__asan_stack_free_9_nid_no_patch(pointer, size, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_stack_malloc_0() { - NotImplemented_nid_no_patch(__func__); - return 0; +std::uintptr_t APS5_VABI __asan_stack_malloc_0(std::uintptr_t size) { + return AsanRuntime::Impl::__asan_stack_malloc_0_nid_no_patch(size, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_stack_malloc_1() { - NotImplemented_nid_no_patch(__func__); - return 0; +std::uintptr_t APS5_VABI __asan_stack_malloc_1(std::uintptr_t size) { + return AsanRuntime::Impl::__asan_stack_malloc_1_nid_no_patch(size, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_stack_malloc_10() { - NotImplemented_nid_no_patch(__func__); - return 0; +std::uintptr_t APS5_VABI __asan_stack_malloc_10(std::uintptr_t size) { + return AsanRuntime::Impl::__asan_stack_malloc_10_nid_no_patch(size, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_stack_malloc_2() { - NotImplemented_nid_no_patch(__func__); - return 0; +std::uintptr_t APS5_VABI __asan_stack_malloc_2(std::uintptr_t size) { + return AsanRuntime::Impl::__asan_stack_malloc_2_nid_no_patch(size, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_stack_malloc_3() { - NotImplemented_nid_no_patch(__func__); - return 0; +std::uintptr_t APS5_VABI __asan_stack_malloc_3(std::uintptr_t size) { + return AsanRuntime::Impl::__asan_stack_malloc_3_nid_no_patch(size, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_stack_malloc_4() { - NotImplemented_nid_no_patch(__func__); - return 0; +std::uintptr_t APS5_VABI __asan_stack_malloc_4(std::uintptr_t size) { + return AsanRuntime::Impl::__asan_stack_malloc_4_nid_no_patch(size, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_stack_malloc_5() { - NotImplemented_nid_no_patch(__func__); - return 0; +std::uintptr_t APS5_VABI __asan_stack_malloc_5(std::uintptr_t size) { + return AsanRuntime::Impl::__asan_stack_malloc_5_nid_no_patch(size, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_stack_malloc_6() { - NotImplemented_nid_no_patch(__func__); - return 0; +std::uintptr_t APS5_VABI __asan_stack_malloc_6(std::uintptr_t size) { + return AsanRuntime::Impl::__asan_stack_malloc_6_nid_no_patch(size, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_stack_malloc_7() { - NotImplemented_nid_no_patch(__func__); - return 0; +std::uintptr_t APS5_VABI __asan_stack_malloc_7(std::uintptr_t size) { + return AsanRuntime::Impl::__asan_stack_malloc_7_nid_no_patch(size, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_stack_malloc_8() { - NotImplemented_nid_no_patch(__func__); - return 0; +std::uintptr_t APS5_VABI __asan_stack_malloc_8(std::uintptr_t size) { + return AsanRuntime::Impl::__asan_stack_malloc_8_nid_no_patch(size, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_stack_malloc_9() { - NotImplemented_nid_no_patch(__func__); - return 0; +std::uintptr_t APS5_VABI __asan_stack_malloc_9(std::uintptr_t size) { + return AsanRuntime::Impl::__asan_stack_malloc_9_nid_no_patch(size, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_stack_malloc_always_0() { - NotImplemented_nid_no_patch(__func__); - return 0; +std::uintptr_t APS5_VABI __asan_stack_malloc_always_0(std::uintptr_t size) { + return AsanRuntime::Impl::__asan_stack_malloc_always_0_nid_no_patch(size, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_stack_malloc_always_1() { - NotImplemented_nid_no_patch(__func__); - return 0; +std::uintptr_t APS5_VABI __asan_stack_malloc_always_1(std::uintptr_t size) { + return AsanRuntime::Impl::__asan_stack_malloc_always_1_nid_no_patch(size, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_stack_malloc_always_10() { - NotImplemented_nid_no_patch(__func__); - return 0; +std::uintptr_t APS5_VABI __asan_stack_malloc_always_10(std::uintptr_t size) { + return AsanRuntime::Impl::__asan_stack_malloc_always_10_nid_no_patch(size, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_stack_malloc_always_2() { - NotImplemented_nid_no_patch(__func__); - return 0; +std::uintptr_t APS5_VABI __asan_stack_malloc_always_2(std::uintptr_t size) { + return AsanRuntime::Impl::__asan_stack_malloc_always_2_nid_no_patch(size, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_stack_malloc_always_3() { - NotImplemented_nid_no_patch(__func__); - return 0; +std::uintptr_t APS5_VABI __asan_stack_malloc_always_3(std::uintptr_t size) { + return AsanRuntime::Impl::__asan_stack_malloc_always_3_nid_no_patch(size, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_stack_malloc_always_4() { - NotImplemented_nid_no_patch(__func__); - return 0; +std::uintptr_t APS5_VABI __asan_stack_malloc_always_4(std::uintptr_t size) { + return AsanRuntime::Impl::__asan_stack_malloc_always_4_nid_no_patch(size, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_stack_malloc_always_5() { - NotImplemented_nid_no_patch(__func__); - return 0; +std::uintptr_t APS5_VABI __asan_stack_malloc_always_5(std::uintptr_t size) { + return AsanRuntime::Impl::__asan_stack_malloc_always_5_nid_no_patch(size, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_stack_malloc_always_6() { - NotImplemented_nid_no_patch(__func__); - return 0; +std::uintptr_t APS5_VABI __asan_stack_malloc_always_6(std::uintptr_t size) { + return AsanRuntime::Impl::__asan_stack_malloc_always_6_nid_no_patch(size, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_stack_malloc_always_7() { - NotImplemented_nid_no_patch(__func__); - return 0; +std::uintptr_t APS5_VABI __asan_stack_malloc_always_7(std::uintptr_t size) { + return AsanRuntime::Impl::__asan_stack_malloc_always_7_nid_no_patch(size, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_stack_malloc_always_8() { - NotImplemented_nid_no_patch(__func__); - return 0; +std::uintptr_t APS5_VABI __asan_stack_malloc_always_8(std::uintptr_t size) { + return AsanRuntime::Impl::__asan_stack_malloc_always_8_nid_no_patch(size, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_stack_malloc_always_9() { - NotImplemented_nid_no_patch(__func__); - return 0; +std::uintptr_t APS5_VABI __asan_stack_malloc_always_9(std::uintptr_t size) { + return AsanRuntime::Impl::__asan_stack_malloc_always_9_nid_no_patch(size, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_store1() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_store1(std::uintptr_t address) { + return AsanRuntime::Impl::__asan_store1_nid_no_patch(address, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_store16() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_store16(std::uintptr_t address) { + return AsanRuntime::Impl::__asan_store16_nid_no_patch(address, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_store16_noabort() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_store16_noabort(std::uintptr_t address) { + return AsanRuntime::Impl::__asan_store16_noabort_nid_no_patch(address, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_store1_noabort() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_store1_noabort(std::uintptr_t address) { + return AsanRuntime::Impl::__asan_store1_noabort_nid_no_patch(address, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_store2() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_store2(std::uintptr_t address) { + return AsanRuntime::Impl::__asan_store2_nid_no_patch(address, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_store2_noabort() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_store2_noabort(std::uintptr_t address) { + return AsanRuntime::Impl::__asan_store2_noabort_nid_no_patch(address, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_store4() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_store4(std::uintptr_t address) { + return AsanRuntime::Impl::__asan_store4_nid_no_patch(address, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_store4_noabort() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_store4_noabort(std::uintptr_t address) { + return AsanRuntime::Impl::__asan_store4_noabort_nid_no_patch(address, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_store8() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_store8(std::uintptr_t address) { + return AsanRuntime::Impl::__asan_store8_nid_no_patch(address, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_store8_noabort() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_store8_noabort(std::uintptr_t address) { + return AsanRuntime::Impl::__asan_store8_noabort_nid_no_patch(address, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_storeN() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_storeN(std::uintptr_t address, std::uintptr_t size) { + return AsanRuntime::Impl::__asan_storeN_nid_no_patch(address, size, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_storeN_noabort() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_storeN_noabort(std::uintptr_t address, std::uintptr_t size) { + return AsanRuntime::Impl::__asan_storeN_noabort_nid_no_patch(address, size, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_unpoison_intra_object_redzone() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_unpoison_intra_object_redzone(std::uintptr_t address, std::uintptr_t size) { + return AsanRuntime::Impl::__asan_unpoison_intra_object_redzone_nid_no_patch(address, size, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_unpoison_memory_region() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_unpoison_memory_region(const volatile void* addr, std::uintptr_t size) { + return AsanRuntime::Impl::__asan_unpoison_memory_region_nid_no_patch(addr, size, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_unpoison_stack_memory() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_unpoison_stack_memory(std::uintptr_t address, std::uintptr_t size) { + return AsanRuntime::Impl::__asan_unpoison_stack_memory_nid_no_patch(address, size, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_unregister_elf_globals() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_unregister_elf_globals(std::uintptr_t* flag, void* start, void* stop) { + return AsanRuntime::Impl::__asan_unregister_elf_globals_nid_no_patch(flag, start, stop, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_unregister_globals() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __asan_unregister_globals(void* globals, std::uintptr_t count) { + return AsanRuntime::Impl::__asan_unregister_globals_nid_no_patch(globals, count, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } int APS5_VABI __asan_unregister_image_globals() { @@ -1006,234 +811,180 @@ int APS5_VABI __asan_unregister_image_globals() { return 0; } -int APS5_VABI __asan_update_allocation_context() { - NotImplemented_nid_no_patch(__func__); - return 0; +int APS5_VABI __asan_update_allocation_context(void* address) { + return AsanRuntime::Impl::__asan_update_allocation_context_nid_no_patch(address, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __asan_version_mismatch_check_v6() { - NotImplemented_nid_no_patch(__func__); - return 0; -} +void APS5_VABI __asan_version_mismatch_check_v6() {} -int APS5_VABI __asan_version_mismatch_check_v7() { - NotImplemented_nid_no_patch(__func__); - return 0; -} +void APS5_VABI __asan_version_mismatch_check_v7() {} -int APS5_VABI __asan_version_mismatch_check_v8() { - NotImplemented_nid_no_patch(__func__); - return 0; -} +void APS5_VABI __asan_version_mismatch_check_v8() {} -int APS5_VABI __sancov_default_options() { - NotImplemented_nid_no_patch(__func__); - return 0; +const char* APS5_VABI __sancov_default_options() { + return ""; } -int APS5_VABI __sanitizer_annotate_contiguous_container() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __sanitizer_annotate_contiguous_container(const void* beg, const void* end, const void* oldMid, const void* newMid) { + return AsanRuntime::Impl::__sanitizer_annotate_contiguous_container_nid_no_patch(beg, end, oldMid, newMid, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __sanitizer_annotate_double_ended_contiguous_container() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __sanitizer_annotate_double_ended_contiguous_container(const void* storageBeg, const void* storageEnd, const void* oldContainerBeg, const void* oldContainerEnd, const void* newContainerBeg, const void* newContainerEnd) { + return AsanRuntime::Impl::__sanitizer_annotate_double_ended_contiguous_container_nid_no_patch(storageBeg, storageEnd, oldContainerBeg, oldContainerEnd, newContainerBeg, newContainerEnd, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __sanitizer_contiguous_container_find_bad_address() { - NotImplemented_nid_no_patch(__func__); - return 0; +const void* APS5_VABI __sanitizer_contiguous_container_find_bad_address(const void* beg, const void* mid, const void* end) { + return AsanRuntime::Impl::__sanitizer_contiguous_container_find_bad_address_nid_no_patch(beg, mid, end, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __sanitizer_cov_dump() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __sanitizer_cov_dump() { + return AsanRuntime::Impl::__sanitizer_cov_dump_nid_no_patch({reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __sanitizer_cov_trace_pc_guard() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __sanitizer_cov_trace_pc_guard(std::uint32_t* guard) { + return AsanRuntime::Impl::__sanitizer_cov_trace_pc_guard_nid_no_patch(guard, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __sanitizer_cov_trace_pc_guard_init() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __sanitizer_cov_trace_pc_guard_init(std::uint32_t* start, std::uint32_t* end) { + return AsanRuntime::Impl::__sanitizer_cov_trace_pc_guard_init_nid_no_patch(start, end, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __sanitizer_double_ended_contiguous_container_find_bad_address() { - NotImplemented_nid_no_patch(__func__); - return 0; +const void* APS5_VABI __sanitizer_double_ended_contiguous_container_find_bad_address(const void* storageBeg, const void* containerBeg, const void* containerEnd, const void* storageEnd) { + return AsanRuntime::Impl::__sanitizer_double_ended_contiguous_container_find_bad_address_nid_no_patch(storageBeg, containerBeg, containerEnd, storageEnd, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __sanitizer_dump_coverage() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __sanitizer_dump_coverage(const std::uintptr_t* pcs, std::uintptr_t length) { + return AsanRuntime::Impl::__sanitizer_dump_coverage_nid_no_patch(pcs, length, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __sanitizer_dump_trace_pc_guard_coverage() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __sanitizer_dump_trace_pc_guard_coverage() { + return AsanRuntime::Impl::__sanitizer_dump_trace_pc_guard_coverage_nid_no_patch({reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __sanitizer_finish_switch_fiber() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __sanitizer_finish_switch_fiber(void* fakeStack, const void** bottomOld, std::uintptr_t* sizeOld) { + return AsanRuntime::Impl::__sanitizer_finish_switch_fiber_nid_no_patch(fakeStack, bottomOld, sizeOld, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __sanitizer_free_hook() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __sanitizer_free_hook(void*) { } -int APS5_VABI __sanitizer_get_allocated_begin() { - NotImplemented_nid_no_patch(__func__); - return 0; +const void* APS5_VABI __sanitizer_get_allocated_begin(const void* pointer) { + return AsanRuntime::Impl::__sanitizer_get_allocated_begin_nid_no_patch(pointer, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __sanitizer_get_allocated_size() { - NotImplemented_nid_no_patch(__func__); - return 0; +std::size_t APS5_VABI __sanitizer_get_allocated_size(const void* pointer) { + return AsanRuntime::Impl::__sanitizer_get_allocated_size_nid_no_patch(pointer, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __sanitizer_get_allocated_size_fast() { - NotImplemented_nid_no_patch(__func__); - return 0; +std::size_t APS5_VABI __sanitizer_get_allocated_size_fast(const void* pointer) { + return AsanRuntime::Impl::__sanitizer_get_allocated_size_fast_nid_no_patch(pointer, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __sanitizer_get_current_allocated_bytes() { - NotImplemented_nid_no_patch(__func__); - return 0; +std::size_t APS5_VABI __sanitizer_get_current_allocated_bytes() { + return AsanRuntime::Impl::__sanitizer_get_current_allocated_bytes_nid_no_patch({reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __sanitizer_get_estimated_allocated_size() { - NotImplemented_nid_no_patch(__func__); - return 0; +std::size_t APS5_VABI __sanitizer_get_estimated_allocated_size(std::size_t size) { + return AsanRuntime::Impl::__sanitizer_get_estimated_allocated_size_nid_no_patch(size, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __sanitizer_get_free_bytes() { - NotImplemented_nid_no_patch(__func__); - return 0; +std::size_t APS5_VABI __sanitizer_get_free_bytes() { + return AsanRuntime::Impl::__sanitizer_get_free_bytes_nid_no_patch({reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __sanitizer_get_heap_size() { - NotImplemented_nid_no_patch(__func__); - return 0; +std::size_t APS5_VABI __sanitizer_get_heap_size() { + return AsanRuntime::Impl::__sanitizer_get_heap_size_nid_no_patch({reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __sanitizer_get_ownership() { - NotImplemented_nid_no_patch(__func__); - return 0; +int APS5_VABI __sanitizer_get_ownership(const void* pointer) { + return AsanRuntime::Impl::__sanitizer_get_ownership_nid_no_patch(pointer, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __sanitizer_get_report_path() { - NotImplemented_nid_no_patch(__func__); - return 0; +const char* APS5_VABI __sanitizer_get_report_path() { + return AsanRuntime::Impl::__sanitizer_get_report_path_nid_no_patch({reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __sanitizer_get_unmapped_bytes() { - NotImplemented_nid_no_patch(__func__); +std::size_t APS5_VABI __sanitizer_get_unmapped_bytes() { return 0; } -int APS5_VABI __sanitizer_malloc_hook() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __sanitizer_malloc_hook(void*, std::size_t) { } -int APS5_VABI __sanitizer_print_stack_trace() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __sanitizer_print_stack_trace() { + return AsanRuntime::Impl::__sanitizer_print_stack_trace_nid_no_patch({reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __sanitizer_ptr_cmp() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __sanitizer_ptr_cmp(void*, void*) { + } -int APS5_VABI __sanitizer_ptr_sub() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __sanitizer_ptr_sub(void*, void*) { + } -int APS5_VABI __sanitizer_purge_allocator() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __sanitizer_purge_allocator() { + return AsanRuntime::Impl::__sanitizer_purge_allocator_nid_no_patch({reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __sanitizer_sandbox_on_notify() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __sanitizer_sandbox_on_notify(void* arguments) { + return AsanRuntime::Impl::__sanitizer_sandbox_on_notify_nid_no_patch(arguments, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __sanitizer_set_death_callback() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __sanitizer_set_death_callback(void (APS5_VABI* callback)()) { + return AsanRuntime::Impl::__sanitizer_set_death_callback_nid_no_patch(callback, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __sanitizer_set_report_fd() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __sanitizer_set_report_fd(void* descriptor) { + return AsanRuntime::Impl::__sanitizer_set_report_fd_nid_no_patch(descriptor, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __sanitizer_set_report_path() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __sanitizer_set_report_path(const char* path) { + return AsanRuntime::Impl::__sanitizer_set_report_path_nid_no_patch(path, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __sanitizer_start_switch_fiber() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __sanitizer_start_switch_fiber(void** fakeStackSave, const void* bottom, std::uintptr_t size) { + return AsanRuntime::Impl::__sanitizer_start_switch_fiber_nid_no_patch(fakeStackSave, bottom, size, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __sanitizer_symbolize_global() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __sanitizer_symbolize_global(std::uintptr_t address, const char* format, char* output, std::uintptr_t outputSize) { + return AsanRuntime::Impl::__sanitizer_symbolize_global_nid_no_patch(address, format, output, outputSize, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __sanitizer_symbolize_pc() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __sanitizer_symbolize_pc(std::uintptr_t pc, const char* format, char* output, std::uintptr_t outputSize) { + return AsanRuntime::Impl::__sanitizer_symbolize_pc_nid_no_patch(pc, format, output, outputSize, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __sanitizer_unaligned_load16() { - NotImplemented_nid_no_patch(__func__); - return 0; +std::uint16_t APS5_VABI __sanitizer_unaligned_load16(const void* ptr) { + return AsanRuntime::Impl::__sanitizer_unaligned_load16_nid_no_patch(ptr, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __sanitizer_unaligned_load32() { - NotImplemented_nid_no_patch(__func__); - return 0; +std::uint32_t APS5_VABI __sanitizer_unaligned_load32(const void* ptr) { + return AsanRuntime::Impl::__sanitizer_unaligned_load32_nid_no_patch(ptr, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __sanitizer_unaligned_load64() { - NotImplemented_nid_no_patch(__func__); - return 0; +std::uint64_t APS5_VABI __sanitizer_unaligned_load64(const void* ptr) { + return AsanRuntime::Impl::__sanitizer_unaligned_load64_nid_no_patch(ptr, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __sanitizer_unaligned_store16() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __sanitizer_unaligned_store16(void* ptr, std::uint16_t val) { + return AsanRuntime::Impl::__sanitizer_unaligned_store16_nid_no_patch(ptr, val, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __sanitizer_unaligned_store32() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __sanitizer_unaligned_store32(void* ptr, std::uint32_t val) { + return AsanRuntime::Impl::__sanitizer_unaligned_store32_nid_no_patch(ptr, val, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __sanitizer_unaligned_store64() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __sanitizer_unaligned_store64(void* ptr, std::uint64_t val) { + return AsanRuntime::Impl::__sanitizer_unaligned_store64_nid_no_patch(ptr, val, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __sanitizer_verify_contiguous_container() { - NotImplemented_nid_no_patch(__func__); - return 0; +int APS5_VABI __sanitizer_verify_contiguous_container(const void* beg, const void* mid, const void* end) { + return AsanRuntime::Impl::__sanitizer_verify_contiguous_container_nid_no_patch(beg, mid, end, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __sanitizer_verify_double_ended_contiguous_container() { - NotImplemented_nid_no_patch(__func__); - return 0; +int APS5_VABI __sanitizer_verify_double_ended_contiguous_container(const void* storageBeg, const void* containerBeg, const void* containerEnd, const void* storageEnd) { + return AsanRuntime::Impl::__sanitizer_verify_double_ended_contiguous_container_nid_no_patch(storageBeg, containerBeg, containerEnd, storageEnd, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } int APS5_VABI __ubsan_current_error_report() { @@ -1246,49 +997,40 @@ int APS5_VABI __ubsan_current_error_report_size() { return 0; } -int APS5_VABI __ubsan_default_options() { - NotImplemented_nid_no_patch(__func__); - return 0; +const char* APS5_VABI __ubsan_default_options() { + return ""; } -int APS5_VABI __ubsan_get_current_report_data() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __ubsan_get_current_report_data(const char** issueKind, const char** message, const char** filename, unsigned* line, unsigned* column, char** memoryAddress) { + return AsanRuntime::Impl::__ubsan_get_current_report_data_nid_no_patch(issueKind, message, filename, line, column, memoryAddress, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __ubsan_handle_add_overflow() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __ubsan_handle_add_overflow(void* data, std::uintptr_t lhs, std::uintptr_t rhs) { + return AsanRuntime::Impl::__ubsan_handle_add_overflow_nid_no_patch(data, lhs, rhs, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __ubsan_handle_add_overflow_abort() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __ubsan_handle_add_overflow_abort(void* data, std::uintptr_t lhs, std::uintptr_t rhs) { + return AsanRuntime::Impl::__ubsan_handle_add_overflow_abort_nid_no_patch(data, lhs, rhs, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __ubsan_handle_alignment_assumption() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __ubsan_handle_alignment_assumption(void* data, std::uintptr_t pointer, std::uintptr_t alignment, std::uintptr_t offset) { + return AsanRuntime::Impl::__ubsan_handle_alignment_assumption_nid_no_patch(data, pointer, alignment, offset, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __ubsan_handle_alignment_assumption_abort() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __ubsan_handle_alignment_assumption_abort(void* data, std::uintptr_t pointer, std::uintptr_t alignment, std::uintptr_t offset) { + return AsanRuntime::Impl::__ubsan_handle_alignment_assumption_abort_nid_no_patch(data, pointer, alignment, offset, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __ubsan_handle_builtin_unreachable() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __ubsan_handle_builtin_unreachable(void* data) { + return AsanRuntime::Impl::__ubsan_handle_builtin_unreachable_nid_no_patch(data, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __ubsan_handle_divrem_overflow() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __ubsan_handle_divrem_overflow(void* data, std::uintptr_t lhs, std::uintptr_t rhs) { + return AsanRuntime::Impl::__ubsan_handle_divrem_overflow_nid_no_patch(data, lhs, rhs, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __ubsan_handle_divrem_overflow_abort() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __ubsan_handle_divrem_overflow_abort(void* data, std::uintptr_t lhs, std::uintptr_t rhs) { + return AsanRuntime::Impl::__ubsan_handle_divrem_overflow_abort_nid_no_patch(data, lhs, rhs, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } int APS5_VABI __ubsan_handle_dynamic_type_cache_miss() { @@ -1301,24 +1043,20 @@ int APS5_VABI __ubsan_handle_dynamic_type_cache_miss_abort() { return 0; } -int APS5_VABI __ubsan_handle_float_cast_overflow() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __ubsan_handle_float_cast_overflow(void* data, std::uintptr_t from) { + return AsanRuntime::Impl::__ubsan_handle_float_cast_overflow_nid_no_patch(data, from, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __ubsan_handle_float_cast_overflow_abort() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __ubsan_handle_float_cast_overflow_abort(void* data, std::uintptr_t from) { + return AsanRuntime::Impl::__ubsan_handle_float_cast_overflow_abort_nid_no_patch(data, from, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __ubsan_handle_function_type_mismatch() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __ubsan_handle_function_type_mismatch(void* data, std::uintptr_t function) { + return AsanRuntime::Impl::__ubsan_handle_function_type_mismatch_nid_no_patch(data, function, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __ubsan_handle_function_type_mismatch_abort() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __ubsan_handle_function_type_mismatch_abort(void* data, std::uintptr_t function) { + return AsanRuntime::Impl::__ubsan_handle_function_type_mismatch_abort_nid_no_patch(data, function, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } int APS5_VABI __ubsan_handle_function_type_mismatch_v1() { @@ -1331,184 +1069,144 @@ int APS5_VABI __ubsan_handle_function_type_mismatch_v1_abort() { return 0; } -int APS5_VABI __ubsan_handle_implicit_conversion() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __ubsan_handle_implicit_conversion(void* data, std::uintptr_t source, std::uintptr_t destination) { + return AsanRuntime::Impl::__ubsan_handle_implicit_conversion_nid_no_patch(data, source, destination, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __ubsan_handle_implicit_conversion_abort() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __ubsan_handle_implicit_conversion_abort(void* data, std::uintptr_t source, std::uintptr_t destination) { + return AsanRuntime::Impl::__ubsan_handle_implicit_conversion_abort_nid_no_patch(data, source, destination, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __ubsan_handle_invalid_builtin() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __ubsan_handle_invalid_builtin(void* data) { + return AsanRuntime::Impl::__ubsan_handle_invalid_builtin_nid_no_patch(data, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __ubsan_handle_invalid_builtin_abort() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __ubsan_handle_invalid_builtin_abort(void* data) { + return AsanRuntime::Impl::__ubsan_handle_invalid_builtin_abort_nid_no_patch(data, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __ubsan_handle_load_invalid_value() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __ubsan_handle_load_invalid_value(void* data, std::uintptr_t value) { + return AsanRuntime::Impl::__ubsan_handle_load_invalid_value_nid_no_patch(data, value, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __ubsan_handle_load_invalid_value_abort() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __ubsan_handle_load_invalid_value_abort(void* data, std::uintptr_t value) { + return AsanRuntime::Impl::__ubsan_handle_load_invalid_value_abort_nid_no_patch(data, value, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __ubsan_handle_missing_return() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __ubsan_handle_missing_return(void* data) { + return AsanRuntime::Impl::__ubsan_handle_missing_return_nid_no_patch(data, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __ubsan_handle_mul_overflow() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __ubsan_handle_mul_overflow(void* data, std::uintptr_t lhs, std::uintptr_t rhs) { + return AsanRuntime::Impl::__ubsan_handle_mul_overflow_nid_no_patch(data, lhs, rhs, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __ubsan_handle_mul_overflow_abort() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __ubsan_handle_mul_overflow_abort(void* data, std::uintptr_t lhs, std::uintptr_t rhs) { + return AsanRuntime::Impl::__ubsan_handle_mul_overflow_abort_nid_no_patch(data, lhs, rhs, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __ubsan_handle_negate_overflow() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __ubsan_handle_negate_overflow(void* data, std::uintptr_t oldValue) { + return AsanRuntime::Impl::__ubsan_handle_negate_overflow_nid_no_patch(data, oldValue, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __ubsan_handle_negate_overflow_abort() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __ubsan_handle_negate_overflow_abort(void* data, std::uintptr_t oldValue) { + return AsanRuntime::Impl::__ubsan_handle_negate_overflow_abort_nid_no_patch(data, oldValue, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __ubsan_handle_nonnull_arg() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __ubsan_handle_nonnull_arg(void* data) { + return AsanRuntime::Impl::__ubsan_handle_nonnull_arg_nid_no_patch(data, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __ubsan_handle_nonnull_arg_abort() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __ubsan_handle_nonnull_arg_abort(void* data) { + return AsanRuntime::Impl::__ubsan_handle_nonnull_arg_abort_nid_no_patch(data, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __ubsan_handle_nonnull_return() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __ubsan_handle_nonnull_return(void* data) { + return AsanRuntime::Impl::__ubsan_handle_nonnull_return_nid_no_patch(data, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __ubsan_handle_nonnull_return_abort() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __ubsan_handle_nonnull_return_abort(void* data) { + return AsanRuntime::Impl::__ubsan_handle_nonnull_return_abort_nid_no_patch(data, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __ubsan_handle_nonnull_return_v1() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __ubsan_handle_nonnull_return_v1(void* data, void* location) { + return AsanRuntime::Impl::__ubsan_handle_nonnull_return_v1_nid_no_patch(data, location, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __ubsan_handle_nonnull_return_v1_abort() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __ubsan_handle_nonnull_return_v1_abort(void* data, void* location) { + return AsanRuntime::Impl::__ubsan_handle_nonnull_return_v1_abort_nid_no_patch(data, location, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __ubsan_handle_nullability_arg() { - NotImplemented_nid_no_patch(__func__); - return 0; -} - -int APS5_VABI __ubsan_handle_nullability_arg_abort() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __ubsan_handle_nullability_arg(void* data) { + return AsanRuntime::Impl::__ubsan_handle_nullability_arg_nid_no_patch(data, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __ubsan_handle_nullability_return_v1() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __ubsan_handle_nullability_arg_abort(void* data) { + return AsanRuntime::Impl::__ubsan_handle_nullability_arg_abort_nid_no_patch(data, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __ubsan_handle_nullability_return_v1_abort() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __ubsan_handle_nullability_return_v1(void* data, void* location) { + return AsanRuntime::Impl::__ubsan_handle_nullability_return_v1_nid_no_patch(data, location, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __ubsan_handle_out_of_bounds() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __ubsan_handle_nullability_return_v1_abort(void* data, void* location) { + return AsanRuntime::Impl::__ubsan_handle_nullability_return_v1_abort_nid_no_patch(data, location, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __ubsan_handle_out_of_bounds_abort() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __ubsan_handle_out_of_bounds(void* data, std::uintptr_t index) { + return AsanRuntime::Impl::__ubsan_handle_out_of_bounds_nid_no_patch(data, index, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __ubsan_handle_pointer_overflow() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __ubsan_handle_out_of_bounds_abort(void* data, std::uintptr_t index) { + return AsanRuntime::Impl::__ubsan_handle_out_of_bounds_abort_nid_no_patch(data, index, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __ubsan_handle_pointer_overflow_abort() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __ubsan_handle_pointer_overflow(void* data, std::uintptr_t base, std::uintptr_t result) { + return AsanRuntime::Impl::__ubsan_handle_pointer_overflow_nid_no_patch(data, base, result, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __ubsan_handle_shift_out_of_bounds() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __ubsan_handle_pointer_overflow_abort(void* data, std::uintptr_t base, std::uintptr_t result) { + return AsanRuntime::Impl::__ubsan_handle_pointer_overflow_abort_nid_no_patch(data, base, result, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __ubsan_handle_shift_out_of_bounds_abort() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __ubsan_handle_shift_out_of_bounds(void* data, std::uintptr_t lhs, std::uintptr_t rhs) { + return AsanRuntime::Impl::__ubsan_handle_shift_out_of_bounds_nid_no_patch(data, lhs, rhs, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __ubsan_handle_sub_overflow() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __ubsan_handle_shift_out_of_bounds_abort(void* data, std::uintptr_t lhs, std::uintptr_t rhs) { + return AsanRuntime::Impl::__ubsan_handle_shift_out_of_bounds_abort_nid_no_patch(data, lhs, rhs, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __ubsan_handle_sub_overflow_abort() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __ubsan_handle_sub_overflow(void* data, std::uintptr_t lhs, std::uintptr_t rhs) { + return AsanRuntime::Impl::__ubsan_handle_sub_overflow_nid_no_patch(data, lhs, rhs, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __ubsan_handle_type_mismatch() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __ubsan_handle_sub_overflow_abort(void* data, std::uintptr_t lhs, std::uintptr_t rhs) { + return AsanRuntime::Impl::__ubsan_handle_sub_overflow_abort_nid_no_patch(data, lhs, rhs, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __ubsan_handle_type_mismatch_abort() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __ubsan_handle_type_mismatch(void* data, std::uintptr_t pointer) { + return AsanRuntime::Impl::__ubsan_handle_type_mismatch_nid_no_patch(data, pointer, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __ubsan_handle_type_mismatch_v1() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __ubsan_handle_type_mismatch_abort(void* data, std::uintptr_t pointer) { + return AsanRuntime::Impl::__ubsan_handle_type_mismatch_abort_nid_no_patch(data, pointer, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __ubsan_handle_type_mismatch_v1_abort() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __ubsan_handle_type_mismatch_v1(void* data, std::uintptr_t pointer) { + return AsanRuntime::Impl::__ubsan_handle_type_mismatch_v1_nid_no_patch(data, pointer, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __ubsan_handle_vla_bound_not_positive() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __ubsan_handle_type_mismatch_v1_abort(void* data, std::uintptr_t pointer) { + return AsanRuntime::Impl::__ubsan_handle_type_mismatch_v1_abort_nid_no_patch(data, pointer, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __ubsan_handle_vla_bound_not_positive_abort() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __ubsan_handle_vla_bound_not_positive(void* data, std::uintptr_t bound) { + return AsanRuntime::Impl::__ubsan_handle_vla_bound_not_positive_nid_no_patch(data, bound, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } -int APS5_VABI __ubsan_vptr_type_cache() { - NotImplemented_nid_no_patch(__func__); - return 0; +void APS5_VABI __ubsan_handle_vla_bound_not_positive_abort(void* data, std::uintptr_t bound) { + return AsanRuntime::Impl::__ubsan_handle_vla_bound_not_positive_abort_nid_no_patch(data, bound, {reinterpret_cast(__builtin_return_address(0)), reinterpret_cast(__builtin_frame_address(0)), __func__}); } } diff --git a/core/libs/prx/libSceAddressSanitizer/include/Api.hpp b/core/libs/prx/libSceAddressSanitizer/include/Api.hpp index aeef024a9c7f..75a76f59509c 100644 --- a/core/libs/prx/libSceAddressSanitizer/include/Api.hpp +++ b/core/libs/prx/libSceAddressSanitizer/include/Api.hpp @@ -1,309 +1,311 @@ #pragma once +#include +#include #include "SceTypes.hpp" extern "C" { -int APS5_VABI __asan_addr_is_in_fake_stack(); -int APS5_VABI __asan_address_is_poisoned(); -int APS5_VABI __asan_after_dynamic_init(); -int APS5_VABI __asan_aligned_alloc(); -int APS5_VABI __asan_alloca_poison(); -int APS5_VABI __asan_allocas_unpoison(); -int APS5_VABI __asan_before_dynamic_init(); -int APS5_VABI __asan_calloc(); +void* APS5_VABI __asan_addr_is_in_fake_stack(void* fakeStack, void* address, void** begin, void** end); +int APS5_VABI __asan_address_is_poisoned(const volatile void* address); +void APS5_VABI __asan_after_dynamic_init(); +void* APS5_VABI __asan_aligned_alloc(std::size_t alignment, std::size_t size); +void APS5_VABI __asan_alloca_poison(std::uintptr_t addr, std::uintptr_t size); +void APS5_VABI __asan_allocas_unpoison(std::uintptr_t top, std::uintptr_t bottom); +void APS5_VABI __asan_before_dynamic_init(const char* moduleName); +void* APS5_VABI __asan_calloc(std::size_t count, std::size_t size); int APS5_VABI __asan_current_error_report(); int APS5_VABI __asan_current_error_report_size(); -int APS5_VABI __asan_describe_address(); +void APS5_VABI __asan_describe_address(std::uintptr_t address); int APS5_VABI __asan_destroy_fake_stack(); -int APS5_VABI __asan_exp_load1(); -int APS5_VABI __asan_exp_load16(); -int APS5_VABI __asan_exp_load16_noabort(); -int APS5_VABI __asan_exp_load1_noabort(); -int APS5_VABI __asan_exp_load2(); -int APS5_VABI __asan_exp_load2_noabort(); -int APS5_VABI __asan_exp_load4(); -int APS5_VABI __asan_exp_load4_noabort(); -int APS5_VABI __asan_exp_load8(); -int APS5_VABI __asan_exp_load8_noabort(); -int APS5_VABI __asan_exp_loadN(); -int APS5_VABI __asan_exp_loadN_noabort(); -int APS5_VABI __asan_exp_store1(); -int APS5_VABI __asan_exp_store16(); -int APS5_VABI __asan_exp_store16_noabort(); -int APS5_VABI __asan_exp_store1_noabort(); -int APS5_VABI __asan_exp_store2(); -int APS5_VABI __asan_exp_store2_noabort(); -int APS5_VABI __asan_exp_store4(); -int APS5_VABI __asan_exp_store4_noabort(); -int APS5_VABI __asan_exp_store8(); -int APS5_VABI __asan_exp_store8_noabort(); -int APS5_VABI __asan_exp_storeN(); -int APS5_VABI __asan_exp_storeN_noabort(); -int APS5_VABI __asan_free(); -int APS5_VABI __asan_get_alloc_stack(); -int APS5_VABI __asan_get_current_fake_stack(); -int APS5_VABI __asan_get_free_stack(); -int APS5_VABI __asan_get_report_access_size(); +void APS5_VABI __asan_exp_load1(std::uintptr_t address, std::uint32_t exp); +void APS5_VABI __asan_exp_load16(std::uintptr_t address, std::uint32_t exp); +void APS5_VABI __asan_exp_load16_noabort(std::uintptr_t address, std::uint32_t exp); +void APS5_VABI __asan_exp_load1_noabort(std::uintptr_t address, std::uint32_t exp); +void APS5_VABI __asan_exp_load2(std::uintptr_t address, std::uint32_t exp); +void APS5_VABI __asan_exp_load2_noabort(std::uintptr_t address, std::uint32_t exp); +void APS5_VABI __asan_exp_load4(std::uintptr_t address, std::uint32_t exp); +void APS5_VABI __asan_exp_load4_noabort(std::uintptr_t address, std::uint32_t exp); +void APS5_VABI __asan_exp_load8(std::uintptr_t address, std::uint32_t exp); +void APS5_VABI __asan_exp_load8_noabort(std::uintptr_t address, std::uint32_t exp); +void APS5_VABI __asan_exp_loadN(std::uintptr_t address, std::uintptr_t size, std::uint32_t exp); +void APS5_VABI __asan_exp_loadN_noabort(std::uintptr_t address, std::uintptr_t size, std::uint32_t exp); +void APS5_VABI __asan_exp_store1(std::uintptr_t address, std::uint32_t exp); +void APS5_VABI __asan_exp_store16(std::uintptr_t address, std::uint32_t exp); +void APS5_VABI __asan_exp_store16_noabort(std::uintptr_t address, std::uint32_t exp); +void APS5_VABI __asan_exp_store1_noabort(std::uintptr_t address, std::uint32_t exp); +void APS5_VABI __asan_exp_store2(std::uintptr_t address, std::uint32_t exp); +void APS5_VABI __asan_exp_store2_noabort(std::uintptr_t address, std::uint32_t exp); +void APS5_VABI __asan_exp_store4(std::uintptr_t address, std::uint32_t exp); +void APS5_VABI __asan_exp_store4_noabort(std::uintptr_t address, std::uint32_t exp); +void APS5_VABI __asan_exp_store8(std::uintptr_t address, std::uint32_t exp); +void APS5_VABI __asan_exp_store8_noabort(std::uintptr_t address, std::uint32_t exp); +void APS5_VABI __asan_exp_storeN(std::uintptr_t address, std::uintptr_t size, std::uint32_t exp); +void APS5_VABI __asan_exp_storeN_noabort(std::uintptr_t address, std::uintptr_t size, std::uint32_t exp); +void APS5_VABI __asan_free(void* pointer); +std::uintptr_t APS5_VABI __asan_get_alloc_stack(std::uintptr_t address, std::uintptr_t* trace, std::uintptr_t size, std::uint32_t* threadId); +void* APS5_VABI __asan_get_current_fake_stack(); +std::uintptr_t APS5_VABI __asan_get_free_stack(std::uintptr_t address, std::uintptr_t* trace, std::uintptr_t size, std::uint32_t* threadId); +std::size_t APS5_VABI __asan_get_report_access_size(); int APS5_VABI __asan_get_report_access_type(); -int APS5_VABI __asan_get_report_address(); -int APS5_VABI __asan_get_report_bp(); -int APS5_VABI __asan_get_report_description(); -int APS5_VABI __asan_get_report_pc(); -int APS5_VABI __asan_get_report_sp(); -int APS5_VABI __asan_get_shadow_mapping(); -int APS5_VABI __asan_handle_no_return(); -int APS5_VABI __asan_init(); +void* APS5_VABI __asan_get_report_address(); +void* APS5_VABI __asan_get_report_bp(); +const char* APS5_VABI __asan_get_report_description(); +void* APS5_VABI __asan_get_report_pc(); +void* APS5_VABI __asan_get_report_sp(); +void APS5_VABI __asan_get_shadow_mapping(std::size_t* scale, std::size_t* offset); +void APS5_VABI __asan_handle_no_return(); +void APS5_VABI __asan_init(); int APS5_VABI __asan_init_v5(); -int APS5_VABI __asan_load1(); -int APS5_VABI __asan_load16(); -int APS5_VABI __asan_load16_noabort(); -int APS5_VABI __asan_load1_noabort(); -int APS5_VABI __asan_load2(); -int APS5_VABI __asan_load2_noabort(); -int APS5_VABI __asan_load4(); -int APS5_VABI __asan_load4_noabort(); -int APS5_VABI __asan_load8(); -int APS5_VABI __asan_load8_noabort(); -int APS5_VABI __asan_loadN(); -int APS5_VABI __asan_loadN_noabort(); -int APS5_VABI __asan_load_cxx_array_cookie(); -int APS5_VABI __asan_locate_address(); -int APS5_VABI __asan_malloc(); +void APS5_VABI __asan_load1(std::uintptr_t address); +void APS5_VABI __asan_load16(std::uintptr_t address); +void APS5_VABI __asan_load16_noabort(std::uintptr_t address); +void APS5_VABI __asan_load1_noabort(std::uintptr_t address); +void APS5_VABI __asan_load2(std::uintptr_t address); +void APS5_VABI __asan_load2_noabort(std::uintptr_t address); +void APS5_VABI __asan_load4(std::uintptr_t address); +void APS5_VABI __asan_load4_noabort(std::uintptr_t address); +void APS5_VABI __asan_load8(std::uintptr_t address); +void APS5_VABI __asan_load8_noabort(std::uintptr_t address); +void APS5_VABI __asan_loadN(std::uintptr_t address, std::uintptr_t size); +void APS5_VABI __asan_loadN_noabort(std::uintptr_t address, std::uintptr_t size); +std::uintptr_t APS5_VABI __asan_load_cxx_array_cookie(std::uintptr_t* p); +const char* APS5_VABI __asan_locate_address(std::uintptr_t address, char* name, std::uintptr_t nameSize, std::uintptr_t* regionAddress, std::uintptr_t* regionSize); +void* APS5_VABI __asan_malloc(std::size_t size); int APS5_VABI __asan_malloc_stats(); -int APS5_VABI __asan_malloc_usable_size(); -int APS5_VABI __asan_memalign(); -int APS5_VABI __asan_memcpy(); -int APS5_VABI __asan_memmove(); -int APS5_VABI __asan_memset(); -int APS5_VABI __asan_option_detect_stack_use_after_return(); -int APS5_VABI __asan_poison_cxx_array_cookie(); -int APS5_VABI __asan_poison_intra_object_redzone(); -int APS5_VABI __asan_poison_memory_region(); -int APS5_VABI __asan_poison_stack_memory(); -int APS5_VABI __asan_posix_memalign(); -int APS5_VABI __asan_print_accumulated_stats(); -int APS5_VABI __asan_realloc(); +std::size_t APS5_VABI __asan_malloc_usable_size(const void* pointer); +void* APS5_VABI __asan_memalign(std::size_t alignment, std::size_t size); +void* APS5_VABI __asan_memcpy(void* to, const void* from, std::uintptr_t size); +void* APS5_VABI __asan_memmove(void* to, const void* from, std::uintptr_t size); +void* APS5_VABI __asan_memset(void* block, int value, std::uintptr_t size); +extern int __asan_option_detect_stack_use_after_return; +void APS5_VABI __asan_poison_cxx_array_cookie(std::uintptr_t p); +void APS5_VABI __asan_poison_intra_object_redzone(std::uintptr_t address, std::uintptr_t size); +void APS5_VABI __asan_poison_memory_region(const volatile void* addr, std::uintptr_t size); +void APS5_VABI __asan_poison_stack_memory(std::uintptr_t address, std::uintptr_t size); +int APS5_VABI __asan_posix_memalign(void** memptr, std::size_t alignment, std::size_t size); +void APS5_VABI __asan_print_accumulated_stats(); +void* APS5_VABI __asan_realloc(void* pointer, std::size_t size); int APS5_VABI __asan_reallocalign(); -int APS5_VABI __asan_region_is_poisoned(); -int APS5_VABI __asan_register_elf_globals(); -int APS5_VABI __asan_register_globals(); +std::uintptr_t APS5_VABI __asan_region_is_poisoned(std::uintptr_t address, std::uintptr_t size); +void APS5_VABI __asan_register_elf_globals(std::uintptr_t* flag, void* start, void* stop); +void APS5_VABI __asan_register_globals(void* globals, std::uintptr_t count); int APS5_VABI __asan_register_image_globals(); -int APS5_VABI __asan_report_error(); -int APS5_VABI __asan_report_exp_load1(); -int APS5_VABI __asan_report_exp_load16(); -int APS5_VABI __asan_report_exp_load16_noabort(); -int APS5_VABI __asan_report_exp_load1_noabort(); -int APS5_VABI __asan_report_exp_load2(); -int APS5_VABI __asan_report_exp_load2_noabort(); -int APS5_VABI __asan_report_exp_load4(); -int APS5_VABI __asan_report_exp_load4_noabort(); -int APS5_VABI __asan_report_exp_load8(); -int APS5_VABI __asan_report_exp_load8_noabort(); -int APS5_VABI __asan_report_exp_load_n(); -int APS5_VABI __asan_report_exp_load_n_noabort(); -int APS5_VABI __asan_report_exp_store1(); -int APS5_VABI __asan_report_exp_store16(); -int APS5_VABI __asan_report_exp_store16_noabort(); -int APS5_VABI __asan_report_exp_store1_noabort(); -int APS5_VABI __asan_report_exp_store2(); -int APS5_VABI __asan_report_exp_store2_noabort(); -int APS5_VABI __asan_report_exp_store4(); -int APS5_VABI __asan_report_exp_store4_noabort(); -int APS5_VABI __asan_report_exp_store8(); -int APS5_VABI __asan_report_exp_store8_noabort(); -int APS5_VABI __asan_report_exp_store_n(); -int APS5_VABI __asan_report_exp_store_n_noabort(); -int APS5_VABI __asan_report_load1(); -int APS5_VABI __asan_report_load16(); -int APS5_VABI __asan_report_load16_noabort(); -int APS5_VABI __asan_report_load1_noabort(); -int APS5_VABI __asan_report_load2(); -int APS5_VABI __asan_report_load2_noabort(); -int APS5_VABI __asan_report_load4(); -int APS5_VABI __asan_report_load4_noabort(); -int APS5_VABI __asan_report_load8(); -int APS5_VABI __asan_report_load8_noabort(); -int APS5_VABI __asan_report_load_n(); -int APS5_VABI __asan_report_load_n_noabort(); +void APS5_VABI __asan_report_error(void* pc, void* bp, void* sp, void* address, int isWrite, std::size_t accessSize, std::uint32_t exp); +void APS5_VABI __asan_report_exp_load1(std::uintptr_t address, std::uint32_t exp); +void APS5_VABI __asan_report_exp_load16(std::uintptr_t address, std::uint32_t exp); +void APS5_VABI __asan_report_exp_load16_noabort(std::uintptr_t address, std::uint32_t exp); +void APS5_VABI __asan_report_exp_load1_noabort(std::uintptr_t address, std::uint32_t exp); +void APS5_VABI __asan_report_exp_load2(std::uintptr_t address, std::uint32_t exp); +void APS5_VABI __asan_report_exp_load2_noabort(std::uintptr_t address, std::uint32_t exp); +void APS5_VABI __asan_report_exp_load4(std::uintptr_t address, std::uint32_t exp); +void APS5_VABI __asan_report_exp_load4_noabort(std::uintptr_t address, std::uint32_t exp); +void APS5_VABI __asan_report_exp_load8(std::uintptr_t address, std::uint32_t exp); +void APS5_VABI __asan_report_exp_load8_noabort(std::uintptr_t address, std::uint32_t exp); +void APS5_VABI __asan_report_exp_load_n(std::uintptr_t address, std::uintptr_t size, std::uint32_t exp); +void APS5_VABI __asan_report_exp_load_n_noabort(std::uintptr_t address, std::uintptr_t size, std::uint32_t exp); +void APS5_VABI __asan_report_exp_store1(std::uintptr_t address, std::uint32_t exp); +void APS5_VABI __asan_report_exp_store16(std::uintptr_t address, std::uint32_t exp); +void APS5_VABI __asan_report_exp_store16_noabort(std::uintptr_t address, std::uint32_t exp); +void APS5_VABI __asan_report_exp_store1_noabort(std::uintptr_t address, std::uint32_t exp); +void APS5_VABI __asan_report_exp_store2(std::uintptr_t address, std::uint32_t exp); +void APS5_VABI __asan_report_exp_store2_noabort(std::uintptr_t address, std::uint32_t exp); +void APS5_VABI __asan_report_exp_store4(std::uintptr_t address, std::uint32_t exp); +void APS5_VABI __asan_report_exp_store4_noabort(std::uintptr_t address, std::uint32_t exp); +void APS5_VABI __asan_report_exp_store8(std::uintptr_t address, std::uint32_t exp); +void APS5_VABI __asan_report_exp_store8_noabort(std::uintptr_t address, std::uint32_t exp); +void APS5_VABI __asan_report_exp_store_n(std::uintptr_t address, std::uintptr_t size, std::uint32_t exp); +void APS5_VABI __asan_report_exp_store_n_noabort(std::uintptr_t address, std::uintptr_t size, std::uint32_t exp); +void APS5_VABI __asan_report_load1(std::uintptr_t address); +void APS5_VABI __asan_report_load16(std::uintptr_t address); +void APS5_VABI __asan_report_load16_noabort(std::uintptr_t address); +void APS5_VABI __asan_report_load1_noabort(std::uintptr_t address); +void APS5_VABI __asan_report_load2(std::uintptr_t address); +void APS5_VABI __asan_report_load2_noabort(std::uintptr_t address); +void APS5_VABI __asan_report_load4(std::uintptr_t address); +void APS5_VABI __asan_report_load4_noabort(std::uintptr_t address); +void APS5_VABI __asan_report_load8(std::uintptr_t address); +void APS5_VABI __asan_report_load8_noabort(std::uintptr_t address); +void APS5_VABI __asan_report_load_n(std::uintptr_t address, std::uintptr_t size); +void APS5_VABI __asan_report_load_n_noabort(std::uintptr_t address, std::uintptr_t size); int APS5_VABI __asan_report_present(); -int APS5_VABI __asan_report_store1(); -int APS5_VABI __asan_report_store16(); -int APS5_VABI __asan_report_store16_noabort(); -int APS5_VABI __asan_report_store1_noabort(); -int APS5_VABI __asan_report_store2(); -int APS5_VABI __asan_report_store2_noabort(); -int APS5_VABI __asan_report_store4(); -int APS5_VABI __asan_report_store4_noabort(); -int APS5_VABI __asan_report_store8(); -int APS5_VABI __asan_report_store8_noabort(); -int APS5_VABI __asan_report_store_n(); -int APS5_VABI __asan_report_store_n_noabort(); -int APS5_VABI __asan_set_error_report_callback(); -int APS5_VABI __asan_set_shadow_00(); -int APS5_VABI __asan_set_shadow_01(); -int APS5_VABI __asan_set_shadow_02(); -int APS5_VABI __asan_set_shadow_03(); -int APS5_VABI __asan_set_shadow_04(); -int APS5_VABI __asan_set_shadow_05(); -int APS5_VABI __asan_set_shadow_06(); -int APS5_VABI __asan_set_shadow_07(); -int APS5_VABI __asan_set_shadow_f1(); -int APS5_VABI __asan_set_shadow_f2(); -int APS5_VABI __asan_set_shadow_f3(); -int APS5_VABI __asan_set_shadow_f5(); -int APS5_VABI __asan_set_shadow_f8(); -int APS5_VABI __asan_stack_free_0(); -int APS5_VABI __asan_stack_free_1(); -int APS5_VABI __asan_stack_free_10(); -int APS5_VABI __asan_stack_free_2(); -int APS5_VABI __asan_stack_free_3(); -int APS5_VABI __asan_stack_free_4(); -int APS5_VABI __asan_stack_free_5(); -int APS5_VABI __asan_stack_free_6(); -int APS5_VABI __asan_stack_free_7(); -int APS5_VABI __asan_stack_free_8(); -int APS5_VABI __asan_stack_free_9(); -int APS5_VABI __asan_stack_malloc_0(); -int APS5_VABI __asan_stack_malloc_1(); -int APS5_VABI __asan_stack_malloc_10(); -int APS5_VABI __asan_stack_malloc_2(); -int APS5_VABI __asan_stack_malloc_3(); -int APS5_VABI __asan_stack_malloc_4(); -int APS5_VABI __asan_stack_malloc_5(); -int APS5_VABI __asan_stack_malloc_6(); -int APS5_VABI __asan_stack_malloc_7(); -int APS5_VABI __asan_stack_malloc_8(); -int APS5_VABI __asan_stack_malloc_9(); -int APS5_VABI __asan_stack_malloc_always_0(); -int APS5_VABI __asan_stack_malloc_always_1(); -int APS5_VABI __asan_stack_malloc_always_10(); -int APS5_VABI __asan_stack_malloc_always_2(); -int APS5_VABI __asan_stack_malloc_always_3(); -int APS5_VABI __asan_stack_malloc_always_4(); -int APS5_VABI __asan_stack_malloc_always_5(); -int APS5_VABI __asan_stack_malloc_always_6(); -int APS5_VABI __asan_stack_malloc_always_7(); -int APS5_VABI __asan_stack_malloc_always_8(); -int APS5_VABI __asan_stack_malloc_always_9(); -int APS5_VABI __asan_store1(); -int APS5_VABI __asan_store16(); -int APS5_VABI __asan_store16_noabort(); -int APS5_VABI __asan_store1_noabort(); -int APS5_VABI __asan_store2(); -int APS5_VABI __asan_store2_noabort(); -int APS5_VABI __asan_store4(); -int APS5_VABI __asan_store4_noabort(); -int APS5_VABI __asan_store8(); -int APS5_VABI __asan_store8_noabort(); -int APS5_VABI __asan_storeN(); -int APS5_VABI __asan_storeN_noabort(); -int APS5_VABI __asan_unpoison_intra_object_redzone(); -int APS5_VABI __asan_unpoison_memory_region(); -int APS5_VABI __asan_unpoison_stack_memory(); -int APS5_VABI __asan_unregister_elf_globals(); -int APS5_VABI __asan_unregister_globals(); +void APS5_VABI __asan_report_store1(std::uintptr_t address); +void APS5_VABI __asan_report_store16(std::uintptr_t address); +void APS5_VABI __asan_report_store16_noabort(std::uintptr_t address); +void APS5_VABI __asan_report_store1_noabort(std::uintptr_t address); +void APS5_VABI __asan_report_store2(std::uintptr_t address); +void APS5_VABI __asan_report_store2_noabort(std::uintptr_t address); +void APS5_VABI __asan_report_store4(std::uintptr_t address); +void APS5_VABI __asan_report_store4_noabort(std::uintptr_t address); +void APS5_VABI __asan_report_store8(std::uintptr_t address); +void APS5_VABI __asan_report_store8_noabort(std::uintptr_t address); +void APS5_VABI __asan_report_store_n(std::uintptr_t address, std::uintptr_t size); +void APS5_VABI __asan_report_store_n_noabort(std::uintptr_t address, std::uintptr_t size); +void APS5_VABI __asan_set_error_report_callback(void (APS5_VABI* callback)(const char*)); +void APS5_VABI __asan_set_shadow_00(std::uintptr_t address, std::uintptr_t size); +void APS5_VABI __asan_set_shadow_01(std::uintptr_t address, std::uintptr_t size); +void APS5_VABI __asan_set_shadow_02(std::uintptr_t address, std::uintptr_t size); +void APS5_VABI __asan_set_shadow_03(std::uintptr_t address, std::uintptr_t size); +void APS5_VABI __asan_set_shadow_04(std::uintptr_t address, std::uintptr_t size); +void APS5_VABI __asan_set_shadow_05(std::uintptr_t address, std::uintptr_t size); +void APS5_VABI __asan_set_shadow_06(std::uintptr_t address, std::uintptr_t size); +void APS5_VABI __asan_set_shadow_07(std::uintptr_t address, std::uintptr_t size); +void APS5_VABI __asan_set_shadow_f1(std::uintptr_t address, std::uintptr_t size); +void APS5_VABI __asan_set_shadow_f2(std::uintptr_t address, std::uintptr_t size); +void APS5_VABI __asan_set_shadow_f3(std::uintptr_t address, std::uintptr_t size); +void APS5_VABI __asan_set_shadow_f5(std::uintptr_t address, std::uintptr_t size); +void APS5_VABI __asan_set_shadow_f8(std::uintptr_t address, std::uintptr_t size); +void APS5_VABI __asan_stack_free_0(std::uintptr_t pointer, std::uintptr_t size); +void APS5_VABI __asan_stack_free_1(std::uintptr_t pointer, std::uintptr_t size); +void APS5_VABI __asan_stack_free_10(std::uintptr_t pointer, std::uintptr_t size); +void APS5_VABI __asan_stack_free_2(std::uintptr_t pointer, std::uintptr_t size); +void APS5_VABI __asan_stack_free_3(std::uintptr_t pointer, std::uintptr_t size); +void APS5_VABI __asan_stack_free_4(std::uintptr_t pointer, std::uintptr_t size); +void APS5_VABI __asan_stack_free_5(std::uintptr_t pointer, std::uintptr_t size); +void APS5_VABI __asan_stack_free_6(std::uintptr_t pointer, std::uintptr_t size); +void APS5_VABI __asan_stack_free_7(std::uintptr_t pointer, std::uintptr_t size); +void APS5_VABI __asan_stack_free_8(std::uintptr_t pointer, std::uintptr_t size); +void APS5_VABI __asan_stack_free_9(std::uintptr_t pointer, std::uintptr_t size); +std::uintptr_t APS5_VABI __asan_stack_malloc_0(std::uintptr_t size); +std::uintptr_t APS5_VABI __asan_stack_malloc_1(std::uintptr_t size); +std::uintptr_t APS5_VABI __asan_stack_malloc_10(std::uintptr_t size); +std::uintptr_t APS5_VABI __asan_stack_malloc_2(std::uintptr_t size); +std::uintptr_t APS5_VABI __asan_stack_malloc_3(std::uintptr_t size); +std::uintptr_t APS5_VABI __asan_stack_malloc_4(std::uintptr_t size); +std::uintptr_t APS5_VABI __asan_stack_malloc_5(std::uintptr_t size); +std::uintptr_t APS5_VABI __asan_stack_malloc_6(std::uintptr_t size); +std::uintptr_t APS5_VABI __asan_stack_malloc_7(std::uintptr_t size); +std::uintptr_t APS5_VABI __asan_stack_malloc_8(std::uintptr_t size); +std::uintptr_t APS5_VABI __asan_stack_malloc_9(std::uintptr_t size); +std::uintptr_t APS5_VABI __asan_stack_malloc_always_0(std::uintptr_t size); +std::uintptr_t APS5_VABI __asan_stack_malloc_always_1(std::uintptr_t size); +std::uintptr_t APS5_VABI __asan_stack_malloc_always_10(std::uintptr_t size); +std::uintptr_t APS5_VABI __asan_stack_malloc_always_2(std::uintptr_t size); +std::uintptr_t APS5_VABI __asan_stack_malloc_always_3(std::uintptr_t size); +std::uintptr_t APS5_VABI __asan_stack_malloc_always_4(std::uintptr_t size); +std::uintptr_t APS5_VABI __asan_stack_malloc_always_5(std::uintptr_t size); +std::uintptr_t APS5_VABI __asan_stack_malloc_always_6(std::uintptr_t size); +std::uintptr_t APS5_VABI __asan_stack_malloc_always_7(std::uintptr_t size); +std::uintptr_t APS5_VABI __asan_stack_malloc_always_8(std::uintptr_t size); +std::uintptr_t APS5_VABI __asan_stack_malloc_always_9(std::uintptr_t size); +void APS5_VABI __asan_store1(std::uintptr_t address); +void APS5_VABI __asan_store16(std::uintptr_t address); +void APS5_VABI __asan_store16_noabort(std::uintptr_t address); +void APS5_VABI __asan_store1_noabort(std::uintptr_t address); +void APS5_VABI __asan_store2(std::uintptr_t address); +void APS5_VABI __asan_store2_noabort(std::uintptr_t address); +void APS5_VABI __asan_store4(std::uintptr_t address); +void APS5_VABI __asan_store4_noabort(std::uintptr_t address); +void APS5_VABI __asan_store8(std::uintptr_t address); +void APS5_VABI __asan_store8_noabort(std::uintptr_t address); +void APS5_VABI __asan_storeN(std::uintptr_t address, std::uintptr_t size); +void APS5_VABI __asan_storeN_noabort(std::uintptr_t address, std::uintptr_t size); +void APS5_VABI __asan_unpoison_intra_object_redzone(std::uintptr_t address, std::uintptr_t size); +void APS5_VABI __asan_unpoison_memory_region(const volatile void* addr, std::uintptr_t size); +void APS5_VABI __asan_unpoison_stack_memory(std::uintptr_t address, std::uintptr_t size); +void APS5_VABI __asan_unregister_elf_globals(std::uintptr_t* flag, void* start, void* stop); +void APS5_VABI __asan_unregister_globals(void* globals, std::uintptr_t count); int APS5_VABI __asan_unregister_image_globals(); -int APS5_VABI __asan_update_allocation_context(); -int APS5_VABI __asan_version_mismatch_check_v6(); -int APS5_VABI __asan_version_mismatch_check_v7(); -int APS5_VABI __asan_version_mismatch_check_v8(); -int APS5_VABI __sancov_default_options(); -int APS5_VABI __sanitizer_annotate_contiguous_container(); -int APS5_VABI __sanitizer_annotate_double_ended_contiguous_container(); -int APS5_VABI __sanitizer_contiguous_container_find_bad_address(); -int APS5_VABI __sanitizer_cov_dump(); -int APS5_VABI __sanitizer_cov_trace_pc_guard(); -int APS5_VABI __sanitizer_cov_trace_pc_guard_init(); -int APS5_VABI __sanitizer_double_ended_contiguous_container_find_bad_address(); -int APS5_VABI __sanitizer_dump_coverage(); -int APS5_VABI __sanitizer_dump_trace_pc_guard_coverage(); -int APS5_VABI __sanitizer_finish_switch_fiber(); -int APS5_VABI __sanitizer_free_hook(); -int APS5_VABI __sanitizer_get_allocated_begin(); -int APS5_VABI __sanitizer_get_allocated_size(); -int APS5_VABI __sanitizer_get_allocated_size_fast(); -int APS5_VABI __sanitizer_get_current_allocated_bytes(); -int APS5_VABI __sanitizer_get_estimated_allocated_size(); -int APS5_VABI __sanitizer_get_free_bytes(); -int APS5_VABI __sanitizer_get_heap_size(); -int APS5_VABI __sanitizer_get_ownership(); -int APS5_VABI __sanitizer_get_report_path(); -int APS5_VABI __sanitizer_get_unmapped_bytes(); -int APS5_VABI __sanitizer_malloc_hook(); -int APS5_VABI __sanitizer_print_stack_trace(); -int APS5_VABI __sanitizer_ptr_cmp(); -int APS5_VABI __sanitizer_ptr_sub(); -int APS5_VABI __sanitizer_purge_allocator(); -int APS5_VABI __sanitizer_sandbox_on_notify(); -int APS5_VABI __sanitizer_set_death_callback(); -int APS5_VABI __sanitizer_set_report_fd(); -int APS5_VABI __sanitizer_set_report_path(); -int APS5_VABI __sanitizer_start_switch_fiber(); -int APS5_VABI __sanitizer_symbolize_global(); -int APS5_VABI __sanitizer_symbolize_pc(); -int APS5_VABI __sanitizer_unaligned_load16(); -int APS5_VABI __sanitizer_unaligned_load32(); -int APS5_VABI __sanitizer_unaligned_load64(); -int APS5_VABI __sanitizer_unaligned_store16(); -int APS5_VABI __sanitizer_unaligned_store32(); -int APS5_VABI __sanitizer_unaligned_store64(); -int APS5_VABI __sanitizer_verify_contiguous_container(); -int APS5_VABI __sanitizer_verify_double_ended_contiguous_container(); +int APS5_VABI __asan_update_allocation_context(void* address); +void APS5_VABI __asan_version_mismatch_check_v6(); +void APS5_VABI __asan_version_mismatch_check_v7(); +void APS5_VABI __asan_version_mismatch_check_v8(); +const char* APS5_VABI __sancov_default_options(); +void APS5_VABI __sanitizer_annotate_contiguous_container(const void* beg, const void* end, const void* oldMid, const void* newMid); +void APS5_VABI __sanitizer_annotate_double_ended_contiguous_container(const void* storageBeg, const void* storageEnd, const void* oldContainerBeg, const void* oldContainerEnd, const void* newContainerBeg, const void* newContainerEnd); +const void* APS5_VABI __sanitizer_contiguous_container_find_bad_address(const void* beg, const void* mid, const void* end); +void APS5_VABI __sanitizer_cov_dump(); +void APS5_VABI __sanitizer_cov_trace_pc_guard(std::uint32_t* guard); +void APS5_VABI __sanitizer_cov_trace_pc_guard_init(std::uint32_t* start, std::uint32_t* end); +const void* APS5_VABI __sanitizer_double_ended_contiguous_container_find_bad_address(const void* storageBeg, const void* containerBeg, const void* containerEnd, const void* storageEnd); +void APS5_VABI __sanitizer_dump_coverage(const std::uintptr_t* pcs, std::uintptr_t length); +void APS5_VABI __sanitizer_dump_trace_pc_guard_coverage(); +void APS5_VABI __sanitizer_finish_switch_fiber(void* fakeStack, const void** bottomOld, std::uintptr_t* sizeOld); +void APS5_VABI __sanitizer_free_hook(void* pointer); +const void* APS5_VABI __sanitizer_get_allocated_begin(const void* pointer); +std::size_t APS5_VABI __sanitizer_get_allocated_size(const void* pointer); +std::size_t APS5_VABI __sanitizer_get_allocated_size_fast(const void* pointer); +std::size_t APS5_VABI __sanitizer_get_current_allocated_bytes(); +std::size_t APS5_VABI __sanitizer_get_estimated_allocated_size(std::size_t size); +std::size_t APS5_VABI __sanitizer_get_free_bytes(); +std::size_t APS5_VABI __sanitizer_get_heap_size(); +int APS5_VABI __sanitizer_get_ownership(const void* pointer); +const char* APS5_VABI __sanitizer_get_report_path(); +std::size_t APS5_VABI __sanitizer_get_unmapped_bytes(); +void APS5_VABI __sanitizer_malloc_hook(void* pointer, std::size_t size); +void APS5_VABI __sanitizer_print_stack_trace(); +void APS5_VABI __sanitizer_ptr_cmp(void* first, void* second); +void APS5_VABI __sanitizer_ptr_sub(void* first, void* second); +void APS5_VABI __sanitizer_purge_allocator(); +void APS5_VABI __sanitizer_sandbox_on_notify(void* arguments); +void APS5_VABI __sanitizer_set_death_callback(void (APS5_VABI* callback)()); +void APS5_VABI __sanitizer_set_report_fd(void* descriptor); +void APS5_VABI __sanitizer_set_report_path(const char* path); +void APS5_VABI __sanitizer_start_switch_fiber(void** fakeStackSave, const void* bottom, std::uintptr_t size); +void APS5_VABI __sanitizer_symbolize_global(std::uintptr_t address, const char* format, char* output, std::uintptr_t outputSize); +void APS5_VABI __sanitizer_symbolize_pc(std::uintptr_t pc, const char* format, char* output, std::uintptr_t outputSize); +std::uint16_t APS5_VABI __sanitizer_unaligned_load16(const void* ptr); +std::uint32_t APS5_VABI __sanitizer_unaligned_load32(const void* ptr); +std::uint64_t APS5_VABI __sanitizer_unaligned_load64(const void* ptr); +void APS5_VABI __sanitizer_unaligned_store16(void* ptr, std::uint16_t value); +void APS5_VABI __sanitizer_unaligned_store32(void* ptr, std::uint32_t value); +void APS5_VABI __sanitizer_unaligned_store64(void* ptr, std::uint64_t value); +int APS5_VABI __sanitizer_verify_contiguous_container(const void* beg, const void* mid, const void* end); +int APS5_VABI __sanitizer_verify_double_ended_contiguous_container(const void* storageBeg, const void* containerBeg, const void* containerEnd, const void* storageEnd); int APS5_VABI __ubsan_current_error_report(); int APS5_VABI __ubsan_current_error_report_size(); -int APS5_VABI __ubsan_default_options(); -int APS5_VABI __ubsan_get_current_report_data(); -int APS5_VABI __ubsan_handle_add_overflow(); -int APS5_VABI __ubsan_handle_add_overflow_abort(); -int APS5_VABI __ubsan_handle_alignment_assumption(); -int APS5_VABI __ubsan_handle_alignment_assumption_abort(); -int APS5_VABI __ubsan_handle_builtin_unreachable(); -int APS5_VABI __ubsan_handle_divrem_overflow(); -int APS5_VABI __ubsan_handle_divrem_overflow_abort(); +const char* APS5_VABI __ubsan_default_options(); +void APS5_VABI __ubsan_get_current_report_data(const char** issueKind, const char** message, const char** filename, unsigned* line, unsigned* column, char** memoryAddress); +void APS5_VABI __ubsan_handle_add_overflow(void* data, std::uintptr_t lhs, std::uintptr_t rhs); +void APS5_VABI __ubsan_handle_add_overflow_abort(void* data, std::uintptr_t lhs, std::uintptr_t rhs); +void APS5_VABI __ubsan_handle_alignment_assumption(void* data, std::uintptr_t pointer, std::uintptr_t alignment, std::uintptr_t offset); +void APS5_VABI __ubsan_handle_alignment_assumption_abort(void* data, std::uintptr_t pointer, std::uintptr_t alignment, std::uintptr_t offset); +void APS5_VABI __ubsan_handle_builtin_unreachable(void* data); +void APS5_VABI __ubsan_handle_divrem_overflow(void* data, std::uintptr_t lhs, std::uintptr_t rhs); +void APS5_VABI __ubsan_handle_divrem_overflow_abort(void* data, std::uintptr_t lhs, std::uintptr_t rhs); int APS5_VABI __ubsan_handle_dynamic_type_cache_miss(); int APS5_VABI __ubsan_handle_dynamic_type_cache_miss_abort(); -int APS5_VABI __ubsan_handle_float_cast_overflow(); -int APS5_VABI __ubsan_handle_float_cast_overflow_abort(); -int APS5_VABI __ubsan_handle_function_type_mismatch(); -int APS5_VABI __ubsan_handle_function_type_mismatch_abort(); +void APS5_VABI __ubsan_handle_float_cast_overflow(void* data, std::uintptr_t from); +void APS5_VABI __ubsan_handle_float_cast_overflow_abort(void* data, std::uintptr_t from); +void APS5_VABI __ubsan_handle_function_type_mismatch(void* data, std::uintptr_t function); +void APS5_VABI __ubsan_handle_function_type_mismatch_abort(void* data, std::uintptr_t function); int APS5_VABI __ubsan_handle_function_type_mismatch_v1(); int APS5_VABI __ubsan_handle_function_type_mismatch_v1_abort(); -int APS5_VABI __ubsan_handle_implicit_conversion(); -int APS5_VABI __ubsan_handle_implicit_conversion_abort(); -int APS5_VABI __ubsan_handle_invalid_builtin(); -int APS5_VABI __ubsan_handle_invalid_builtin_abort(); -int APS5_VABI __ubsan_handle_load_invalid_value(); -int APS5_VABI __ubsan_handle_load_invalid_value_abort(); -int APS5_VABI __ubsan_handle_missing_return(); -int APS5_VABI __ubsan_handle_mul_overflow(); -int APS5_VABI __ubsan_handle_mul_overflow_abort(); -int APS5_VABI __ubsan_handle_negate_overflow(); -int APS5_VABI __ubsan_handle_negate_overflow_abort(); -int APS5_VABI __ubsan_handle_nonnull_arg(); -int APS5_VABI __ubsan_handle_nonnull_arg_abort(); -int APS5_VABI __ubsan_handle_nonnull_return(); -int APS5_VABI __ubsan_handle_nonnull_return_abort(); -int APS5_VABI __ubsan_handle_nonnull_return_v1(); -int APS5_VABI __ubsan_handle_nonnull_return_v1_abort(); -int APS5_VABI __ubsan_handle_nullability_arg(); -int APS5_VABI __ubsan_handle_nullability_arg_abort(); -int APS5_VABI __ubsan_handle_nullability_return_v1(); -int APS5_VABI __ubsan_handle_nullability_return_v1_abort(); -int APS5_VABI __ubsan_handle_out_of_bounds(); -int APS5_VABI __ubsan_handle_out_of_bounds_abort(); -int APS5_VABI __ubsan_handle_pointer_overflow(); -int APS5_VABI __ubsan_handle_pointer_overflow_abort(); -int APS5_VABI __ubsan_handle_shift_out_of_bounds(); -int APS5_VABI __ubsan_handle_shift_out_of_bounds_abort(); -int APS5_VABI __ubsan_handle_sub_overflow(); -int APS5_VABI __ubsan_handle_sub_overflow_abort(); -int APS5_VABI __ubsan_handle_type_mismatch(); -int APS5_VABI __ubsan_handle_type_mismatch_abort(); -int APS5_VABI __ubsan_handle_type_mismatch_v1(); -int APS5_VABI __ubsan_handle_type_mismatch_v1_abort(); -int APS5_VABI __ubsan_handle_vla_bound_not_positive(); -int APS5_VABI __ubsan_handle_vla_bound_not_positive_abort(); -int APS5_VABI __ubsan_vptr_type_cache(); +void APS5_VABI __ubsan_handle_implicit_conversion(void* data, std::uintptr_t source, std::uintptr_t destination); +void APS5_VABI __ubsan_handle_implicit_conversion_abort(void* data, std::uintptr_t source, std::uintptr_t destination); +void APS5_VABI __ubsan_handle_invalid_builtin(void* data); +void APS5_VABI __ubsan_handle_invalid_builtin_abort(void* data); +void APS5_VABI __ubsan_handle_load_invalid_value(void* data, std::uintptr_t value); +void APS5_VABI __ubsan_handle_load_invalid_value_abort(void* data, std::uintptr_t value); +void APS5_VABI __ubsan_handle_missing_return(void* data); +void APS5_VABI __ubsan_handle_mul_overflow(void* data, std::uintptr_t lhs, std::uintptr_t rhs); +void APS5_VABI __ubsan_handle_mul_overflow_abort(void* data, std::uintptr_t lhs, std::uintptr_t rhs); +void APS5_VABI __ubsan_handle_negate_overflow(void* data, std::uintptr_t oldValue); +void APS5_VABI __ubsan_handle_negate_overflow_abort(void* data, std::uintptr_t oldValue); +void APS5_VABI __ubsan_handle_nonnull_arg(void* data); +void APS5_VABI __ubsan_handle_nonnull_arg_abort(void* data); +void APS5_VABI __ubsan_handle_nonnull_return(void* data); +void APS5_VABI __ubsan_handle_nonnull_return_abort(void* data); +void APS5_VABI __ubsan_handle_nonnull_return_v1(void* data, void* location); +void APS5_VABI __ubsan_handle_nonnull_return_v1_abort(void* data, void* location); +void APS5_VABI __ubsan_handle_nullability_arg(void* data); +void APS5_VABI __ubsan_handle_nullability_arg_abort(void* data); +void APS5_VABI __ubsan_handle_nullability_return_v1(void* data, void* location); +void APS5_VABI __ubsan_handle_nullability_return_v1_abort(void* data, void* location); +void APS5_VABI __ubsan_handle_out_of_bounds(void* data, std::uintptr_t index); +void APS5_VABI __ubsan_handle_out_of_bounds_abort(void* data, std::uintptr_t index); +void APS5_VABI __ubsan_handle_pointer_overflow(void* data, std::uintptr_t base, std::uintptr_t result); +void APS5_VABI __ubsan_handle_pointer_overflow_abort(void* data, std::uintptr_t base, std::uintptr_t result); +void APS5_VABI __ubsan_handle_shift_out_of_bounds(void* data, std::uintptr_t lhs, std::uintptr_t rhs); +void APS5_VABI __ubsan_handle_shift_out_of_bounds_abort(void* data, std::uintptr_t lhs, std::uintptr_t rhs); +void APS5_VABI __ubsan_handle_sub_overflow(void* data, std::uintptr_t lhs, std::uintptr_t rhs); +void APS5_VABI __ubsan_handle_sub_overflow_abort(void* data, std::uintptr_t lhs, std::uintptr_t rhs); +void APS5_VABI __ubsan_handle_type_mismatch(void* data, std::uintptr_t pointer); +void APS5_VABI __ubsan_handle_type_mismatch_abort(void* data, std::uintptr_t pointer); +void APS5_VABI __ubsan_handle_type_mismatch_v1(void* data, std::uintptr_t pointer); +void APS5_VABI __ubsan_handle_type_mismatch_v1_abort(void* data, std::uintptr_t pointer); +void APS5_VABI __ubsan_handle_vla_bound_not_positive(void* data, std::uintptr_t bound); +void APS5_VABI __ubsan_handle_vla_bound_not_positive_abort(void* data, std::uintptr_t bound); +extern std::uintptr_t __ubsan_vptr_type_cache[128]; } diff --git a/core/libs/prx/libSceAddressSanitizer/src/Allocator.hpp b/core/libs/prx/libSceAddressSanitizer/src/Allocator.hpp new file mode 100644 index 000000000000..70d82bc46d63 --- /dev/null +++ b/core/libs/prx/libSceAddressSanitizer/src/Allocator.hpp @@ -0,0 +1,3 @@ +#pragma once + +#include "asan_anyps5/src/Allocator.hpp" diff --git a/core/libs/prx/libSceAddressSanitizer/src/BackingMemory.hpp b/core/libs/prx/libSceAddressSanitizer/src/BackingMemory.hpp new file mode 100644 index 000000000000..136d28dc5551 --- /dev/null +++ b/core/libs/prx/libSceAddressSanitizer/src/BackingMemory.hpp @@ -0,0 +1,3 @@ +#pragma once + +#include "asan_anyps5/src/BackingMemory.hpp" diff --git a/core/libs/prx/libSceAddressSanitizer/src/Container.hpp b/core/libs/prx/libSceAddressSanitizer/src/Container.hpp new file mode 100644 index 000000000000..8402d4278928 --- /dev/null +++ b/core/libs/prx/libSceAddressSanitizer/src/Container.hpp @@ -0,0 +1,3 @@ +#pragma once + +#include "asan_anyps5/src/Container.hpp" diff --git a/core/libs/prx/libSceAddressSanitizer/src/Coverage.hpp b/core/libs/prx/libSceAddressSanitizer/src/Coverage.hpp new file mode 100644 index 000000000000..34b22ec44557 --- /dev/null +++ b/core/libs/prx/libSceAddressSanitizer/src/Coverage.hpp @@ -0,0 +1,3 @@ +#pragma once + +#include "asan_anyps5/src/Coverage.hpp" diff --git a/core/libs/prx/libSceAddressSanitizer/src/Describe.hpp b/core/libs/prx/libSceAddressSanitizer/src/Describe.hpp new file mode 100644 index 000000000000..8def5f6c8818 --- /dev/null +++ b/core/libs/prx/libSceAddressSanitizer/src/Describe.hpp @@ -0,0 +1,3 @@ +#pragma once + +#include "asan_anyps5/src/Describe.hpp" diff --git a/core/libs/prx/libSceAddressSanitizer/src/ErrorReport.hpp b/core/libs/prx/libSceAddressSanitizer/src/ErrorReport.hpp new file mode 100644 index 000000000000..6a0d64b4f5ff --- /dev/null +++ b/core/libs/prx/libSceAddressSanitizer/src/ErrorReport.hpp @@ -0,0 +1,3 @@ +#pragma once + +#include "asan_anyps5/src/ErrorReport.hpp" diff --git a/core/libs/prx/libSceAddressSanitizer/src/FakeStack.hpp b/core/libs/prx/libSceAddressSanitizer/src/FakeStack.hpp new file mode 100644 index 000000000000..928b7fbcdc8b --- /dev/null +++ b/core/libs/prx/libSceAddressSanitizer/src/FakeStack.hpp @@ -0,0 +1,3 @@ +#pragma once + +#include "asan_anyps5/src/FakeStack.hpp" diff --git a/core/libs/prx/libSceAddressSanitizer/src/Globals.hpp b/core/libs/prx/libSceAddressSanitizer/src/Globals.hpp new file mode 100644 index 000000000000..edd42e3bb343 --- /dev/null +++ b/core/libs/prx/libSceAddressSanitizer/src/Globals.hpp @@ -0,0 +1,3 @@ +#pragma once + +#include "asan_anyps5/src/Globals.hpp" diff --git a/core/libs/prx/libSceAddressSanitizer/src/ModuleLookup.hpp b/core/libs/prx/libSceAddressSanitizer/src/ModuleLookup.hpp new file mode 100644 index 000000000000..f7b390a44ee3 --- /dev/null +++ b/core/libs/prx/libSceAddressSanitizer/src/ModuleLookup.hpp @@ -0,0 +1,3 @@ +#pragma once + +#include "asan_anyps5/src/ModuleLookup.hpp" diff --git a/core/libs/prx/libSceAddressSanitizer/src/Report.hpp b/core/libs/prx/libSceAddressSanitizer/src/Report.hpp new file mode 100644 index 000000000000..a140dc06764f --- /dev/null +++ b/core/libs/prx/libSceAddressSanitizer/src/Report.hpp @@ -0,0 +1,3 @@ +#pragma once + +#include "asan_anyps5/src/Report.hpp" diff --git a/core/libs/prx/libSceAddressSanitizer/src/ReportFile.hpp b/core/libs/prx/libSceAddressSanitizer/src/ReportFile.hpp new file mode 100644 index 000000000000..87d54cea41ae --- /dev/null +++ b/core/libs/prx/libSceAddressSanitizer/src/ReportFile.hpp @@ -0,0 +1,3 @@ +#pragma once + +#include "asan_anyps5/src/ReportFile.hpp" diff --git a/core/libs/prx/libSceAddressSanitizer/src/ShadowAddressSpace.hpp b/core/libs/prx/libSceAddressSanitizer/src/ShadowAddressSpace.hpp new file mode 100644 index 000000000000..bcae4fa2981a --- /dev/null +++ b/core/libs/prx/libSceAddressSanitizer/src/ShadowAddressSpace.hpp @@ -0,0 +1,3 @@ +#pragma once + +#include "asan_anyps5/src/ShadowAddressSpace.hpp" diff --git a/core/libs/prx/libSceAddressSanitizer/src/ShadowCheck.hpp b/core/libs/prx/libSceAddressSanitizer/src/ShadowCheck.hpp new file mode 100644 index 000000000000..8e97d53e0482 --- /dev/null +++ b/core/libs/prx/libSceAddressSanitizer/src/ShadowCheck.hpp @@ -0,0 +1,3 @@ +#pragma once + +#include "asan_anyps5/src/ShadowCheck.hpp" diff --git a/core/libs/prx/libSceAddressSanitizer/src/ShadowRequire.hpp b/core/libs/prx/libSceAddressSanitizer/src/ShadowRequire.hpp new file mode 100644 index 000000000000..c1c56e2c4be4 --- /dev/null +++ b/core/libs/prx/libSceAddressSanitizer/src/ShadowRequire.hpp @@ -0,0 +1,3 @@ +#pragma once + +#include "asan_anyps5/src/ShadowRequire.hpp" diff --git a/core/libs/prx/libSceAddressSanitizer/src/StackBounds.hpp b/core/libs/prx/libSceAddressSanitizer/src/StackBounds.hpp new file mode 100644 index 000000000000..bff4d078987a --- /dev/null +++ b/core/libs/prx/libSceAddressSanitizer/src/StackBounds.hpp @@ -0,0 +1,3 @@ +#pragma once + +#include "asan_anyps5/src/StackBounds.hpp" diff --git a/core/libs/prx/libSceAddressSanitizer/src/StackTrace.hpp b/core/libs/prx/libSceAddressSanitizer/src/StackTrace.hpp new file mode 100644 index 000000000000..d2926f0c8a26 --- /dev/null +++ b/core/libs/prx/libSceAddressSanitizer/src/StackTrace.hpp @@ -0,0 +1,3 @@ +#pragma once + +#include "asan_anyps5/src/StackTrace.hpp" diff --git a/core/libs/prx/libSceAddressSanitizer/src/Ubsan.hpp b/core/libs/prx/libSceAddressSanitizer/src/Ubsan.hpp new file mode 100644 index 000000000000..55a79aee3c1d --- /dev/null +++ b/core/libs/prx/libSceAddressSanitizer/src/Ubsan.hpp @@ -0,0 +1,3 @@ +#pragma once + +#include "asan_anyps5/src/Ubsan.hpp" diff --git a/core/libs/tests/AddressSanitizerDiagnostic.cmake b/core/libs/tests/AddressSanitizerDiagnostic.cmake new file mode 100644 index 000000000000..c7beabb0e053 --- /dev/null +++ b/core/libs/tests/AddressSanitizerDiagnostic.cmake @@ -0,0 +1,8 @@ +execute_process(COMMAND "${EXECUTABLE}" ${MODE} ${ARGUMENT} OUTPUT_VARIABLE output ERROR_VARIABLE output RESULT_VARIABLE result) +if(NOT result STREQUAL STATUS) + message(FATAL_ERROR "${MODE} ${ARGUMENT}: exit status ${result}, expected ${STATUS}\n${output}") +endif() +if(NOT output MATCHES "${PATTERN}") + message(FATAL_ERROR "${MODE} ${ARGUMENT}: output does not match ${PATTERN}\n${output}") +endif() +message(STATUS "${MODE} ${ARGUMENT}: exit status ${result} and diagnostic matched") diff --git a/core/libs/tests/GuestAddressSanitizerBacking.cpp b/core/libs/tests/GuestAddressSanitizerBacking.cpp new file mode 100644 index 000000000000..701e7871b7a0 --- /dev/null +++ b/core/libs/tests/GuestAddressSanitizerBacking.cpp @@ -0,0 +1,113 @@ +#include "prx/libSceAddressSanitizer/include/Api.hpp" +#include "prx/libSceAddressSanitizer/src/BackingMemory.hpp" +#include "prx/libSceAddressSanitizer/src/ShadowRequire.hpp" +#include +#include +#include +#include +#include +#include +#include +#include + +static bool GuestRange(std::uintptr_t address, std::size_t size) { + return address < (1ull << 47) && size <= (1ull << 47) - address && + (address + size <= AsanRuntime::ShadowBase || address >= AsanRuntime::ShadowBase + AsanRuntime::ShadowSize); +} + +static bool Released(void* pointer) { + MEMORY_BASIC_INFORMATION memory{}; + return VirtualQuery(pointer, &memory, sizeof(memory)) == sizeof(memory) && memory.State == MEM_FREE; +} + +static int InvalidRanges(std::uintptr_t host) { + const std::array, 5> ranges{{ + {host, 8}, + {AsanRuntime::ShadowBase - 8, 16}, + {(1ull << 47) - 8, 16}, + {1ull << 47, 8}, + {8, std::numeric_limits::max()} + }}; + for (const auto& [address, size] : ranges) { + try { + RequireShadowRange_nid_no_patch(address, size, __func__); + std::fprintf(stderr, "accepted invalid backing range: %p size=%zu\n", reinterpret_cast(address), size); + return 1; + } catch (const std::invalid_argument&) { + } + } + return 0; +} + +int main() { + constexpr auto firstGuest = AsanRuntime::ShadowBase + AsanRuntime::ShadowSize; + constexpr auto hostAddress = AsanRuntime::ShadowBase + (firstGuest >> 3); + SYSTEM_INFO info{}; + GetSystemInfo(&info); + const auto hostBytes = static_cast(info.dwAllocationGranularity); + auto* host = static_cast(VirtualAlloc(reinterpret_cast(hostAddress), hostBytes, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE)); + if (host != reinterpret_cast(hostAddress)) return 1; + std::memset(host, 0x5a, hostBytes); + if (!AsanRuntime::InitializeShadow_nid_no_patch()) return 2; + if (AsanRuntime::ShadowRangeAvailable_nid_no_patch(hostAddress, hostAddress + hostBytes)) return 3; + const auto projected = AsanRuntime::ShadowBase + (hostAddress >> 3); + if (!AsanRuntime::ShadowRangeAvailable_nid_no_patch(projected, projected + 1)) return 4; + if (InvalidRanges(hostAddress)) return 5; + + for (const auto alignment : {std::size_t{8}, std::size_t{65536}, std::size_t{1} << 20}) { + void* block = AsanRuntime::AllocateBacking_nid_no_patch(8193, alignment); + const auto address = reinterpret_cast(block); + if (!block || !GuestRange(address, 8193) || address % alignment != 0) { + std::fprintf(stderr, "backing allocation failed: pointer=%p alignment=%zu error=%lu\n", block, alignment, GetLastError()); + return 6; + } + RequireShadowRange_nid_no_patch(address, 8193, __func__); + std::memset(block, 0x39, 8193); + AsanRuntime::FreeBacking_nid_no_patch(block, alignment); + if (!Released(block)) return 7; + } + + auto* p = static_cast(__asan_malloc(13)); + if (!p || !GuestRange(reinterpret_cast(p), 13)) return 8; + if (__asan_address_is_poisoned(p) || __asan_address_is_poisoned(p + 12) || !__asan_address_is_poisoned(p + 13) || !__asan_address_is_poisoned(p - 1)) return 9; + __asan_memset(p, 0x6b, 13); + p = static_cast(__asan_realloc(p, 257)); + if (!p || !GuestRange(reinterpret_cast(p), 257)) return 10; + for (std::size_t i = 0; i < 13; ++i) if (p[i] != 0x6b) return 11; + if (__asan_region_is_poisoned(reinterpret_cast(p), 257) || !__asan_address_is_poisoned(p + 257)) return 12; + std::uintptr_t begin = 0; + std::uintptr_t size = 0; + if (std::strcmp(__asan_locate_address(reinterpret_cast(p), nullptr, 0, &begin, &size), "heap") || begin != reinterpret_cast(p) || size != 257) return 13; + MEMORY_BASIC_INFORMATION heapMemory{}; + if (VirtualQuery(p, &heapMemory, sizeof(heapMemory)) != sizeof(heapMemory)) return 14; + __asan_free(p); + if (!__asan_address_is_poisoned(p)) return 15; + __sanitizer_purge_allocator(); + if (!Released(heapMemory.AllocationBase)) return 16; + + void* fakeBase = nullptr; + int fakeResult = 0; + std::thread thread([&] { + const auto frame = __asan_stack_malloc_always_0(64); + if (!frame || !GuestRange(frame, 64) || __asan_region_is_poisoned(frame, 64)) { + fakeResult = 17; + return; + } + __asan_memset(reinterpret_cast(frame), 0x42, 32); + MEMORY_BASIC_INFORMATION memory{}; + if (VirtualQuery(reinterpret_cast(frame), &memory, sizeof(memory)) != sizeof(memory)) { + fakeResult = 18; + return; + } + fakeBase = memory.AllocationBase; + __asan_stack_free_0(frame, 64); + if (!__asan_address_is_poisoned(reinterpret_cast(frame))) fakeResult = 19; + }); + thread.join(); + if (fakeResult) return fakeResult; + if (!fakeBase || !Released(fakeBase)) return 20; + for (std::size_t i = 0; i < hostBytes; ++i) if (host[i] != 0x5a) return 21; + std::printf("host allocation in shadow=%p; heap=%p; fake stack backing=%p; shadow hole preserved\n", static_cast(host), static_cast(p), fakeBase); + if (!VirtualFree(host, 0, MEM_RELEASE)) return 22; + return 0; +} diff --git a/core/libs/tests/GuestAddressSanitizerMapping.cpp b/core/libs/tests/GuestAddressSanitizerMapping.cpp new file mode 100644 index 000000000000..6801aed6a943 --- /dev/null +++ b/core/libs/tests/GuestAddressSanitizerMapping.cpp @@ -0,0 +1,400 @@ +#include "prx/libSceAddressSanitizer/src/ShadowAddressSpace.hpp" +#include "prx/libSceAddressSanitizer/include/Api.hpp" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +inline constexpr uintptr_t REGION_BASE = 1ULL << 40; +inline constexpr uintptr_t REGION_SIZE = 16ULL << 40; + +alignas(8) static std::array reportBuffer{}; +static std::uintptr_t reportExpected = 0; + +static void APS5_VABI PrintReportCallback(const char* text) { + std::fprintf(stderr, "callback present=%d type=%d size=%zu desc=%s address=%s text=%s\n", __asan_report_present(), __asan_get_report_access_type(), + __asan_get_report_access_size(), __asan_get_report_description(), + reinterpret_cast(__asan_get_report_address()) == reportExpected ? "ok" : "bad", + std::string_view(text).find("Shadow byte legend") != std::string_view::npos ? "ok" : "bad"); +} + +static void APS5_VABI PrintDeathCallback() { + std::fputs("death callback\n", stderr); +} + +int main(int argc, char* argv[]) { + SYSTEM_INFO si; + GetSystemInfo(&si); + if (si.dwPageSize != 4096) return 1; + if (argc > 1 && std::string_view(argv[1]) == "collision") { + void* prep = VirtualAlloc(reinterpret_cast(REGION_BASE), 4096, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); + if (prep != reinterpret_cast(REGION_BASE)) return 2; + constexpr uint32_t SENTINEL = 0xDEADBEEF; + *reinterpret_cast(prep) = SENTINEL; + if (!AsanRuntime::InitializeShadow_nid_no_patch()) return 3; + try { + __asan_poison_memory_region(reinterpret_cast(0x100), 8); + return 5; + } catch (const std::exception&) { + } + try { + __asan_load1(0x100); + return 6; + } catch (const std::exception&) { + } + if (*reinterpret_cast(prep) != SENTINEL) return 4; + constexpr std::uintptr_t app = 0x30000000; + __asan_poison_memory_region(reinterpret_cast(app), 8); + if (!__asan_address_is_poisoned(reinterpret_cast(app))) return 7; + __asan_unpoison_memory_region(reinterpret_cast(app), 8); + if (__asan_address_is_poisoned(reinterpret_cast(app))) return 8; + auto* last = reinterpret_cast(REGION_BASE + REGION_SIZE - 1); + *last = 0x7a; + if (*last != 0x7a) return 9; + return 0; + } + if (argc > 2 && std::string_view(argv[1]) == "report") { + __asan_set_error_report_callback(PrintReportCallback); + __sanitizer_set_death_callback(PrintDeathCallback); + const auto base = reinterpret_cast(reportBuffer.data()); + __asan_poison_memory_region(reportBuffer.data() + 16, 16); + const std::string_view mode(argv[2]); + if (mode == "load4") { + reportExpected = base + 16; + __asan_load4(base + 16); + } else if (mode == "storeN") { + reportExpected = base + 16; + __asan_storeN(base + 8, 16); + } else if (mode == "load16") { + __asan_load16(base); + reportExpected = base + 16; + __asan_load16(base + 4); + } else if (mode == "unaligned") { + reportExpected = base + 16; + __sanitizer_unaligned_store32(reportBuffer.data() + 14, 0); + } else if (mode == "partial") { + __asan_poison_memory_region(reportBuffer.data() + 4, 12); + __asan_load4(base); + __asan_load1(base + 3); + reportExpected = base + 4; + __asan_load1(base + 4); + } else if (mode == "report_error") { + reportExpected = base + 20; + __asan_report_error(reinterpret_cast(0x1000), reinterpret_cast(0x2000), reinterpret_cast(0x3000), reinterpret_cast(base + 20), 1, 2, 0); + } + return 2; + } + uintptr_t sharedPage = REGION_BASE + 4096 * 8; + std::barrier sync(16); + std::atomic threadOk{true}; + std::array threads; + for (int i = 0; i < 16; ++i) { + threads[i] = std::thread([i, sharedPage, &sync, &threadOk]() { + sync.arrive_and_wait(); + if (!AsanRuntime::InitializeShadow_nid_no_patch()) threadOk.store(false, std::memory_order_relaxed); + sync.arrive_and_wait(); + if (!threadOk.load(std::memory_order_relaxed)) return; + std::atomic_ref ref(*reinterpret_cast(sharedPage)); + ref.fetch_add(1, std::memory_order_relaxed); + uintptr_t threadPages = REGION_BASE + 4096 * (100 + i * 32); + for (uintptr_t j = 0; j < 32; ++j) { + volatile uint32_t* p = reinterpret_cast(threadPages + j * 4096); + if (*p != 0) threadOk.store(false, std::memory_order_relaxed); + uint32_t val = static_cast((i + 1) * 1000 + j + 1); + *p = val; + if (*p != val) threadOk.store(false, std::memory_order_relaxed); + } + }); + } + for (auto& t : threads) t.join(); + if (!threadOk.load(std::memory_order_relaxed)) return 7; + if (*reinterpret_cast(sharedPage) != 16) return 8; + auto* last = reinterpret_cast(REGION_BASE + REGION_SIZE - 1); + if (*last != 0) return 9; + *last = 0x7a; + if (*last != 0x7a || !AsanRuntime::InitializeShadow_nid_no_patch()) return 10; + constexpr std::uintptr_t app = 0x30000000; + auto* shadow = reinterpret_cast(REGION_BASE + (app >> 3)); + shadow[0] = -8; + shadow[1] = -7; + shadow[2] = -9; + __asan_unpoison_stack_memory(app, 10); + if (shadow[0] != 0 || shadow[1] != 2 || shadow[2] != -9) return 11; + __asan_unpoison_stack_memory(app + 1, 0); + try { + __asan_unpoison_stack_memory(app + 1, 1); + return 12; + } catch (const std::exception&) { + } + try { + __asan_unpoison_stack_memory(REGION_BASE, 8); + return 13; + } catch (const std::exception&) { + } + { + __asan_version_mismatch_check_v6(); + __asan_version_mismatch_check_v7(); + __asan_version_mismatch_check_v8(); + + __asan_unpoison_stack_memory(app, 24); + __asan_poison_stack_memory(app, 16); + if (shadow[0] != -8) return 60; + if (shadow[1] != -8) return 61; + if (shadow[2] != 0) return 62; + + __asan_poison_stack_memory(app, 0); + if (shadow[0] != -8) return 63; + if (shadow[1] != -8) return 64; + if (shadow[2] != 0) return 65; + + __asan_unpoison_stack_memory(app, 24); + if (shadow[0] != 0) return 66; + if (shadow[1] != 0) return 67; + if (shadow[2] != 0) return 68; + + try { + __asan_poison_stack_memory(app + 1, 1); + return 69; + } catch (const std::exception&) {} + + try { + __asan_poison_stack_memory((1ULL << 47) - 8, 16); + return 70; + } catch (const std::exception&) {} + } + constexpr std::uintptr_t object = 0x40000001; + auto* objectShadow = reinterpret_cast(REGION_BASE + (object >> 3)); + objectShadow[0] = 0; + objectShadow[1] = 0; + objectShadow[2] = -9; + __asan_poison_intra_object_redzone(object, 15); + if (objectShadow[0] != 1 || objectShadow[1] != -69 || objectShadow[2] != -9) return 14; + if (__asan_address_is_poisoned(reinterpret_cast(object - 1)) != 0) return 18; + if (__asan_address_is_poisoned(reinterpret_cast(object)) != 1) return 19; + if (__asan_region_is_poisoned(object - 1, 3) != object) return 20; + if (__asan_region_is_poisoned(object + 2, 1) != object + 2) return 21; + if (__asan_region_is_poisoned(object + 16, 0) != 0) return 22; + __asan_unpoison_intra_object_redzone(object, 15); + if (objectShadow[0] != 0 || objectShadow[1] != 0 || objectShadow[2] != -9) return 15; + if (__asan_region_is_poisoned(object - 1, 16) != 0) return 23; + try { + __asan_region_is_poisoned(REGION_BASE - 1, 2); + return 24; + } catch (const std::exception&) { + } + try { + __asan_poison_intra_object_redzone(object, 0); + return 16; + } catch (const std::exception&) { + } + try { + __asan_unpoison_intra_object_redzone(object, 14); + return 17; + } catch (const std::exception&) { + } + constexpr std::uintptr_t allocaTop = 0x50000003; + auto* allocaShadow = reinterpret_cast(REGION_BASE + (allocaTop >> 3)); + allocaShadow[0] = -8; + allocaShadow[1] = -8; + allocaShadow[2] = -8; + __asan_allocas_unpoison(allocaTop, allocaTop + 20); + if (allocaShadow[0] != 0 || allocaShadow[1] != 0 || allocaShadow[2] != -8) return 25; + __asan_allocas_unpoison(0, allocaTop); + __asan_allocas_unpoison(allocaTop + 1, allocaTop); + try { + __asan_allocas_unpoison(REGION_BASE - 8, REGION_BASE + 8); + return 26; + } catch (const std::exception&) { + } + { + constexpr std::uintptr_t base = 0x60000000; + auto* s = reinterpret_cast(REGION_BASE + (base >> 3)); + __asan_poison_cxx_array_cookie(base); + if (s[0] != static_cast(0xac)) return 100; + s[0] = 0; + alignas(8) std::uintptr_t cookie = 0x1234; + auto* cookieShadow = reinterpret_cast(REGION_BASE + (reinterpret_cast(&cookie) >> 3)); + const auto cookieSaved = *cookieShadow; + *cookieShadow = static_cast(0xac); + if (__asan_load_cxx_array_cookie(&cookie) != 0x1234) return 101; + *cookieShadow = static_cast(0xfd); + if (__asan_load_cxx_array_cookie(&cookie) != 0) return 102; + *cookieShadow = 0; + if (__asan_load_cxx_array_cookie(&cookie) != 0x1234) return 103; + *cookieShadow = cookieSaved; + try { + __asan_poison_cxx_array_cookie(REGION_BASE); + return 104; + } catch (const std::exception&) { + } + __asan_alloca_poison(base + 32, 10); + const std::array expected{-54, -54, -54, -54, 0, 2, -53, -53, -53, -53, -53, -53}; + for (std::size_t i = 0; i < expected.size(); ++i) { + if (s[i] != expected[i]) return 105; + } + if (s[12] != 0) return 106; + for (std::size_t i = 0; i < 13; ++i) s[i] = 0; + __asan_alloca_poison(base + 32, 32); + const std::array exact{-54, -54, -54, -54, 0, 0, 0, 0, -53, -53, -53, -53}; + for (std::size_t i = 0; i < exact.size(); ++i) { + if (s[i] != exact[i]) return 107; + } + try { + __asan_alloca_poison(base + 33, 1); + return 108; + } catch (const std::exception&) { + } + try { + __asan_alloca_poison(0, 8); + return 109; + } catch (const std::exception&) { + } + try { + __asan_alloca_poison(base + 32, ~std::uintptr_t{0} - base); + return 110; + } catch (const std::exception&) { + } + for (std::size_t i = 0; i < 13; ++i) s[i] = 0; + } + { + constexpr std::uintptr_t app = 0x70000000; + volatile std::int8_t* shadow = reinterpret_cast(REGION_BASE + (app >> 3)); + + shadow[0] = 0; + shadow[1] = 0; + shadow[2] = 0; + shadow[3] = 0; + shadow[4] = 0; + + __asan_poison_memory_region(reinterpret_cast(app), 32); + if (shadow[0] != -9) return 80; + if (shadow[1] != -9) return 81; + if (shadow[2] != -9) return 82; + if (shadow[3] != -9) return 83; + if (shadow[4] != 0) return 84; + + __asan_unpoison_memory_region(reinterpret_cast(app), 32); + if (shadow[0] != 0) return 85; + if (shadow[1] != 0) return 86; + if (shadow[2] != 0) return 87; + if (shadow[3] != 0) return 88; + + __asan_poison_memory_region(reinterpret_cast(app + 3), 13); + if (shadow[0] != 3) return 89; + if (shadow[1] != -9) return 90; + + __asan_unpoison_memory_region(reinterpret_cast(app), 16); + if (shadow[0] != 0) return 91; + if (shadow[1] != 0) return 92; + + shadow[0] = 6; + __asan_poison_memory_region(reinterpret_cast(app + 2), 4); + if (shadow[0] != 2) return 93; + + __asan_unpoison_memory_region(reinterpret_cast(app), 5); + if (shadow[0] != 5) return 94; + + shadow[0] = -9; + __asan_poison_memory_region(reinterpret_cast(app), 0); + if (shadow[0] != -9) return 95; + __asan_unpoison_memory_region(reinterpret_cast(app), 0); + if (shadow[0] != -9) return 96; + + try { + __asan_poison_memory_region(reinterpret_cast(REGION_BASE), 8); + return 97; + } catch (const std::exception&) { + } + + try { + __asan_poison_memory_region(reinterpret_cast((1ULL << 47) - 4), 8); + return 98; + } catch (const std::exception&) { + } + + shadow[0] = 0; + shadow[1] = 0; + shadow[2] = 0; + shadow[3] = 0; + shadow[4] = 0; + { + constexpr std::uintptr_t top = (1ULL << 47) - 8; + auto* topShadow = reinterpret_cast(REGION_BASE + (top >> 3)); + __asan_poison_memory_region(reinterpret_cast(top), 8); + if (*topShadow != -9) return 99; + __asan_unpoison_memory_region(reinterpret_cast(top), 8); + if (*topShadow != 0) return 79; + } + } + alignas(8) std::array unaligned{}; + auto* unalignedPtr = unaligned.data() + 1; + auto unalignedAddress = reinterpret_cast(unalignedPtr); + auto* unalignedShadow = reinterpret_cast(REGION_BASE + (unalignedAddress >> 3)); + const auto shadow0 = unalignedShadow[0]; + const auto shadow1 = unalignedShadow[1]; + unalignedShadow[0] = 0; + unalignedShadow[1] = 0; + __sanitizer_unaligned_store64(unalignedPtr, 0x1122334455667788ull); + if (__sanitizer_unaligned_load64(unalignedPtr) != 0x1122334455667788ull) return 27; + __sanitizer_unaligned_store32(unalignedPtr, 0xaabbccddu); + if (__sanitizer_unaligned_load32(unalignedPtr) != 0xaabbccddu) return 28; + __sanitizer_unaligned_store16(unalignedPtr, 0x1234u); + if (__sanitizer_unaligned_load16(unalignedPtr) != 0x1234u) return 29; + { + alignas(16) std::array clean{}; + const auto base = reinterpret_cast(clean.data()); + auto* cleanShadow = reinterpret_cast(REGION_BASE + (base >> 3)); + for (std::size_t i = 0; i < 8; ++i) cleanShadow[i] = 0; + __asan_load1(base); + __asan_load2(base); + __asan_load4(base); + __asan_load8(base); + __asan_load16(base); + __asan_store1(base); + __asan_store2(base); + __asan_store4(base); + __asan_store8(base); + __asan_store16(base); + __asan_load1_noabort(base); + __asan_load2_noabort(base); + __asan_load4_noabort(base); + __asan_load8_noabort(base); + __asan_load16_noabort(base); + __asan_store1_noabort(base); + __asan_store2_noabort(base); + __asan_store4_noabort(base); + __asan_store8_noabort(base); + __asan_store16_noabort(base); + __asan_loadN(base, 64); + __asan_storeN(base, 64); + __asan_loadN_noabort(base, 64); + __asan_storeN_noabort(base, 64); + __asan_loadN(base, 0); + cleanShadow[0] = 4; + __asan_load4(base); + __asan_load2(base + 2); + __asan_store1(base + 3); + __asan_loadN(base, 4); + __sanitizer_unaligned_store16(clean.data() + 2, 0x1234u); + if (__sanitizer_unaligned_load16(clean.data() + 2) != 0x1234u) return 30; + cleanShadow[0] = 0; + try { + __asan_load1(REGION_BASE); + return 31; + } catch (const std::exception&) { + } + try { + __asan_loadN(REGION_BASE - 8, 16); + return 32; + } catch (const std::exception&) { + } + } + unalignedShadow[0] = shadow0; + unalignedShadow[1] = shadow1; + return 0; +} diff --git a/core/libs/tests/GuestAddressSanitizerRuntime.cpp b/core/libs/tests/GuestAddressSanitizerRuntime.cpp new file mode 100644 index 000000000000..d3485102a2f3 --- /dev/null +++ b/core/libs/tests/GuestAddressSanitizerRuntime.cpp @@ -0,0 +1,969 @@ +#include "prx/libSceAddressSanitizer/include/Api.hpp" +#include +#include +#include +#include +#include +#include +#include +#include + +alignas(16) static std::array buffer{}; + +static std::uintptr_t Address(std::size_t offset) { + return reinterpret_cast(buffer.data()) + offset; +} + +static const void* Pointer(std::size_t offset) { + return buffer.data() + offset; +} + +static void Reset() { + __asan_unpoison_memory_region(buffer.data(), buffer.size()); + buffer.fill(0); +} + +static int Poisoned(std::size_t offset) { + return __asan_address_is_poisoned(buffer.data() + offset); +} + +static int CleanAccess() { + Reset(); + __asan_exp_load1(Address(0), 1); + __asan_exp_load2(Address(0), 1); + __asan_exp_load4(Address(0), 1); + __asan_exp_load8(Address(0), 1); + __asan_exp_load16(Address(0), 1); + __asan_exp_store1(Address(0), 1); + __asan_exp_store2(Address(0), 1); + __asan_exp_store4(Address(0), 1); + __asan_exp_store8(Address(0), 1); + __asan_exp_store16(Address(0), 1); + __asan_exp_load1_noabort(Address(0), 1); + __asan_exp_load2_noabort(Address(0), 1); + __asan_exp_load4_noabort(Address(0), 1); + __asan_exp_load8_noabort(Address(0), 1); + __asan_exp_load16_noabort(Address(0), 1); + __asan_exp_store1_noabort(Address(0), 1); + __asan_exp_store2_noabort(Address(0), 1); + __asan_exp_store4_noabort(Address(0), 1); + __asan_exp_store8_noabort(Address(0), 1); + __asan_exp_store16_noabort(Address(0), 1); + __asan_exp_loadN(Address(0), 100, 1); + __asan_exp_storeN(Address(0), 100, 1); + __asan_exp_loadN_noabort(Address(0), 100, 1); + __asan_exp_storeN_noabort(Address(0), 100, 1); + __sanitizer_ptr_cmp(buffer.data(), buffer.data() + 64); + __sanitizer_ptr_sub(buffer.data() + 64, buffer.data()); + return 0; +} + +static int Contiguous() { + Reset(); + __sanitizer_annotate_contiguous_container(Pointer(0), Pointer(64), Pointer(64), Pointer(20)); + if (Poisoned(19) || !Poisoned(20) || !Poisoned(23) || !Poisoned(24) || !Poisoned(63) || Poisoned(64)) return 1; + if (!__sanitizer_verify_contiguous_container(Pointer(0), Pointer(20), Pointer(64))) return 2; + if (__sanitizer_verify_contiguous_container(Pointer(0), Pointer(30), Pointer(64))) return 3; + if (__sanitizer_contiguous_container_find_bad_address(Pointer(0), Pointer(30), Pointer(64)) != Pointer(20)) return 4; + if (__sanitizer_contiguous_container_find_bad_address(Pointer(0), Pointer(10), Pointer(64)) != Pointer(10)) return 5; + __sanitizer_annotate_contiguous_container(Pointer(0), Pointer(64), Pointer(20), Pointer(50)); + if (Poisoned(49) || !Poisoned(50) || !Poisoned(63)) return 6; + if (!__sanitizer_verify_contiguous_container(Pointer(0), Pointer(50), Pointer(64))) return 7; + __sanitizer_annotate_contiguous_container(Pointer(0), Pointer(64), Pointer(50), Pointer(0)); + if (!Poisoned(0) || !Poisoned(63)) return 8; + __sanitizer_annotate_contiguous_container(Pointer(0), Pointer(64), Pointer(0), Pointer(64)); + if (Poisoned(0) || Poisoned(63)) return 9; + __sanitizer_annotate_contiguous_container(Pointer(3), Pointer(61), Pointer(61), Pointer(35)); + if (Poisoned(34) || !Poisoned(35) || !Poisoned(55) || Poisoned(56)) return 10; + if (!__sanitizer_verify_contiguous_container(Pointer(3), Pointer(35), Pointer(61))) return 11; + return 0; +} + +static int DoubleEnded() { + Reset(); + __sanitizer_annotate_double_ended_contiguous_container(Pointer(0), Pointer(64), Pointer(0), Pointer(64), Pointer(16), Pointer(40)); + if (!Poisoned(0) || !Poisoned(15) || Poisoned(16) || Poisoned(39) || !Poisoned(40) || !Poisoned(63)) return 1; + if (!__sanitizer_verify_double_ended_contiguous_container(Pointer(0), Pointer(16), Pointer(40), Pointer(64))) return 2; + if (__sanitizer_verify_double_ended_contiguous_container(Pointer(0), Pointer(8), Pointer(40), Pointer(64))) return 3; + if (__sanitizer_double_ended_contiguous_container_find_bad_address(Pointer(0), Pointer(8), Pointer(40), Pointer(64)) != Pointer(8)) return 4; + __sanitizer_annotate_double_ended_contiguous_container(Pointer(0), Pointer(64), Pointer(16), Pointer(40), Pointer(8), Pointer(56)); + if (!Poisoned(7) || Poisoned(8) || Poisoned(55) || !Poisoned(56)) return 5; + __sanitizer_annotate_double_ended_contiguous_container(Pointer(0), Pointer(64), Pointer(8), Pointer(56), Pointer(24), Pointer(30)); + if (!Poisoned(23) || Poisoned(24) || Poisoned(29) || !Poisoned(30)) return 6; + __sanitizer_annotate_double_ended_contiguous_container(Pointer(0), Pointer(64), Pointer(24), Pointer(30), Pointer(24), Pointer(30)); + if (!__sanitizer_verify_double_ended_contiguous_container(Pointer(0), Pointer(24), Pointer(30), Pointer(64))) return 7; + return 0; +} + +static int Memory() { + Reset(); + for (std::size_t i = 0; i < 32; ++i) buffer[i] = static_cast(i + 1); + if (__asan_memcpy(buffer.data() + 64, buffer.data(), 32) != buffer.data() + 64) return 1; + if (std::memcmp(buffer.data() + 64, buffer.data(), 32) != 0) return 2; + if (__asan_memmove(buffer.data() + 4, buffer.data(), 28) != buffer.data() + 4) return 3; + if (buffer[4] != 1 || buffer[31] != 28) return 4; + if (__asan_memset(buffer.data() + 96, 0x5a, 16) != buffer.data() + 96) return 5; + if (buffer[96] != 0x5a || buffer[111] != 0x5a || buffer[112] != 0) return 6; + __asan_memcpy(buffer.data(), buffer.data(), 16); + __asan_memset(buffer.data(), 0, 0); + __asan_memcpy(buffer.data() + 1, buffer.data(), 0); + return 0; +} + +struct Type { + std::uint16_t kind; + std::uint16_t info; + char name[16]; +}; + +static const Type signedInt = {0, 11, "'int'"}; +static const Type unsignedInt = {0, 10, "'unsigned int'"}; +static const Type boolType = {0, 6, "'bool'"}; +static const Type unsignedChar = {0, 6, "'unsigned char'"}; +static const Type doubleType = {1, 64, "'double'"}; +static const Type intArray = {0xffff, 0, "'int [4]'"}; +static const Type charPointer = {0xffff, 0, "'char *'"}; +static const Type functionPointer = {0xffff, 0, "'void (*)(int)'"}; + +struct Location { + const char* file; + std::uint32_t line; + std::uint32_t column; +}; + +struct OverflowData { + Location loc; + const Type* type; +}; + +struct ShiftData { + Location loc; + const Type* lhs; + const Type* rhs; +}; + +struct TypeMismatchData { + Location loc; + const Type* type; + unsigned char logAlignment; + unsigned char kind; +}; + +struct LegacyTypeMismatchData { + Location loc; + const Type* type; + std::uintptr_t alignment; + unsigned char kind; +}; + +struct LegacyNonNullReturnData { + Location loc; + Location attrLoc; +}; + +struct NonNullArgData { + Location loc; + Location attrLoc; + int index; +}; + +struct ConversionData { + Location loc; + const Type* from; + const Type* to; + unsigned char kind; +}; + +struct FloatCastData { + Location loc; + const Type* from; + const Type* to; +}; + +struct BuiltinData { + Location loc; + unsigned char kind; +}; + +struct AlignmentData { + Location loc; + Location assumptionLoc; + const Type* type; +}; + +struct NonNullReturnData { + Location attrLoc; +}; + +struct FunctionData { + Location loc; + const Type* type; +}; + +static void APS5_VABI PrintDeathCallback() { + std::fputs("death callback\n", stderr); +} + +static std::uintptr_t Word(std::int64_t value) { + return static_cast(value); +} + +static void Sample() { +} + +static int UbsanArithmetic() { + static OverflowData add = {{"test.cpp", 10, 5}, &signedInt}; + static OverflowData sub = {{"test.cpp", 11, 6}, &unsignedInt}; + static OverflowData mul = {{"test.cpp", 12, 7}, &signedInt}; + static OverflowData negate = {{"test.cpp", 13, 8}, &signedInt}; + static OverflowData divZero = {{"test.cpp", 14, 9}, &signedInt}; + static OverflowData divMinus = {{"test.cpp", 15, 10}, &signedInt}; + static ShiftData shiftLarge = {{"test.cpp", 16, 11}, &signedInt, &signedInt}; + static ShiftData shiftNegative = {{"test.cpp", 17, 12}, &signedInt, &signedInt}; + static ShiftData leftNegative = {{"test.cpp", 18, 13}, &signedInt, &signedInt}; + static ShiftData leftBase = {{"test.cpp", 19, 14}, &signedInt, &signedInt}; + static struct { + Location loc; + const Type* array; + const Type* index; + } bounds = {{"test.cpp", 20, 15}, &intArray, &signedInt}; + static OverflowData vla = {{"test.cpp", 21, 16}, &signedInt}; + __ubsan_handle_add_overflow(&add, 2147483647, 1); + __ubsan_handle_sub_overflow(&sub, 0, 1); + __ubsan_handle_mul_overflow(&mul, 65536, 65536); + __ubsan_handle_negate_overflow(&negate, 0x80000000u); + __ubsan_handle_divrem_overflow(&divZero, 5, 0); + __ubsan_handle_divrem_overflow(&divMinus, 0x80000000u, 0xffffffffu); + __ubsan_handle_shift_out_of_bounds(&shiftLarge, 1, 40); + __ubsan_handle_shift_out_of_bounds(&shiftNegative, 1, 0xffffffffu); + __ubsan_handle_shift_out_of_bounds(&leftNegative, 0xffffffffu, 3); + __ubsan_handle_shift_out_of_bounds(&leftBase, 1073741824, 2); + __ubsan_handle_out_of_bounds(&bounds, 4); + __ubsan_handle_vla_bound_not_positive(&vla, 0xfffffffdu); + return 0; +} + +static int UbsanMisc() { + static TypeMismatchData nullLoad = {{"test.cpp", 30, 3}, &signedInt, 2, 0}; + static TypeMismatchData misaligned = {{"test.cpp", 31, 4}, &signedInt, 2, 1}; + static TypeMismatchData insufficient = {{"test.cpp", 32, 5}, &signedInt, 2, 0}; + static NonNullArgData nonNull = {{"test.cpp", 33, 6}, {"decl.h", 5, 1}, 2}; + static NonNullArgData nullability = {{"test.cpp", 34, 7}, {"decl.h", 6, 2}, 1}; + static OverflowData pointerA = {{"test.cpp", 35, 8}, nullptr}; + static OverflowData pointerB = {{"test.cpp", 36, 9}, nullptr}; + static OverflowData pointerC = {{"test.cpp", 37, 10}, nullptr}; + static OverflowData pointerD = {{"test.cpp", 38, 11}, nullptr}; + static OverflowData invalid = {{"test.cpp", 39, 12}, &boolType}; + static ConversionData conversion = {{"test.cpp", 40, 13}, &signedInt, &unsignedChar, 1}; + static FloatCastData floatCast = {{"test.cpp", 41, 14}, &doubleType, &signedInt}; + static BuiltinData builtin = {{"test.cpp", 42, 15}, 0}; + static AlignmentData alignment = {{"test.cpp", 43, 16}, {"test.cpp", 44, 17}, &charPointer}; + static NonNullReturnData returnData = {{"decl.h", 9, 2}}; + static Location returnLocation = {"test.cpp", 45, 18}; + static FunctionData function = {{"test.cpp", 46, 19}, &functionPointer}; + const auto base = Address(16); + __ubsan_handle_type_mismatch_v1(&nullLoad, 0); + __ubsan_handle_type_mismatch_v1(&misaligned, base + 1); + __ubsan_handle_type_mismatch_v1(&insufficient, base); + __ubsan_handle_nonnull_arg(&nonNull); + __ubsan_handle_nullability_arg(&nullability); + __ubsan_handle_pointer_overflow(&pointerA, 0, 0); + __ubsan_handle_pointer_overflow(&pointerB, 0, 16); + __ubsan_handle_pointer_overflow(&pointerC, 0x1000, 0); + __ubsan_handle_pointer_overflow(&pointerD, 0x1000, 0x800); + __ubsan_handle_load_invalid_value(&invalid, 5); + __ubsan_handle_implicit_conversion(&conversion, 300, 44); + double huge = 1e10; + std::uint64_t bits; + std::memcpy(&bits, &huge, sizeof(bits)); + __ubsan_handle_float_cast_overflow(&floatCast, bits); + __ubsan_handle_invalid_builtin(&builtin); + __ubsan_handle_alignment_assumption(&alignment, base + 3, 8, 0); + __ubsan_handle_nullability_return_v1(&returnData, &returnLocation); + __ubsan_handle_function_type_mismatch(&function, reinterpret_cast(&Sample)); + return 0; +} + +static int UbsanData() { + static OverflowData add = {{"test.cpp", 50, 4}, &signedInt}; + __ubsan_handle_add_overflow(&add, Word(2147483647), 1); + const char* kind = nullptr; + const char* message = nullptr; + const char* file = nullptr; + unsigned line = 0; + unsigned column = 0; + char* memory = reinterpret_cast(1); + __ubsan_get_current_report_data(&kind, &message, &file, &line, &column, &memory); + std::printf("data kind=%s file=%s line=%u column=%u memory=%p message=%s\n", kind, file, line, column, static_cast(memory), message); + return 0; +} + +static int UbsanLegacyType(bool abort, bool repeated) { + LegacyTypeMismatchData nullLoad = {{"legacy.cpp", 101, 3}, &signedInt, 4, 0}; + LegacyTypeMismatchData misaligned = {{"legacy.cpp", 102, 7}, &signedInt, 256, 1}; + LegacyTypeMismatchData insufficient = {{"legacy.cpp", 103, 9}, &signedInt, 4, 2}; + LegacyTypeMismatchData zeroAlignment = {{"legacy.cpp", 104, 11}, &signedInt, 0, 3}; + if (repeated || !abort) { + __ubsan_handle_type_mismatch(&nullLoad, 0); + __ubsan_handle_type_mismatch(&nullLoad, 0); + if (nullLoad.loc.column != UINT32_MAX) return 1; + if (nullLoad.alignment != 4 || nullLoad.kind != 0) return 2; + } + if (abort) { + __sanitizer_set_death_callback(PrintDeathCallback); + __ubsan_handle_type_mismatch_abort(&nullLoad, 0); + return 3; + } + __ubsan_handle_type_mismatch(&misaligned, Address(16) + 1); + __ubsan_handle_type_mismatch(&insufficient, Address(16)); + __ubsan_handle_type_mismatch(&zeroAlignment, Address(16) + 1); + if (misaligned.loc.column != UINT32_MAX || insufficient.loc.column != UINT32_MAX || zeroAlignment.loc.column != UINT32_MAX) return 4; + std::puts("legacy type returned"); + return 0; +} + +static int UbsanLegacyReturn(bool abort, bool repeated) { + LegacyNonNullReturnData data = {{"legacy.cpp", 201, 5}, {"legacy.h", 8, 2}}; + LegacyNonNullReturnData noAttribute = {{"legacy.cpp", 202, 6}, {nullptr, 0, 0}}; + if (repeated || !abort) { + __ubsan_handle_nonnull_return(&data); + __ubsan_handle_nonnull_return(&data); + if (data.loc.column != UINT32_MAX || data.attrLoc.column != 2) return 1; + } + if (abort) { + __sanitizer_set_death_callback(PrintDeathCallback); + __ubsan_handle_nonnull_return_abort(&data); + return 2; + } + __ubsan_handle_nonnull_return(&noAttribute); + if (noAttribute.loc.column != UINT32_MAX) return 3; + const char* kind; + const char* message; + const char* file; + unsigned line; + unsigned column; + char* memory; + __ubsan_get_current_report_data(&kind, &message, &file, &line, &column, &memory); + if (std::strcmp(kind, "invalid-null-return") != 0 || std::strcmp(file, "legacy.cpp") != 0 || line != 202 || column != 6 || memory != nullptr) return 4; + std::puts("legacy return returned"); + return 0; +} + +static int UbsanDedup() { + static OverflowData add = {{"test.cpp", 60, 4}, &signedInt}; + const char* capture = "ubsan-dedup.log"; + std::freopen(capture, "w", stderr); + __ubsan_handle_add_overflow(&add, 2147483647, 1); + __ubsan_handle_add_overflow(&add, 2147483647, 1); + __ubsan_handle_add_overflow(&add, 2147483647, 1); + std::fclose(stderr); + std::FILE* file = std::fopen(capture, "r"); + if (file == nullptr) return 1; + int reports = 0; + char line[512]; + while (std::fgets(line, sizeof(line), file) != nullptr) { + if (std::strstr(line, "runtime error") != nullptr) ++reports; + } + std::fclose(file); + std::remove(capture); + std::printf("dedup count=%d\n", reports); + return 0; +} + +static int Heap() { + auto* p = static_cast(__asan_malloc(13)); + if (!p) return 1; + if (reinterpret_cast(p) % 8) return 2; + for (int i = 0; i < 13; ++i) { + if (p[i] != 0xbe) return 3; + } + if (__asan_address_is_poisoned(p + 12) || !__asan_address_is_poisoned(p + 13) || !__asan_address_is_poisoned(p - 1)) return 4; + if (__sanitizer_get_allocated_size(p) != 13 || __asan_malloc_usable_size(p) != 13) return 5; + if (!__sanitizer_get_ownership(p) || __sanitizer_get_ownership(p + 1)) return 6; + if (__sanitizer_get_allocated_begin(p + 5) != p) return 7; + if (__sanitizer_get_allocated_size_fast(p) != 13) return 8; + const std::size_t before = __sanitizer_get_current_allocated_bytes(); + auto* q = static_cast(__asan_calloc(5, 7)); + for (int i = 0; i < 35; ++i) { + if (q[i] != 0) return 9; + } + if (__sanitizer_get_current_allocated_bytes() != before + 35) return 10; + if (__sanitizer_get_heap_size() == 0 || __sanitizer_get_free_bytes() > __sanitizer_get_heap_size()) return 11; + std::memset(q, 0x42, 35); + auto* r = static_cast(__asan_realloc(q, 100)); + if (r == q) return 12; + for (int i = 0; i < 35; ++i) { + if (r[i] != 0x42) return 13; + } + if (!__asan_address_is_poisoned(q) || __sanitizer_get_ownership(q)) return 14; + if (__asan_address_is_poisoned(r + 99) || !__asan_address_is_poisoned(r + 100)) return 15; + if (__asan_realloc(r, 0) != nullptr) return 16; + if (!__asan_address_is_poisoned(r)) return 17; + auto* grown = static_cast(__asan_realloc(nullptr, 8)); + if (!grown || __sanitizer_get_allocated_size(grown) != 8) return 18; + __asan_free(grown); + __asan_free(nullptr); + auto* zero = static_cast(__asan_malloc(0)); + if (!zero || __sanitizer_get_allocated_size(zero) != 1) return 19; + __asan_free(zero); + if (__asan_malloc(13) == p) return 20; + if (!__asan_update_allocation_context(p) || __asan_update_allocation_context(p + 1)) return 21; + std::uintptr_t trace[4] = {}; + std::uint32_t tid = 99; + if (__asan_get_alloc_stack(reinterpret_cast(p), trace, 4, &tid) != 1 || trace[0] == 0 || tid == 99) return 22; + if (__asan_get_free_stack(reinterpret_cast(p), trace, 4, &tid) != 0) return 23; + __asan_free(p); + if (!__asan_address_is_poisoned(p) || __asan_get_free_stack(reinterpret_cast(p), trace, 4, &tid) != 1) return 24; + if (__sanitizer_get_ownership(p)) return 25; + __sanitizer_purge_allocator(); + if (__asan_address_is_poisoned(zero)) return 26; + return 0; +} + +static int WrapperCallSites() { + void* p = __asan_malloc(19); + std::uintptr_t trace[1] = {}; + std::uint32_t tid = 0; + char module[512] = {}; + if (__asan_get_alloc_stack(reinterpret_cast(p), trace, 1, &tid) != 1) return 1; + __sanitizer_symbolize_pc(trace[0], "%m", module, sizeof(module)); + if (!std::strstr(module, "guest_addresssanitizer_runtime_tests")) return 2; + if (!__asan_update_allocation_context(p)) return 3; + if (__asan_get_alloc_stack(reinterpret_cast(p), trace, 1, &tid) != 1) return 4; + __sanitizer_symbolize_pc(trace[0], "%m", module, sizeof(module)); + if (!std::strstr(module, "guest_addresssanitizer_runtime_tests")) return 5; + __asan_free(p); + if (__asan_get_free_stack(reinterpret_cast(p), trace, 1, &tid) != 1) return 6; + __sanitizer_symbolize_pc(trace[0], "%m", module, sizeof(module)); + if (!std::strstr(module, "guest_addresssanitizer_runtime_tests")) return 7; + __sanitizer_purge_allocator(); + return 0; +} + +static int HeapAligned() { + void* a = __asan_memalign(64, 10); + if (!a || reinterpret_cast(a) % 64) return 1; + if (__sanitizer_get_allocated_size(a) != 10 || !__asan_address_is_poisoned(static_cast(a) + 10)) return 2; + void* b = __asan_aligned_alloc(32, 64); + if (!b || reinterpret_cast(b) % 32) return 3; + void* c = nullptr; + if (__asan_posix_memalign(&c, 128, 5) != 0 || !c || reinterpret_cast(c) % 128) return 4; + void* d = __asan_memalign(4096, 100000); + if (!d || reinterpret_cast(d) % 4096 || __asan_address_is_poisoned(static_cast(d) + 99999) || !__asan_address_is_poisoned(static_cast(d) + 100000)) return 5; + void* e = __asan_memalign(0, 8); + if (!e || reinterpret_cast(e) % 8) return 6; + __asan_free(a); + __asan_free(b); + __asan_free(c); + __asan_free(d); + __asan_free(e); + return 0; +} + +static int HeapStats() { + void* p = __asan_malloc(100); + __asan_free(p); + __asan_print_accumulated_stats(); + return 0; +} + +#define FAKE_CLASS(n) \ + { \ + const std::uintptr_t size = std::uintptr_t{64} << n; \ + const std::uintptr_t first = __asan_stack_malloc_always_##n(size); \ + if (!first || __asan_region_is_poisoned(first, size)) return 10 + n; \ + __asan_stack_free_##n(first, size); \ + if (__asan_region_is_poisoned(first, size) != first) return 30 + n; \ + const std::uintptr_t second = __asan_stack_malloc_always_##n(size); \ + if (!second || second == first) return 50 + n; \ + __asan_stack_free_##n(second, size); \ + } + +static int FakeStack() { + if (__asan_stack_malloc_0(64) != 0 || __asan_stack_malloc_10(65536) != 0) return 1; + if (__asan_get_current_fake_stack() != nullptr) return 2; + if (__asan_addr_is_in_fake_stack(nullptr, buffer.data(), nullptr, nullptr) != nullptr) return 3; + FAKE_CLASS(0) + FAKE_CLASS(1) + FAKE_CLASS(2) + FAKE_CLASS(3) + FAKE_CLASS(4) + FAKE_CLASS(5) + FAKE_CLASS(6) + FAKE_CLASS(7) + FAKE_CLASS(8) + FAKE_CLASS(9) + FAKE_CLASS(10) +#if defined(__linux__) && !defined(__ANDROID__) + if (__asan_get_current_fake_stack() == nullptr) return 80; + const auto conditional = __asan_stack_malloc_0(64); + if (!conditional) return 81; + __asan_stack_free_0(conditional, 64); +#else + if (__asan_get_current_fake_stack() != nullptr || __asan_stack_malloc_0(64) != 0) return 80; +#endif + return 0; +} + +static int FakeStackOption() { + if (__asan_option_detect_stack_use_after_return != 0) return 1; + if (__asan_stack_malloc_0(64) != 0 || __asan_get_current_fake_stack() != nullptr) return 2; + __asan_option_detect_stack_use_after_return = 1; + const auto frame = __asan_stack_malloc_0(64); + void* stack = __asan_get_current_fake_stack(); + if (!frame || !stack) return 3; + if (__asan_address_is_poisoned(reinterpret_cast(frame))) return 4; + __asan_stack_free_0(frame, 64); + if (!__asan_address_is_poisoned(reinterpret_cast(frame))) return 5; + __asan_option_detect_stack_use_after_return = 0; +#if defined(__linux__) && !defined(__ANDROID__) + if (__asan_get_current_fake_stack() != stack) return 6; + const auto conditional = __asan_stack_malloc_0(64); + if (!conditional) return 7; + __asan_stack_free_0(conditional, 64); +#else + if (__asan_get_current_fake_stack() != nullptr || __asan_stack_malloc_0(64) != 0) return 6; +#endif + const auto always = __asan_stack_malloc_always_0(64); + if (!always) return 8; + __asan_stack_free_0(always, 64); + return 0; +} + +static int VptrCacheData() { + for (const auto hash : __ubsan_vptr_type_cache) { + if (hash != 0) return 1; + } + for (std::size_t index = 0; index < std::size(__ubsan_vptr_type_cache); ++index) { + __ubsan_vptr_type_cache[index] = UINTPTR_MAX - index; + } + for (std::size_t index = 0; index < std::size(__ubsan_vptr_type_cache); ++index) { + if (__ubsan_vptr_type_cache[index] != UINTPTR_MAX - index) return 2; + } + return 0; +} + +static int NoReturn() { + volatile char local[256]; + __asan_poison_memory_region(const_cast(local), sizeof(local)); + if (!__asan_address_is_poisoned(const_cast(local) + 10)) return 1; + __asan_handle_no_return(); + if (__asan_region_is_poisoned(reinterpret_cast(local), sizeof(local))) return 2; + return 0; +} + +struct TestLocation { + const char* file; + int line; + int column; +}; + +struct TestGlobal { + std::uintptr_t beg; + std::uintptr_t size; + std::uintptr_t sizeWithRedzone; + const char* name; + const char* module; + std::uintptr_t hasDynamicInit; + const TestLocation* location; + std::uintptr_t odrIndicator; +}; + +alignas(64) static unsigned char globalArea[256]; +alignas(64) static unsigned char secondArea[64]; +static TestLocation globalLocation = {"test.cpp", 5, 6}; +static unsigned char odrIndicator; +alignas(8) static TestGlobal globalTable[2]; +alignas(8) static TestGlobal secondTable[1]; + +static int GlobalsInvalidArray() { + using Callback = void (APS5_VABI*)(void*, std::uintptr_t); + const Callback callbacks[] = {__asan_register_globals, __asan_unregister_globals}; + for (const auto callback : callbacks) { + callback(nullptr, 0); + bool nullRejected = false; + try { + callback(nullptr, 1); + } catch (const std::invalid_argument&) { + nullRejected = true; + } + if (!nullRejected) return 1; + for (const auto count : {std::numeric_limits::max() / sizeof(TestGlobal) + 1, std::numeric_limits::max()}) { + bool overflowRejected = false; + try { + callback(reinterpret_cast(std::uintptr_t{0x1000}), count); + } catch (const std::invalid_argument&) { + overflowRejected = true; + } + if (!overflowRejected) return 2; + } + } + return 0; +} + +static std::uintptr_t Area(const unsigned char* base, std::size_t offset = 0) { + return reinterpret_cast(base) + offset; +} + +static void FillGlobals(std::uintptr_t indicator) { + globalTable[0] = {Area(globalArea), 13, 64, "g1", "test.module", 0, &globalLocation, indicator}; + globalTable[1] = {Area(globalArea, 128), 16, 32, "g2", "test.module", 0, &globalLocation, indicator ? indicator + 1 : 0}; +} + +static int Globals() { + std::memset(globalArea, 0, sizeof(globalArea)); + FillGlobals(0); + __asan_register_globals(globalTable, 2); + const unsigned char* a = globalArea; + if (__asan_address_is_poisoned(a + 12) || !__asan_address_is_poisoned(a + 13) || !__asan_address_is_poisoned(a + 15) || !__asan_address_is_poisoned(a + 16) || !__asan_address_is_poisoned(a + 63)) return 1; + if (__asan_address_is_poisoned(a + 64) || __asan_address_is_poisoned(a + 128) || __asan_address_is_poisoned(a + 143) || !__asan_address_is_poisoned(a + 144) || !__asan_address_is_poisoned(a + 159) || __asan_address_is_poisoned(a + 160)) return 2; + if (!__asan_address_is_poisoned(globalTable)) return 3; + char name[8] = {}; + std::uintptr_t begin = 0; + std::uintptr_t size = 0; + const char* kind = __asan_locate_address(Area(a, 5), name, sizeof(name), &begin, &size); + if (std::strcmp(kind, "global") || std::strcmp(name, "g1") || begin != Area(a) || size != 13) return 4; + kind = __asan_locate_address(Area(a, 134), name, 2, &begin, &size); + if (std::strcmp(kind, "global") || std::strcmp(name, "g") || begin != Area(a, 128) || size != 16) return 5; + __asan_unregister_globals(globalTable, 2); + if (__asan_region_is_poisoned(Area(a), 160) || __asan_address_is_poisoned(globalTable)) return 6; + kind = __asan_locate_address(Area(a, 5), name, sizeof(name), &begin, &size); + if (std::strcmp(kind, "heap-invalid") || name[0] != 0 || begin != 0 || size != 0) return 7; + return 0; +} + +static int GlobalsElf() { + std::memset(globalArea, 0, sizeof(globalArea)); + FillGlobals(0); + std::uintptr_t flag = 0; + __asan_register_elf_globals(&flag, globalTable, globalTable + 2); + if (flag != 1 || !__asan_address_is_poisoned(globalArea + 20)) return 1; + __asan_register_elf_globals(&flag, globalTable, globalTable + 2); + __asan_unregister_elf_globals(&flag, globalTable, globalTable + 2); + if (flag != 0 || __asan_region_is_poisoned(Area(globalArea), 160)) return 2; + __asan_unregister_elf_globals(&flag, globalTable, globalTable + 2); + __asan_register_elf_globals(&flag, nullptr, nullptr); + if (flag != 0) return 3; + return 0; +} + +static int GlobalsOdrIndicator() { + std::memset(globalArea, 0, sizeof(globalArea)); + std::memset(secondArea, 0, sizeof(secondArea)); + odrIndicator = 0; + globalTable[0] = {Area(globalArea), 13, 64, "older", "test.module", 0, &globalLocation, reinterpret_cast(&odrIndicator)}; + __asan_register_globals(globalTable, 1); + if (odrIndicator != 1) return 1; + secondTable[0] = {Area(secondArea), 24, 64, "newer", "other.module", 0, &globalLocation, reinterpret_cast(&odrIndicator)}; + __asan_register_globals(secondTable, 1); + return 2; +} + +static int GlobalsOdrPoison() { + std::memset(globalArea, 0, sizeof(globalArea)); + globalTable[0] = {Area(globalArea), 13, 64, "older", "test.module", 0, &globalLocation, 0}; + __asan_register_globals(globalTable, 1); + secondTable[0] = {Area(globalArea), 24, 64, "newer", "other.module", 0, &globalLocation, 0}; + __asan_register_globals(secondTable, 1); + return 2; +} + +static int GlobalsDescribe() { + std::memset(globalArea, 0, sizeof(globalArea)); + std::memcpy(globalArea + 128, "text\0", 5); + FillGlobals(0); + globalTable[1].size = 5; + __asan_register_globals(globalTable, 2); + __asan_describe_address(Area(globalArea, 130)); + __asan_describe_address(Area(globalArea, 134)); + __asan_describe_address(Area(globalArea, 250)); + return 0; +} + +static int Fibers() { + static unsigned char fiberStack[4096]; + void* save = nullptr; + __sanitizer_start_switch_fiber(&save, fiberStack, sizeof(fiberStack)); + const void* oldBottom = nullptr; + std::size_t oldSize = 0; + __sanitizer_finish_switch_fiber(save, &oldBottom, &oldSize); + if (!oldBottom || oldSize == 0) return 1; + __sanitizer_start_switch_fiber(nullptr, oldBottom, oldSize); + const void* fiberBottom = nullptr; + std::size_t fiberSize = 0; + __sanitizer_finish_switch_fiber(nullptr, &fiberBottom, &fiberSize); + if (fiberBottom != fiberStack || fiberSize != sizeof(fiberStack)) return 2; + return 0; +} + +static int Locate() { + char name[16] = {}; + std::uintptr_t begin = 1; + std::uintptr_t size = 1; + char* p = static_cast(__asan_malloc(10)); + const char* kind = __asan_locate_address(reinterpret_cast(p + 2), name, sizeof(name), &begin, &size); + if (std::strcmp(kind, "heap") || begin != reinterpret_cast(p) || size != 10 || name[0] != 0) return 1; + kind = __asan_locate_address(reinterpret_cast(p + 12), nullptr, 0, nullptr, nullptr); + if (std::strcmp(kind, "heap")) return 2; + kind = __asan_locate_address(std::uintptr_t{1} << 40, name, sizeof(name), &begin, &size); + if (std::strcmp(kind, "low shadow")) return 3; + kind = __asan_locate_address((std::uintptr_t{1} << 40) + (std::uintptr_t{1} << 37), name, sizeof(name), &begin, &size); + if (std::strcmp(kind, "shadow gap")) return 4; + kind = __asan_locate_address((std::uintptr_t{1} << 40) + (std::uintptr_t{1} << 44) - 8, name, sizeof(name), &begin, &size); + if (std::strcmp(kind, "high shadow")) return 5; + __asan_free(p); + return 0; +} + +static int DescribeHeap() { + char* p = static_cast(__asan_malloc(10)); + __asan_describe_address(reinterpret_cast(p + 3)); + __asan_describe_address(reinterpret_cast(p + 12)); + __asan_describe_address(reinterpret_cast(p - 4)); + __asan_free(p); + __asan_describe_address(reinterpret_cast(p)); + __asan_describe_address(std::uintptr_t{0x1000}); + __asan_describe_address(std::uintptr_t{1} << 40); + return 0; +} + +static std::string ReadFile(const char* path) { + std::string content; + if (std::FILE* file = std::fopen(path, "rb")) { + char block[256]; + std::size_t count = 0; + while ((count = std::fread(block, 1, sizeof(block), file)) != 0) { + content.append(block, count); + } + std::fclose(file); + } + return content; +} + +static int ReportPath() { + __sanitizer_set_report_path("asan_report_path_test.log"); + const std::string path = __sanitizer_get_report_path(); + if (path.rfind("asan_report_path_test.log.", 0) != 0) return 1; + __asan_describe_address(0x1000); + __sanitizer_set_report_path("stderr"); + const std::string content = ReadFile(path.c_str()); + std::remove(path.c_str()); + if (content.find("Address 0x000000001000 is a wild pointer") == std::string::npos) return 2; + __asan_describe_address(0x2000); + std::printf("report path ok\n"); + return 0; +} + +static int ReportStdout() { + __sanitizer_set_report_path("stdout"); + __asan_describe_address(0x3000); + return 0; +} + +static int ReportDescriptor() { + __sanitizer_set_report_fd(reinterpret_cast(1)); + __asan_describe_address(0x4000); + return 0; +} + +static int StackTraceMode() { + __sanitizer_print_stack_trace(); + return 0; +} + +static int Symbolize() { + char buffer[256] = {}; + const std::uintptr_t pc = reinterpret_cast(&Symbolize) + 1; + __sanitizer_symbolize_pc(pc, "%M", buffer, sizeof(buffer)); + std::printf("symbolized=%s\n", buffer); + __sanitizer_symbolize_pc(pc, "%%|%n|%b|%f|%F|%q|%l|%c", buffer, sizeof(buffer)); + std::printf("literal=%s\n", buffer); + __sanitizer_symbolize_pc(pc, "%p", buffer, 5); + std::printf("short=%s\n", buffer); + __sanitizer_symbolize_pc(pc, "%p", buffer, 0); + std::memset(buffer, 'x', 4); + buffer[4] = 0; + __sanitizer_symbolize_global(reinterpret_cast(&buffer), "%g", buffer, sizeof(buffer)); + std::printf("global=<%s>\n", buffer); + return 0; +} + +static int Coverage() { + std::uint32_t guards[4] = {}; + __sanitizer_cov_trace_pc_guard_init(guards, guards + 4); + if (guards[0] != 1 || guards[3] != 4) return 1; + std::uint32_t other[2] = {}; + __sanitizer_cov_trace_pc_guard_init(other, other + 2); + if (other[0] != 5 || other[1] != 6) return 2; + __sanitizer_cov_trace_pc_guard_init(guards, guards + 4); + if (guards[0] != 1) return 3; + std::uint32_t zero = 0; + __sanitizer_cov_trace_pc_guard(&zero); + __sanitizer_cov_trace_pc_guard(&guards[1]); + __sanitizer_dump_trace_pc_guard_coverage(); + __sanitizer_cov_dump(); + const std::uintptr_t pcs[3] = {reinterpret_cast(&Coverage) + 4, 0, reinterpret_cast(&Coverage) + 2}; + __sanitizer_dump_coverage(pcs, 3); + return 0; +} + +static int SandboxNotify() { + __sanitizer_sandbox_on_notify(nullptr); + return 0; +} + +int main(int argc, char* argv[]) { + if (argc < 2) return 100; + const std::string_view mode(argv[1]); + if (mode == "ubsan_legacy_type") return UbsanLegacyType(false, false); + if (mode == "ubsan_legacy_type_abort") return UbsanLegacyType(true, false); + if (mode == "ubsan_legacy_type_repeat_abort") return UbsanLegacyType(true, true); + if (mode == "ubsan_legacy_return") return UbsanLegacyReturn(false, false); + if (mode == "ubsan_legacy_return_abort") return UbsanLegacyReturn(true, false); + if (mode == "ubsan_legacy_return_repeat_abort") return UbsanLegacyReturn(true, true); + if (mode == "fake_stack_option") return FakeStackOption(); + if (mode == "vptr_cache_data") return VptrCacheData(); + if (mode == "globals_invalid_array") return GlobalsInvalidArray(); + if (mode == "ubsan_arithmetic") return UbsanArithmetic(); + if (mode == "ubsan_misc") return UbsanMisc(); + if (mode == "ubsan_data") return UbsanData(); + if (mode == "ubsan_dedup") return UbsanDedup(); + if (mode == "ubsan_abort") { + static OverflowData sub = {{"test.cpp", 70, 2}, &unsignedInt}; + __sanitizer_set_death_callback(PrintDeathCallback); + __ubsan_handle_sub_overflow_abort(&sub, 0, 1); + return 2; + } + if (mode == "ubsan_unreachable") { + static Location unreachable = {"test.cpp", 71, 3}; + __sanitizer_set_death_callback(PrintDeathCallback); + __ubsan_handle_builtin_unreachable(&unreachable); + return 2; + } + if (mode == "heap") return Heap(); + if (mode == "wrapper_call_sites") return WrapperCallSites(); + if (mode == "heap_aligned") return HeapAligned(); + if (mode == "heap_stats") return HeapStats(); + if (mode == "heap_double_free") { + void* p = __asan_malloc(10); + __asan_free(p); + __asan_free(p); + return 2; + } + if (mode == "heap_bad_free") { + __asan_free(buffer.data()); + return 2; + } + if (mode == "heap_interior_free") { + char* p = static_cast(__asan_malloc(32)); + __asan_free(p + 1); + return 2; + } + if (mode == "heap_usable_size_unowned") { + __asan_malloc_usable_size(buffer.data()); + return 2; + } + if (mode == "heap_allocated_size_unowned") { + __sanitizer_get_allocated_size(buffer.data()); + return 2; + } + if (mode == "heap_calloc_overflow") { + __asan_calloc(1ull << 40, 1ull << 40); + return 2; + } + if (mode == "heap_aligned_alloc_bad") { + __asan_aligned_alloc(24, 48); + return 2; + } + if (mode == "heap_posix_memalign_bad") { + void* p = nullptr; + __asan_posix_memalign(&p, 12, 8); + return 2; + } + if (mode == "heap_memalign_bad") { + __asan_memalign(24, 8); + return 2; + } + if (mode == "heap_too_big") { + __asan_malloc(1ull << 41); + return 2; + } + if (mode == "heap_realloc_freed") { + void* p = __asan_malloc(10); + __asan_free(p); + __asan_realloc(p, 20); + return 2; + } + if (mode == "fake_stack") return FakeStack(); + if (mode == "no_return") return NoReturn(); + if (mode == "globals") return Globals(); + if (mode == "globals_elf") return GlobalsElf(); + if (mode == "globals_odr_indicator") return GlobalsOdrIndicator(); + if (mode == "globals_odr_poison") return GlobalsOdrPoison(); + if (mode == "globals_describe") return GlobalsDescribe(); + if (mode == "fibers") return Fibers(); + if (mode == "locate") return Locate(); + if (mode == "describe_heap") return DescribeHeap(); + if (mode == "init") { + __asan_init(); + __asan_poison_memory_region(buffer.data(), 16); + return __asan_address_is_poisoned(buffer.data()) ? 0 : 1; + } + if (mode == "fiber_unstarted") { + __sanitizer_finish_switch_fiber(nullptr, nullptr, nullptr); + return 2; + } + if (mode == "fiber_double_start") { + __sanitizer_start_switch_fiber(nullptr, buffer.data(), buffer.size()); + __sanitizer_start_switch_fiber(nullptr, buffer.data(), buffer.size()); + return 2; + } + if (mode == "report_path") return ReportPath(); + if (mode == "report_stdout") return ReportStdout(); + if (mode == "report_descriptor") return ReportDescriptor(); + if (mode == "stack_trace") return StackTraceMode(); + if (mode == "symbolize") return Symbolize(); + if (mode == "coverage") return Coverage(); + if (mode == "sandbox_notify") return SandboxNotify(); + if (mode == "symbolize_bad") { + char buffer[16] = {}; + __sanitizer_symbolize_pc(0x1000, "%z", buffer, sizeof(buffer)); + return 2; + } + if (mode == "clean") return CleanAccess(); + if (mode == "contiguous") return Contiguous(); + if (mode == "double_ended") return DoubleEnded(); + if (mode == "memory") return Memory(); + if (mode == "fatal_control") { + std::fprintf(stderr, "ERROR: AddressSanitizer: use-after-poison on address 0x000000001010 at pc 0x000000002000 bp 0x000000003000 sp 0x000000004000\nREAD of size 4 at 0x000000001010 thread T-1\nABORTING\n"); + return 2; + } + Reset(); + __asan_poison_memory_region(buffer.data() + 16, 16); + if (mode == "exp_load4") { + __asan_exp_load4(Address(16), 7); + } else if (mode == "exp_store16_noabort") { + __asan_exp_store16_noabort(Address(8), 7); + } else if (mode == "exp_loadN") { + __asan_exp_loadN(Address(8), 16, 7); + } else if (mode == "report_exp_store2") { + __asan_report_exp_store2(Address(20), 7); + } else if (mode == "report_exp_load_n") { + __asan_report_exp_load_n(Address(20), 6, 7); + } else if (mode == "memcpy_source") { + __asan_memcpy(buffer.data() + 64, buffer.data() + 8, 16); + } else if (mode == "memset_poison") { + __asan_memset(buffer.data() + 8, 0, 16); + } else if (mode == "memmove_poison") { + __asan_memmove(buffer.data() + 20, buffer.data(), 8); + } else if (mode == "memcpy_overlap") { + __asan_memcpy(buffer.data() + 4, buffer.data(), 16); + } else if (mode == "memset_negative") { + __asan_memset(buffer.data(), 0, static_cast(-1)); + } else if (mode == "container_params") { + __sanitizer_annotate_contiguous_container(Pointer(3), Pointer(64), Pointer(40), Pointer(2)); + } else if (mode == "double_ended_params") { + __sanitizer_annotate_double_ended_contiguous_container(Pointer(3), Pointer(64), Pointer(10), Pointer(5), Pointer(8), Pointer(12)); + } + return 2; +} diff --git a/core/libs/tests/GuestAddressSanitizerShadow.cpp b/core/libs/tests/GuestAddressSanitizerShadow.cpp new file mode 100644 index 000000000000..2db6c64f463d --- /dev/null +++ b/core/libs/tests/GuestAddressSanitizerShadow.cpp @@ -0,0 +1,263 @@ +#include "prx/libSceAddressSanitizer/libSceAddressSanitizer.hpp" +#include "prx/libSceAddressSanitizer/src/ShadowCheck.hpp" +#include "prx/libSceAddressSanitizer/src/ErrorReport.hpp" +#include "prx/libSceAddressSanitizer/src/Report.hpp" +#include +#include +#include +#include +#include +#include +#include +#include + +static void APS5_VABI TestErrorReportCallback(const char*) {} + +int main() { + { + std::uint8_t value = 0; + const std::array, 18> bugs{{ + {0xfa, "heap-buffer-overflow"}, {0xac, "heap-buffer-overflow"}, {0xfd, "heap-use-after-free"}, + {0xf1, "stack-buffer-underflow"}, {0xf6, "initialization-order-fiasco"}, {0xf2, "stack-buffer-overflow"}, + {0xf3, "stack-buffer-overflow"}, {0xf5, "stack-use-after-return"}, {0xf7, "use-after-poison"}, + {0xfc, "container-overflow"}, {0xf8, "stack-use-after-scope"}, {0xf9, "global-buffer-overflow"}, + {0xbb, "intra-object-overflow"}, {0xca, "dynamic-stack-buffer-overflow"}, {0xcb, "dynamic-stack-buffer-overflow"}, + {0x80, "unknown-crash"}, {0xfe, "unknown-crash"}, {0x00, "unknown-crash"}}}; + for (const auto& [magic, name] : bugs) { + const std::array shadow{magic, 0}; + if (AsanRuntime::DescribeBug_nid_no_patch(shadow.data(), 4, value) != name || value != magic) return 140; + } + const std::array partial{4, 0xfa}; + if (std::string_view(AsanRuntime::DescribeBug_nid_no_patch(partial.data(), 4, value)) != "heap-buffer-overflow" || value != 0xfa) return 141; + const std::array wide{0, 0xf7}; + if (std::string_view(AsanRuntime::DescribeBug_nid_no_patch(wide.data(), 16, value)) != "use-after-poison" || value != 0xf7) return 142; + if (std::string_view(AsanRuntime::DescribeBug_nid_no_patch(wide.data(), 8, value)) != "unknown-crash" || value != 0) return 143; + if (std::string_view(AsanRuntime::DescribeBug_nid_no_patch(partial.data(), 0, value)) != "unknown-crash" || value != 0) return 144; + std::string text; + AsanRuntime::AppendPointer_nid_no_patch(text, 0x1234); + if (text != "0x000000001234") return 145; + text.clear(); + AsanRuntime::AppendPointer_nid_no_patch(text, 0x123456789abcdef0ull); + if (text != "0x123456789abcdef0") return 146; + text.clear(); + AsanRuntime::AppendReportHeader_nid_no_patch(text, "use-after-poison", 0x30000004, 0x1000, 0x2000, 0x3000, false, 4); + if (text != "=================================================================\n" + "ERROR: AddressSanitizer: use-after-poison on address 0x000030000004 at pc 0x000000001000 bp 0x000000002000 sp 0x000000003000\n" + "READ of size 4 at 0x000030000004 thread T-1\n") return 147; + text.clear(); + AsanRuntime::AppendReportHeader_nid_no_patch(text, "x", 0, 0, 0, 0, true, 1); + if (text.find("\nWRITE of size 1 at ") == std::string::npos) return 148; + text.clear(); + AsanRuntime::AppendReportHeader_nid_no_patch(text, "x", 0, 0, 0, 0, true, 0); + if (text.find("\nACCESS of size 0 at ") == std::string::npos) return 149; + std::array row{}; + for (std::size_t i = 0; i < row.size(); ++i) row[i] = static_cast(i); + text.clear(); + AsanRuntime::AppendShadowRow_nid_no_patch(text, "=>", 0x30000000, row.data(), row.data() + 3); + if (text != "=>0x000030000000: 00 01 02[03]04 05 06 07 08 09 0a 0b 0c 0d 0e 0f\n") return 150; + text.clear(); + AsanRuntime::AppendShadowRow_nid_no_patch(text, " ", 0, row.data(), row.data()); + if (text != " 0x000000000000:[00]01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f\n") return 151; + alignas(16) std::array fake{}; + fake[100] = 0xf7; + text.clear(); + AsanRuntime::AppendShadowMemory_nid_no_patch(text, reinterpret_cast(fake.data()), fake.size(), 8 * 100); + if (text.rfind("Shadow bytes around the buggy address:\n", 0) != 0) return 152; + if (text.find("=>0x000000000300: 00 00 00 00[f7]00") == std::string::npos) return 153; + std::size_t rows = 0; + for (std::size_t at = 0; at < text.size(); at = text.find('\n', at) + 1) { + if (text.compare(at, 4, " 0x") == 0 || text.compare(at, 4, "=>0x") == 0) ++rows; + if (text.find('\n', at) == std::string::npos) break; + } + if (rows != 11) return 154; + if (!std::string_view(text).ends_with(" Right alloca redzone: cb\n")) return 155; + text.clear(); + AsanRuntime::AppendShadowMemory_nid_no_patch(text, reinterpret_cast(fake.data()), fake.size(), 0); + if (text.rfind("Shadow bytes around the buggy address:\n=>0x000000000000:[00]", 0) != 0) return 156; + } + { + if (AsanRuntime::LoadErrorReportCallback_nid_no_patch() != nullptr) return 130; + __asan_set_error_report_callback(TestErrorReportCallback); + if (AsanRuntime::LoadErrorReportCallback_nid_no_patch() != TestErrorReportCallback) return 131; + __asan_set_error_report_callback(nullptr); + if (AsanRuntime::LoadErrorReportCallback_nid_no_patch() != nullptr) return 132; + } + + { + if (__asan_report_present() != 0) { + return 40; + } + if (__asan_get_report_pc() != nullptr) { + return 41; + } + if (__asan_get_report_bp() != nullptr) { + return 42; + } + if (__asan_get_report_sp() != nullptr) { + return 43; + } + if (__asan_get_report_address() != nullptr) { + return 44; + } + if (__asan_get_report_access_type() != 0) { + return 45; + } + if (__asan_get_report_access_size() != 0) { + return 46; + } + if (__asan_get_report_description() != nullptr) { + return 47; + } + + *AsanRuntime::CurrentErrorReport_nid_no_patch() = { + .generic = true, + .pc = 0x1000, + .bp = 0x2000, + .sp = 0x3000, + .address = 0x4000, + .isWrite = true, + .accessSize = 8, + .description = "heap-buffer-overflow", + }; + + if (__asan_report_present() != 1) { + return 48; + } + if (__asan_get_report_pc() != reinterpret_cast(static_cast(0x1000))) { + return 49; + } + if (__asan_get_report_bp() != reinterpret_cast(static_cast(0x2000))) { + return 50; + } + if (__asan_get_report_sp() != reinterpret_cast(static_cast(0x3000))) { + return 51; + } + if (__asan_get_report_address() != reinterpret_cast(static_cast(0x4000))) { + return 52; + } + if (__asan_get_report_access_type() != 1) { + return 53; + } + if (__asan_get_report_access_size() != 8) { + return 54; + } + if (__asan_get_report_description() != AsanRuntime::CurrentErrorReport_nid_no_patch()->description) { + return 55; + } + + AsanRuntime::CurrentErrorReport_nid_no_patch()->isWrite = false; + if (__asan_get_report_access_type() != 0) { + return 56; + } + + *AsanRuntime::CurrentErrorReport_nid_no_patch() = {}; + if (__asan_report_present() != 0) { + return 57; + } + } + + if (__sanitizer_get_unmapped_bytes() != 0) return 23; + + for (std::size_t size : {std::size_t{0}, std::size_t{1}, std::size_t{4096}, std::numeric_limits::max()}) { + if (__sanitizer_get_estimated_allocated_size(size) != size) return 22; + } + + __sanitizer_malloc_hook(nullptr, 0); + __sanitizer_free_hook(nullptr); + + if (__ubsan_default_options() == nullptr || __ubsan_default_options()[0] != '\0') return 20; + if (__sancov_default_options() == nullptr || __sancov_default_options()[0] != '\0') return 21; + + { + std::size_t scale = 0; + std::size_t offset = 0; + __asan_get_shadow_mapping(&scale, &offset); + if (scale != 3 || offset != (1ull << 40)) return 18; + __asan_get_shadow_mapping(nullptr, nullptr); + __asan_get_shadow_mapping(&scale, nullptr); + __asan_get_shadow_mapping(nullptr, &offset); + __asan_get_shadow_mapping(&scale, &scale); + if (scale != offset) return 19; + } + + { + const std::array shadow{0, 3, -8, 7}; + if (FindFirstPoisoned_nid_no_patch(shadow.data(), shadow.size(), 0, 11).has_value()) return 2; + if (FindFirstPoisoned_nid_no_patch(shadow.data(), shadow.size(), 0, 16) != 11) return 3; + if (FindFirstPoisoned_nid_no_patch(shadow.data(), shadow.size(), 16, 1) != 16) return 4; + if (FindFirstPoisoned_nid_no_patch(shadow.data(), shadow.size(), 24, 8) != 31) return 5; + if (FindFirstPoisoned_nid_no_patch(nullptr, 0, 0, 0).has_value()) return 6; + try { + (void)FindFirstPoisoned_nid_no_patch(shadow.data(), shadow.size(), 31, 2); + return 7; + } catch (const std::exception&) { + } + try { + (void)FindFirstPoisoned_nid_no_patch(shadow.data(), shadow.size(), std::numeric_limits::max(), 2); + return 8; + } catch (const std::exception&) { + } + } + + { + std::array shadow{0, 0, 2, 0, 0}; + UpdateStackShadow_nid_no_patch(shadow.data(), shadow.size(), 8, 10, true); + if (shadow[0] != 0 || shadow[1] != -8 || shadow[2] != -8 || shadow[3] != 0) return 9; + UpdateStackShadow_nid_no_patch(shadow.data(), shadow.size(), 8, 10, false); + if (shadow[1] != 0 || shadow[2] != 2) return 10; + try { + UpdateStackShadow_nid_no_patch(shadow.data(), shadow.size(), 32, 9, true); + return 11; + } catch (const std::exception&) { + if (shadow[4] != 0) return 12; + } + } + struct Entry { + decltype(&__asan_set_shadow_00) fn; + std::uint8_t val; + }; + const Entry table[] = { + {__asan_set_shadow_00, 0x00}, {__asan_set_shadow_01, 0x01}, + {__asan_set_shadow_02, 0x02}, {__asan_set_shadow_03, 0x03}, + {__asan_set_shadow_04, 0x04}, {__asan_set_shadow_05, 0x05}, + {__asan_set_shadow_06, 0x06}, {__asan_set_shadow_07, 0x07}, + {__asan_set_shadow_f1, 0xf1}, {__asan_set_shadow_f2, 0xf2}, + {__asan_set_shadow_f3, 0xf3}, {__asan_set_shadow_f5, 0xf5}, + {__asan_set_shadow_f8, 0xf8} + }; + for (const auto& e : table) { + try { + e.fn(0, 8); + std::fprintf(stderr, "Null address did not throw\n"); + return 1; + } catch (const std::exception&) { + } + } + for (const auto& e : table) { + try { + e.fn(std::numeric_limits::max() - 1, 4); + std::fprintf(stderr, "Wrapped address range did not throw\n"); + return 1; + } catch (const std::exception&) { + } + } + std::array buf; + for (const auto& e : table) { + for (std::size_t off : {0ULL, 1ULL, 7ULL, 16ULL}) { + for (std::size_t len : {0ULL, 1ULL, 7ULL, 8ULL, 31ULL, 63ULL}) { + buf.fill(0xAA); + auto addr = reinterpret_cast(buf.data() + off); + e.fn(addr, len); + e.fn(addr, len); + for (std::size_t i = 0; i < buf.size(); ++i) { + std::uint8_t exp = (i >= off && i < off + len) ? e.val : 0xAA; + if (buf[i] != exp) { + std::fprintf(stderr, "Shadow byte verification error at %zu\n", i); + return 1; + } + } + } + } + } + return 0; +} diff --git a/core/libs/tests/test_addresssanitizer_legacy.py b/core/libs/tests/test_addresssanitizer_legacy.py new file mode 100644 index 000000000000..44b9a52cbcca --- /dev/null +++ b/core/libs/tests/test_addresssanitizer_legacy.py @@ -0,0 +1,42 @@ +import re +import subprocess +import sys + + +def run(executable, mode, status, patterns, reports): + result = subprocess.run([executable, mode], capture_output=True, text=True, timeout=10) + output = result.stdout + result.stderr + if result.returncode != status: + raise AssertionError(f"{mode}: exit {result.returncode}, expected {status}\n{output}") + for pattern in patterns: + if re.search(pattern, output) is None: + raise AssertionError(f"{mode}: missing {pattern!r}\n{output}") + if output.count("runtime error:") != reports: + raise AssertionError(f"{mode}: expected {reports} diagnostics\n{output}") + if output.count("death callback") != int(status == 1): + raise AssertionError(f"{mode}: unexpected death callback count\n{output}") + + +def main(): + executable = sys.argv[1] + run(executable, "ubsan_legacy_type", 0, [ + r"legacy.cpp:101:3: runtime error: load of null pointer of type 'int'", + r"legacy.cpp:102:7: runtime error: store to misaligned address 0x[0-9a-f]+ for type 'int', which requires 256 byte alignment", + r"legacy.cpp:103:9: runtime error: reference binding to address 0x[0-9a-f]+ with insufficient space for an object of type 'int'", + r"legacy.cpp:104:11: runtime error: member access within address 0x[0-9a-f]+ with insufficient space for an object of type 'int'", + r"legacy type returned", + ], 4) + run(executable, "ubsan_legacy_return", 0, [ + r"legacy.cpp:201:5: runtime error: null pointer returned from function declared to never return null", + r"legacy.h:8:2: note: returns_nonnull attribute specified here", + r"legacy.cpp:202:6: runtime error: null pointer returned from function declared to never return null", + r"legacy return returned", + ], 2) + for kind, diagnostic in [("type", "load of null pointer of type 'int'"), ("return", "null pointer returned from function declared to never return null")]: + run(executable, f"ubsan_legacy_{kind}_abort", 1, [diagnostic, "SUMMARY: UndefinedBehaviorSanitizer:"], 1) + run(executable, f"ubsan_legacy_{kind}_repeat_abort", 1, [diagnostic, "SUMMARY: UndefinedBehaviorSanitizer:"], 2) + print("legacy UBSan diagnostics, deduplication and fatal exits passed") + + +if __name__ == "__main__": + main() diff --git a/docs/dev/debt/libSceAddressSanitizer.md b/docs/dev/debt/libSceAddressSanitizer.md index d8397ff9ee93..a5917626c28f 100644 --- a/docs/dev/debt/libSceAddressSanitizer.md +++ b/docs/dev/debt/libSceAddressSanitizer.md @@ -2,4 +2,29 @@ ### Unknown function info -- [__asan_addr_is_in_fake_stack, __asan_address_is_poisoned, __asan_after_dynamic_init, __asan_aligned_alloc, __asan_alloca_poison, __asan_allocas_unpoison, __asan_before_dynamic_init, __asan_calloc, __asan_current_error_report, __asan_current_error_report_size, __asan_describe_address, __asan_destroy_fake_stack, __asan_exp_load1, __asan_exp_load16, __asan_exp_load16_noabort, __asan_exp_load1_noabort, __asan_exp_load2, __asan_exp_load2_noabort, __asan_exp_load4, __asan_exp_load4_noabort, __asan_exp_load8, __asan_exp_load8_noabort, __asan_exp_loadN, __asan_exp_loadN_noabort, __asan_exp_store1, __asan_exp_store16, __asan_exp_store16_noabort, __asan_exp_store1_noabort, __asan_exp_store2, __asan_exp_store2_noabort, __asan_exp_store4, __asan_exp_store4_noabort, __asan_exp_store8, __asan_exp_store8_noabort, __asan_exp_storeN, __asan_exp_storeN_noabort, __asan_free, __asan_get_alloc_stack, __asan_get_current_fake_stack, __asan_get_free_stack, __asan_get_report_access_size, __asan_get_report_access_type, __asan_get_report_address, __asan_get_report_bp, __asan_get_report_description, __asan_get_report_pc, __asan_get_report_sp, __asan_get_shadow_mapping, __asan_handle_no_return, __asan_init, __asan_init_v5, __asan_load1, __asan_load16, __asan_load16_noabort, __asan_load1_noabort, __asan_load2, __asan_load2_noabort, __asan_load4, __asan_load4_noabort, __asan_load8, __asan_load8_noabort, __asan_loadN, __asan_loadN_noabort, __asan_load_cxx_array_cookie, __asan_locate_address, __asan_malloc, __asan_malloc_stats, __asan_malloc_usable_size, __asan_memalign, __asan_memcpy, __asan_memmove, __asan_memset, __asan_option_detect_stack_use_after_return, __asan_poison_cxx_array_cookie, __asan_poison_intra_object_redzone, __asan_poison_memory_region, __asan_poison_stack_memory, __asan_posix_memalign, __asan_print_accumulated_stats, __asan_realloc, __asan_reallocalign, __asan_region_is_poisoned, __asan_register_elf_globals, __asan_register_globals, __asan_register_image_globals, __asan_report_error, __asan_report_exp_load1, __asan_report_exp_load16, __asan_report_exp_load16_noabort, __asan_report_exp_load1_noabort, __asan_report_exp_load2, __asan_report_exp_load2_noabort, __asan_report_exp_load4, __asan_report_exp_load4_noabort, __asan_report_exp_load8, __asan_report_exp_load8_noabort, __asan_report_exp_load_n, __asan_report_exp_load_n_noabort, __asan_report_exp_store1, __asan_report_exp_store16, __asan_report_exp_store16_noabort, __asan_report_exp_store1_noabort, __asan_report_exp_store2, __asan_report_exp_store2_noabort, __asan_report_exp_store4, __asan_report_exp_store4_noabort, __asan_report_exp_store8, __asan_report_exp_store8_noabort, __asan_report_exp_store_n, __asan_report_exp_store_n_noabort, __asan_report_load1, __asan_report_load16, __asan_report_load16_noabort, __asan_report_load1_noabort, __asan_report_load2, __asan_report_load2_noabort, __asan_report_load4, __asan_report_load4_noabort, __asan_report_load8, __asan_report_load8_noabort, __asan_report_load_n, __asan_report_load_n_noabort, __asan_report_present, __asan_report_store1, __asan_report_store16, __asan_report_store16_noabort, __asan_report_store1_noabort, __asan_report_store2, __asan_report_store2_noabort, __asan_report_store4, __asan_report_store4_noabort, __asan_report_store8, __asan_report_store8_noabort, __asan_report_store_n, __asan_report_store_n_noabort, __asan_set_error_report_callback, __asan_set_shadow_00, __asan_set_shadow_01, __asan_set_shadow_02, __asan_set_shadow_03, __asan_set_shadow_04, __asan_set_shadow_05, __asan_set_shadow_06, __asan_set_shadow_07, __asan_set_shadow_f1, __asan_set_shadow_f2, __asan_set_shadow_f3, __asan_set_shadow_f5, __asan_set_shadow_f8, __asan_stack_free_0, __asan_stack_free_1, __asan_stack_free_10, __asan_stack_free_2, __asan_stack_free_3, __asan_stack_free_4, __asan_stack_free_5, __asan_stack_free_6, __asan_stack_free_7, __asan_stack_free_8, __asan_stack_free_9, __asan_stack_malloc_0, __asan_stack_malloc_1, __asan_stack_malloc_10, __asan_stack_malloc_2, __asan_stack_malloc_3, __asan_stack_malloc_4, __asan_stack_malloc_5, __asan_stack_malloc_6, __asan_stack_malloc_7, __asan_stack_malloc_8, __asan_stack_malloc_9, __asan_stack_malloc_always_0, __asan_stack_malloc_always_1, __asan_stack_malloc_always_10, __asan_stack_malloc_always_2, __asan_stack_malloc_always_3, __asan_stack_malloc_always_4, __asan_stack_malloc_always_5, __asan_stack_malloc_always_6, __asan_stack_malloc_always_7, __asan_stack_malloc_always_8, __asan_stack_malloc_always_9, __asan_store1, __asan_store16, __asan_store16_noabort, __asan_store1_noabort, __asan_store2, __asan_store2_noabort, __asan_store4, __asan_store4_noabort, __asan_store8, __asan_store8_noabort, __asan_storeN, __asan_storeN_noabort, __asan_unpoison_intra_object_redzone, __asan_unpoison_memory_region, __asan_unpoison_stack_memory, __asan_unregister_elf_globals, __asan_unregister_globals, __asan_unregister_image_globals, __asan_update_allocation_context, __asan_version_mismatch_check_v6, __asan_version_mismatch_check_v7, __asan_version_mismatch_check_v8, __sancov_default_options, __sanitizer_annotate_contiguous_container, __sanitizer_annotate_double_ended_contiguous_container, __sanitizer_contiguous_container_find_bad_address, __sanitizer_cov_dump, __sanitizer_cov_trace_pc_guard, __sanitizer_cov_trace_pc_guard_init, __sanitizer_double_ended_contiguous_container_find_bad_address, __sanitizer_dump_coverage, __sanitizer_dump_trace_pc_guard_coverage, __sanitizer_finish_switch_fiber, __sanitizer_free_hook, __sanitizer_get_allocated_begin, __sanitizer_get_allocated_size, __sanitizer_get_allocated_size_fast, __sanitizer_get_current_allocated_bytes, __sanitizer_get_estimated_allocated_size, __sanitizer_get_free_bytes, __sanitizer_get_heap_size, __sanitizer_get_ownership, __sanitizer_get_report_path, __sanitizer_get_unmapped_bytes, __sanitizer_malloc_hook, __sanitizer_print_stack_trace, __sanitizer_ptr_cmp, __sanitizer_ptr_sub, __sanitizer_purge_allocator, __sanitizer_sandbox_on_notify, __sanitizer_set_death_callback, __sanitizer_set_report_fd, __sanitizer_set_report_path, __sanitizer_start_switch_fiber, __sanitizer_symbolize_global, __sanitizer_symbolize_pc, __sanitizer_unaligned_load16, __sanitizer_unaligned_load32, __sanitizer_unaligned_load64, __sanitizer_unaligned_store16, __sanitizer_unaligned_store32, __sanitizer_unaligned_store64, __sanitizer_verify_contiguous_container, __sanitizer_verify_double_ended_contiguous_container, __ubsan_current_error_report, __ubsan_current_error_report_size, __ubsan_default_options, __ubsan_get_current_report_data, __ubsan_handle_add_overflow, __ubsan_handle_add_overflow_abort, __ubsan_handle_alignment_assumption, __ubsan_handle_alignment_assumption_abort, __ubsan_handle_builtin_unreachable, __ubsan_handle_divrem_overflow, __ubsan_handle_divrem_overflow_abort, __ubsan_handle_dynamic_type_cache_miss, __ubsan_handle_dynamic_type_cache_miss_abort, __ubsan_handle_float_cast_overflow, __ubsan_handle_float_cast_overflow_abort, __ubsan_handle_function_type_mismatch, __ubsan_handle_function_type_mismatch_abort, __ubsan_handle_function_type_mismatch_v1, __ubsan_handle_function_type_mismatch_v1_abort, __ubsan_handle_implicit_conversion, __ubsan_handle_implicit_conversion_abort, __ubsan_handle_invalid_builtin, __ubsan_handle_invalid_builtin_abort, __ubsan_handle_load_invalid_value, __ubsan_handle_load_invalid_value_abort, __ubsan_handle_missing_return, __ubsan_handle_mul_overflow, __ubsan_handle_mul_overflow_abort, __ubsan_handle_negate_overflow, __ubsan_handle_negate_overflow_abort, __ubsan_handle_nonnull_arg, __ubsan_handle_nonnull_arg_abort, __ubsan_handle_nonnull_return, __ubsan_handle_nonnull_return_abort, __ubsan_handle_nonnull_return_v1, __ubsan_handle_nonnull_return_v1_abort, __ubsan_handle_nullability_arg, __ubsan_handle_nullability_arg_abort, __ubsan_handle_nullability_return_v1, __ubsan_handle_nullability_return_v1_abort, __ubsan_handle_out_of_bounds, __ubsan_handle_out_of_bounds_abort, __ubsan_handle_pointer_overflow, __ubsan_handle_pointer_overflow_abort, __ubsan_handle_shift_out_of_bounds, __ubsan_handle_shift_out_of_bounds_abort, __ubsan_handle_sub_overflow, __ubsan_handle_sub_overflow_abort, __ubsan_handle_type_mismatch, __ubsan_handle_type_mismatch_abort, __ubsan_handle_type_mismatch_v1, __ubsan_handle_type_mismatch_v1_abort, __ubsan_handle_vla_bound_not_positive, __ubsan_handle_vla_bound_not_positive_abort, __ubsan_vptr_type_cache](../../../core/libs/prx/libSceAddressSanitizer/Export.cpp) (libSceAddressSanitizer) - names and NIDs verified from pinned [ps5rs stubs](https://github.com/claimore22/ps5rs/tree/5f252a658ff470bcb2b6cd15205fd8ca64ae4477/data/stubs/by_library) (`libSceAddressSanitizer_nosubmission.txt`), with NID match confirmed via `tools/nid_names.py` `compute_nid`. Signatures, parameter layouts, and runtime behavior remain unverified; all paths throw through `NotImplemented_nid_no_patch`. +- [__asan_current_error_report](../../../core/libs/prx/libSceAddressSanitizer/Export.cpp) (libSceAddressSanitizer) - absent from [LLVM 18.1.8](https://github.com/llvm/llvm-project/tree/llvmorg-18.1.8/compiler-rt/lib); signature and behaviour unknown, so it throws; name and NID from [ps5rs](https://github.com/claimore22/ps5rs/tree/5f252a658ff470bcb2b6cd15205fd8ca64ae4477/data/stubs/by_library) +- [__asan_current_error_report_size](../../../core/libs/prx/libSceAddressSanitizer/Export.cpp) (libSceAddressSanitizer) - absent from [LLVM 18.1.8](https://github.com/llvm/llvm-project/tree/llvmorg-18.1.8/compiler-rt/lib); signature and behaviour unknown, so it throws; name and NID from [ps5rs](https://github.com/claimore22/ps5rs/tree/5f252a658ff470bcb2b6cd15205fd8ca64ae4477/data/stubs/by_library) +- [__asan_destroy_fake_stack](../../../core/libs/prx/libSceAddressSanitizer/Export.cpp) (libSceAddressSanitizer) - absent from [LLVM 18.1.8](https://github.com/llvm/llvm-project/tree/llvmorg-18.1.8/compiler-rt/lib); signature and behaviour unknown, so it throws; name and NID from [ps5rs](https://github.com/claimore22/ps5rs/tree/5f252a658ff470bcb2b6cd15205fd8ca64ae4477/data/stubs/by_library) +- [__asan_init_v5](../../../core/libs/prx/libSceAddressSanitizer/Export.cpp) (libSceAddressSanitizer) - the [LLVM 3.6](https://github.com/llvm/llvm-project/blob/llvmorg-3.6.0/compiler-rt/lib/asan/asan_interface_internal.h) initializer uses seven-word global descriptors, while this runtime reads the eight-word descriptors of LLVM 18.1.8. ABI v5 registration and report callbacks are unsupported, so it throws instead of initializing an incompatible runtime. +- [__asan_malloc_stats](../../../core/libs/prx/libSceAddressSanitizer/Export.cpp) (libSceAddressSanitizer) - absent from [LLVM 18.1.8](https://github.com/llvm/llvm-project/tree/llvmorg-18.1.8/compiler-rt/lib); signature and behaviour unknown, so it throws; name and NID from [ps5rs](https://github.com/claimore22/ps5rs/tree/5f252a658ff470bcb2b6cd15205fd8ca64ae4477/data/stubs/by_library) +- [__asan_reallocalign](../../../core/libs/prx/libSceAddressSanitizer/Export.cpp) (libSceAddressSanitizer) - absent from [LLVM 18.1.8](https://github.com/llvm/llvm-project/tree/llvmorg-18.1.8/compiler-rt/lib); signature and behaviour unknown, so it throws; name and NID from [ps5rs](https://github.com/claimore22/ps5rs/tree/5f252a658ff470bcb2b6cd15205fd8ca64ae4477/data/stubs/by_library) +- [__asan_register_image_globals](../../../core/libs/prx/libSceAddressSanitizer/Export.cpp) (libSceAddressSanitizer) - needs the lookup of the instrumented globals section of a loaded image, which [LLVM 18.1.8](https://github.com/llvm/llvm-project/tree/llvmorg-18.1.8/compiler-rt/lib) implements only for Windows and Mach-O, so it throws; `__asan_register_elf_globals` is implemented +- [__asan_unregister_image_globals](../../../core/libs/prx/libSceAddressSanitizer/Export.cpp) (libSceAddressSanitizer) - needs the lookup of the instrumented globals section of a loaded image, which [LLVM 18.1.8](https://github.com/llvm/llvm-project/tree/llvmorg-18.1.8/compiler-rt/lib) implements only for Windows and Mach-O, so it throws; `__asan_unregister_elf_globals` is implemented +- [__ubsan_current_error_report](../../../core/libs/prx/libSceAddressSanitizer/Export.cpp) (libSceAddressSanitizer) - absent from [LLVM 18.1.8](https://github.com/llvm/llvm-project/tree/llvmorg-18.1.8/compiler-rt/lib); signature and behaviour unknown, so it throws; name and NID from [ps5rs](https://github.com/claimore22/ps5rs/tree/5f252a658ff470bcb2b6cd15205fd8ca64ae4477/data/stubs/by_library) +- [__ubsan_current_error_report_size](../../../core/libs/prx/libSceAddressSanitizer/Export.cpp) (libSceAddressSanitizer) - absent from [LLVM 18.1.8](https://github.com/llvm/llvm-project/tree/llvmorg-18.1.8/compiler-rt/lib); signature and behaviour unknown, so it throws; name and NID from [ps5rs](https://github.com/claimore22/ps5rs/tree/5f252a658ff470bcb2b6cd15205fd8ca64ae4477/data/stubs/by_library) +- [__ubsan_handle_dynamic_type_cache_miss](../../../core/libs/prx/libSceAddressSanitizer/Export.cpp) (libSceAddressSanitizer) - needs the C++ type hash cache of [LLVM 18.1.8](https://github.com/llvm/llvm-project/tree/llvmorg-18.1.8/compiler-rt/lib) and the console RTTI layout, which is unverified, so it throws +- [__ubsan_handle_dynamic_type_cache_miss_abort](../../../core/libs/prx/libSceAddressSanitizer/Export.cpp) (libSceAddressSanitizer) - needs the C++ type hash cache of [LLVM 18.1.8](https://github.com/llvm/llvm-project/tree/llvmorg-18.1.8/compiler-rt/lib) and the console RTTI layout, which is unverified, so it throws +- [__ubsan_handle_function_type_mismatch_v1](../../../core/libs/prx/libSceAddressSanitizer/Export.cpp) (libSceAddressSanitizer) - the [GCC 15.2 compatibility handler](https://github.com/gcc-mirror/gcc/blob/releases/gcc-15.2.0/libsanitizer/ubsan/ubsan_handlers_cxx.cpp) takes data, a function address and two RTTI pointers. Console RTTI equality rules are unverified, so it throws; the two-argument `__ubsan_handle_function_type_mismatch` is implemented. +- [__ubsan_handle_function_type_mismatch_v1_abort](../../../core/libs/prx/libSceAddressSanitizer/Export.cpp) (libSceAddressSanitizer) - the [GCC 15.2 compatibility handler](https://github.com/gcc-mirror/gcc/blob/releases/gcc-15.2.0/libsanitizer/ubsan/ubsan_handlers_cxx.cpp) takes data, a function address and two RTTI pointers. Console RTTI equality rules are unverified, so it throws; the two-argument `__ubsan_handle_function_type_mismatch` is implemented. + +### Functional + +- [Shadow memory](../../../core/libs/prx/libSceAddressSanitizer/src/ShadowAddressSpace.hpp) (libSceAddressSanitizer) - the console mapping is unverified; the first export that touches the shadow reserves the PlayStation mapping of [LLVM 18.1.8](https://github.com/llvm/llvm-project/blob/llvmorg-18.1.8/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp) (scale 3, offset `1 << 40`) or `__asan_init`. Ranges reaching above `1 << 47` or into the shadow throw. Windows reserves only the free parts of the shadow range; runtime exports that need shadow the host already holds throw, but instrumented code that touches it inline reads or writes that host memory. A concurrent protection change can race with Windows page commitment, and the Linux mapping has not been run. Other POSIX hosts without `MAP_FIXED_NOREPLACE`, such as macOS, build the same backend but reserve no shadow, so every export that needs it throws. +- [Runtime state](../../../core/libs/prx/libSceAddressSanitizer/Export.cpp) (libSceAddressSanitizer) - threads are numbered by first use instead of being registered, option parsing is missing, and the stack bounds come from the host thread, so a clean shadow does not prove an address is valid. Exports that read options use the [LLVM 18.1.8](https://github.com/llvm/llvm-project/blob/llvmorg-18.1.8/compiler-rt/lib/asan/asan_flags.inc) defaults (`allow_user_poisoning`, `poison_array_cookie`, `poison_partial` and `halt_on_error` true; `check_initialization_order` and `detect_stack_use_after_return` false), so `__asan_before_dynamic_init` and `__asan_after_dynamic_init` do nothing; the exported `__asan_option_detect_stack_use_after_return` starts at 0 and gates fake-stack creation, with Linux retaining its cached fake stack; guest overrides of `__asan_default_options` and of the default hooks are ignored. +- [Allocator](../../../core/libs/prx/libSceAddressSanitizer/src/Allocator.hpp) (libSceAddressSanitizer) - blocks come from host virtual-memory reservations on Windows and `operator new` on Linux, not the console allocator, and the quarantine is one global 256 MiB list without thread caches. Windows reserves each backing block separately with `VirtualAlloc2` and does not pool pages. Recycled blocks return to the host and their shadow is cleared rather than kept poisoned. Allocation and free keep only the caller address as their stack, so `__asan_get_alloc_stack` and `__asan_get_free_stack` return one frame. `allocator_may_return_null`, `max_allocation_size_mb`, the malloc hooks and `new`/`delete` mismatch checks are missing, so failures abort, and `__asan_print_accumulated_stats` omits the StackDepot and allocator lines. +- [Globals and fake stacks](../../../core/libs/prx/libSceAddressSanitizer/src/Globals.hpp) (libSceAddressSanitizer) - registration keeps a copy of each global, drops it on unregistration and records no registration stack, so ODR reports have none. A fake stack is created per thread with the log of the host stack size clamped to 16..20, and `__asan_handle_no_return` unpoisons from the caller to the host stack top; both throw if the host cannot report the stack. Stack addresses are recognised only by their shadow magic and are attributed to the calling thread. Fiber switches track the stack bounds but not the console fiber layout. +- [Reports and symbolizer](../../../core/libs/prx/libSceAddressSanitizer/src/ReportFile.hpp) (libSceAddressSanitizer) - there is no symbolizer, so frames show the module and offset only and `__sanitizer_symbolize_global` returns an empty string. The unwinder follows only frames with host unwind data (Windows) or glibc `backtrace` (Linux, unrun). `__sanitizer_set_report_fd` does not close the previous descriptor and the parent directories of a report path are not created. `coverage` is off as in [LLVM 18.1.8](https://github.com/llvm/llvm-project/blob/llvmorg-18.1.8/compiler-rt/lib/sanitizer_common/sanitizer_coverage_libcdep_new.cpp), so only `__sanitizer_dump_coverage` writes `.sancov` files, to the working directory. +- [Error reports](../../../core/libs/prx/libSceAddressSanitizer/Export.cpp) (libSceAddressSanitizer) - unlike [LLVM 18.1.8](https://github.com/llvm/llvm-project/blob/llvmorg-18.1.8/compiler-rt/lib/asan/asan_errors.cpp), access reports omit the pid prefix, stack trace, address description and summary line and name every thread `T-1`; allocator, global and UBSan reports keep the text but have no stack trace and no pid prefix; `_noabort` callbacks also exit with code 1; a misaligned 16-byte check also reports a poisoned third granule, which the LLVM fast path skips. The console report text and exit path are unverified. +- [Signatures and defaults](../../../core/libs/prx/libSceAddressSanitizer/include/Api.hpp) (libSceAddressSanitizer) - implemented exports take the signatures of the LLVM 18.1.8 public sanitizer headers and compiler-emitted callbacks, with the legacy type-mismatch and nonnull-return layouts from [LLVM 3.8](https://github.com/llvm/llvm-project/blob/llvmorg-3.8.0/compiler-rt/lib/ubsan/ubsan_handlers.h), and the empty default options, empty hooks, zero `__sanitizer_get_unmapped_bytes` and empty version mismatch checks of LLVM 18.1.8; the console ABI and values are unverified. + +- [RTTI cache](../../../core/libs/prx/libSceAddressSanitizer/include/Api.hpp) (libSceAddressSanitizer) - `__ubsan_vptr_type_cache` is an exported zero-initialized array of 128 pointer-sized hashes, as in [LLVM 18.1.8](https://github.com/llvm/llvm-project/blob/llvmorg-18.1.8/compiler-rt/lib/ubsan/ubsan_type_hash.h). The dynamic-type miss handlers still throw, so the runtime cannot validate or populate cache entries. Console RTTI validation is unverified. diff --git a/tools/package_release.py b/tools/package_release.py index 4a39a4b7c7fb..434e2968c630 100644 --- a/tools/package_release.py +++ b/tools/package_release.py @@ -78,6 +78,12 @@ def package(platform, build, output, version): licenses.append((ROOT / "3rdparty/vorbis/COPYING", "libs/licenses/vorbis.txt")) if expected & {"libSceOpusDec.prx", "libSceOpusCeltDec.prx"}: licenses.append((ROOT / "3rdparty/opus/COPYING", "libs/licenses/opus.txt")) + if "libSceAddressSanitizer.prx" in expected: + licenses.extend((ROOT / source, destination) for source, destination in ( + ("3rdparty/compiler-rt/LICENSE.TXT", "libs/licenses/compiler-rt.txt"), + ("3rdparty/compiler-rt/lib/asan_anyps5/NOTICE", "libs/licenses/compiler-rt-anyps5-notice.txt"), + ("3rdparty/compiler-rt/lib/asan_anyps5/LICENSE.GPL-2.0", "libs/licenses/compiler-rt-anyps5-gpl2.txt"), + )) if platform == "windows": runtime = windows_runtime(build) files.extend(runtime / name for name in ("libgcc_s_seh-1.dll", "libstdc++-6.dll", "libwinpthread-1.dll")) diff --git a/tools/tests/test_package_release.py b/tools/tests/test_package_release.py index 60086a337b67..1fab2711e498 100644 --- a/tools/tests/test_package_release.py +++ b/tools/tests/test_package_release.py @@ -143,6 +143,42 @@ def setUp(self): self.addCleanup(patch.stopall) patch.object(package_release, "ROOT", self.source, create=True).start() + def test_sanitizer_notices_in_patched_and_unpatched_archives(self): + (self.source / "core/libs/prx/libSceAddressSanitizer").mkdir() + (self.unpatched.parent / "libSceAddressSanitizer.prx").write_bytes(b"unpatched sanitizer") + (self.library.parent / "libSceAddressSanitizer.prx").write_bytes(b"sanitizer") + notices = { + "LICENSE.TXT": ("compiler-rt.txt", b"upstream compiler-rt licence"), + "lib/asan_anyps5/NOTICE": ("compiler-rt-anyps5-notice.txt", b"modified port source attribution"), + "lib/asan_anyps5/LICENSE.GPL-2.0": ("compiler-rt-anyps5-gpl2.txt", b"port GPLv2 licence"), + } + for source, (_, content) in notices.items(): + path = self.source / "3rdparty/compiler-rt" / source + path.parent.mkdir(parents=True, exist_ok=True) + path.write_bytes(content) + package_release.package("linux", self.build, self.output, "v1") + for stem in ("prx-linux-v1", "prx-linux-unpatched-v1"): + with zipfile.ZipFile(self.output / f"{stem}.zip") as archive: + for name, content in notices.values(): + self.assertEqual(archive.read(f"libs/licenses/{name}"), content) + with tarfile.open(self.output / f"{stem}.tar.gz") as archive: + for name, content in notices.values(): + self.assertEqual(archive.extractfile(f"libs/licenses/{name}").read(), content) + for source in notices: + path = self.source / "3rdparty/compiler-rt" / source + content = path.read_bytes() + for replacement in (None, b""): + with self.subTest(source=source, replacement=replacement): + if replacement is None: + path.unlink() + else: + path.write_bytes(replacement) + before = {file.name: file.read_bytes() for file in self.output.iterdir()} + with self.assertRaisesRegex(RuntimeError, "Missing or empty release file"): + package_release.package("linux", self.build, self.output, "v1") + self.assertEqual(before, {file.name: file.read_bytes() for file in self.output.iterdir()}) + path.write_bytes(content) + def test_unpatched_archives_preserve_originals_and_exclude_stale_files(self): (self.unpatched.parent / "libRemoved.prx").write_bytes(b"obsolete") before = {path: (path.read_bytes(), path.stat().st_mtime_ns) for path in (self.library, self.unpatched, self.implib)}