summaryrefslogtreecommitdiff
path: root/lib/interception/interception.h
diff options
context:
space:
mode:
authorAlexander Potapenko <glider@google.com>2012-08-17 09:00:08 +0000
committerAlexander Potapenko <glider@google.com>2012-08-17 09:00:08 +0000
commit0ef531054fc25c11e372cbab1384f10954984219 (patch)
treea6952b51cb50a52ded620a97e0fdce096e410d38 /lib/interception/interception.h
parentbbbb20b7212155ebc5b5b4ee1c68c987dcf30320 (diff)
downloadcompiler-rt-0ef531054fc25c11e372cbab1384f10954984219.tar.gz
compiler-rt-0ef531054fc25c11e372cbab1384f10954984219.tar.bz2
compiler-rt-0ef531054fc25c11e372cbab1384f10954984219.tar.xz
Commit the source and CMake changes that will allow to build ASan runtime
as a shared library on Mac OS. This will provide an alternative to mach_override. git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@162091 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/interception/interception.h')
-rw-r--r--lib/interception/interception.h48
1 files changed, 34 insertions, 14 deletions
diff --git a/lib/interception/interception.h b/lib/interception/interception.h
index d0505237..b52a1067 100644
--- a/lib/interception/interception.h
+++ b/lib/interception/interception.h
@@ -75,6 +75,16 @@
// mach_override, a handy framework for patching functions at runtime.
// To avoid possible name clashes, our replacement functions have
// the "wrap_" prefix on Mac.
+// An alternative to function patching is to create a dylib containing a
+// __DATA,__interpose section that associates library functions with their
+// wrappers. When this dylib is preloaded before an executable using
+// DYLD_INSERT_LIBRARIES, it routes all the calls to interposed functions done
+// through stubs to the wrapper functions. Such a library is built with
+// -DMAC_INTERPOSE_FUNCTIONS=1.
+
+#if !defined(MAC_INTERPOSE_FUNCTIONS) || !defined(__APPLE__)
+# define MAC_INTERPOSE_FUNCTIONS 0
+#endif
#if defined(__APPLE__)
# define WRAP(x) wrap_##x
@@ -101,15 +111,21 @@
__attribute__((weak, alias("__interceptor_" #func), visibility("default")));
#endif
-#define PTR_TO_REAL(x) real_##x
-#define REAL(x) __interception::PTR_TO_REAL(x)
-#define FUNC_TYPE(x) x##_f
-
-#define DECLARE_REAL(ret_type, func, ...) \
- typedef ret_type (*FUNC_TYPE(func))(__VA_ARGS__); \
- namespace __interception { \
- extern FUNC_TYPE(func) PTR_TO_REAL(func); \
- }
+#if !MAC_INTERPOSE_FUNCTIONS
+# define PTR_TO_REAL(x) real_##x
+# define REAL(x) __interception::PTR_TO_REAL(x)
+# define FUNC_TYPE(x) x##_f
+
+# define DECLARE_REAL(ret_type, func, ...) \
+ typedef ret_type (*FUNC_TYPE(func))(__VA_ARGS__); \
+ namespace __interception { \
+ extern FUNC_TYPE(func) PTR_TO_REAL(func); \
+ }
+#else // MAC_INTERPOSE_FUNCTIONS
+# define REAL(x) x
+# define DECLARE_REAL(ret_type, func, ...) \
+ extern "C" ret_type func(__VA_ARGS__);
+#endif // MAC_INTERPOSE_FUNCTIONS
#define DECLARE_REAL_AND_INTERCEPTOR(ret_type, func, ...) \
DECLARE_REAL(ret_type, func, ##__VA_ARGS__) \
@@ -118,11 +134,15 @@
// FIXME(timurrrr): We might need to add DECLARE_REAL_EX etc to support
// different calling conventions later.
-#define DEFINE_REAL_EX(ret_type, convention, func, ...) \
- typedef ret_type (convention *FUNC_TYPE(func))(__VA_ARGS__); \
- namespace __interception { \
- FUNC_TYPE(func) PTR_TO_REAL(func); \
- }
+#if !MAC_INTERPOSE_FUNCTIONS
+# define DEFINE_REAL_EX(ret_type, convention, func, ...) \
+ typedef ret_type (convention *FUNC_TYPE(func))(__VA_ARGS__); \
+ namespace __interception { \
+ FUNC_TYPE(func) PTR_TO_REAL(func); \
+ }
+#else
+# define DEFINE_REAL_EX(ret_type, convention, func, ...)
+#endif
// Generally, you don't need to use DEFINE_REAL by itself, as INTERCEPTOR
// macros does its job. In exceptional cases you may need to call REAL(foo)