Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions core/libs/prx/libkernel/System/src/Process.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
#endif

extern "C" int* APS5_VABI __error_nid_postfix();
extern "C" int APS5_VABI stat_nid_postfix(const char* path, FileStat* sb);

namespace {

Expand Down Expand Up @@ -347,6 +348,14 @@ int APS5_VABI execv_nid_postfix(const char* path, char* const* arguments) {
return -1;
}

int APS5_VABI execve_nid_postfix(const char* path, char* const* arguments, char* const* environment) {
(void)path;
(void)arguments;
(void)environment;
NotImplemented_nid_no_patch("execve: executable replacement");
return -1;
}

int APS5_VABI sceKernelGetCurrentCpu(void) {
#ifdef _WIN32
PROCESSOR_NUMBER processor{};
Expand Down
32 changes: 19 additions & 13 deletions core/libs/tests/GuestExecvp.cpp
Original file line number Diff line number Diff line change
@@ -1,23 +1,29 @@
#include "prx/libc/include/general/VabiMacros.hpp"
#include "prx/libc/include/General.hpp"
#include <cstdlib>
#include <stdexcept>
#include <string>
extern "C" int APS5_VABI execvp_nid_postfix(const char*, char* const*);
static void Require(bool value) { if (!value) std::abort(); }
static bool ReportsNotImplemented(const char* file, char* const* arguments) {
extern "C" {
int APS5_VABI execvp_nid_postfix(const char*, char* const*);
int APS5_VABI execv_nid_postfix(const char*, char* const*);
int APS5_VABI execve_nid_postfix(const char*, char* const*, char* const*);
}
template <typename TCall> static bool Throws(TCall call, const std::string& message) {
try {
execvp_nid_postfix(file, arguments);
call();
} catch (const std::runtime_error& error) {
return std::string(error.what()) == "execvp: executable replacement not implemented";
return error.what() == message;
}
return false;
}
static void Require(bool value) { if (!value) std::abort(); }
int main() {
char shell[] = "sh";
char option[] = "-c";
char command[] = "exit 0";
char* arguments[] = {shell, option, command, nullptr};
Require(ReportsNotImplemented("sh", arguments));
Require(ReportsNotImplemented("/bin/sh", arguments));
Require(ReportsNotImplemented(nullptr, nullptr));
char name[] = "sh";
char* arguments[] = {name, nullptr};
char variable[] = "HOME=/";
char* environment[] = {variable, nullptr};
Require(Throws([&] { execvp_nid_postfix("sh", arguments); }, "execvp: executable replacement not implemented"));
Require(Throws([&] { execvp_nid_postfix("/bin/sh", arguments); }, "execvp: executable replacement not implemented"));
Require(Throws([&] { execvp_nid_postfix(nullptr, nullptr); }, "execvp: executable replacement not implemented"));
Require(Throws([&] { execv_nid_postfix("/bin/sh", arguments); }, "execv: executable replacement not implemented"));
Require(Throws([&] { execve_nid_postfix("/bin/sh", arguments, environment); }, "execve: executable replacement not implemented"));
}
1 change: 1 addition & 0 deletions docs/dev/debt/libkernel.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@
- [dup and dup2](../../../core/libs/prx/libkernel/File/src/Stdio.cpp) (libkernel) throw for the combinations they do not model: `dup2` of a guest socket onto descriptors 0 to 2, whose host streams libc writes without the socket table, and on Windows duplicating a directory descriptor. Guest sockets share one socket object between the duplicates; the numbers come from the host descriptor table like those of files. The errno values for descriptor exhaustion are not verified against the console.
- [waitpid](../../../core/libs/prx/libkernel/System/src/Process.cpp) (libkernel) returns -1 with `ECHILD` (`EINVAL` for unknown options): nothing here creates a child process; child processes would need a real `waitpid`.
- [execv](../../../core/libs/prx/libkernel/System/src/Process.cpp) (libkernel) throws: replacing the process image is not supported, the same as `execvp`. PPSA97358 imports it and fails to load without it.
- [execve](../../../core/libs/prx/libkernel/System/src/Process.cpp) (libkernel) throws like `execvp`: replacing the process image is not supported. The console behavior for invalid arguments and executable path lookups is not modeled.
- [kern.proc.pathname](../../../core/libs/prx/libkernel/System/src/SystemConfiguration.cpp) (libkernel) returns `/app0/eboot.bin` for pid -1 and the calling process, following FreeBSD's `sysctl_kern_proc_pathname`; the exact pathname on retail consoles remains unverified.
- [machdep.cacheline_size](../../../core/libs/prx/libkernel/System/src/SystemConfiguration.cpp) (libkernel) returns -1 with `ENOENT`, matching FreeBSD amd64 where this sysctl OID is not defined.
- [hw.model](../../../core/libs/prx/libkernel/System/src/SystemConfiguration.cpp) (libkernel) reports the host CPU's name, built as FreeBSD 11 builds `hw.model`: the CPUID brand string (leaves 0x80000002 to 0x80000004) without leading spaces ([identcpu.c](https://github.com/freebsd/freebsd-src/blob/release/11.0.0/sys/x86/x86/identcpu.c#L683-L691)). Trailing padding stays, as it does there, so an AMD host's name ends in spaces. The name a PS5 reports is unknown. A write returns -1 with `EPERM`. A host without an x86 CPUID brand string, such as an Apple Silicon Mac, throws. PPSA99203 only prints it (`[console] hw.model: %s`)
Expand Down
Loading