1 /*--------------------------------------------------------------------*/
2 /*--- Client-space code for DRD. drd_libstdcxx_intercepts.c ---*/
3 /*--------------------------------------------------------------------*/
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() */
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))
63 #define __always_inline __inline__
66 static __always_inline
67 int __cxa_guard_acquire_intercept(void *guard
)
71 VALGRIND_GET_ORIG_FN(fn
);
72 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ_DRD_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_DRD_POST_MUTEX_LOCK
,
78 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ_DRD_PRE_MUTEX_UNLOCK
,
79 guard
, mutex_type_cxa_guard
, 0, 0, 0);
80 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ_DRD_POST_MUTEX_UNLOCK
,
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
)
96 VALGRIND_GET_ORIG_FN(fn
);
97 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ_DRD_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_DRD_POST_MUTEX_UNLOCK
,
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
));