Implement signal action invocation with mask handling and update NSO loading to use PatchManager

This commit is contained in:
bdm
2026-07-01 22:38:26 +08:00
parent df11cf7697
commit 6422cba5ba
3 changed files with 29 additions and 13 deletions
+25 -2
View File
@@ -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)};
-8
View File
@@ -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);