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
16 #include "mozilla/Assertions.h"
19 static inline T
dlsym_wrapper(void* aHandle
, const char* aName
) {
21 return reinterpret_cast<T
>(__wrap_dlsym(aHandle
, aName
));
23 return reinterpret_cast<T
>(dlsym(aHandle
, aName
));
27 static inline void* dlopen_wrapper(const char* aPath
, int flags
) {
29 return __wrap_dlopen(aPath
, flags
);
31 return dlopen(aPath
, flags
);
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
);
44 if ((real_symbol
== nullptr) || (real_symbol
== aReplacementSymbol
)) {
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 differs 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
52 void* handle
= dlopen_wrapper("libc.so", RTLD_LAZY
);
55 real_symbol
= dlsym_wrapper
<T
>(handle
, aName
);
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!",
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.",
77 #define GET_REAL_SYMBOL(name) get_real_symbol(#name, name)
79 #endif // InterposerHelper_h