Bug 1752703 - Move the pthread_thread_create() interposer under mozglue and prepare for having a single place where we place interposer functions r=glandium
Differential Revision: https://phabricator.services.mozilla.com/D164470
This commit is contained in:
@@ -53,11 +53,6 @@ LOCAL_INCLUDES += [
|
|||||||
"/xpcom/build",
|
"/xpcom/build",
|
||||||
]
|
]
|
||||||
|
|
||||||
# The pthred_create() interposer needs to be linked as early as possible so
|
|
||||||
# that it will appear before libpthread when resolving symbols.
|
|
||||||
if CONFIG["OS_ARCH"] == "Linux" and CONFIG["MOZ_CRASHREPORTER"]:
|
|
||||||
USE_LIBS += ["pthread_create_interposer"]
|
|
||||||
|
|
||||||
if CONFIG["LIBFUZZER"]:
|
if CONFIG["LIBFUZZER"]:
|
||||||
USE_LIBS += ["fuzzer"]
|
USE_LIBS += ["fuzzer"]
|
||||||
LOCAL_INCLUDES += [
|
LOCAL_INCLUDES += [
|
||||||
|
|||||||
@@ -16,11 +16,6 @@ else:
|
|||||||
"MozillaRuntimeMain.cpp",
|
"MozillaRuntimeMain.cpp",
|
||||||
]
|
]
|
||||||
|
|
||||||
# The pthred_create() interposer needs to be linked as early as possible so
|
|
||||||
# that it will appear before libpthread when resolving symbols.
|
|
||||||
if CONFIG["OS_ARCH"] == "Linux" and CONFIG["MOZ_CRASHREPORTER"]:
|
|
||||||
USE_LIBS += ["pthread_create_interposer"]
|
|
||||||
|
|
||||||
include("/ipc/chromium/chromium-config.mozbuild")
|
include("/ipc/chromium/chromium-config.mozbuild")
|
||||||
|
|
||||||
LOCAL_INCLUDES += [
|
LOCAL_INCLUDES += [
|
||||||
|
|||||||
@@ -155,6 +155,7 @@ rsync_filter_list = """
|
|||||||
|
|
||||||
+ /mozglue/baseprofiler/**
|
+ /mozglue/baseprofiler/**
|
||||||
+ /mozglue/build/**
|
+ /mozglue/build/**
|
||||||
|
+ /mozglue/interposers/**
|
||||||
+ /mozglue/misc/**
|
+ /mozglue/misc/**
|
||||||
+ /mozglue/moz.build
|
+ /mozglue/moz.build
|
||||||
+ /mozglue/static/**
|
+ /mozglue/static/**
|
||||||
|
|||||||
@@ -10,11 +10,6 @@ SOURCES += [
|
|||||||
"xpcshell.cpp",
|
"xpcshell.cpp",
|
||||||
]
|
]
|
||||||
|
|
||||||
# The pthred_create() interposer needs to be linked as early as possible so
|
|
||||||
# that it will appear before libpthread when resolving symbols.
|
|
||||||
if CONFIG["OS_ARCH"] == "Linux" and CONFIG["MOZ_CRASHREPORTER"]:
|
|
||||||
USE_LIBS += ["pthread_create_interposer"]
|
|
||||||
|
|
||||||
if CONFIG["LIBFUZZER"]:
|
if CONFIG["LIBFUZZER"]:
|
||||||
USE_LIBS += ["fuzzer"]
|
USE_LIBS += ["fuzzer"]
|
||||||
|
|
||||||
|
|||||||
66
mozglue/interposers/InterposerHelper.h
Normal file
66
mozglue/interposers/InterposerHelper.h
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
/* 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/. */
|
||||||
|
|
||||||
|
#ifndef InterposerHelper_h
|
||||||
|
#define InterposerHelper_h
|
||||||
|
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
#ifdef MOZ_LINKER
|
||||||
|
# include "Linker.h"
|
||||||
|
#else
|
||||||
|
# include <dlfcn.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "mozilla/Assertions.h"
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
static inline T dlsym_wrapper(void* aHandle, const char* aName) {
|
||||||
|
#ifdef MOZ_LINKER
|
||||||
|
return reinterpret_cast<T>(__wrap_dlsym(aHandle, aName));
|
||||||
|
#else
|
||||||
|
return reinterpret_cast<T>(dlsym(aHandle, aName));
|
||||||
|
#endif // MOZ_LINKER
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
static T get_real_symbol(const char* aName, T aReplacementSymbol) {
|
||||||
|
// T can only be a function pointer
|
||||||
|
static_assert(std::is_function<typename std::remove_pointer<T>::type>::value);
|
||||||
|
|
||||||
|
// Find the corresponding function in the linked libraries
|
||||||
|
T real_symbol = dlsym_wrapper<T>(RTLD_NEXT, aName);
|
||||||
|
|
||||||
|
#if defined(ANDROID)
|
||||||
|
if (real_symbol == nullptr) {
|
||||||
|
// On old versions of Android the application runtime links in libc before
|
||||||
|
// we get a chance to link libmozglue, so its symbols don't appear when
|
||||||
|
// resolving them with RTLD_NEXT but rather with RTLD_DEFAULT. If RTLD_NEXT
|
||||||
|
// failed to find a symbol we try again with RTLD_DEFAULT. The checks below
|
||||||
|
// make sure that we crash in case the symbol we get matches the
|
||||||
|
// replacement one so this is safe albeit a bit weird.
|
||||||
|
real_symbol = dlsym_wrapper<T>(RTLD_DEFAULT, aName);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (real_symbol == nullptr) {
|
||||||
|
MOZ_CRASH_UNSAFE_PRINTF(
|
||||||
|
"%s() interposition failed but the interposer function is "
|
||||||
|
"still being called, this won't work!",
|
||||||
|
aName);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (real_symbol == aReplacementSymbol) {
|
||||||
|
MOZ_CRASH_UNSAFE_PRINTF(
|
||||||
|
"We could not obtain the real %s(). Calling the symbol we "
|
||||||
|
"got would make us enter an infinite loop so stop here instead.",
|
||||||
|
aName);
|
||||||
|
}
|
||||||
|
|
||||||
|
return real_symbol;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define GET_REAL_SYMBOL(name) get_real_symbol(#name, name)
|
||||||
|
|
||||||
|
#endif // InterposerHelper_h
|
||||||
20
mozglue/interposers/moz.build
Normal file
20
mozglue/interposers/moz.build
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||||
|
# vim: set filetype=python:
|
||||||
|
# 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/.
|
||||||
|
Library("interposers")
|
||||||
|
|
||||||
|
DEFINES["IMPL_MFBT"] = True
|
||||||
|
|
||||||
|
if CONFIG["MOZ_CRASHREPORTER"]:
|
||||||
|
UNIFIED_SOURCES += [
|
||||||
|
"pthread_create_interposer.cpp",
|
||||||
|
]
|
||||||
|
|
||||||
|
if CONFIG["MOZ_LINKER"] and CONFIG["MOZ_WIDGET_TOOLKIT"] == "android":
|
||||||
|
LOCAL_INCLUDES += [
|
||||||
|
"/mozglue/linker",
|
||||||
|
]
|
||||||
|
|
||||||
|
FINAL_LIBRARY = "mozglue"
|
||||||
@@ -4,7 +4,6 @@
|
|||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
#include <dlfcn.h>
|
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@@ -13,6 +12,8 @@
|
|||||||
#include "mozilla/Assertions.h"
|
#include "mozilla/Assertions.h"
|
||||||
#include "mozilla/DebugOnly.h"
|
#include "mozilla/DebugOnly.h"
|
||||||
|
|
||||||
|
#include "InterposerHelper.h"
|
||||||
|
|
||||||
using mozilla::DebugOnly;
|
using mozilla::DebugOnly;
|
||||||
|
|
||||||
struct SigAltStack {
|
struct SigAltStack {
|
||||||
@@ -83,30 +84,12 @@ void* set_alt_signal_stack_and_start(PthreadCreateParams* params) {
|
|||||||
return thread_rv;
|
return thread_rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
using pthread_create_func_t = int (*)(pthread_t*, const pthread_attr_t*,
|
|
||||||
void* (*)(void*), void*);
|
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
// This interposer replaces libpthread's pthread_create() so that we can
|
// This interposer replaces libpthread's pthread_create() so that we can
|
||||||
// inject an alternate signal stack in every new thread.
|
// inject an alternate signal stack in every new thread.
|
||||||
__attribute__((visibility("default"))) int pthread_create(
|
MFBT_API int pthread_create(pthread_t* thread, const pthread_attr_t* attr,
|
||||||
pthread_t* thread, const pthread_attr_t* attr,
|
|
||||||
void* (*start_routine)(void*), void* arg) {
|
void* (*start_routine)(void*), void* arg) {
|
||||||
// static const pthread_create_func_t real_pthread_create =
|
static const auto real_pthread_create = GET_REAL_SYMBOL(pthread_create);
|
||||||
static const pthread_create_func_t real_pthread_create =
|
|
||||||
(pthread_create_func_t)dlsym(RTLD_NEXT, "pthread_create");
|
|
||||||
|
|
||||||
if (real_pthread_create == nullptr) {
|
|
||||||
MOZ_CRASH(
|
|
||||||
"pthread_create() interposition failed but the interposer function is "
|
|
||||||
"still being called, this won't work!");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (real_pthread_create == pthread_create) {
|
|
||||||
MOZ_CRASH(
|
|
||||||
"We could not obtain the real pthread_create(). Calling the symbol we "
|
|
||||||
"got would make us enter an infinte loop so stop here instead.");
|
|
||||||
}
|
|
||||||
|
|
||||||
PthreadCreateParams* params =
|
PthreadCreateParams* params =
|
||||||
(PthreadCreateParams*)malloc(sizeof(PthreadCreateParams));
|
(PthreadCreateParams*)malloc(sizeof(PthreadCreateParams));
|
||||||
@@ -13,6 +13,9 @@ if CONFIG["MOZ_LINKER"] or CONFIG["MOZ_WIDGET_TOOLKIT"] == "android":
|
|||||||
if CONFIG["MOZ_WIDGET_TOOLKIT"] == "android":
|
if CONFIG["MOZ_WIDGET_TOOLKIT"] == "android":
|
||||||
DIRS += ["android"]
|
DIRS += ["android"]
|
||||||
|
|
||||||
|
if CONFIG["OS_ARCH"] == "Linux":
|
||||||
|
DIRS += ["interposers"]
|
||||||
|
|
||||||
DIRS += [
|
DIRS += [
|
||||||
"baseprofiler",
|
"baseprofiler",
|
||||||
"build",
|
"build",
|
||||||
|
|||||||
@@ -53,7 +53,6 @@ if CONFIG["MOZ_CRASHREPORTER"]:
|
|||||||
"google-breakpad/src/common",
|
"google-breakpad/src/common",
|
||||||
"google-breakpad/src/common/linux",
|
"google-breakpad/src/common/linux",
|
||||||
"google-breakpad/src/processor",
|
"google-breakpad/src/processor",
|
||||||
"pthread_create_interposer",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
if CONFIG["MOZ_OXIDIZED_BREAKPAD"]:
|
if CONFIG["MOZ_OXIDIZED_BREAKPAD"]:
|
||||||
|
|||||||
@@ -1,12 +0,0 @@
|
|||||||
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
|
|
||||||
# vim: set filetype=python:
|
|
||||||
# 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/.
|
|
||||||
Library("pthread_create_interposer")
|
|
||||||
|
|
||||||
NoVisibilityFlags()
|
|
||||||
|
|
||||||
UNIFIED_SOURCES += [
|
|
||||||
"pthread_create_interposer.cpp",
|
|
||||||
]
|
|
||||||
Reference in New Issue
Block a user