Skip to content

Commit d2ac277

Browse files
committed
[compiler-rt] Introduce the notion of an interceptor trampoline
To make the interceptor implementation more flexible, allowing for 2 levels of indirection instead of just 1 in the current scheme (where the intercepted function aliases the interceptor implementation), introduce the notion of an interceptor "trampoline". A trampoline may be a real function (and not just an alias, where aliases of aliases do not work), which will simply forward to the interceptor implementation; the intercepted function will then alias the trampoline: func -[alias]-> trampoline -[call]-> interceptor Make the necessary changes to prepare for introducing real trampolines. This change does not yet introduce any real trampolines, and so trampoline == interceptor, and we currently still just have: func -[alias]-> interceptor NFC. Reviewed By: dvyukov, vitalybuka, MaskRay Differential Revision: https://reviews.llvm.org/D151316
1 parent f3c3f63 commit d2ac277

File tree

3 files changed

+22
-16
lines changed

3 files changed

+22
-16
lines changed

compiler-rt/lib/interception/interception.h

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -118,18 +118,21 @@ const interpose_substitution substitution_##func_name[] \
118118
}
119119

120120
# define WRAP(x) wrap_##x
121+
# define TRAMPOLINE(x) WRAP(x)
121122
# define INTERCEPTOR_ATTRIBUTE
122123
# define DECLARE_WRAPPER(ret_type, func, ...)
123124

124125
#elif SANITIZER_WINDOWS
125126
# define WRAP(x) __asan_wrap_##x
127+
# define TRAMPOLINE(x) WRAP(x)
126128
# define INTERCEPTOR_ATTRIBUTE __declspec(dllexport)
127129
# define DECLARE_WRAPPER(ret_type, func, ...) \
128130
extern "C" ret_type func(__VA_ARGS__);
129131
# define DECLARE_WRAPPER_WINAPI(ret_type, func, ...) \
130132
extern "C" __declspec(dllimport) ret_type __stdcall func(__VA_ARGS__);
131133
#elif SANITIZER_FREEBSD || SANITIZER_NETBSD
132134
# define WRAP(x) __interceptor_ ## x
135+
# define TRAMPOLINE(x) WRAP(x)
133136
# define INTERCEPTOR_ATTRIBUTE __attribute__((visibility("default")))
134137
// FreeBSD's dynamic linker (incompliantly) gives non-weak symbols higher
135138
// priority than weak ones so weak aliases won't work for indirect calls
@@ -139,6 +142,7 @@ const interpose_substitution substitution_##func_name[] \
139142
__attribute__((alias("__interceptor_" #func), visibility("default")));
140143
#elif !SANITIZER_FUCHSIA
141144
# define WRAP(x) __interceptor_ ## x
145+
# define TRAMPOLINE(x) WRAP(x)
142146
# define INTERCEPTOR_ATTRIBUTE __attribute__((visibility("default")))
143147
# define DECLARE_WRAPPER(ret_type, func, ...) \
144148
extern "C" ret_type func(__VA_ARGS__) \
@@ -172,14 +176,16 @@ const interpose_substitution substitution_##func_name[] \
172176
#endif // SANITIZER_APPLE
173177

174178
#if !SANITIZER_FUCHSIA
175-
# define DECLARE_REAL_AND_INTERCEPTOR(ret_type, func, ...) \
179+
# define DECLARE_REAL_AND_INTERCEPTOR(ret_type, func, ...) \
176180
DECLARE_REAL(ret_type, func, __VA_ARGS__) \
181+
extern "C" ret_type TRAMPOLINE(func)(__VA_ARGS__); \
177182
extern "C" ret_type WRAP(func)(__VA_ARGS__);
178183
// Declare an interceptor and its wrapper defined in a different translation
179184
// unit (ex. asm).
180-
# define DECLARE_EXTERN_INTERCEPTOR_AND_WRAPPER(ret_type, func, ...) \
181-
extern "C" ret_type WRAP(func)(__VA_ARGS__); \
182-
extern "C" ret_type func(__VA_ARGS__);
185+
# define DECLARE_EXTERN_INTERCEPTOR_AND_WRAPPER(ret_type, func, ...) \
186+
extern "C" ret_type TRAMPOLINE(func)(__VA_ARGS__); \
187+
extern "C" ret_type WRAP(func)(__VA_ARGS__); \
188+
extern "C" ret_type func(__VA_ARGS__);
183189
#else
184190
# define DECLARE_REAL_AND_INTERCEPTOR(ret_type, func, ...)
185191
# define DECLARE_EXTERN_INTERCEPTOR_AND_WRAPPER(ret_type, func, ...)

compiler-rt/lib/interception/interception_linux.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ static int StrCmp(const char *s1, const char *s2) {
3333
}
3434
#endif
3535

36-
static void *GetFuncAddr(const char *name, uptr wrapper_addr) {
36+
static void *GetFuncAddr(const char *name, uptr trampoline) {
3737
#if SANITIZER_NETBSD
3838
// FIXME: Find a better way to handle renames
3939
if (StrCmp(name, "sigaction"))
@@ -50,17 +50,17 @@ static void *GetFuncAddr(const char *name, uptr wrapper_addr) {
5050

5151
// In case `name' is not loaded, dlsym ends up finding the actual wrapper.
5252
// We don't want to intercept the wrapper and have it point to itself.
53-
if ((uptr)addr == wrapper_addr)
53+
if ((uptr)addr == trampoline)
5454
addr = nullptr;
5555
}
5656
return addr;
5757
}
5858

5959
bool InterceptFunction(const char *name, uptr *ptr_to_real, uptr func,
60-
uptr wrapper) {
61-
void *addr = GetFuncAddr(name, wrapper);
60+
uptr trampoline) {
61+
void *addr = GetFuncAddr(name, trampoline);
6262
*ptr_to_real = (uptr)addr;
63-
return addr && (func == wrapper);
63+
return addr && (func == trampoline);
6464
}
6565

6666
// dlvsym is a GNU extension supported by some other platforms.
@@ -70,12 +70,12 @@ static void *GetFuncAddr(const char *name, const char *ver) {
7070
}
7171

7272
bool InterceptFunction(const char *name, const char *ver, uptr *ptr_to_real,
73-
uptr func, uptr wrapper) {
73+
uptr func, uptr trampoline) {
7474
void *addr = GetFuncAddr(name, ver);
7575
*ptr_to_real = (uptr)addr;
76-
return addr && (func == wrapper);
76+
return addr && (func == trampoline);
7777
}
78-
#endif // SANITIZER_GLIBC || SANITIZER_FREEBSD || SANITIZER_NETBSD
78+
# endif // SANITIZER_GLIBC || SANITIZER_FREEBSD || SANITIZER_NETBSD
7979

8080
} // namespace __interception
8181

compiler-rt/lib/interception/interception_linux.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,17 +23,17 @@
2323

2424
namespace __interception {
2525
bool InterceptFunction(const char *name, uptr *ptr_to_real, uptr func,
26-
uptr wrapper);
26+
uptr trampoline);
2727
bool InterceptFunction(const char *name, const char *ver, uptr *ptr_to_real,
28-
uptr func, uptr wrapper);
28+
uptr func, uptr trampoline);
2929
} // namespace __interception
3030

3131
#define INTERCEPT_FUNCTION_LINUX_OR_FREEBSD(func) \
3232
::__interception::InterceptFunction( \
3333
#func, \
3434
(::__interception::uptr *) & REAL(func), \
3535
(::__interception::uptr) & (func), \
36-
(::__interception::uptr) & WRAP(func))
36+
(::__interception::uptr) & TRAMPOLINE(func))
3737

3838
// dlvsym is a GNU extension supported by some other platforms.
3939
#if SANITIZER_GLIBC || SANITIZER_FREEBSD || SANITIZER_NETBSD
@@ -42,7 +42,7 @@ bool InterceptFunction(const char *name, const char *ver, uptr *ptr_to_real,
4242
#func, symver, \
4343
(::__interception::uptr *) & REAL(func), \
4444
(::__interception::uptr) & (func), \
45-
(::__interception::uptr) & WRAP(func))
45+
(::__interception::uptr) & TRAMPOLINE(func))
4646
#else
4747
#define INTERCEPT_FUNCTION_VER_LINUX_OR_FREEBSD(func, symver) \
4848
INTERCEPT_FUNCTION_LINUX_OR_FREEBSD(func)

0 commit comments

Comments
 (0)