drd_libstdcxx_intercepts.c revision f056aab665da328ce8e768dd58de616803efcc14
1f056aab665da328ce8e768dd58de616803efcc14bart/*--------------------------------------------------------------------*/ 2f056aab665da328ce8e768dd58de616803efcc14bart/*--- Client-space code for DRD. drd_libstdcxx_intercepts.c ---*/ 3f056aab665da328ce8e768dd58de616803efcc14bart/*--------------------------------------------------------------------*/ 4f056aab665da328ce8e768dd58de616803efcc14bart 5f056aab665da328ce8e768dd58de616803efcc14bart/* 6f056aab665da328ce8e768dd58de616803efcc14bart This file is part of DRD, a thread error detector. 7f056aab665da328ce8e768dd58de616803efcc14bart 8f056aab665da328ce8e768dd58de616803efcc14bart Copyright (C) 2014 Bart Van Assche <bvanassche@acm.org>. 9f056aab665da328ce8e768dd58de616803efcc14bart 10f056aab665da328ce8e768dd58de616803efcc14bart This program is free software; you can redistribute it and/or 11f056aab665da328ce8e768dd58de616803efcc14bart modify it under the terms of the GNU General Public License as 12f056aab665da328ce8e768dd58de616803efcc14bart published by the Free Software Foundation; either version 2 of the 13f056aab665da328ce8e768dd58de616803efcc14bart License, or (at your option) any later version. 14f056aab665da328ce8e768dd58de616803efcc14bart 15f056aab665da328ce8e768dd58de616803efcc14bart This program is distributed in the hope that it will be useful, but 16f056aab665da328ce8e768dd58de616803efcc14bart WITHOUT ANY WARRANTY; without even the implied warranty of 17f056aab665da328ce8e768dd58de616803efcc14bart MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18f056aab665da328ce8e768dd58de616803efcc14bart General Public License for more details. 19f056aab665da328ce8e768dd58de616803efcc14bart 20f056aab665da328ce8e768dd58de616803efcc14bart You should have received a copy of the GNU General Public License 21f056aab665da328ce8e768dd58de616803efcc14bart along with this program; if not, write to the Free Software 22f056aab665da328ce8e768dd58de616803efcc14bart Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 23f056aab665da328ce8e768dd58de616803efcc14bart 02111-1307, USA. 24f056aab665da328ce8e768dd58de616803efcc14bart 25f056aab665da328ce8e768dd58de616803efcc14bart The GNU General Public License is contained in the file COPYING. 26f056aab665da328ce8e768dd58de616803efcc14bart*/ 27f056aab665da328ce8e768dd58de616803efcc14bart 28f056aab665da328ce8e768dd58de616803efcc14bart/* --------------------------------------------------------------------- 29f056aab665da328ce8e768dd58de616803efcc14bart ALL THE CODE IN THIS FILE RUNS ON THE SIMULATED CPU. 30f056aab665da328ce8e768dd58de616803efcc14bart 31f056aab665da328ce8e768dd58de616803efcc14bart These functions are not called directly - they're the targets of code 32f056aab665da328ce8e768dd58de616803efcc14bart redirection or load notifications (see pub_core_redir.h for info). 33f056aab665da328ce8e768dd58de616803efcc14bart They're named weirdly so that the intercept code can find them when the 34f056aab665da328ce8e768dd58de616803efcc14bart shared object is initially loaded. 35f056aab665da328ce8e768dd58de616803efcc14bart 36f056aab665da328ce8e768dd58de616803efcc14bart Note that this filename has the "drd_" prefix because it can appear 37f056aab665da328ce8e768dd58de616803efcc14bart in stack traces, and the "drd_" makes it a little clearer that it 38f056aab665da328ce8e768dd58de616803efcc14bart originates from Valgrind. 39f056aab665da328ce8e768dd58de616803efcc14bart ------------------------------------------------------------------ */ 40f056aab665da328ce8e768dd58de616803efcc14bart 41f056aab665da328ce8e768dd58de616803efcc14bart#include "drd_basics.h" /* DRD_() */ 42f056aab665da328ce8e768dd58de616803efcc14bart#include "drd_clientreq.h" 43f056aab665da328ce8e768dd58de616803efcc14bart#include "pub_tool_redir.h" /* VG_WRAP_FUNCTION_ZZ() */ 44f056aab665da328ce8e768dd58de616803efcc14bart 45f056aab665da328ce8e768dd58de616803efcc14bart/* From <cxxabi.h> */ 46f056aab665da328ce8e768dd58de616803efcc14bartint __cxa_guard_acquire(void* guard); 47f056aab665da328ce8e768dd58de616803efcc14bartvoid __cxa_guard_release(void* guard) __attribute__((__nothrow__)); 48f056aab665da328ce8e768dd58de616803efcc14bartvoid __cxa_guard_abort(void* guard) __attribute__((__nothrow__)); 49f056aab665da328ce8e768dd58de616803efcc14bart 50f056aab665da328ce8e768dd58de616803efcc14bart#define LIBSTDCXX_FUNC(ret_ty, zf, implf, argl_decl, argl) \ 51f056aab665da328ce8e768dd58de616803efcc14bart ret_ty VG_WRAP_FUNCTION_ZZ(VG_Z_LIBSTDCXX_SONAME,zf) argl_decl; \ 52f056aab665da328ce8e768dd58de616803efcc14bart ret_ty VG_WRAP_FUNCTION_ZZ(VG_Z_LIBSTDCXX_SONAME,zf) argl_decl \ 53f056aab665da328ce8e768dd58de616803efcc14bart { return implf argl; } 54f056aab665da328ce8e768dd58de616803efcc14bart 55f056aab665da328ce8e768dd58de616803efcc14bart/* 56f056aab665da328ce8e768dd58de616803efcc14bart * Not inlining one of the intercept functions will cause the regression 57f056aab665da328ce8e768dd58de616803efcc14bart * tests to fail because this would cause an additional stackfram to appear 58f056aab665da328ce8e768dd58de616803efcc14bart * in the output. The __always_inline macro guarantees that inlining will 59f056aab665da328ce8e768dd58de616803efcc14bart * happen, even when compiling with optimization disabled. 60f056aab665da328ce8e768dd58de616803efcc14bart */ 61f056aab665da328ce8e768dd58de616803efcc14bart#undef __always_inline /* since already defined in <cdefs.h> */ 62f056aab665da328ce8e768dd58de616803efcc14bart#if __GNUC__ > 3 || __GNUC__ == 3 && __GNUC_MINOR__ >= 2 63f056aab665da328ce8e768dd58de616803efcc14bart#define __always_inline __inline__ __attribute__((always_inline)) 64f056aab665da328ce8e768dd58de616803efcc14bart#else 65f056aab665da328ce8e768dd58de616803efcc14bart#define __always_inline __inline__ 66f056aab665da328ce8e768dd58de616803efcc14bart#endif 67f056aab665da328ce8e768dd58de616803efcc14bart 68f056aab665da328ce8e768dd58de616803efcc14bartstatic __always_inline 69f056aab665da328ce8e768dd58de616803efcc14bartint __cxa_guard_acquire_intercept(void *guard) 70f056aab665da328ce8e768dd58de616803efcc14bart{ 71f056aab665da328ce8e768dd58de616803efcc14bart int ret; 72f056aab665da328ce8e768dd58de616803efcc14bart OrigFn fn; 73f056aab665da328ce8e768dd58de616803efcc14bart VALGRIND_GET_ORIG_FN(fn); 74f056aab665da328ce8e768dd58de616803efcc14bart VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__PRE_MUTEX_LOCK, 75f056aab665da328ce8e768dd58de616803efcc14bart guard, mutex_type_cxa_guard, 0, 0, 0); 76f056aab665da328ce8e768dd58de616803efcc14bart CALL_FN_W_W(ret, fn, guard); 77f056aab665da328ce8e768dd58de616803efcc14bart VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__POST_MUTEX_LOCK, 78f056aab665da328ce8e768dd58de616803efcc14bart guard, 1, 0, 0, 0); 79f056aab665da328ce8e768dd58de616803efcc14bart if (ret == 0) { 80f056aab665da328ce8e768dd58de616803efcc14bart VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__PRE_MUTEX_UNLOCK, 81f056aab665da328ce8e768dd58de616803efcc14bart guard, mutex_type_cxa_guard, 0, 0, 0); 82f056aab665da328ce8e768dd58de616803efcc14bart VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__POST_MUTEX_UNLOCK, 83f056aab665da328ce8e768dd58de616803efcc14bart guard, 0, 0, 0, 0); 84f056aab665da328ce8e768dd58de616803efcc14bart } 85f056aab665da328ce8e768dd58de616803efcc14bart return ret; 86f056aab665da328ce8e768dd58de616803efcc14bart} 87f056aab665da328ce8e768dd58de616803efcc14bart 88f056aab665da328ce8e768dd58de616803efcc14bartLIBSTDCXX_FUNC(int, ZuZucxaZuguardZuacquire, __cxa_guard_acquire_intercept, 89f056aab665da328ce8e768dd58de616803efcc14bart (void *guard), (guard)); 90f056aab665da328ce8e768dd58de616803efcc14bartLIBSTDCXX_FUNC(int, ZuZucxaZuguardZuacquireZAZACXXABIZu1Zd3, 91f056aab665da328ce8e768dd58de616803efcc14bart __cxa_guard_acquire_intercept, (void *guard), (guard)); 92f056aab665da328ce8e768dd58de616803efcc14bart 93f056aab665da328ce8e768dd58de616803efcc14bartstatic __always_inline 94f056aab665da328ce8e768dd58de616803efcc14bartvoid __cxa_guard_abort_release_intercept(void *guard) 95f056aab665da328ce8e768dd58de616803efcc14bart{ 96f056aab665da328ce8e768dd58de616803efcc14bart int ret; 97f056aab665da328ce8e768dd58de616803efcc14bart OrigFn fn; 98f056aab665da328ce8e768dd58de616803efcc14bart VALGRIND_GET_ORIG_FN(fn); 99f056aab665da328ce8e768dd58de616803efcc14bart VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__PRE_MUTEX_UNLOCK, 100f056aab665da328ce8e768dd58de616803efcc14bart guard, mutex_type_cxa_guard, 0, 0, 0); 101f056aab665da328ce8e768dd58de616803efcc14bart CALL_FN_W_W(ret, fn, guard); 102f056aab665da328ce8e768dd58de616803efcc14bart VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__POST_MUTEX_UNLOCK, 103f056aab665da328ce8e768dd58de616803efcc14bart guard, 0, 0, 0, 0); 104f056aab665da328ce8e768dd58de616803efcc14bart} 105f056aab665da328ce8e768dd58de616803efcc14bart 106f056aab665da328ce8e768dd58de616803efcc14bartLIBSTDCXX_FUNC(void, ZuZucxaZuguardZurelease, 107f056aab665da328ce8e768dd58de616803efcc14bart __cxa_guard_abort_release_intercept, (void *guard), (guard)); 108f056aab665da328ce8e768dd58de616803efcc14bartLIBSTDCXX_FUNC(void, ZuZucxaZuguardZuabort, 109f056aab665da328ce8e768dd58de616803efcc14bart __cxa_guard_abort_release_intercept, (void *guard), (guard)); 110