mirror of
https://github.com/citron-neo/emulator.git
synced 2026-07-05 15:21:57 -07:00
Implement signal action invocation with mask handling and update NSO loading to use PatchManager
This commit is contained in:
@@ -27,6 +27,28 @@ namespace {
|
||||
struct sigaction g_orig_bus_action;
|
||||
struct sigaction g_orig_segv_action;
|
||||
|
||||
template <typename Callback>
|
||||
void InvokeOriginalActionWithMask(int sig, const struct sigaction& original, Callback&& callback) {
|
||||
sigset_t callback_mask = original.sa_mask;
|
||||
sigset_t previous_mask;
|
||||
|
||||
if ((original.sa_flags & SA_NODEFER) == 0) {
|
||||
sigaddset(&callback_mask, sig);
|
||||
}
|
||||
|
||||
sigprocmask(SIG_BLOCK, &callback_mask, &previous_mask);
|
||||
|
||||
if ((original.sa_flags & SA_NODEFER) != 0) {
|
||||
sigset_t nodefer_mask;
|
||||
sigemptyset(&nodefer_mask);
|
||||
sigaddset(&nodefer_mask, sig);
|
||||
sigprocmask(SIG_UNBLOCK, &nodefer_mask, nullptr);
|
||||
}
|
||||
|
||||
callback();
|
||||
sigprocmask(SIG_SETMASK, &previous_mask, nullptr);
|
||||
}
|
||||
|
||||
void ForwardSignalToOriginalAction(int sig, siginfo_t* info, void* raw_context,
|
||||
const struct sigaction& original) {
|
||||
if (original.sa_handler == SIG_IGN) {
|
||||
@@ -40,12 +62,13 @@ void ForwardSignalToOriginalAction(int sig, siginfo_t* info, void* raw_context,
|
||||
}
|
||||
|
||||
if ((original.sa_flags & SA_SIGINFO) != 0 && original.sa_sigaction != nullptr) {
|
||||
original.sa_sigaction(sig, info, raw_context);
|
||||
InvokeOriginalActionWithMask(sig, original,
|
||||
[&] { original.sa_sigaction(sig, info, raw_context); });
|
||||
return;
|
||||
}
|
||||
|
||||
if ((original.sa_flags & SA_SIGINFO) == 0 && original.sa_handler != nullptr) {
|
||||
original.sa_handler(sig);
|
||||
InvokeOriginalActionWithMask(sig, original, [&] { original.sa_handler(sig); });
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -200,6 +200,9 @@ AppLoader_DeconstructedRomDirectory::LoadResult AppLoader_DeconstructedRomDirect
|
||||
}
|
||||
metadata.Print();
|
||||
|
||||
const FileSys::PatchManager pm{metadata.GetTitleID(), system.GetFileSystemController(),
|
||||
system.GetContentProvider()};
|
||||
|
||||
// Enable NCE only for applications with 39-bit address space.
|
||||
const bool is_39bit =
|
||||
metadata.GetAddressSpaceType() == FileSys::ProgramAddressSpaceType::Is39Bit;
|
||||
@@ -227,7 +230,7 @@ AppLoader_DeconstructedRomDirectory::LoadResult AppLoader_DeconstructedRomDirect
|
||||
|
||||
const bool should_pass_arguments = std::strcmp(module, "rtld") == 0;
|
||||
const auto tentative_next_load_addr = AppLoader_NSO::LoadModule(
|
||||
process, system, *module_file, next_code_size, should_pass_arguments, false, {},
|
||||
process, system, *module_file, next_code_size, should_pass_arguments, false, pm,
|
||||
patch_ctx.GetPatchers(), patch_ctx.GetLastIndex());
|
||||
if (!tentative_next_load_addr) {
|
||||
return std::nullopt;
|
||||
@@ -284,8 +287,6 @@ AppLoader_DeconstructedRomDirectory::LoadResult AppLoader_DeconstructedRomDirect
|
||||
modules.clear();
|
||||
const VAddr base_address{GetInteger(process.GetEntryPoint())};
|
||||
VAddr next_load_addr{base_address};
|
||||
const FileSys::PatchManager pm{metadata.GetTitleID(), system.GetFileSystemController(),
|
||||
system.GetContentProvider()};
|
||||
for (size_t i = 0; i < static_modules.size(); i++) {
|
||||
const auto& module = static_modules[i];
|
||||
const FileSys::VirtualFile module_file{dir->GetFile(module)};
|
||||
|
||||
@@ -150,14 +150,6 @@ std::optional<VAddr> AppLoader_NSO::LoadModule(Kernel::KProcess& process, Core::
|
||||
// Apply patches if necessary
|
||||
const auto name = nso_file.GetName();
|
||||
const bool has_nso_patch = pm && pm->HasNSOPatch(nso_header.build_id, name);
|
||||
#ifdef HAS_NCE
|
||||
if (load_into_process && patches && Settings::IsNceEnabled() && has_nso_patch) {
|
||||
LOG_WARNING(Loader,
|
||||
"NCE layout preflight used the unpatched NSO image while runtime patches "
|
||||
"are present: module={}, build_id={}",
|
||||
name, Common::HexToString(nso_header.build_id));
|
||||
}
|
||||
#endif
|
||||
if (pm && (has_nso_patch || Settings::values.dump_nso)) {
|
||||
std::span<u8> patchable_section(program_image.data() + module_start,
|
||||
program_image.size() - module_start);
|
||||
|
||||
Reference in New Issue
Block a user