]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/valgrind/src/valgrind-3.6.0-svn/exp-sgcheck/h_intercepts.c
update
[l4.git] / l4 / pkg / valgrind / src / valgrind-3.6.0-svn / exp-sgcheck / h_intercepts.c
1
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-2010 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.  If you copy more in, please keep
45    them in the same order as in mc_replace_strmem.c. */
46
47
48 #define STRRCHR(soname, fnname) \
49    char* VG_REPLACE_FUNCTION_ZU(soname,fnname)( const char* s, int c ); \
50    char* VG_REPLACE_FUNCTION_ZU(soname,fnname)( const char* s, int c ) \
51    { \
52       UChar  ch   = (UChar)((UInt)c); \
53       UChar* p    = (UChar*)s; \
54       UChar* last = NULL; \
55       while (True) { \
56          if (*p == ch) last = p; \
57          if (*p == 0) return last; \
58          p++; \
59       } \
60    }
61
62 // Apparently rindex() is the same thing as strrchr()
63 STRRCHR(VG_Z_LIBC_SONAME,   strrchr)
64 STRRCHR(VG_Z_LIBC_SONAME,   rindex)
65 #if defined(VGO_linux)
66 STRRCHR(VG_Z_LIBC_SONAME,   __GI_strrchr)
67 STRRCHR(VG_Z_LD_LINUX_SO_2, rindex)
68 #elif defined(VGO_darwin)
69 STRRCHR(VG_Z_DYLD,          strrchr)
70 STRRCHR(VG_Z_DYLD,          rindex)
71 #endif
72
73
74 #define STRCHR(soname, fnname) \
75    char* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( const char* s, int c ); \
76    char* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( const char* s, int c ) \
77    { \
78       UChar  ch = (UChar)((UInt)c); \
79       UChar* p  = (UChar*)s; \
80       while (True) { \
81          if (*p == ch) return p; \
82          if (*p == 0) return NULL; \
83          p++; \
84       } \
85    }
86
87 // Apparently index() is the same thing as strchr()
88 STRCHR(VG_Z_LIBC_SONAME,          strchr)
89 STRCHR(VG_Z_LIBC_SONAME,          index)
90 #if defined(VGO_linux)
91 STRCHR(VG_Z_LIBC_SONAME,          __GI_strchr)
92 STRCHR(VG_Z_LD_LINUX_SO_2,        strchr)
93 STRCHR(VG_Z_LD_LINUX_SO_2,        index)
94 STRCHR(VG_Z_LD_LINUX_X86_64_SO_2, strchr)
95 STRCHR(VG_Z_LD_LINUX_X86_64_SO_2, index)
96 #elif defined(VGO_darwin)
97 STRCHR(VG_Z_DYLD,                 strchr)
98 STRCHR(VG_Z_DYLD,                 index)
99 #endif
100
101
102 #define STRNLEN(soname, fnname) \
103    SizeT VG_REPLACE_FUNCTION_ZU(soname,fnname) ( const char* str, SizeT n ); \
104    SizeT VG_REPLACE_FUNCTION_ZU(soname,fnname) ( const char* str, SizeT n ) \
105    { \
106       SizeT i = 0; \
107       while (i < n && str[i] != 0) i++; \
108       return i; \
109    }
110
111 STRNLEN(VG_Z_LIBC_SONAME, strnlen)
112
113
114 // Note that this replacement often doesn't get used because gcc inlines
115 // calls to strlen() with its own built-in version.  This can be very
116 // confusing if you aren't expecting it.  Other small functions in this file
117 // may also be inline by gcc.
118 #define STRLEN(soname, fnname) \
119    SizeT VG_REPLACE_FUNCTION_ZU(soname,fnname)( const char* str ); \
120    SizeT VG_REPLACE_FUNCTION_ZU(soname,fnname)( const char* str ) \
121    { \
122       SizeT i = 0; \
123       while (str[i] != 0) i++; \
124       return i; \
125    }
126
127 STRLEN(VG_Z_LIBC_SONAME,          strlen)
128 #if defined(VGO_linux)
129 STRLEN(VG_Z_LIBC_SONAME,          __GI_strlen)
130 STRLEN(VG_Z_LD_LINUX_SO_2,        strlen)
131 STRLEN(VG_Z_LD_LINUX_X86_64_SO_2, strlen)
132 STRLEN(VG_Z_LD_SO_1,              strlen)
133 #endif
134
135
136 #define STRCPY(soname, fnname) \
137    char* VG_REPLACE_FUNCTION_ZU(soname, fnname) ( char* dst, const char* src ); \
138    char* VG_REPLACE_FUNCTION_ZU(soname, fnname) ( char* dst, const char* src ) \
139    { \
140       Char* dst_orig = dst; \
141       \
142       while (*src) *dst++ = *src++; \
143       *dst = 0; \
144       \
145       return dst_orig; \
146    }
147
148 STRCPY(VG_Z_LIBC_SONAME, strcpy)
149 #if defined(VGO_linux)
150 STRCPY(VG_Z_LIBC_SONAME, __GI_strcpy)
151 #elif defined(VGO_darwin)
152 STRCPY(VG_Z_DYLD,        strcpy)
153 #endif
154
155
156 #define STRNCMP(soname, fnname) \
157    int VG_REPLACE_FUNCTION_ZU(soname,fnname) \
158           ( const char* s1, const char* s2, SizeT nmax ); \
159    int VG_REPLACE_FUNCTION_ZU(soname,fnname) \
160           ( const char* s1, const char* s2, SizeT nmax ) \
161    { \
162       SizeT n = 0; \
163       while (True) { \
164          if (n >= nmax) return 0; \
165          if (*s1 == 0 && *s2 == 0) return 0; \
166          if (*s1 == 0) return -1; \
167          if (*s2 == 0) return 1; \
168          \
169          if (*(unsigned char*)s1 < *(unsigned char*)s2) return -1; \
170          if (*(unsigned char*)s1 > *(unsigned char*)s2) return 1; \
171          \
172          s1++; s2++; n++; \
173       } \
174    }
175
176 STRNCMP(VG_Z_LIBC_SONAME, strncmp)
177 #if defined(VGO_linux)
178 STRNCMP(VG_Z_LIBC_SONAME, __GI_strncmp)
179 #elif defined(VGO_darwin)
180 STRNCMP(VG_Z_DYLD,        strncmp)
181 #endif
182
183
184 #define STRCMP(soname, fnname) \
185    int VG_REPLACE_FUNCTION_ZU(soname,fnname) \
186           ( const char* s1, const char* s2 ); \
187    int VG_REPLACE_FUNCTION_ZU(soname,fnname) \
188           ( const char* s1, const char* s2 ) \
189    { \
190       register unsigned char c1; \
191       register unsigned char c2; \
192       while (True) { \
193          c1 = *(unsigned char *)s1; \
194          c2 = *(unsigned char *)s2; \
195          if (c1 != c2) break; \
196          if (c1 == 0) break; \
197          s1++; s2++; \
198       } \
199       if ((unsigned char)c1 < (unsigned char)c2) return -1; \
200       if ((unsigned char)c1 > (unsigned char)c2) return 1; \
201       return 0; \
202    }
203
204 STRCMP(VG_Z_LIBC_SONAME,          strcmp)
205 #if defined(VGO_linux)
206 STRCMP(VG_Z_LIBC_SONAME,          __GI_strcmp)
207 STRCMP(VG_Z_LD_LINUX_X86_64_SO_2, strcmp)
208 STRCMP(VG_Z_LD64_SO_1,            strcmp)
209 #endif
210
211
212 #define MEMCHR(soname, fnname) \
213    void* VG_REPLACE_FUNCTION_ZU(soname,fnname) (const void *s, int c, SizeT n); \
214    void* VG_REPLACE_FUNCTION_ZU(soname,fnname) (const void *s, int c, SizeT n) \
215    { \
216       SizeT i; \
217       UChar c0 = (UChar)c; \
218       UChar* p = (UChar*)s; \
219       for (i = 0; i < n; i++) \
220          if (p[i] == c0) return (void*)(&p[i]); \
221       return NULL; \
222    }
223
224 MEMCHR(VG_Z_LIBC_SONAME, memchr)
225 #if defined(VGO_darwin)
226 MEMCHR(VG_Z_DYLD,        memchr)
227 #endif
228
229
230 #define MEMCPY(soname, fnname) \
231    void* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
232             ( void *dst, const void *src, SizeT sz ); \
233    void* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
234             ( void *dest, const void *src, SizeT sz ) \
235    { \
236    const UChar*  s  = (const UChar*)src; \
237          UChar*  d  =       (UChar*)dest; \
238    const UWord*  sW = (const UWord*)src; \
239          UWord*  dW =       (UWord*)dest; \
240    const UWord   al = sizeof(UWord)-1; \
241    \
242    if (0 == (((UWord)dW) & al) && 0 == (((UWord)sW) & al)) { \
243       while (sz >= 4 * sizeof(UWord)) { \
244          dW[0] = sW[0]; \
245          dW[1] = sW[1]; \
246          dW[2] = sW[2]; \
247          dW[3] = sW[3]; \
248          sz -= 4 * sizeof(UWord); \
249          dW += 4; \
250          sW += 4; \
251       } \
252       if (sz == 0) \
253          return dest; \
254       while (sz >= 1 * sizeof(UWord)) { \
255          dW[0] = sW[0]; \
256          sz -= 1 * sizeof(UWord); \
257          dW += 1; \
258          sW += 1; \
259       } \
260       if (sz == 0) \
261          return dest; \
262       s = (const UChar*)sW; \
263       d = (UChar*)dW; \
264    } \
265    \
266    while (sz--) \
267       *d++ = *s++; \
268    \
269    return dest; \
270    }
271
272 MEMCPY(VG_Z_LIBC_SONAME, memcpy)
273 #if defined(VGO_linux)
274 MEMCPY(VG_Z_LD_SO_1,     memcpy) /* ld.so.1 */
275 MEMCPY(VG_Z_LD64_SO_1,   memcpy) /* ld64.so.1 */
276 #endif
277
278
279 /* Copy SRC to DEST, returning the address of the terminating '\0' in
280    DEST. (minor variant of strcpy) */
281 #define STPCPY(soname, fnname) \
282    char* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( char* dst, const char* src ); \
283    char* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( char* dst, const char* src ) \
284    { \
285       while (*src) *dst++ = *src++; \
286       *dst = 0; \
287       \
288       return dst; \
289    }
290
291 STPCPY(VG_Z_LIBC_SONAME,          stpcpy)
292 #if defined(VGO_linux)
293 STPCPY(VG_Z_LD_LINUX_SO_2,        stpcpy)
294 STPCPY(VG_Z_LD_LINUX_X86_64_SO_2, stpcpy)
295 #endif
296
297
298 /* Find the first occurrence of C in S.  */
299 #define GLIBC232_RAWMEMCHR(soname, fnname) \
300    char* VG_REPLACE_FUNCTION_ZU(soname,fnname) (const char* s, int c_in); \
301    char* VG_REPLACE_FUNCTION_ZU(soname,fnname) (const char* s, int c_in) \
302    { \
303       unsigned char  c        = (unsigned char) c_in; \
304       unsigned char* char_ptr = (unsigned char *)s; \
305       while (1) { \
306          if (*char_ptr == c) return char_ptr; \
307          char_ptr++; \
308       } \
309    }
310
311 GLIBC232_RAWMEMCHR(VG_Z_LIBC_SONAME, rawmemchr)
312 #if defined (VGO_linux)
313 GLIBC232_RAWMEMCHR(VG_Z_LIBC_SONAME, __GI___rawmemchr)
314 #endif
315
316
317 #define STRSTR(soname, fnname) \
318    void* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
319          (void* haystack, void* needle); \
320    void* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
321          (void* haystack, void* needle) \
322    { \
323       UChar* h = (UChar*)haystack; \
324       UChar* n = (UChar*)needle; \
325       \
326       /* find the length of n, not including terminating zero */ \
327       UWord nlen = 0; \
328       while (n[nlen]) nlen++; \
329       \
330       /* if n is the empty string, match immediately. */ \
331       if (nlen == 0) return h; \
332       \
333       /* assert(nlen >= 1); */ \
334       UChar n0 = n[0]; \
335       \
336       while (1) { \
337          UChar hh = *h; \
338          if (hh == 0) return NULL; \
339          if (hh != n0) { h++; continue; } \
340          \
341          UWord i; \
342          for (i = 0; i < nlen; i++) { \
343             if (n[i] != h[i]) \
344                break; \
345          } \
346          /* assert(i >= 0 && i <= nlen); */ \
347          if (i == nlen) \
348             return h; \
349          \
350          h++; \
351       } \
352    }
353
354 #if defined(VGO_linux)
355 STRSTR(VG_Z_LIBC_SONAME,          strstr)
356 #endif
357
358
359 #define STRPBRK(soname, fnname) \
360    void* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
361          (void* sV, void* acceptV); \
362    void* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
363          (void* sV, void* acceptV) \
364    { \
365       UChar* s = (UChar*)sV; \
366       UChar* accept = (UChar*)acceptV; \
367       \
368       /*  find the length of 'accept', not including terminating zero */ \
369       UWord nacc = 0; \
370       while (accept[nacc]) nacc++; \
371       \
372       /* if n is the empty string, fail immediately. */ \
373       if (nacc == 0) return NULL; \
374       \
375       /* assert(nacc >= 1); */ \
376       while (1) { \
377          UWord i; \
378          UChar sc = *s; \
379          if (sc == 0) \
380             break; \
381          for (i = 0; i < nacc; i++) { \
382             if (sc == accept[i]) \
383                return s; \
384          } \
385          s++; \
386       } \
387       \
388       return NULL; \
389    }
390
391 #if defined(VGO_linux)
392 STRPBRK(VG_Z_LIBC_SONAME,          strpbrk)
393 #endif
394
395
396 /*--------------------------------------------------------------------*/
397 /*--- end                                          pc_intercepts.c ---*/
398 /*--------------------------------------------------------------------*/