common: Add libc sigaction hook
This commit is contained in:
parent
5a182f4e7c
commit
20011dfeb8
|
@ -166,6 +166,13 @@ if (WIN32)
|
||||||
target_link_libraries(common PRIVATE ntdll)
|
target_link_libraries(common PRIVATE ntdll)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if (NOT WIN32)
|
||||||
|
target_sources(common PRIVATE
|
||||||
|
signal_chain.cpp
|
||||||
|
signal_chain.h
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
if(ANDROID)
|
if(ANDROID)
|
||||||
target_sources(common
|
target_sources(common
|
||||||
PRIVATE
|
PRIVATE
|
||||||
|
|
42
src/common/signal_chain.cpp
Normal file
42
src/common/signal_chain.cpp
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include <dlfcn.h>
|
||||||
|
|
||||||
|
#include "common/assert.h"
|
||||||
|
#include "common/dynamic_library.h"
|
||||||
|
#include "common/scope_exit.h"
|
||||||
|
#include "common/signal_chain.h"
|
||||||
|
|
||||||
|
namespace Common {
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
T* LookupLibcSymbol(const char* name) {
|
||||||
|
#if defined(__BIONIC__)
|
||||||
|
Common::DynamicLibrary provider("libc.so");
|
||||||
|
if (!provider.IsOpen()) {
|
||||||
|
UNREACHABLE_MSG("Failed to open libc!");
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
// For other operating environments, we assume the symbol is not overriden.
|
||||||
|
const char* base = nullptr;
|
||||||
|
Common::DynamicLibrary provider(base);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void* sym = provider.GetSymbolAddress(name);
|
||||||
|
if (sym == nullptr) {
|
||||||
|
sym = dlsym(RTLD_DEFAULT, name);
|
||||||
|
}
|
||||||
|
if (sym == nullptr) {
|
||||||
|
UNREACHABLE_MSG("Unable to find symbol {}!", name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return reinterpret_cast<T*>(sym);
|
||||||
|
}
|
||||||
|
|
||||||
|
int SigAction(int signum, const struct sigaction* act, struct sigaction* oldact) {
|
||||||
|
static auto libc_sigaction = LookupLibcSymbol<decltype(sigaction)>("sigaction");
|
||||||
|
return libc_sigaction(signum, act, oldact);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Common
|
19
src/common/signal_chain.h
Normal file
19
src/common/signal_chain.h
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifndef _WIN32
|
||||||
|
|
||||||
|
#include <signal.h>
|
||||||
|
|
||||||
|
namespace Common {
|
||||||
|
|
||||||
|
// Android's ART overrides sigaction with its own wrapper. This is problematic for SIGSEGV
|
||||||
|
// in particular, because ARTs handler access TPIDR_EL0, so this extracts the libc version
|
||||||
|
// and calls it directly.
|
||||||
|
int SigAction(int signum, const struct sigaction* act, struct sigaction* oldact);
|
||||||
|
|
||||||
|
} // namespace Common
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in a new issue