mirror of
https://github.com/boykopovar/AnyPS5.git
synced 2026-10-22 16:43:05 -05:00
XPSemu (PPSA97358) imports eleven posix_spawn calls from libSceLibcInternal.prx, one reference each, and no call site is known. Predicted stop (import order, not measured), behind isnanf (idx 296): `FAIL: unresolved ELF import 44hlATrd47U from libSceLibcInternal.prx` (posix_spawnattr_init, idx 347), followed by p--TkNVsXjA, LG6O0oW9bQU, Sj7y+JO5PcM, Ud8CbISKRGM, Hq9-2AMG+ks, IUfBO5UIZNc, Heh4KJwyoX8 (348-355), UV4m0bznVtU, Ani6e+T-y6Q and 3Nr9caNHhyg (379-381). The nine object calls follow FreeBSD release/11.4.0 (8c639945a445) lib/libc/gen/posix_spawn.c: posix_spawnattr_init allocates a zeroed attribute object (ENOMEM on failure), _destroy frees it, _setflags and _setsigdefault store the value; posix_spawn_file_actions_init allocates an empty list (-1 on failure, as in 11.4), _destroy frees it with its entries, and _addopen (path copied), _adddup2 and _addclose append in order after returning EBADF for a negative descriptor. Null or uninitialized objects, which FreeBSD dereferences, throw. posix_spawn and posix_spawnp throw "process creation not implemented", as execvp does: FreeBSD validates no argument before rfork/vfork, and no child process can be created here. TechnicalDebt records them. guest_posix_spawn covers the attribute round trips, the recorded action sequence, the EBADF cases and the throws. NIDs computed with tools/nid_names.py and present in aerolib. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
120 lines
4.7 KiB
C++
120 lines
4.7 KiB
C++
#include "prx/libSceLibcInternal/include/Spawn.hpp"
|
|
#include "prx/libc/include/General.hpp"
|
|
#include <cstdint>
|
|
#include <new>
|
|
#include <stdexcept>
|
|
#include <string>
|
|
#include <utility>
|
|
|
|
namespace {
|
|
|
|
constexpr int BadDescriptor = 9;
|
|
constexpr int OutOfMemory = 12;
|
|
|
|
PosixSpawnAttributes& Attributes(PosixSpawnAttributes* const* attributes, const char* function) {
|
|
if (attributes == nullptr || *attributes == nullptr) throw std::invalid_argument(std::string(function) + ": uninitialized attributes");
|
|
return **attributes;
|
|
}
|
|
|
|
PosixSpawnFileActions& FileActions(PosixSpawnFileActions* const* actions, const char* function) {
|
|
if (actions == nullptr || *actions == nullptr) throw std::invalid_argument(std::string(function) + ": uninitialized file actions");
|
|
return **actions;
|
|
}
|
|
|
|
int Append(PosixSpawnFileActions& actions, PosixSpawnFileAction action) {
|
|
try {
|
|
actions.actions.push_back(std::move(action));
|
|
} catch (const std::bad_alloc&) {
|
|
return OutOfMemory;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
}
|
|
|
|
extern "C" {
|
|
|
|
int APS5_VABI posix_spawnattr_init_nid_postfix(PosixSpawnAttributes** attributes) {
|
|
if (attributes == nullptr) throw std::invalid_argument("posix_spawnattr_init: null attributes");
|
|
auto* created = new (std::nothrow) PosixSpawnAttributes{};
|
|
if (created == nullptr) return OutOfMemory;
|
|
*attributes = created;
|
|
return 0;
|
|
}
|
|
|
|
int APS5_VABI posix_spawnattr_destroy_nid_postfix(PosixSpawnAttributes** attributes) {
|
|
if (attributes == nullptr) throw std::invalid_argument("posix_spawnattr_destroy: null attributes");
|
|
delete *attributes;
|
|
return 0;
|
|
}
|
|
|
|
int APS5_VABI posix_spawnattr_setflags_nid_postfix(PosixSpawnAttributes** attributes, std::int16_t flags) {
|
|
Attributes(attributes, "posix_spawnattr_setflags").flags = flags;
|
|
return 0;
|
|
}
|
|
|
|
int APS5_VABI posix_spawnattr_setsigdefault_nid_postfix(PosixSpawnAttributes** attributes, const GuestSignalSet* signalDefault) {
|
|
auto& target = Attributes(attributes, "posix_spawnattr_setsigdefault");
|
|
if (signalDefault == nullptr) throw std::invalid_argument("posix_spawnattr_setsigdefault: null signal set");
|
|
target.signalDefault = *signalDefault;
|
|
return 0;
|
|
}
|
|
|
|
int APS5_VABI posix_spawn_file_actions_init_nid_postfix(PosixSpawnFileActions** actions) {
|
|
if (actions == nullptr) throw std::invalid_argument("posix_spawn_file_actions_init: null file actions");
|
|
auto* created = new (std::nothrow) PosixSpawnFileActions{};
|
|
if (created == nullptr) return -1;
|
|
*actions = created;
|
|
return 0;
|
|
}
|
|
|
|
int APS5_VABI posix_spawn_file_actions_destroy_nid_postfix(PosixSpawnFileActions** actions) {
|
|
delete &FileActions(actions, "posix_spawn_file_actions_destroy");
|
|
return 0;
|
|
}
|
|
|
|
int APS5_VABI posix_spawn_file_actions_addopen_nid_postfix(PosixSpawnFileActions** actions, int descriptor, const char* path, int openFlags, std::uint16_t mode) {
|
|
if (descriptor < 0) return BadDescriptor;
|
|
if (path == nullptr) throw std::invalid_argument("posix_spawn_file_actions_addopen: null path");
|
|
auto& target = FileActions(actions, "posix_spawn_file_actions_addopen");
|
|
try {
|
|
return Append(target, {PosixSpawnFileActionKind::Open, descriptor, path, openFlags, mode, 0});
|
|
} catch (const std::bad_alloc&) {
|
|
return OutOfMemory;
|
|
}
|
|
}
|
|
|
|
int APS5_VABI posix_spawn_file_actions_adddup2_nid_postfix(PosixSpawnFileActions** actions, int descriptor, int newDescriptor) {
|
|
if (descriptor < 0 || newDescriptor < 0) return BadDescriptor;
|
|
return Append(FileActions(actions, "posix_spawn_file_actions_adddup2"), {PosixSpawnFileActionKind::Duplicate, descriptor, {}, 0, 0, newDescriptor});
|
|
}
|
|
|
|
int APS5_VABI posix_spawn_file_actions_addclose_nid_postfix(PosixSpawnFileActions** actions, int descriptor) {
|
|
if (descriptor < 0) return BadDescriptor;
|
|
return Append(FileActions(actions, "posix_spawn_file_actions_addclose"), {PosixSpawnFileActionKind::Close, descriptor, {}, 0, 0, 0});
|
|
}
|
|
|
|
int APS5_VABI posix_spawn_nid_postfix(std::int32_t* processId, const char* path, PosixSpawnFileActions* const* actions, PosixSpawnAttributes* const* attributes, char* const* arguments, char* const* environment) {
|
|
(void)processId;
|
|
(void)path;
|
|
(void)actions;
|
|
(void)attributes;
|
|
(void)arguments;
|
|
(void)environment;
|
|
NotImplemented_nid_no_patch("posix_spawn: process creation");
|
|
return -1;
|
|
}
|
|
|
|
int APS5_VABI posix_spawnp_nid_postfix(std::int32_t* processId, const char* file, PosixSpawnFileActions* const* actions, PosixSpawnAttributes* const* attributes, char* const* arguments, char* const* environment) {
|
|
(void)processId;
|
|
(void)file;
|
|
(void)actions;
|
|
(void)attributes;
|
|
(void)arguments;
|
|
(void)environment;
|
|
NotImplemented_nid_no_patch("posix_spawnp: process creation");
|
|
return -1;
|
|
}
|
|
|
|
}
|