Merge pull request #2543 from overlordxrz-source/feat/libkernel-kill
feat(libkernel): implement kill
This commit is contained in:
commit
3afc78464c
|
|
@ -422,6 +422,16 @@ if(BUILD_TESTING)
|
|||
set_tests_properties(guest_signals PROPERTIES ENVIRONMENT_MODIFICATION
|
||||
"PATH=path_list_prepend:$<TARGET_FILE_DIR:libkernel>")
|
||||
endif()
|
||||
add_test_executable(guest_kill_tests ${LIBS_INCLUDE_DIR}/tests/GuestKill.cpp)
|
||||
target_include_directories(guest_kill_tests PRIVATE ${LIBS_INCLUDE_DIR})
|
||||
target_link_libraries(guest_kill_tests PRIVATE libkernel libc)
|
||||
configure_windows_unwind(guest_kill_tests)
|
||||
add_test(NAME guest_kill COMMAND guest_kill_tests)
|
||||
set_tests_properties(guest_kill PROPERTIES TIMEOUT 20)
|
||||
if(WIN32)
|
||||
set_tests_properties(guest_kill PROPERTIES ENVIRONMENT_MODIFICATION
|
||||
"PATH=path_list_prepend:$<TARGET_FILE_DIR:libkernel>")
|
||||
endif()
|
||||
add_test_executable(guest_signal_set_tests ${LIBS_INCLUDE_DIR}/tests/GuestSignalSets.cpp)
|
||||
target_include_directories(guest_signal_set_tests PRIVATE ${LIBS_INCLUDE_DIR})
|
||||
target_link_libraries(guest_signal_set_tests PRIVATE libkernel libc)
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
#include <stdexcept>
|
||||
|
||||
extern "C" int* APS5_VABI __error_nid_postfix();
|
||||
extern "C" int APS5_VABI getpid_nid_postfix(void);
|
||||
|
||||
struct GuestSignalSet {
|
||||
std::uint32_t bits[4];
|
||||
|
|
@ -120,6 +121,12 @@ int APS5_VABI raise_nid_postfix(int guest) {
|
|||
if (result) *__error_nid_postfix() = 22;
|
||||
return result ? -1 : 0;
|
||||
}
|
||||
int APS5_VABI kill_nid_postfix(int pid, int guest) {
|
||||
if (guest < 0 || guest > MaxSignal) { *__error_nid_postfix() = 22; return -1; }
|
||||
const int self = getpid_nid_postfix();
|
||||
if (pid != self && pid != 0 && pid != -self) { *__error_nid_postfix() = 3; return -1; }
|
||||
return guest == 0 ? 0 : raise_nid_postfix(guest);
|
||||
}
|
||||
int APS5_VABI sigaltstack_nid_postfix(const GuestStack* stack, GuestStack* previous) {
|
||||
GuestStack replacement = alternateStack;
|
||||
if (stack != nullptr) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,46 @@
|
|||
#include "prx/libc/include/general/VabiMacros.hpp"
|
||||
#include <csignal>
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
#include <initializer_list>
|
||||
using Handler = void (APS5_VABI *)(int);
|
||||
extern "C" {
|
||||
Handler APS5_VABI signal_nid_postfix(int, Handler);
|
||||
int APS5_VABI kill_nid_postfix(int, int);
|
||||
int APS5_VABI getpid_nid_postfix(void);
|
||||
int* APS5_VABI __error_nid_postfix();
|
||||
}
|
||||
volatile std::sig_atomic_t received = 0;
|
||||
void APS5_VABI Callback(int value) { received = value; }
|
||||
static void Require(bool value) { if (!value) std::abort(); }
|
||||
static void Fails(int pid, int guest, int error) {
|
||||
*__error_nid_postfix() = 0;
|
||||
Require(kill_nid_postfix(pid, guest) == -1 && *__error_nid_postfix() == error);
|
||||
}
|
||||
int main() {
|
||||
const int self = getpid_nid_postfix();
|
||||
const auto invalid = reinterpret_cast<Handler>(static_cast<std::uintptr_t>(-1));
|
||||
const auto ignore = reinterpret_cast<Handler>(std::uintptr_t{1});
|
||||
for (int target : {self, 0, -self}) Require(kill_nid_postfix(target, 0) == 0);
|
||||
for (int target : {self + 1, -1, -(self + 1)}) {
|
||||
Fails(target, 0, 3);
|
||||
Fails(target, 15, 3);
|
||||
}
|
||||
for (int guest : {-1, 129}) {
|
||||
Fails(self, guest, 22);
|
||||
Fails(self + 1, guest, 22);
|
||||
}
|
||||
Require(signal_nid_postfix(15, Callback) != invalid);
|
||||
for (int target : {self, 0, -self}) {
|
||||
received = 0;
|
||||
Require(kill_nid_postfix(target, 0) == 0 && received == 0);
|
||||
Require(kill_nid_postfix(target, 15) == 0 && received == 15);
|
||||
}
|
||||
received = 0;
|
||||
Fails(self + 1, 15, 3);
|
||||
Require(received == 0);
|
||||
Require(signal_nid_postfix(15, ignore) == Callback);
|
||||
Require(kill_nid_postfix(self, 15) == 0 && received == 0);
|
||||
Require(signal_nid_postfix(15, nullptr) == ignore);
|
||||
Fails(self, 100, 22);
|
||||
}
|
||||
|
|
@ -445,5 +445,6 @@ Throughout the project, every function at every stage either **does exactly what
|
|||
- [sceVideodec2CreateDecoder](../../core/libs/prx/libSceVideodec2/Export.cpp) (libSceVideodec2) decodes HEVC (codec type 974921) and VP9 (2382845) through FFmpeg, besides H.264. The tags come from SharpProspero's `Videodec2CodecType` and EVO-PLAYER-PS5's `sce_videodec2.h`, which records them from hardware runs. HEVC input is converted from length-prefixed NAL units to Annex B as for H.264, and VP9 frames are passed through. Output is the same 8-bit NV12 for every codec; a decoder for HEVC Main10 or VP9 Profile 2 is created, but a frame deeper than 8 bits throws, since the console's 10-bit output layout is unknown, and `QueryDecoderMemoryInfo` reports the 8-bit frame size for it. `sceVideodec2GetPictureInfo` and `sceVideodec2GetAvcPictureInfo` throw for HEVC and VP9 pictures, which use other layouts (`SceVideodec2HevcPictureInfo`, `SceVideodec2Vp9PictureInfo`), and `sceVideodec2GetHevcPictureInfo` and `sceVideodec2GetVp9PictureInfo` are not exported
|
||||
- [syslog](../../core/libs/prx/libc/src/Syslog.cpp) (libc) writes each message to `stderr` as `[syslog:<priority>] <message>`, with a newline added when missing, instead of sending it to the console's system log. Priority and facility handling follow FreeBSD's `vsyslog`: `%m` expands to the guest errno's message, unknown bits are reported (as priority 0x23, since FreeBSD passes `LOG_ERR|LOG_CONS|LOG_PERROR|LOG_PID` as the priority) and masked, a missing facility becomes `LOG_USER`, and errno is preserved. `openlog`, `setlogmask` and `closelog` are not implemented, so the identity, options and mask they set are not applied
|
||||
- [sigaction](../../core/libs/prx/libkernel/System/src/Signals.cpp) (libkernel) records the handler, flags and mask of every signal from 1 to 128 and reports them back, following FreeBSD's `sigaction` (`EINVAL` for other signals, and for a handler on `SIGKILL` or `SIGSTOP`); `signal` records its handler with `SA_RESTART`, as FreeBSD's libc does. Only handlers without `SA_SIGINFO` on the signals `signal` already delivers (`SIGINT`, `SIGILL`, `SIGABRT`, `SIGFPE`, `SIGSEGV`, `SIGTERM`) run, the same way `signal` handlers do; their mask and flags are not applied. `SA_SIGINFO` handlers and other signals (`SIGBUS`, `SIGHUP`, ...) are recorded but never called, since that needs FreeBSD's `siginfo_t` and `ucontext_t`; `raise` of an `SA_SIGINFO` handler on a signal `signal` delivers throws instead of terminating, and `raise` of the other signals still returns `EINVAL`
|
||||
- [kill](../../core/libs/prx/libkernel/System/src/Signals.cpp) (libkernel) follows FreeBSD's `kern_kill` and `killpg1` for the only guest process: `EINVAL` for signals outside 0 to 128, signal 0 only checks that the target exists, and its own pid, 0 and minus its own pid (the guest is taken to lead its own process group) signal it through `raise`, so they share `raise`'s limits above. Any other pid, and -1, which skips the caller, report `ESRCH`, so `EPERM` is never reported
|
||||
- [AJM](../../core/libs/prx/libSceAjm.native/src/Ajm.cpp), [APR](../../core/libs/prx/libkernel/Apr/src/Apr.cpp) and [NGS2](../../core/libs/prx/libSceNgs2.native/src/System.cpp) state is allocated with `new` and never freed on purpose: title threads still call into these libraries while `std::exit` runs static destructors, so ordinary statics would be destroyed under them. Keep them leaked; `guest_ajm_teardown` covers the AJM case on Unix.
|
||||
- [Null vertex buffer V#](../../core/libs/prx/libSceAgcDriver/Graphics/include/VertexInput.hpp) (libSceAgcDriver) - a V# whose four dwords are all zero is bound to a zeroed vertex buffer of the attribute's size with stride 0, so every component of its attribute reads 0. This follows the V# fields in the [AMD RDNA2 ISA](https://gpuopen.com/download/rdna2-shader-instruction-set-architecture.pdf) (`NUM_RECORDS` 0, `DST_SEL` 0 selects 0), not measured on hardware.
|
||||
|
|
|
|||
Loading…
Reference in New Issue