mirror of
https://github.com/boykopovar/AnyPS5.git
synced 2026-11-05 13:20:11 +00:00
feat(libc): implement std::_Throw(const std::bad_array_new_length&)
Follow the console libc.prx (PPSA02530) at 0xcb2d0: ignore the argument and throw the static bad_array_new_length object. Star Wars Racer (PPSA28416) imports it.
This commit is contained in:
1 parent
3a2b919816
commit
c7b70f44b0
5 files changed
+45
No files matched your search
@@ -1079,6 +1079,15 @@ if(BUILD_TESTING)
|
||||
set_tests_properties(guest_underflow_error PROPERTIES ENVIRONMENT_MODIFICATION
|
||||
"PATH=path_list_prepend:$<TARGET_FILE_DIR:libc>")
|
||||
endif()
|
||||
add_test_executable(guest_throw_bad_array_new_length_tests ${LIBS_INCLUDE_DIR}/tests/GuestThrowBadArrayNewLength.cpp)
|
||||
target_include_directories(guest_throw_bad_array_new_length_tests PRIVATE ${LIBS_INCLUDE_DIR})
|
||||
target_link_libraries(guest_throw_bad_array_new_length_tests PRIVATE libc)
|
||||
configure_windows_unwind(guest_throw_bad_array_new_length_tests)
|
||||
add_test(NAME guest_throw_bad_array_new_length COMMAND guest_throw_bad_array_new_length_tests)
|
||||
if(WIN32)
|
||||
set_tests_properties(guest_throw_bad_array_new_length PROPERTIES ENVIRONMENT_MODIFICATION
|
||||
"PATH=path_list_prepend:$<TARGET_FILE_DIR:libc>")
|
||||
endif()
|
||||
if(WIN32)
|
||||
add_test_executable(exception_personality_tests ${LIBS_INCLUDE_DIR}/tests/ExceptionPersonality.cpp)
|
||||
target_include_directories(exception_personality_tests PRIVATE ${LIBS_INCLUDE_DIR})
|
||||
|
||||
@@ -1404,6 +1404,7 @@ int APS5_VABI dl_iterate_phdr_nid_postfix(int (*callback)(dl_phdr_info*, std::si
|
||||
[[noreturn]] void APS5_VABI __cxa_bad_cast_nid_postfix();
|
||||
[[noreturn]] void APS5_VABI __cxa_bad_typeid_nid_postfix();
|
||||
[[noreturn]] void APS5_VABI __cxa_throw_bad_array_new_length_nid_postfix();
|
||||
[[noreturn]] void APS5_VABI _ZSt6_ThrowRKSt20bad_array_new_length_nid_postfix(const LibcException::ExceptionObject* error);
|
||||
[[noreturn]] void APS5_VABI _ZSt11_Xbad_allocv_nid_postfix();
|
||||
[[noreturn]] void APS5_VABI _ZSt14_Xout_of_rangePKc_nid_postfix(const char* message);
|
||||
[[noreturn]] void APS5_VABI _ZSt14_Xlength_errorPKc_nid_postfix(const char* message);
|
||||
|
||||
@@ -551,6 +551,7 @@ const char* APS5_VABI _ZNKSt8ios_base7failure4whatEv_nid_postfix(const LibcExcep
|
||||
[[noreturn]] void APS5_VABI __cxa_bad_cast_nid_postfix() { LibcException::ThrowPlain(_ZTVSt8bad_cast_nid_postfix); }
|
||||
[[noreturn]] void APS5_VABI __cxa_bad_typeid_nid_postfix() { LibcException::ThrowPlain(_ZTVSt10bad_typeid_nid_postfix); }
|
||||
[[noreturn]] void APS5_VABI __cxa_throw_bad_array_new_length_nid_postfix() { LibcException::ThrowPlain(_ZTVSt20bad_array_new_length_nid_postfix); }
|
||||
[[noreturn]] void APS5_VABI _ZSt6_ThrowRKSt20bad_array_new_length_nid_postfix(const LibcException::ExceptionObject*) { LibcException::ThrowPlain(_ZTVSt20bad_array_new_length_nid_postfix); }
|
||||
[[noreturn]] void APS5_VABI _ZSt11_Xbad_allocv_nid_postfix() { LibcException::ThrowPlain(_ZTVSt9bad_alloc_nid_postfix); }
|
||||
[[noreturn]] void APS5_VABI _ZSt14_Xout_of_rangePKc_nid_postfix(const char* message) { LibcException::ThrowMessage(_ZTVSt12out_of_range_nid_postfix, message); }
|
||||
[[noreturn]] void APS5_VABI _ZSt14_Xlength_errorPKc_nid_postfix(const char* message) { LibcException::ThrowMessage(_ZTVSt12length_error_nid_postfix, message); }
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
#include "prx/libc/include/Api.hpp"
|
||||
#include "prx/libc/include/general/VabiMacros.hpp"
|
||||
#include <cstddef>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
struct TypeRecord { const void* const* vtable; const char* name; const TypeRecord* base; };
|
||||
struct Vtable { std::ptrdiff_t offset; const TypeRecord* type; const void* destroy; const void* deleteObject; const char* (APS5_VABI *what)(const LibcException::ExceptionObject*); };
|
||||
|
||||
extern "C" {
|
||||
extern const TypeRecord _ZTISt9bad_alloc_nid_postfix;
|
||||
extern const TypeRecord _ZTISt20bad_array_new_length_nid_postfix;
|
||||
extern const Vtable _ZTVSt20bad_array_new_length_nid_postfix;
|
||||
}
|
||||
|
||||
static void Require(bool value) { if (!value) std::abort(); }
|
||||
|
||||
int main() {
|
||||
const auto& type = _ZTISt20bad_array_new_length_nid_postfix;
|
||||
Require(std::strcmp(type.name, "St20bad_array_new_length") == 0);
|
||||
Require(type.base == &_ZTISt9bad_alloc_nid_postfix);
|
||||
const auto& table = _ZTVSt20bad_array_new_length_nid_postfix;
|
||||
Require(table.offset == 0 && table.type == &type && table.what != nullptr);
|
||||
|
||||
bool thrown = false;
|
||||
try {
|
||||
_ZSt6_ThrowRKSt20bad_array_new_length_nid_postfix(nullptr);
|
||||
} catch (...) {
|
||||
thrown = true;
|
||||
}
|
||||
Require(thrown);
|
||||
return 0;
|
||||
}
|
||||
@@ -191,6 +191,7 @@
|
||||
- [std::clog, std::wclog and the facet ids](../../../core/libs/prx/libc/src/LocaleSupport.cpp) (libc): `std::clog` and `std::wclog` are 0x400-byte zeroed objects like the rest of the `NSTDSTR` stream set (the console's `libc.prx` sizes `std::clog` at 96 bytes, measured from its dynsym `st_size`), and the `numpunct<char>::id` and `time_put<char>::id` objects are 8-byte zeros like the other facet ids.
|
||||
- [std::__throw_bad_variant_access](../../../core/libs/prx/libc/src/exception/StandardExceptions.cpp) (libc) throws `std::bad_variant_access` with the `what()` string `bad_variant_access`, the one [LLVM libc++](https://github.com/llvm/llvm-project/blob/main/libcxx/src/variant.cpp) returns, since the export carries libc++'s `__throw_bad_variant_access` name; the console's string is unverified. Onimusha: Way of the Sword (PPSA27836 01.000.001) imports it from `libc`, and its bundled `libc.prx` does not export it.
|
||||
- [std::bad_optional_access and std::_Throw_bad_optional_access](../../../core/libs/prx/libc/src/exception/StandardExceptions.cpp) (libc) provide the exception type, constructor, destructor, and `what()` exports alongside `_Throw_bad_optional_access`, returning the `what()` string `bad_optional_access` matching Dinkumware and libc++ conventions; the console libc.prx string is unverified. PPSA26578 (issue #7624) and PPSA34015 import `_ZSt26_Throw_bad_optional_accessv` (`KwzEip7m6TM`) from `libc`.
|
||||
- [std::_Throw(const std::bad_array_new_length&)](../../../core/libs/prx/libc/src/exception/StandardExceptions.cpp) (libc, NID `1cKlQv7Kvmg`) is a 52-byte function at `0xcb2d0` in the `libc.prx` bundled with PPSA02530: it ignores its argument, allocates the 8-byte exception object with the static `_ZTVSt20bad_array_new_length`, and throws it. Star Wars Racer (PPSA28416) imports it from `libc`.
|
||||
- [The scanf family](../../../core/libs/prx/libc/src/Formatting.cpp) (libc), the `_s` forms included, decodes the input of the 16-bit wide conversions (`%ls`, `%lc`, `%l[`, `%S`, `%C`) on Linux as UTF-8, mirroring the narrow printf family, where FreeBSD uses the locale's `mbrtowc` (one byte per character in the C locale); the console's locale encoding is unverified. Input that is not UTF-8, a character outside the BMP, a scanset member outside ASCII, positional arguments next to a wide conversion and wide conversions in `fscanf` throw. Each character is stored as one 16-bit unit, widths and `_s` sizes count characters, and a `%lc` field cut short by the end of the input keeps what it read, as FreeBSD's `convert_wchar` does. Windows hands `%ls`, `%lc` and `%l[` to the host, whose `wchar_t` is 16 bits
|
||||
- [The scanf family](../../../core/libs/prx/libc/include/WindowsScanning.hpp) (libc) on Windows returns 0, as C17 and FreeBSD do, when input fails after only suppressed conversions have completed (`sscanf("12", "%*d%d", &value)`). Linux hands the format to glibc, which returns `EOF` there. On Windows the host stops a `%x`, `%X`, `%i` or `%p` after the `x` of a `0x` that no hex digit follows (or that the width cuts off), and a float conversion (`%e`, `%f`, `%g`, `%a`) after the `e` of an exponent with no digits (`1e`), where C17 and FreeBSD stop before the `x` or the `e`
|
||||
- [The scanf family](../../../core/libs/prx/libc/src/Formatting.cpp) (libc) on Linux reads a `q` length as `ll`, as glibc does. On Windows a `q` directive ends the scan with nothing stored, as the console's own libc does for `%qd`; FreeBSD 11.4's source reads it as `ll`.
|
||||
|
||||
Reference in new issue
Block a user