blob: ed80a6f17db3d48bcf1b326446b81b5713d9c976 [file] [log] [blame]
bart9d9fb662008-07-07 17:27:48 +00001/*--------------------------------------------------------------------*/
2/*--- Client-space code for drd. drd_qtcore_intercepts.c ---*/
3/*--------------------------------------------------------------------*/
4
5/*
bart86562bd2009-02-16 19:43:56 +00006 This file is part of drd, a thread error detector.
bart9d9fb662008-07-07 17:27:48 +00007
Elliott Hughesed398002017-06-21 14:41:24 -07008 Copyright (C) 2006-2017 Bart Van Assche <bvanassche@acm.org>.
bart9d9fb662008-07-07 17:27:48 +00009
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.
14
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.
19
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
23 02111-1307, USA.
24
25 The GNU General Public License is contained in the file COPYING.
26*/
27
28/* ---------------------------------------------------------------------
bart31b983d2010-02-21 14:52:59 +000029 ALL THE CODE IN THIS FILE RUNS ON THE SIMULATED CPU.
bart9d9fb662008-07-07 17:27:48 +000030
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.
35
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 ------------------------------------------------------------------ */
40
41#include <assert.h>
42#include "drd_clientreq.h"
43#include "pub_tool_redir.h"
44
45
46// Defines.
47
bartbedfd232009-03-26 19:07:15 +000048#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)
bart9d9fb662008-07-07 17:27:48 +000051
52
53
54//////////////////////////////////////////////////////////////////
55// QMutex intercepts.
56//////////////////////////////////////////////////////////////////
57
58
59typedef enum { qt_nonrecursive = 0, qt_recursive = 1 } qt_mutex_mode;
60
61
62/** Convert a Qt4 mutex type to a DRD mutex type. */
63static MutexT qt_to_drd_mutex_type(qt_mutex_mode mode)
64{
bartbedfd232009-03-26 19:07:15 +000065 switch (mode)
66 {
67 case qt_nonrecursive:
68 return mutex_type_default_mutex;
69 case qt_recursive:
70 return mutex_type_recursive_mutex;
71 }
72 return mutex_type_invalid_mutex;
bart9d9fb662008-07-07 17:27:48 +000073}
74
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.
78 */
79static MutexT mutex_type(void* qt4_mutex)
80{
bartbedfd232009-03-26 19:07:15 +000081 return mutex_type_unknown;
bart9d9fb662008-07-07 17:27:48 +000082}
83
84
85// QMutex::QMutex(RecursionMode) -- _ZN6QMutexC1ENS_13RecursionModeE,
86QT4CORE_FUNC(void, _ZN6QMutexC1ENS_13RecursionModeE,
87 void* mutex,
88 qt_mutex_mode mode)
89{
bartbedfd232009-03-26 19:07:15 +000090 int ret;
bartbedfd232009-03-26 19:07:15 +000091 OrigFn fn;
92 VALGRIND_GET_ORIG_FN(fn);
bartfc4c28f2013-10-01 16:55:58 +000093 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__PRE_MUTEX_INIT,
bart575ce8e2011-05-15 07:04:03 +000094 mutex, qt_to_drd_mutex_type(mode), 0, 0, 0);
bartbedfd232009-03-26 19:07:15 +000095 CALL_FN_W_WW(ret, fn, mutex, mode);
bartfc4c28f2013-10-01 16:55:58 +000096 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__POST_MUTEX_INIT,
bart575ce8e2011-05-15 07:04:03 +000097 mutex, 0, 0, 0, 0);
bart9d9fb662008-07-07 17:27:48 +000098}
99
100// QMutex::QMutex(RecursionMode) -- _ZN6QMutexC2ENS_13RecursionModeE
101QT4CORE_FUNC(void, _ZN6QMutexC2ENS_13RecursionModeE,
102 void* mutex,
103 qt_mutex_mode mode)
104{
bartbedfd232009-03-26 19:07:15 +0000105 int ret;
bartbedfd232009-03-26 19:07:15 +0000106 OrigFn fn;
107 VALGRIND_GET_ORIG_FN(fn);
bartfc4c28f2013-10-01 16:55:58 +0000108 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__PRE_MUTEX_INIT,
bart575ce8e2011-05-15 07:04:03 +0000109 mutex, qt_to_drd_mutex_type(mode), 0, 0, 0);
bartbedfd232009-03-26 19:07:15 +0000110 CALL_FN_W_WW(ret, fn, mutex, mode);
bartfc4c28f2013-10-01 16:55:58 +0000111 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__POST_MUTEX_INIT,
bart575ce8e2011-05-15 07:04:03 +0000112 mutex, 0, 0, 0, 0);
bart9d9fb662008-07-07 17:27:48 +0000113}
114
115// QMutex::~QMutex() -- _ZN6QMutexD1Ev
116QT4CORE_FUNC(void, _ZN6QMutexD1Ev,
117 void* mutex)
118{
bartbedfd232009-03-26 19:07:15 +0000119 int ret;
bartbedfd232009-03-26 19:07:15 +0000120 OrigFn fn;
121 VALGRIND_GET_ORIG_FN(fn);
bartfc4c28f2013-10-01 16:55:58 +0000122 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__PRE_MUTEX_DESTROY,
bart575ce8e2011-05-15 07:04:03 +0000123 mutex, 0, 0, 0, 0);
bartbedfd232009-03-26 19:07:15 +0000124 CALL_FN_W_W(ret, fn, mutex);
bartfc4c28f2013-10-01 16:55:58 +0000125 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__POST_MUTEX_DESTROY,
bart575ce8e2011-05-15 07:04:03 +0000126 mutex, mutex_type(mutex), 0, 0, 0);
bart9d9fb662008-07-07 17:27:48 +0000127}
128
129// QMutex::~QMutex() -- _ZN6QMutexD2Ev
130QT4CORE_FUNC(void, _ZN6QMutexD2Ev,
131 void** mutex)
132{
bartbedfd232009-03-26 19:07:15 +0000133 int ret;
bartbedfd232009-03-26 19:07:15 +0000134 OrigFn fn;
135 VALGRIND_GET_ORIG_FN(fn);
bartfc4c28f2013-10-01 16:55:58 +0000136 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__PRE_MUTEX_DESTROY,
bart575ce8e2011-05-15 07:04:03 +0000137 mutex, 0, 0, 0, 0);
bartbedfd232009-03-26 19:07:15 +0000138 CALL_FN_W_W(ret, fn, mutex);
bartfc4c28f2013-10-01 16:55:58 +0000139 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__POST_MUTEX_DESTROY,
bart575ce8e2011-05-15 07:04:03 +0000140 mutex, mutex_type(mutex), 0, 0, 0);
bart9d9fb662008-07-07 17:27:48 +0000141}
142
143// QMutex::lock() -- _ZN6QMutex4lockEv
144QT4CORE_FUNC(void, _ZN6QMutex4lockEv,
145 void* mutex)
146{
bartbedfd232009-03-26 19:07:15 +0000147 int ret;
bartbedfd232009-03-26 19:07:15 +0000148 OrigFn fn;
149 VALGRIND_GET_ORIG_FN(fn);
bartfc4c28f2013-10-01 16:55:58 +0000150 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__PRE_MUTEX_LOCK,
bart575ce8e2011-05-15 07:04:03 +0000151 mutex, mutex_type(mutex), 0, 0, 0);
bartbedfd232009-03-26 19:07:15 +0000152 CALL_FN_W_W(ret, fn, mutex);
bartfc4c28f2013-10-01 16:55:58 +0000153 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__POST_MUTEX_LOCK,
bart575ce8e2011-05-15 07:04:03 +0000154 mutex, 1, 0, 0, 0);
bart9d9fb662008-07-07 17:27:48 +0000155}
156
157// QMutex::tryLock() -- _ZN6QMutex7tryLockEv
158QT4CORE_FUNC(int, _ZN6QMutex7tryLockEv,
159 void* mutex)
160{
bartbedfd232009-03-26 19:07:15 +0000161 int ret;
bartbedfd232009-03-26 19:07:15 +0000162 OrigFn fn;
163 VALGRIND_GET_ORIG_FN(fn);
bartfc4c28f2013-10-01 16:55:58 +0000164 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__PRE_MUTEX_LOCK,
bart575ce8e2011-05-15 07:04:03 +0000165 mutex, mutex_type(mutex), 1, 0, 0);
bartbedfd232009-03-26 19:07:15 +0000166 CALL_FN_W_W(ret, fn, mutex);
bartfc4c28f2013-10-01 16:55:58 +0000167 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__POST_MUTEX_LOCK,
bart575ce8e2011-05-15 07:04:03 +0000168 mutex, ret, 0, 0, 0);
bartbedfd232009-03-26 19:07:15 +0000169 return ret;
bart9d9fb662008-07-07 17:27:48 +0000170}
171
172// QMutex::tryLock(int) -- _ZN6QMutex7tryLockEi
173QT4CORE_FUNC(int, _ZN6QMutex7tryLockEi,
174 void* mutex,
bart83473622008-07-07 18:36:45 +0000175 int timeout_ms)
bart9d9fb662008-07-07 17:27:48 +0000176{
bartbedfd232009-03-26 19:07:15 +0000177 int ret;
bartbedfd232009-03-26 19:07:15 +0000178 OrigFn fn;
179 VALGRIND_GET_ORIG_FN(fn);
bartfc4c28f2013-10-01 16:55:58 +0000180 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__PRE_MUTEX_LOCK,
bart575ce8e2011-05-15 07:04:03 +0000181 mutex, mutex_type(mutex), 1, 0, 0);
bartbedfd232009-03-26 19:07:15 +0000182 CALL_FN_W_WW(ret, fn, mutex, timeout_ms);
bartfc4c28f2013-10-01 16:55:58 +0000183 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__POST_MUTEX_LOCK,
bart575ce8e2011-05-15 07:04:03 +0000184 mutex, ret, 0, 0, 0);
bartbedfd232009-03-26 19:07:15 +0000185 return ret;
bart9d9fb662008-07-07 17:27:48 +0000186}
187
188// QMutex::unlock() -- _ZN6QMutex6unlockEv
189QT4CORE_FUNC(void, _ZN6QMutex6unlockEv,
190 void* mutex)
191{
bartbedfd232009-03-26 19:07:15 +0000192 int ret;
bartbedfd232009-03-26 19:07:15 +0000193 OrigFn fn;
194 VALGRIND_GET_ORIG_FN(fn);
bartfc4c28f2013-10-01 16:55:58 +0000195 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__PRE_MUTEX_UNLOCK,
bart575ce8e2011-05-15 07:04:03 +0000196 mutex, mutex_type(mutex), 0, 0, 0);
bartbedfd232009-03-26 19:07:15 +0000197 CALL_FN_W_W(ret, fn, mutex);
bartfc4c28f2013-10-01 16:55:58 +0000198 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__POST_MUTEX_UNLOCK,
bart575ce8e2011-05-15 07:04:03 +0000199 mutex, 0, 0, 0, 0);
bart9d9fb662008-07-07 17:27:48 +0000200}