1 /*--------------------------------------------------------------------*/
2 /*--- Client-space code for drd. drd_qtcore_intercepts.c ---*/
3 /*--------------------------------------------------------------------*/
6 This file is part of drd, a thread error detector.
8 Copyright (C) 2006-2020 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 ------------------------------------------------------------------ */
40 #include "drd_clientreq.h"
41 #include "pub_tool_redir.h"
46 #define QT4CORE_FUNC(ret_ty, f, args...) \
47 ret_ty VG_WRAP_FUNCTION_ZU(libQtCoreZdsoZd4,f)(args); \
48 ret_ty VG_WRAP_FUNCTION_ZU(libQtCoreZdsoZd4,f)(args)
52 //////////////////////////////////////////////////////////////////
54 //////////////////////////////////////////////////////////////////
57 typedef enum { qt_nonrecursive
= 0, qt_recursive
= 1 } qt_mutex_mode
;
60 /** Convert a Qt4 mutex type to a DRD mutex type. */
61 static MutexT
qt_to_drd_mutex_type(qt_mutex_mode mode
)
66 return mutex_type_default_mutex
;
68 return mutex_type_recursive_mutex
;
70 return mutex_type_invalid_mutex
;
73 /** Find out the type of a Qt4 mutex (recursive or not).
74 * Since it's not possible to do this in a portable way, return
75 * mutex_type_unknown and let drd_mutex.c look up the real mutex type.
77 static MutexT
mutex_type(void* qt4_mutex
)
79 return mutex_type_unknown
;
83 // QMutex::QMutex(RecursionMode) -- _ZN6QMutexC1ENS_13RecursionModeE,
84 QT4CORE_FUNC(void, _ZN6QMutexC1ENS_13RecursionModeE
,
90 VALGRIND_GET_ORIG_FN(fn
);
91 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ_DRD_PRE_MUTEX_INIT
,
92 mutex
, qt_to_drd_mutex_type(mode
), 0, 0, 0);
93 CALL_FN_W_WW(ret
, fn
, mutex
, mode
);
94 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ_DRD_POST_MUTEX_INIT
,
98 // QMutex::QMutex(RecursionMode) -- _ZN6QMutexC2ENS_13RecursionModeE
99 QT4CORE_FUNC(void, _ZN6QMutexC2ENS_13RecursionModeE
,
105 VALGRIND_GET_ORIG_FN(fn
);
106 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ_DRD_PRE_MUTEX_INIT
,
107 mutex
, qt_to_drd_mutex_type(mode
), 0, 0, 0);
108 CALL_FN_W_WW(ret
, fn
, mutex
, mode
);
109 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ_DRD_POST_MUTEX_INIT
,
113 // QMutex::~QMutex() -- _ZN6QMutexD1Ev
114 QT4CORE_FUNC(void, _ZN6QMutexD1Ev
,
119 VALGRIND_GET_ORIG_FN(fn
);
120 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ_DRD_PRE_MUTEX_DESTROY
,
122 CALL_FN_W_W(ret
, fn
, mutex
);
123 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ_DRD_POST_MUTEX_DESTROY
,
124 mutex
, mutex_type(mutex
), 0, 0, 0);
127 // QMutex::~QMutex() -- _ZN6QMutexD2Ev
128 QT4CORE_FUNC(void, _ZN6QMutexD2Ev
,
133 VALGRIND_GET_ORIG_FN(fn
);
134 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ_DRD_PRE_MUTEX_DESTROY
,
136 CALL_FN_W_W(ret
, fn
, mutex
);
137 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ_DRD_POST_MUTEX_DESTROY
,
138 mutex
, mutex_type(mutex
), 0, 0, 0);
141 // QMutex::lock() -- _ZN6QMutex4lockEv
142 QT4CORE_FUNC(void, _ZN6QMutex4lockEv
,
147 VALGRIND_GET_ORIG_FN(fn
);
148 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ_DRD_PRE_MUTEX_LOCK
,
149 mutex
, mutex_type(mutex
), 0, 0, 0);
150 CALL_FN_W_W(ret
, fn
, mutex
);
151 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ_DRD_POST_MUTEX_LOCK
,
155 // QMutex::tryLock() -- _ZN6QMutex7tryLockEv
156 QT4CORE_FUNC(int, _ZN6QMutex7tryLockEv
,
161 VALGRIND_GET_ORIG_FN(fn
);
162 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ_DRD_PRE_MUTEX_LOCK
,
163 mutex
, mutex_type(mutex
), 1, 0, 0);
164 CALL_FN_W_W(ret
, fn
, mutex
);
165 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ_DRD_POST_MUTEX_LOCK
,
166 mutex
, ret
, 0, 0, 0);
170 // QMutex::tryLock(int) -- _ZN6QMutex7tryLockEi
171 QT4CORE_FUNC(int, _ZN6QMutex7tryLockEi
,
177 VALGRIND_GET_ORIG_FN(fn
);
178 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ_DRD_PRE_MUTEX_LOCK
,
179 mutex
, mutex_type(mutex
), 1, 0, 0);
180 CALL_FN_W_WW(ret
, fn
, mutex
, timeout_ms
);
181 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ_DRD_POST_MUTEX_LOCK
,
182 mutex
, ret
, 0, 0, 0);
186 // QMutex::unlock() -- _ZN6QMutex6unlockEv
187 QT4CORE_FUNC(void, _ZN6QMutex6unlockEv
,
192 VALGRIND_GET_ORIG_FN(fn
);
193 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ_DRD_PRE_MUTEX_UNLOCK
,
194 mutex
, mutex_type(mutex
), 0, 0, 0);
195 CALL_FN_W_W(ret
, fn
, mutex
);
196 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ_DRD_POST_MUTEX_UNLOCK
,