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-2013 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, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
25 The GNU General Public License is contained in the file COPYING.
28 /* ---------------------------------------------------------------------
29 ALL THE CODE IN THIS FILE RUNS ON THE SIMULATED CPU.
31 These functions are not called directly - they're the targets of code
32 redirection or load notifications (see pub_core_redir.h for info).
33 They're named weirdly so that the intercept code can find them when the
34 shared object is initially loaded.
36 Note that this filename has the "drd_" prefix because it can appear
37 in stack traces, and the "drd_" makes it a little clearer that it
38 originates from Valgrind.
39 ------------------------------------------------------------------ */
42 #include "drd_clientreq.h"
43 #include "pub_tool_redir.h"
48 #define QT4CORE_FUNC(ret_ty, f, args...) \
49 ret_ty VG_WRAP_FUNCTION_ZU(libQtCoreZdsoZd4,f)(args); \
50 ret_ty VG_WRAP_FUNCTION_ZU(libQtCoreZdsoZd4,f)(args)
54 //////////////////////////////////////////////////////////////////
56 //////////////////////////////////////////////////////////////////
59 typedef enum { qt_nonrecursive
= 0, qt_recursive
= 1 } qt_mutex_mode
;
62 /** Convert a Qt4 mutex type to a DRD mutex type. */
63 static MutexT
qt_to_drd_mutex_type(qt_mutex_mode mode
)
68 return mutex_type_default_mutex
;
70 return mutex_type_recursive_mutex
;
72 return mutex_type_invalid_mutex
;
75 /** Find out the type of a Qt4 mutex (recursive or not).
76 * Since it's not possible to do this in a portable way, return
77 * mutex_type_unknown and let drd_mutex.c look up the real mutex type.
79 static MutexT
mutex_type(void* qt4_mutex
)
81 return mutex_type_unknown
;
85 // QMutex::QMutex(RecursionMode) -- _ZN6QMutexC1ENS_13RecursionModeE,
86 QT4CORE_FUNC(void, _ZN6QMutexC1ENS_13RecursionModeE
,
92 VALGRIND_GET_ORIG_FN(fn
);
93 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__PRE_MUTEX_INIT
,
94 mutex
, qt_to_drd_mutex_type(mode
), 0, 0, 0);
95 CALL_FN_W_WW(ret
, fn
, mutex
, mode
);
96 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__POST_MUTEX_INIT
,
100 // QMutex::QMutex(RecursionMode) -- _ZN6QMutexC2ENS_13RecursionModeE
101 QT4CORE_FUNC(void, _ZN6QMutexC2ENS_13RecursionModeE
,
107 VALGRIND_GET_ORIG_FN(fn
);
108 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__PRE_MUTEX_INIT
,
109 mutex
, qt_to_drd_mutex_type(mode
), 0, 0, 0);
110 CALL_FN_W_WW(ret
, fn
, mutex
, mode
);
111 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__POST_MUTEX_INIT
,
115 // QMutex::~QMutex() -- _ZN6QMutexD1Ev
116 QT4CORE_FUNC(void, _ZN6QMutexD1Ev
,
121 VALGRIND_GET_ORIG_FN(fn
);
122 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__PRE_MUTEX_DESTROY
,
124 CALL_FN_W_W(ret
, fn
, mutex
);
125 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__POST_MUTEX_DESTROY
,
126 mutex
, mutex_type(mutex
), 0, 0, 0);
129 // QMutex::~QMutex() -- _ZN6QMutexD2Ev
130 QT4CORE_FUNC(void, _ZN6QMutexD2Ev
,
135 VALGRIND_GET_ORIG_FN(fn
);
136 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__PRE_MUTEX_DESTROY
,
138 CALL_FN_W_W(ret
, fn
, mutex
);
139 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__POST_MUTEX_DESTROY
,
140 mutex
, mutex_type(mutex
), 0, 0, 0);
143 // QMutex::lock() -- _ZN6QMutex4lockEv
144 QT4CORE_FUNC(void, _ZN6QMutex4lockEv
,
149 VALGRIND_GET_ORIG_FN(fn
);
150 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__PRE_MUTEX_LOCK
,
151 mutex
, mutex_type(mutex
), 0, 0, 0);
152 CALL_FN_W_W(ret
, fn
, mutex
);
153 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__POST_MUTEX_LOCK
,
157 // QMutex::tryLock() -- _ZN6QMutex7tryLockEv
158 QT4CORE_FUNC(int, _ZN6QMutex7tryLockEv
,
163 VALGRIND_GET_ORIG_FN(fn
);
164 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__PRE_MUTEX_LOCK
,
165 mutex
, mutex_type(mutex
), 1, 0, 0);
166 CALL_FN_W_W(ret
, fn
, mutex
);
167 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__POST_MUTEX_LOCK
,
168 mutex
, ret
, 0, 0, 0);
172 // QMutex::tryLock(int) -- _ZN6QMutex7tryLockEi
173 QT4CORE_FUNC(int, _ZN6QMutex7tryLockEi
,
179 VALGRIND_GET_ORIG_FN(fn
);
180 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__PRE_MUTEX_LOCK
,
181 mutex
, mutex_type(mutex
), 1, 0, 0);
182 CALL_FN_W_WW(ret
, fn
, mutex
, timeout_ms
);
183 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__POST_MUTEX_LOCK
,
184 mutex
, ret
, 0, 0, 0);
188 // QMutex::unlock() -- _ZN6QMutex6unlockEv
189 QT4CORE_FUNC(void, _ZN6QMutex6unlockEv
,
194 VALGRIND_GET_ORIG_FN(fn
);
195 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__PRE_MUTEX_UNLOCK
,
196 mutex
, mutex_type(mutex
), 0, 0, 0);
197 CALL_FN_W_W(ret
, fn
, mutex
);
198 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__POST_MUTEX_UNLOCK
,