diff options
Diffstat (limited to 'data/patches/gnuzilla-bug-1036286-2.patch')
-rw-r--r-- | data/patches/gnuzilla-bug-1036286-2.patch | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/data/patches/gnuzilla-bug-1036286-2.patch b/data/patches/gnuzilla-bug-1036286-2.patch new file mode 100644 index 0000000..6708062 --- /dev/null +++ b/data/patches/gnuzilla-bug-1036286-2.patch @@ -0,0 +1,105 @@ +--- a/mozglue/linker/CustomElf.cpp ++++ a/mozglue/linker/CustomElf.cpp +@@ -1,16 +1,17 @@ + /* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + + #include <cstring> + #include <sys/mman.h> + #include <vector> + #include <dlfcn.h> ++#include <signal.h> + #include "CustomElf.h" + #include "Mappable.h" + #include "Logging.h" + + using namespace Elf; + using namespace mozilla; + + /* TODO: Fill ElfLoader::Singleton.lastError on errors. */ +@@ -348,16 +349,21 @@ CustomElf::GetSymbolPtrInDeps(const char + if (strcmp(symbol + 2, "dso_handle") == 0) + return const_cast<CustomElf *>(this); + if (strcmp(symbol + 2, "moz_linker_stats") == 0) + return FunctionPtr(&ElfLoader::stats); + #ifdef __ARM_EABI__ + if (strcmp(symbol + 2, "gnu_Unwind_Find_exidx") == 0) + return FunctionPtr(__wrap___gnu_Unwind_Find_exidx); + #endif ++ } else if (symbol[0] == 's' && symbol[1] == 'i') { ++ if (strcmp(symbol + 2, "gnal") == 0) ++ return FunctionPtr(signal); ++ if (strcmp(symbol + 2, "gaction") == 0) ++ return FunctionPtr(sigaction); + } + + #define MISSING_FLASH_SYMNAME_START "_ZN7android10VectorImpl19reservedVectorImpl" + + // Android changed some symbols that Flash depended on in 4.4, + // so stub those out here + if (strncmp(symbol, + MISSING_FLASH_SYMNAME_START, +--- a/mozglue/linker/ElfLoader.cpp ++++ a/mozglue/linker/ElfLoader.cpp +@@ -1014,17 +1014,59 @@ SEGVHandler::FinishInitialization() + { + /* Ideally, we'd need some locking here, but in practice, we're not + * going to race with another thread. */ + initialized = true; + + if (signalHandlingBroken || signalHandlingSlow) + return; + +- if (!Divert(sigaction, __wrap_sigaction)) ++ typedef int (*sigaction_func)(int, const struct sigaction *, ++ struct sigaction *); ++ ++ sigaction_func libc_sigaction; ++ ++#if defined(ANDROID) ++ /* Android > 4.4 comes with a sigaction wrapper in a LD_PRELOADed library ++ * (libsigchain) for ART. That wrapper kind of does the same trick as we ++ * do, so we need extra care in handling it. ++ * - Divert the libc's sigaction, assuming the LD_PRELOADed library uses ++ * it under the hood (which is more or less true according to the source ++ * of that library, since it's doing a lookup in RTLD_NEXT) ++ * - With the LD_PRELOADed library in place, all calls to sigaction from ++ * from system libraries will go to the LD_PRELOADed library. ++ * - The LD_PRELOADed library calls to sigaction go to our __wrap_sigaction. ++ * - The calls to sigaction from libraries faulty.lib loads are sent to ++ * the LD_PRELOADed library. ++ * In practice, for signal handling, this means: ++ * - The signal handler registered to the kernel is ours. ++ * - Our handler redispatches to the LD_PRELOADed library's if there's a ++ * segfault we don't handle. ++ * - The LD_PRELOADed library redispatches according to whatever system ++ * library or faulty.lib-loaded library set with sigaction. ++ * ++ * When there is no sigaction wrapper in place: ++ * - Divert the libc's sigaction. ++ * - Calls to sigaction from system library and faulty.lib-loaded libraries ++ * all go to the libc's sigaction, which end up in our __wrap_sigaction. ++ * - The signal handler registered to the kernel is ours. ++ * - Our handler redispatches according to whatever system library or ++ * faulty.lib-loaded library set with sigaction. ++ */ ++ void *libc = dlopen("libc.so", RTLD_GLOBAL | RTLD_LAZY); ++ if (libc) { ++ libc_sigaction = ++ reinterpret_cast<sigaction_func>(dlsym(libc, "sigaction")); ++ } else ++#endif ++ { ++ libc_sigaction = sigaction; ++ } ++ ++ if (!Divert(libc_sigaction, __wrap_sigaction)) + return; + + /* Setup an alternative stack if the already existing one is not big + * enough, or if there is none. */ + if (sigaltstack(nullptr, &oldStack) == 0) { + if (oldStack.ss_flags == SS_ONSTACK) + oldStack.ss_flags = 0; + if (!oldStack.ss_sp || oldStack.ss_size < stackSize) { |