drd/tests/swapcontext: Improve the portability of this test further
[valgrind.git] / drd / drd_libstdcxx_intercepts.c
blobf0fb0871d89a00ee7c3379c0a8174fb2c62922d4
1 /*--------------------------------------------------------------------*/
2 /*--- Client-space code for DRD. drd_libstdcxx_intercepts.c ---*/
3 /*--------------------------------------------------------------------*/
5 /*
6 This file is part of DRD, a thread error detector.
8 Copyright (C) 2014-2017 Bart Van Assche <bvanassche@acm.org>.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2 of the
13 License, or (at your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, see <http://www.gnu.org/licenses/>.
23 The GNU General Public License is contained in the file COPYING.
26 /* ---------------------------------------------------------------------
27 ALL THE CODE IN THIS FILE RUNS ON THE SIMULATED CPU.
29 These functions are not called directly - they're the targets of code
30 redirection or load notifications (see pub_core_redir.h for info).
31 They're named weirdly so that the intercept code can find them when the
32 shared object is initially loaded.
34 Note that this filename has the "drd_" prefix because it can appear
35 in stack traces, and the "drd_" makes it a little clearer that it
36 originates from Valgrind.
37 ------------------------------------------------------------------ */
39 #include "drd_basics.h" /* DRD_() */
40 #include "drd_clientreq.h"
41 #include "pub_tool_redir.h" /* VG_WRAP_FUNCTION_ZZ() */
43 /* From <cxxabi.h> */
44 int __cxa_guard_acquire(void* guard);
45 void __cxa_guard_release(void* guard) __attribute__((__nothrow__));
46 void __cxa_guard_abort(void* guard) __attribute__((__nothrow__));
48 #define LIBSTDCXX_FUNC(ret_ty, zf, implf, argl_decl, argl) \
49 ret_ty VG_WRAP_FUNCTION_ZZ(VG_Z_LIBSTDCXX_SONAME,zf) argl_decl; \
50 ret_ty VG_WRAP_FUNCTION_ZZ(VG_Z_LIBSTDCXX_SONAME,zf) argl_decl \
51 { return implf argl; }
54 * Not inlining one of the intercept functions will cause the regression
55 * tests to fail because this would cause an additional stackfram to appear
56 * in the output. The __always_inline macro guarantees that inlining will
57 * happen, even when compiling with optimization disabled.
59 #undef __always_inline /* since already defined in <cdefs.h> */
60 #if __GNUC__ > 3 || __GNUC__ == 3 && __GNUC_MINOR__ >= 2
61 #define __always_inline __inline__ __attribute__((always_inline))
62 #else
63 #define __always_inline __inline__
64 #endif
66 static __always_inline
67 int __cxa_guard_acquire_intercept(void *guard)
69 int ret;
70 OrigFn fn;
71 VALGRIND_GET_ORIG_FN(fn);
72 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__PRE_MUTEX_LOCK,
73 guard, mutex_type_cxa_guard, 0, 0, 0);
74 CALL_FN_W_W(ret, fn, guard);
75 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__POST_MUTEX_LOCK,
76 guard, 1, 0, 0, 0);
77 if (ret == 0) {
78 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__PRE_MUTEX_UNLOCK,
79 guard, mutex_type_cxa_guard, 0, 0, 0);
80 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__POST_MUTEX_UNLOCK,
81 guard, 0, 0, 0, 0);
83 return ret;
86 LIBSTDCXX_FUNC(int, ZuZucxaZuguardZuacquire, __cxa_guard_acquire_intercept,
87 (void *guard), (guard));
88 LIBSTDCXX_FUNC(int, ZuZucxaZuguardZuacquireZAZACXXABIZu1Zd3,
89 __cxa_guard_acquire_intercept, (void *guard), (guard));
91 static __always_inline
92 void __cxa_guard_abort_release_intercept(void *guard)
94 int ret;
95 OrigFn fn;
96 VALGRIND_GET_ORIG_FN(fn);
97 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__PRE_MUTEX_UNLOCK,
98 guard, mutex_type_cxa_guard, 0, 0, 0);
99 CALL_FN_W_W(ret, fn, guard);
100 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__POST_MUTEX_UNLOCK,
101 guard, 0, 0, 0, 0);
104 LIBSTDCXX_FUNC(void, ZuZucxaZuguardZurelease,
105 __cxa_guard_abort_release_intercept, (void *guard), (guard));
106 LIBSTDCXX_FUNC(void, ZuZucxaZuguardZuabort,
107 __cxa_guard_abort_release_intercept, (void *guard), (guard));