Merge pull request #8702 from nikowolf123/feat/libcinternal-underscore-err-warn-progname

feat(libSceLibcInternal): export _err, _warn and _getprogname
This commit is contained in:
Dean authored and GitHub committed 2026-10-24 03:25:55 +13:00
commit efc6cd8f1b
5 files changed
+32

No files matched your search

+13
View File
@@ -108,6 +108,13 @@ void APS5_VABI warn_nid_postfix(const char* format, ...) {
APS5_ERR_VA_END(args);
}
void APS5_VABI _warn_nid_postfix(const char* format, ...) {
APS5_ERR_VA_LIST args;
APS5_ERR_VA_START(args, format);
vwarn_nid_postfix(format, reinterpret_cast<VaList*>(args));
APS5_ERR_VA_END(args);
}
void APS5_VABI warnx_nid_postfix(const char* format, ...) {
APS5_ERR_VA_LIST args;
APS5_ERR_VA_START(args, format);
@@ -128,6 +135,12 @@ void APS5_VABI warnx_nid_postfix(const char* format, ...) {
verrc_nid_postfix(status, code, format, reinterpret_cast<VaList*>(args));
}
[[noreturn]] void APS5_VABI _err_nid_postfix(int status, const char* format, ...) {
APS5_ERR_VA_LIST args;
APS5_ERR_VA_START(args, format);
verr_nid_postfix(status, format, reinterpret_cast<VaList*>(args));
}
[[noreturn]] void APS5_VABI errx_nid_postfix(int status, const char* format, ...) {
APS5_ERR_VA_LIST args;
APS5_ERR_VA_START(args, format);
@@ -109,6 +109,10 @@ const char* APS5_VABI getprogname_nid_postfix() {
return __progname_nid_postfix;
}
const char* APS5_VABI _getprogname_nid_postfix() {
return getprogname_nid_postfix();
}
void APS5_VABI __cxa_finalize_nid_postfix(void* dsoHandle) {
CxaFinalize_nid_no_patch(dsoHandle);
}
+11
View File
@@ -17,9 +17,11 @@ extern "C" {
void APS5_VABI err_set_file_nid_postfix(FileStream* stream);
void APS5_VABI err_set_exit_nid_postfix(ErrExit function);
void APS5_VABI warn_nid_postfix(const char* format, ...);
void APS5_VABI _warn_nid_postfix(const char* format, ...);
void APS5_VABI warnc_nid_postfix(int code, const char* format, ...);
void APS5_VABI warnx_nid_postfix(const char* format, ...);
[[noreturn]] void APS5_VABI err_nid_postfix(int status, const char* format, ...);
[[noreturn]] void APS5_VABI _err_nid_postfix(int status, const char* format, ...);
[[noreturn]] void APS5_VABI errc_nid_postfix(int status, int code, const char* format, ...);
[[noreturn]] void APS5_VABI errx_nid_postfix(int status, const char* format, ...);
void APS5_VABI vwarn_nid_postfix(const char* format, VaList* args);
@@ -148,6 +150,9 @@ int main() {
*__error_nid_postfix() = 2;
warn_nid_postfix(nullptr);
Require(capture.Take() == "prog: " + noEntry + "\n", "warn without format");
*__error_nid_postfix() = 13;
_warn_nid_postfix("open %s", "b.txt");
Require(capture.Take() == "prog: open b.txt: " + denied + "\n", "_warn");
warnc_nid_postfix(13, "%d-%s", 7, "x");
Require(capture.Take() == "prog: 7-x: " + denied + "\n", "warnc");
warnx_nid_postfix("plain %c", 'q');
@@ -163,6 +168,12 @@ int main() {
*__error_nid_postfix() = 2;
Require(ExitStatus([] { err_nid_postfix(5, "e"); }) == 5, "err status");
Require(capture.Take() == "prog: e: " + noEntry + "\n", "err text");
*__error_nid_postfix() = 13;
Require(ExitStatus([] { _err_nid_postfix(7, "%s %d", "f", 8); }) == 7 && g_hookStatus == 7, "_err status");
Require(capture.Take() == "prog: f 8: " + denied + "\n", "_err text");
*__error_nid_postfix() = 2;
Require(ExitStatus([] { _warn_nid_postfix(nullptr); }) == -1 && g_hookStatus == 7, "_warn does not exit");
Require(capture.Take() == "prog: " + noEntry + "\n", "_warn without format");
*__error_nid_postfix() = 2;
CallVariant(Variant::Warn, 0, 0, "open %s", "a.txt");
+3
View File
@@ -4,6 +4,7 @@
extern "C" {
const char* APS5_VABI getprogname_nid_postfix();
const char* APS5_VABI _getprogname_nid_postfix();
extern const char* __progname_nid_postfix;
int* APS5_VABI __error_nid_postfix();
}
@@ -14,12 +15,14 @@ int main() {
const char* const original = __progname_nid_postfix;
*__error_nid_postfix() = 45;
Require(getprogname_nid_postfix() == original);
Require(_getprogname_nid_postfix() == original);
Require(std::strcmp(getprogname_nid_postfix(), "eboot.bin") == 0);
Require(*__error_nid_postfix() == 45);
char renamed[] = "quake2";
__progname_nid_postfix = renamed;
Require(getprogname_nid_postfix() == renamed);
Require(_getprogname_nid_postfix() == renamed);
renamed[0] = 'Q';
Require(std::strcmp(getprogname_nid_postfix(), "Quake2") == 0);
+1
View File
@@ -16,4 +16,5 @@
- [getopt, getopt_long](../../../core/libs/prx/libSceLibcInternal/Getopt.cpp) (libSceLibcInternal) follow FreeBSD 11 [getopt.c](https://github.com/freebsd/freebsd-src/blob/8c639945a44588f6cfdddfb057bb5aad88735da0/lib/libc/stdlib/getopt.c) and [getopt_long.c](https://github.com/freebsd/freebsd-src/blob/8c639945a44588f6cfdddfb057bb5aad88735da0/lib/libc/stdlib/getopt_long.c) with `GNU_COMPATIBLE`: `getopt` does not permute, `getopt_long` permutes unless `POSIXLY_CORRECT` is set in the guest environment or the option string starts with `+`, and the exported `opterr`, `optind`, `optopt`, `optreset` and `optarg` start at 1, 1, 0, 0 and null. Warnings go to the guest's current `stderr` prefixed with `__progname`, where FreeBSD's `warnx` keeps the `stderr` of its first call. A null `getopt` option string, a null argument vector or argument, a negative `optind` and an `optind` moved inside a pending permutation throw where FreeBSD faults. `getopt_long_only` is not exported. That the console's `libSceLibcInternal` uses this FreeBSD code is unverified
- [posix_spawnattr_getflags, getpgroup, getschedparam, getschedpolicy, getsigdefault, getsigmask, setpgroup, setschedparam, setschedpolicy and setsigmask](../../../core/libs/prx/libSceLibcInternal/Spawn.cpp) (libSceLibcInternal) read and write the 0x30-byte attribute object at the offsets of the console's `libSceLibcInternal.sprx` (SDK 4.5x build of `J03950001`, 0x8D860 to 0x8D910: flags at 0, process group at 4, scheduling parameter at 8, policy at 0xC, default and masked signal sets at 0x10 and 0x20), which never fail there and return 0; the layout matched on a PS5 (firmware 13.60). Uninitialized attributes and null pointers, which the console dereferences, throw as the existing setters do
- [sys_siglist and sys_nsig](../../../core/libs/prx/libSceLibcInternal/SignalList.cpp) (libSceLibcInternal) hold the 32 descriptions and the count of [FreeBSD 11.4](https://github.com/freebsd/freebsd-src/blob/8c639945a44588f6cfdddfb057bb5aad88735da0/lib/libc/gen/siglist.c#L73-L107) `siglist.c` (`NSIG` 32, signal 0 to `SIGUSR2`); the console's table was not read
- [_err, _warn](../../../core/libs/prx/libSceLibcInternal/Err.cpp) and [_getprogname](../../../core/libs/prx/libSceLibcInternal/Export.cpp) (libSceLibcInternal) are assumed to be the same functions as `err`, `warn` and `getprogname` and run their code; the console's module was not read. FreeBSD 11.4 defines the underscore names and makes the public names weak references to them ([`_err`](https://github.com/freebsd/freebsd-src/blob/8c639945a44588f6cfdddfb057bb5aad88735da0/lib/libc/gen/err.c#L70-L79), [`_warn`](https://github.com/freebsd/freebsd-src/blob/8c639945a44588f6cfdddfb057bb5aad88735da0/lib/libc/gen/err.c#L135-L144), [`_getprogname`](https://github.com/freebsd/freebsd-src/blob/8c639945a44588f6cfdddfb057bb5aad88735da0/lib/libc/gen/getprogname.c#L10-L17))
- [inet_aton, inet_addr, inet_ntoa and inet_ntoa_r](../../../core/libs/prx/libSceLibcInternal/Inet.cpp) (libSceLibcInternal) follow the FreeBSD code in the console's `libSceLibcInternal.sprx` (SDK 4.5x build of `J03950001`, 0x8ADE0 to 0x8B3D0) and matched it on a PS5 (firmware 13.60) for 20 `inet_aton` inputs; a null text, which the console dereferences, throws. `inet_ntoa_r` formats through libkernel's `__inet_ntop`, so a null buffer with room for the text throws and a null buffer that is too small sets `ENOSPC`, as `__inet_ntop` does for a null destination; the console's `inet_ntoa_r` was not measured with a null buffer