Bug 1858509 add thread-safety annotations around MediaSourceDemuxer::mMonitor r=alwu
[gecko.git] / mozglue / interposers / InterposerHelper.h
blobfddc05a163bb91f3cc6a43922c0552ab966be15b
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 #ifndef InterposerHelper_h
6 #define InterposerHelper_h
8 #include <type_traits>
10 #ifdef MOZ_LINKER
11 # include "Linker.h"
12 #else
13 # include <dlfcn.h>
14 #endif
16 #include "mozilla/Assertions.h"
18 template <typename T>
19 static inline T dlsym_wrapper(void* aHandle, const char* aName) {
20 #ifdef MOZ_LINKER
21 return reinterpret_cast<T>(__wrap_dlsym(aHandle, aName));
22 #else
23 return reinterpret_cast<T>(dlsym(aHandle, aName));
24 #endif // MOZ_LINKER
27 static inline void* dlopen_wrapper(const char* aPath, int flags) {
28 #ifdef MOZ_LINKER
29 return __wrap_dlopen(aPath, flags);
30 #else
31 return dlopen(aPath, flags);
32 #endif // MOZ_LINKER
35 template <typename T>
36 static T get_real_symbol(const char* aName, T aReplacementSymbol) {
37 // T can only be a function pointer
38 static_assert(std::is_function<typename std::remove_pointer<T>::type>::value);
40 // Find the corresponding function in the linked libraries
41 T real_symbol = dlsym_wrapper<T>(RTLD_NEXT, aName);
43 #if defined(ANDROID)
44 if (real_symbol == nullptr) {
45 // On old versions of Android the application runtime links in libc before
46 // we get a chance to link libmozglue, so its symbols don't appear when
47 // resolving them with RTLD_NEXT. This behavior differ between the
48 // different versions of Android so we'll just look for them directly into
49 // libc.so. Note that this won't work if we're trying to interpose
50 // functions that are in other libraries, but hopefully we'll never have
51 // to do that.
52 void* handle = dlopen_wrapper("libc.so", RTLD_LAZY);
54 if (handle) {
55 real_symbol = dlsym_wrapper<T>(handle, aName);
58 #endif
60 if (real_symbol == nullptr) {
61 MOZ_CRASH_UNSAFE_PRINTF(
62 "%s() interposition failed but the interposer function is "
63 "still being called, this won't work!",
64 aName);
67 if (real_symbol == aReplacementSymbol) {
68 MOZ_CRASH_UNSAFE_PRINTF(
69 "We could not obtain the real %s(). Calling the symbol we "
70 "got would make us enter an infinite loop so stop here instead.",
71 aName);
74 return real_symbol;
77 #define GET_REAL_SYMBOL(name) get_real_symbol(#name, name)
79 #endif // InterposerHelper_h