blob: 8b95cb5aa25627002f538a0143e05961936cf1df [file] [log] [blame]
sewardj024598e2008-09-18 14:43:05 +00001
2/*--------------------------------------------------------------------*/
3/*--- Ptrcheck: a pointer-use checker. pc_intercepts.c ---*/
4/*--------------------------------------------------------------------*/
5
6/*
7 This file is part of Ptrcheck, a Valgrind tool for checking pointer
8 use in programs.
9
10 Copyright (C) 2003-2008 Nicholas Nethercote
11 njn@valgrind.org
12
13 This program is free software; you can redistribute it and/or
14 modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation; either version 2 of the
16 License, or (at your option) any later version.
17
18 This program is distributed in the hope that it will be useful, but
19 WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
26 02111-1307, USA.
27
28 The GNU General Public License is contained in the file COPYING.
29*/
30
31/* Nothing actually in here. However it appears this file is needed
32 to make malloc intercepting work. (jrs, 2 july 08 -- not sure about
33 that).
34*/
35
36#include "pub_tool_basics.h"
37#include "pub_tool_hashtable.h"
38#include "pub_tool_redir.h"
39#include "pub_tool_tooliface.h"
40#include "valgrind.h"
41
42
43/* The following intercepts are copied verbatim from
44 memcheck/mc_replace_strmem.c. */
45
46/* --------- Some handy Z-encoded names. --------- */
47
48/* --- Soname of the standard C library. --- */
49
50#if defined(VGO_linux)
51# define m_libc_soname libcZdsoZa // libc.so*
52#elif defined(VGP_ppc32_aix5)
53 /* AIX has both /usr/lib/libc.a and /usr/lib/libc_r.a. */
54# define m_libc_soname libcZaZdaZLshrZdoZR // libc*.a(shr.o)
55#elif defined(VGP_ppc64_aix5)
56# define m_libc_soname libcZaZdaZLshrZu64ZdoZR // libc*.a(shr_64.o)
57#else
58# error "Unknown platform"
59#endif
60
61/* --- Sonames for Linux ELF linkers. --- */
62
63#define m_ld_linux_so_2 ldZhlinuxZdsoZd2 // ld-linux.so.2
64#define m_ld_linux_x86_64_so_2 ldZhlinuxZhx86Zh64ZdsoZd2 // ld-linux-x86-64.so.2
65#define m_ld64_so_1 ld64ZdsoZd1 // ld64.so.1
66#define m_ld_so_1 ldZdsoZd1 // ld.so.1
67
68
69
70
71#define STRCMP(soname, fnname) \
72 int VG_REPLACE_FUNCTION_ZU(soname,fnname) \
73 ( const char* s1, const char* s2 ); \
74 int VG_REPLACE_FUNCTION_ZU(soname,fnname) \
75 ( const char* s1, const char* s2 ) \
76 { \
77 register unsigned char c1; \
78 register unsigned char c2; \
79 while (True) { \
80 c1 = *(unsigned char *)s1; \
81 c2 = *(unsigned char *)s2; \
82 if (c1 != c2) break; \
83 if (c1 == 0) break; \
84 s1++; s2++; \
85 } \
86 if ((unsigned char)c1 < (unsigned char)c2) return -1; \
87 if ((unsigned char)c1 > (unsigned char)c2) return 1; \
88 return 0; \
89 }
90
91STRCMP(m_libc_soname, strcmp)
92STRCMP(m_ld_linux_x86_64_so_2, strcmp)
93STRCMP(m_ld64_so_1, strcmp)
94
95
96// Note that this replacement often doesn't get used because gcc inlines
97// calls to strlen() with its own built-in version. This can be very
98// confusing if you aren't expecting it. Other small functions in this file
99// may also be inline by gcc.
100#define STRLEN(soname, fnname) \
101 SizeT VG_REPLACE_FUNCTION_ZU(soname,fnname)( const char* str ); \
102 SizeT VG_REPLACE_FUNCTION_ZU(soname,fnname)( const char* str ) \
103 { \
104 SizeT i = 0; \
105 while (str[i] != 0) i++; \
106 return i; \
107 }
108
109STRLEN(m_libc_soname, strlen)
110STRLEN(m_ld_linux_so_2, strlen)
111STRLEN(m_ld_linux_x86_64_so_2, strlen)
112
113
114#define MEMCPY(soname, fnname) \
115 void* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
116 ( void *dst, const void *src, SizeT sz ); \
117 void* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
118 ( void *dest, const void *src, SizeT sz ) \
119 { \
120 const UChar* s = (const UChar*)src; \
121 UChar* d = (UChar*)dest; \
122 const UWord* sW = (const UWord*)src; \
123 UWord* dW = (UWord*)dest; \
124 const UWord al = sizeof(UWord)-1; \
125 \
126 if (0 == (((UWord)dW) & al) && 0 == (((UWord)sW) & al)) { \
127 while (sz >= 4 * sizeof(UWord)) { \
128 dW[0] = sW[0]; \
129 dW[1] = sW[1]; \
130 dW[2] = sW[2]; \
131 dW[3] = sW[3]; \
132 sz -= 4 * sizeof(UWord); \
133 dW += 4; \
134 sW += 4; \
135 } \
136 if (sz == 0) \
137 return dest; \
138 while (sz >= 1 * sizeof(UWord)) { \
139 dW[0] = sW[0]; \
140 sz -= 1 * sizeof(UWord); \
141 dW += 1; \
142 sW += 1; \
143 } \
144 if (sz == 0) \
145 return dest; \
146 s = (const UChar*)sW; \
147 d = (UChar*)dW; \
148 } \
149 \
150 while (sz--) \
151 *d++ = *s++; \
152 \
153 return dest; \
154 }
155
156MEMCPY(m_libc_soname, memcpy)
157MEMCPY(m_ld_so_1, memcpy) /* ld.so.1 */
158MEMCPY(m_ld64_so_1, memcpy) /* ld64.so.1 */
159
160
161/*--------------------------------------------------------------------*/
162/*--- end pc_intercepts.c ---*/
163/*--------------------------------------------------------------------*/