blob: fbb88c3295a79109d6aa33537d71e33d02af3319 [file] [log] [blame]
bartbedfd232009-03-26 19:07:15 +00001/* -*- mode: C; c-basic-offset: 3; -*- */
bart9d9fb662008-07-07 17:27:48 +00002
3/*--------------------------------------------------------------------*/
4/*--- Client-space code for drd. drd_qtcore_intercepts.c ---*/
5/*--------------------------------------------------------------------*/
6
7/*
bart86562bd2009-02-16 19:43:56 +00008 This file is part of drd, a thread error detector.
bart9d9fb662008-07-07 17:27:48 +00009
njn9f207462009-03-10 22:02:09 +000010 Copyright (C) 2006-2009 Bart Van Assche <bart.vanassche@gmail.com>.
bart9d9fb662008-07-07 17:27:48 +000011
12 This program is free software; you can redistribute it and/or
13 modify it under the terms of the GNU General Public License as
14 published by the Free Software Foundation; either version 2 of the
15 License, or (at your option) any later version.
16
17 This program is distributed in the hope that it will be useful, but
18 WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 General Public License for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
25 02111-1307, USA.
26
27 The GNU General Public License is contained in the file COPYING.
28*/
29
30/* ---------------------------------------------------------------------
bart31b983d2010-02-21 14:52:59 +000031 ALL THE CODE IN THIS FILE RUNS ON THE SIMULATED CPU.
bart9d9fb662008-07-07 17:27:48 +000032
33 These functions are not called directly - they're the targets of code
34 redirection or load notifications (see pub_core_redir.h for info).
35 They're named weirdly so that the intercept code can find them when the
36 shared object is initially loaded.
37
38 Note that this filename has the "drd_" prefix because it can appear
39 in stack traces, and the "drd_" makes it a little clearer that it
40 originates from Valgrind.
41 ------------------------------------------------------------------ */
42
43#include <assert.h>
44#include "drd_clientreq.h"
45#include "pub_tool_redir.h"
46
47
48// Defines.
49
bartbedfd232009-03-26 19:07:15 +000050#define QT4CORE_FUNC(ret_ty, f, args...) \
51 ret_ty VG_WRAP_FUNCTION_ZU(libQtCoreZdsoZd4,f)(args); \
52 ret_ty VG_WRAP_FUNCTION_ZU(libQtCoreZdsoZd4,f)(args)
bart9d9fb662008-07-07 17:27:48 +000053
54
55
56//////////////////////////////////////////////////////////////////
57// QMutex intercepts.
58//////////////////////////////////////////////////////////////////
59
60
61typedef enum { qt_nonrecursive = 0, qt_recursive = 1 } qt_mutex_mode;
62
63
64/** Convert a Qt4 mutex type to a DRD mutex type. */
65static MutexT qt_to_drd_mutex_type(qt_mutex_mode mode)
66{
bartbedfd232009-03-26 19:07:15 +000067 switch (mode)
68 {
69 case qt_nonrecursive:
70 return mutex_type_default_mutex;
71 case qt_recursive:
72 return mutex_type_recursive_mutex;
73 }
74 return mutex_type_invalid_mutex;
bart9d9fb662008-07-07 17:27:48 +000075}
76
77/** Find out the type of a Qt4 mutex (recursive or not).
78 * Since it's not possible to do this in a portable way, return
79 * mutex_type_unknown and let drd_mutex.c look up the real mutex type.
80 */
81static MutexT mutex_type(void* qt4_mutex)
82{
bartbedfd232009-03-26 19:07:15 +000083 return mutex_type_unknown;
bart9d9fb662008-07-07 17:27:48 +000084}
85
86
87// QMutex::QMutex(RecursionMode) -- _ZN6QMutexC1ENS_13RecursionModeE,
88QT4CORE_FUNC(void, _ZN6QMutexC1ENS_13RecursionModeE,
89 void* mutex,
90 qt_mutex_mode mode)
91{
bartbedfd232009-03-26 19:07:15 +000092 int ret;
93 int res;
94 OrigFn fn;
95 VALGRIND_GET_ORIG_FN(fn);
96 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_MUTEX_INIT,
97 mutex, qt_to_drd_mutex_type(mode), 0, 0, 0);
98 CALL_FN_W_WW(ret, fn, mutex, mode);
99 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_MUTEX_INIT,
100 mutex, 0, 0, 0, 0);
bart9d9fb662008-07-07 17:27:48 +0000101}
102
103// QMutex::QMutex(RecursionMode) -- _ZN6QMutexC2ENS_13RecursionModeE
104QT4CORE_FUNC(void, _ZN6QMutexC2ENS_13RecursionModeE,
105 void* mutex,
106 qt_mutex_mode mode)
107{
bartbedfd232009-03-26 19:07:15 +0000108 int ret;
109 int res;
110 OrigFn fn;
111 VALGRIND_GET_ORIG_FN(fn);
112 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_MUTEX_INIT,
113 mutex, qt_to_drd_mutex_type(mode), 0, 0, 0);
114 CALL_FN_W_WW(ret, fn, mutex, mode);
115 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_MUTEX_INIT,
116 mutex, 0, 0, 0, 0);
bart9d9fb662008-07-07 17:27:48 +0000117}
118
119// QMutex::~QMutex() -- _ZN6QMutexD1Ev
120QT4CORE_FUNC(void, _ZN6QMutexD1Ev,
121 void* mutex)
122{
bartbedfd232009-03-26 19:07:15 +0000123 int ret;
124 int res;
125 OrigFn fn;
126 VALGRIND_GET_ORIG_FN(fn);
127 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_MUTEX_DESTROY,
128 mutex, 0, 0, 0, 0);
129 CALL_FN_W_W(ret, fn, mutex);
130 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_MUTEX_DESTROY,
131 mutex, mutex_type(mutex), 0, 0, 0);
bart9d9fb662008-07-07 17:27:48 +0000132}
133
134// QMutex::~QMutex() -- _ZN6QMutexD2Ev
135QT4CORE_FUNC(void, _ZN6QMutexD2Ev,
136 void** mutex)
137{
bartbedfd232009-03-26 19:07:15 +0000138 int ret;
139 int res;
140 OrigFn fn;
141 VALGRIND_GET_ORIG_FN(fn);
142 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_MUTEX_DESTROY,
143 mutex, 0, 0, 0, 0);
144 CALL_FN_W_W(ret, fn, mutex);
145 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_MUTEX_DESTROY,
146 mutex, mutex_type(mutex), 0, 0, 0);
bart9d9fb662008-07-07 17:27:48 +0000147}
148
149// QMutex::lock() -- _ZN6QMutex4lockEv
150QT4CORE_FUNC(void, _ZN6QMutex4lockEv,
151 void* mutex)
152{
bartbedfd232009-03-26 19:07:15 +0000153 int ret;
154 int res;
155 OrigFn fn;
156 VALGRIND_GET_ORIG_FN(fn);
157 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__PRE_MUTEX_LOCK,
158 mutex, mutex_type(mutex), 0, 0, 0);
159 CALL_FN_W_W(ret, fn, mutex);
160 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__POST_MUTEX_LOCK,
161 mutex, 1, 0, 0, 0);
bart9d9fb662008-07-07 17:27:48 +0000162}
163
164// QMutex::tryLock() -- _ZN6QMutex7tryLockEv
165QT4CORE_FUNC(int, _ZN6QMutex7tryLockEv,
166 void* mutex)
167{
bartbedfd232009-03-26 19:07:15 +0000168 int ret;
169 int res;
170 OrigFn fn;
171 VALGRIND_GET_ORIG_FN(fn);
172 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__PRE_MUTEX_LOCK,
173 mutex, mutex_type(mutex), 1, 0, 0);
174 CALL_FN_W_W(ret, fn, mutex);
175 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_MUTEX_LOCK,
176 mutex, ret, 0, 0, 0);
177 return ret;
bart9d9fb662008-07-07 17:27:48 +0000178}
179
180// QMutex::tryLock(int) -- _ZN6QMutex7tryLockEi
181QT4CORE_FUNC(int, _ZN6QMutex7tryLockEi,
182 void* mutex,
bart83473622008-07-07 18:36:45 +0000183 int timeout_ms)
bart9d9fb662008-07-07 17:27:48 +0000184{
bartbedfd232009-03-26 19:07:15 +0000185 int ret;
186 int res;
187 OrigFn fn;
188 VALGRIND_GET_ORIG_FN(fn);
189 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__PRE_MUTEX_LOCK,
190 mutex, mutex_type(mutex), 1, 0, 0);
191 CALL_FN_W_WW(ret, fn, mutex, timeout_ms);
192 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_MUTEX_LOCK,
193 mutex, ret, 0, 0, 0);
194 return ret;
bart9d9fb662008-07-07 17:27:48 +0000195}
196
197// QMutex::unlock() -- _ZN6QMutex6unlockEv
198QT4CORE_FUNC(void, _ZN6QMutex6unlockEv,
199 void* mutex)
200{
bartbedfd232009-03-26 19:07:15 +0000201 int ret;
202 int res;
203 OrigFn fn;
204 VALGRIND_GET_ORIG_FN(fn);
205 VALGRIND_DO_CLIENT_REQUEST(res, -1,
206 VG_USERREQ__PRE_MUTEX_UNLOCK,
207 mutex, mutex_type(mutex), 0, 0, 0);
208 CALL_FN_W_W(ret, fn, mutex);
209 VALGRIND_DO_CLIENT_REQUEST(res, -1,
210 VG_USERREQ__POST_MUTEX_UNLOCK,
211 mutex, 0, 0, 0, 0);
bart9d9fb662008-07-07 17:27:48 +0000212}