]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/valgrind/src/valgrind-3.6.0-svn/memcheck/mc_replace_strmem.c
update
[l4.git] / l4 / pkg / valgrind / src / valgrind-3.6.0-svn / memcheck / mc_replace_strmem.c
1
2 /*--------------------------------------------------------------------*/
3 /*--- Replacements for strcpy(), memcpy() et al, which run on the  ---*/
4 /*--- simulated CPU.                                               ---*/
5 /*---                                          mc_replace_strmem.c ---*/
6 /*--------------------------------------------------------------------*/
7
8 /*
9    This file is part of MemCheck, a heavyweight Valgrind tool for
10    detecting memory errors.
11
12    Copyright (C) 2000-2010 Julian Seward 
13       jseward@acm.org
14
15    This program is free software; you can redistribute it and/or
16    modify it under the terms of the GNU General Public License as
17    published by the Free Software Foundation; either version 2 of the
18    License, or (at your option) any later version.
19
20    This program is distributed in the hope that it will be useful, but
21    WITHOUT ANY WARRANTY; without even the implied warranty of
22    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
23    General Public License for more details.
24
25    You should have received a copy of the GNU General Public License
26    along with this program; if not, write to the Free Software
27    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
28    02111-1307, USA.
29
30    The GNU General Public License is contained in the file COPYING.
31 */
32
33 #include "pub_tool_basics.h"
34 #include "pub_tool_hashtable.h"
35 #include "pub_tool_redir.h"
36 #include "pub_tool_tooliface.h"
37 #include "valgrind.h"
38
39 #include "mc_include.h"
40 #include "memcheck.h"
41
42 /* ---------------------------------------------------------------------
43    We have our own versions of these functions for two reasons:
44    (a) it allows us to do overlap checking
45    (b) some of the normal versions are hyper-optimised, which fools
46        Memcheck and cause spurious value warnings.  Our versions are
47        simpler.
48
49    Note that overenthusiastic use of PLT bypassing by the glibc people also
50    means that we need to patch multiple versions of some of the functions to
51    our own implementations.
52
53    THEY RUN ON THE SIMD CPU!
54    ------------------------------------------------------------------ */
55
56 /* Figure out if [dst .. dst+dstlen-1] overlaps with 
57                  [src .. src+srclen-1].
58    We assume that the address ranges do not wrap around
59    (which is safe since on Linux addresses >= 0xC0000000
60    are not accessible and the program will segfault in this
61    circumstance, presumably).
62 */
63 static __inline__
64 Bool is_overlap ( void* dst, const void* src, SizeT dstlen, SizeT srclen )
65 {
66    Addr loS, hiS, loD, hiD;
67
68    if (dstlen == 0 || srclen == 0)
69       return False;
70
71    loS = (Addr)src;
72    loD = (Addr)dst;
73    hiS = loS + srclen - 1;
74    hiD = loD + dstlen - 1;
75
76    /* So figure out if [loS .. hiS] overlaps with [loD .. hiD]. */
77    if (loS < loD) {
78       return !(hiS < loD);
79    }
80    else if (loD < loS) {
81       return !(hiD < loS);
82    }
83    else { 
84       /* They start at same place.  Since we know neither of them has
85          zero length, they must overlap. */
86       return True;
87    }
88 }
89
90 // This is a macro rather than a function because we don't want to have an
91 // extra function in the stack trace.
92 #define RECORD_OVERLAP_ERROR(s, src, dst, len)                  \
93   VALGRIND_DO_CLIENT_REQUEST_EXPR(0,                            \
94                   _VG_USERREQ__MEMCHECK_RECORD_OVERLAP_ERROR,   \
95                   s, src, dst, len, 0)
96
97
98 #define STRRCHR(soname, fnname) \
99    char* VG_REPLACE_FUNCTION_ZU(soname,fnname)( const char* s, int c ); \
100    char* VG_REPLACE_FUNCTION_ZU(soname,fnname)( const char* s, int c ) \
101    { \
102       UChar  ch   = (UChar)((UInt)c); \
103       UChar* p    = (UChar*)s; \
104       UChar* last = NULL; \
105       while (True) { \
106          if (*p == ch) last = p; \
107          if (*p == 0) return last; \
108          p++; \
109       } \
110    }
111
112 // Apparently rindex() is the same thing as strrchr()
113 STRRCHR(VG_Z_LIBC_SONAME,   strrchr)
114 STRRCHR(VG_Z_LIBC_SONAME,   rindex)
115 #if defined(VGO_linux)
116 STRRCHR(VG_Z_LIBC_SONAME,   __GI_strrchr)
117 STRRCHR(VG_Z_LD_LINUX_SO_2, rindex)
118 #elif defined(VGO_darwin)
119 STRRCHR(VG_Z_DYLD,          strrchr)
120 STRRCHR(VG_Z_DYLD,          rindex)
121 #endif
122    
123
124 #define STRCHR(soname, fnname) \
125    char* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( const char* s, int c ); \
126    char* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( const char* s, int c ) \
127    { \
128       UChar  ch = (UChar)((UInt)c); \
129       UChar* p  = (UChar*)s; \
130       while (True) { \
131          if (*p == ch) return p; \
132          if (*p == 0) return NULL; \
133          p++; \
134       } \
135    }
136
137 // Apparently index() is the same thing as strchr()
138 STRCHR(VG_Z_LIBC_SONAME,          strchr)
139 STRCHR(VG_Z_LIBC_SONAME,          index)
140 #if defined(VGO_linux)
141 STRCHR(VG_Z_LIBC_SONAME,          __GI_strchr)
142 STRCHR(VG_Z_LD_LINUX_SO_2,        strchr)
143 STRCHR(VG_Z_LD_LINUX_SO_2,        index)
144 STRCHR(VG_Z_LD_LINUX_X86_64_SO_2, strchr)
145 STRCHR(VG_Z_LD_LINUX_X86_64_SO_2, index)
146 #elif defined(VGO_darwin)
147 STRCHR(VG_Z_DYLD,                 strchr)
148 STRCHR(VG_Z_DYLD,                 index)
149 #endif
150
151
152 #define STRCAT(soname, fnname) \
153    char* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( char* dst, const char* src ); \
154    char* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( char* dst, const char* src ) \
155    { \
156       const Char* src_orig = src; \
157             Char* dst_orig = dst; \
158       while (*dst) dst++; \
159       while (*src) *dst++ = *src++; \
160       *dst = 0; \
161       \
162       /* This is a bit redundant, I think;  any overlap and the strcat will */ \
163       /* go forever... or until a seg fault occurs. */ \
164       if (is_overlap(dst_orig,  \
165                      src_orig,  \
166                      (Addr)dst-(Addr)dst_orig+1,  \
167                      (Addr)src-(Addr)src_orig+1)) \
168          RECORD_OVERLAP_ERROR("strcat", dst_orig, src_orig, 0); \
169       \
170       return dst_orig; \
171    }
172
173 STRCAT(VG_Z_LIBC_SONAME, strcat)
174 #if defined(VGO_linux)
175 STRCAT(VG_Z_LIBC_SONAME, __GI_strcat)
176 #endif
177
178 #define STRNCAT(soname, fnname) \
179    char* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
180             ( char* dst, const char* src, SizeT n ); \
181    char* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
182             ( char* dst, const char* src, SizeT n ) \
183    { \
184       const Char* src_orig = src; \
185             Char* dst_orig = dst; \
186       SizeT m = 0; \
187       \
188       while (*dst) dst++; \
189       while (m < n && *src) { m++; *dst++ = *src++; } /* concat <= n chars */ \
190       *dst = 0;                                       /* always add null   */ \
191       \
192       /* This checks for overlap after copying, unavoidable without */ \
193       /* pre-counting lengths... should be ok */ \
194       if (is_overlap(dst_orig,  \
195                      src_orig,  \
196                      (Addr)dst-(Addr)dst_orig+1,  \
197                      (Addr)src-(Addr)src_orig+1)) \
198          RECORD_OVERLAP_ERROR("strncat", dst_orig, src_orig, n); \
199       \
200       return dst_orig; \
201    }
202
203 STRNCAT(VG_Z_LIBC_SONAME, strncat)
204 #if defined(VGO_darwin)
205 STRNCAT(VG_Z_DYLD,        strncat)
206 #endif
207
208
209 /* Append src to dst. n is the size of dst's buffer. dst is guaranteed 
210    to be nul-terminated after the copy, unless n <= strlen(dst_orig). 
211    Returns min(n, strlen(dst_orig)) + strlen(src_orig). 
212    Truncation occurred if retval >= n. 
213 */
214 #define STRLCAT(soname, fnname) \
215     SizeT VG_REPLACE_FUNCTION_ZU(soname,fnname) \
216         ( char* dst, const char* src, SizeT n ); \
217     SizeT VG_REPLACE_FUNCTION_ZU(soname,fnname) \
218         ( char* dst, const char* src, SizeT n ) \
219    { \
220       const Char* src_orig = src; \
221       Char* dst_orig = dst; \
222       SizeT m = 0; \
223 \
224       while (m < n && *dst) { m++; dst++; } \
225       if (m < n) { \
226          /* Fill as far as dst_orig[n-2], then nul-terminate. */ \
227          while (m < n-1 && *src) { m++; *dst++ = *src++; } \
228          *dst = 0; \
229       } else { \
230          /* No space to copy anything to dst. m == n */ \
231       } \
232       /* Finish counting min(n, strlen(dst_orig)) + strlen(src_orig) */ \
233       while (*src) { m++; src++; } \
234       /* This checks for overlap after copying, unavoidable without */ \
235       /* pre-counting lengths... should be ok */ \
236       if (is_overlap(dst_orig,  \
237                      src_orig,  \
238                      (Addr)dst-(Addr)dst_orig+1,  \
239                      (Addr)src-(Addr)src_orig+1)) \
240          RECORD_OVERLAP_ERROR("strlcat", dst_orig, src_orig, n); \
241 \
242       return m; \
243    }
244
245 #if defined(VGO_darwin)
246 STRLCAT(VG_Z_LIBC_SONAME, strlcat)
247 STRLCAT(VG_Z_DYLD,        strlcat)
248 #endif
249
250
251 #define STRNLEN(soname, fnname) \
252    SizeT VG_REPLACE_FUNCTION_ZU(soname,fnname) ( const char* str, SizeT n ); \
253    SizeT VG_REPLACE_FUNCTION_ZU(soname,fnname) ( const char* str, SizeT n ) \
254    { \
255       SizeT i = 0; \
256       while (i < n && str[i] != 0) i++; \
257       return i; \
258    }
259
260 STRNLEN(VG_Z_LIBC_SONAME, strnlen)
261 #if defined(VGO_linux)
262 STRNLEN(VG_Z_LIBC_SONAME, __GI_strnlen)
263 #endif
264    
265
266 // Note that this replacement often doesn't get used because gcc inlines
267 // calls to strlen() with its own built-in version.  This can be very
268 // confusing if you aren't expecting it.  Other small functions in this file
269 // may also be inline by gcc.
270 #define STRLEN(soname, fnname) \
271    SizeT VG_REPLACE_FUNCTION_ZU(soname,fnname)( const char* str ); \
272    SizeT VG_REPLACE_FUNCTION_ZU(soname,fnname)( const char* str ) \
273    { \
274       SizeT i = 0; \
275       while (str[i] != 0) i++; \
276       return i; \
277    }
278
279 STRLEN(VG_Z_LIBC_SONAME,          strlen)
280 #if defined(VGO_linux)
281 STRLEN(VG_Z_LIBC_SONAME,          __GI_strlen)
282 STRLEN(VG_Z_LD_LINUX_SO_2,        strlen)
283 STRLEN(VG_Z_LD_LINUX_X86_64_SO_2, strlen)
284 #endif
285
286
287 #define STRCPY(soname, fnname) \
288    char* VG_REPLACE_FUNCTION_ZU(soname, fnname) ( char* dst, const char* src ); \
289    char* VG_REPLACE_FUNCTION_ZU(soname, fnname) ( char* dst, const char* src ) \
290    { \
291       const Char* src_orig = src; \
292             Char* dst_orig = dst; \
293       \
294       while (*src) *dst++ = *src++; \
295       *dst = 0; \
296       \
297       /* This checks for overlap after copying, unavoidable without */ \
298       /* pre-counting length... should be ok */ \
299       if (is_overlap(dst_orig,  \
300                      src_orig,  \
301                      (Addr)dst-(Addr)dst_orig+1,  \
302                      (Addr)src-(Addr)src_orig+1)) \
303          RECORD_OVERLAP_ERROR("strcpy", dst_orig, src_orig, 0); \
304       \
305       return dst_orig; \
306    }
307
308 STRCPY(VG_Z_LIBC_SONAME, strcpy)
309 #if defined(VGO_linux)
310 STRCPY(VG_Z_LIBC_SONAME, __GI_strcpy)
311 #elif defined(VGO_darwin)
312 STRCPY(VG_Z_DYLD,        strcpy)
313 #endif
314
315
316 #define STRNCPY(soname, fnname) \
317    char* VG_REPLACE_FUNCTION_ZU(soname, fnname) \
318             ( char* dst, const char* src, SizeT n ); \
319    char* VG_REPLACE_FUNCTION_ZU(soname, fnname) \
320             ( char* dst, const char* src, SizeT n ) \
321    { \
322       const Char* src_orig = src; \
323             Char* dst_orig = dst; \
324       SizeT m = 0; \
325       \
326       while (m   < n && *src) { m++; *dst++ = *src++; } \
327       /* Check for overlap after copying; all n bytes of dst are relevant, */ \
328       /* but only m+1 bytes of src if terminator was found */ \
329       if (is_overlap(dst_orig, src_orig, n, (m < n) ? m+1 : n)) \
330          RECORD_OVERLAP_ERROR("strncpy", dst, src, n); \
331       while (m++ < n) *dst++ = 0;         /* must pad remainder with nulls */ \
332  \
333       return dst_orig; \
334    }
335
336 STRNCPY(VG_Z_LIBC_SONAME, strncpy)
337 #if defined(VGO_linux)
338 STRNCPY(VG_Z_LIBC_SONAME, __GI_strncpy)
339 #elif defined(VGO_darwin)
340 STRNCPY(VG_Z_DYLD,        strncpy)
341 #endif
342
343
344 /* Copy up to n-1 bytes from src to dst. Then nul-terminate dst if n > 0. 
345    Returns strlen(src). Does not zero-fill the remainder of dst. */
346 #define STRLCPY(soname, fnname) \
347    SizeT VG_REPLACE_FUNCTION_ZU(soname, fnname) \
348        ( char* dst, const char* src, SizeT n ); \
349    SizeT VG_REPLACE_FUNCTION_ZU(soname, fnname) \
350        ( char* dst, const char* src, SizeT n ) \
351    { \
352       const char* src_orig = src; \
353       char* dst_orig = dst; \
354       SizeT m = 0; \
355 \
356       while (m < n-1 && *src) { m++; *dst++ = *src++; } \
357       /* m non-nul bytes have now been copied, and m <= n-1. */ \
358       /* Check for overlap after copying; all n bytes of dst are relevant, */ \
359       /* but only m+1 bytes of src if terminator was found */ \
360       if (is_overlap(dst_orig, src_orig, n, (m < n) ? m+1 : n)) \
361           RECORD_OVERLAP_ERROR("strlcpy", dst, src, n); \
362       /* Nul-terminate dst. */ \
363       if (n > 0) *dst = 0; \
364       /* Finish counting strlen(src). */ \
365       while (*src) src++; \
366       return src - src_orig; \
367    }
368
369 #if defined(VGO_darwin)
370 STRLCPY(VG_Z_LIBC_SONAME, strlcpy)
371 STRLCPY(VG_Z_DYLD,        strlcpy)
372 #endif
373
374
375 #define STRNCMP(soname, fnname) \
376    int VG_REPLACE_FUNCTION_ZU(soname,fnname) \
377           ( const char* s1, const char* s2, SizeT nmax ); \
378    int VG_REPLACE_FUNCTION_ZU(soname,fnname) \
379           ( const char* s1, const char* s2, SizeT nmax ) \
380    { \
381       SizeT n = 0; \
382       while (True) { \
383          if (n >= nmax) return 0; \
384          if (*s1 == 0 && *s2 == 0) return 0; \
385          if (*s1 == 0) return -1; \
386          if (*s2 == 0) return 1; \
387          \
388          if (*(unsigned char*)s1 < *(unsigned char*)s2) return -1; \
389          if (*(unsigned char*)s1 > *(unsigned char*)s2) return 1; \
390          \
391          s1++; s2++; n++; \
392       } \
393    }
394
395 STRNCMP(VG_Z_LIBC_SONAME, strncmp)
396 #if defined(VGO_linux)
397 STRNCMP(VG_Z_LIBC_SONAME, __GI_strncmp)
398 #elif defined(VGO_darwin)
399 STRNCMP(VG_Z_DYLD,        strncmp)
400 #endif
401
402
403 #define STRCASECMP(soname, fnname) \
404    int VG_REPLACE_FUNCTION_ZU(soname,fnname) \
405           ( const char* s1, const char* s2 ); \
406    int VG_REPLACE_FUNCTION_ZU(soname,fnname) \
407           ( const char* s1, const char* s2 ) \
408    { \
409       extern int tolower(int); \
410       register unsigned char c1; \
411       register unsigned char c2; \
412       while (True) { \
413          c1 = tolower(*(unsigned char *)s1); \
414          c2 = tolower(*(unsigned char *)s2); \
415          if (c1 != c2) break; \
416          if (c1 == 0) break; \
417          s1++; s2++; \
418       } \
419       if ((unsigned char)c1 < (unsigned char)c2) return -1; \
420       if ((unsigned char)c1 > (unsigned char)c2) return 1; \
421       return 0; \
422    }
423
424 STRCASECMP(VG_Z_LIBC_SONAME, strcasecmp)
425 #if defined(VGO_linux)
426 STRCASECMP(VG_Z_LIBC_SONAME, __GI_strcasecmp)
427 #endif
428
429
430 #define STRNCASECMP(soname, fnname) \
431    int VG_REPLACE_FUNCTION_ZU(soname,fnname) \
432           ( const char* s1, const char* s2, SizeT nmax ); \
433    int VG_REPLACE_FUNCTION_ZU(soname,fnname) \
434           ( const char* s1, const char* s2, SizeT nmax ) \
435    { \
436       extern int tolower(int); \
437       SizeT n = 0; \
438       while (True) { \
439          if (n >= nmax) return 0; \
440          if (*s1 == 0 && *s2 == 0) return 0; \
441          if (*s1 == 0) return -1; \
442          if (*s2 == 0) return 1; \
443          \
444          if (tolower(*(unsigned char*)s1) < tolower(*(unsigned char*)s2)) return -1; \
445          if (tolower(*(unsigned char*)s1) > tolower(*(unsigned char*)s2)) return 1; \
446          \
447          s1++; s2++; n++; \
448       } \
449    }
450
451 STRNCASECMP(VG_Z_LIBC_SONAME, strncasecmp)
452 #if defined(VGO_linux)
453 STRNCASECMP(VG_Z_LIBC_SONAME, __GI_strncasecmp)
454 #elif defined(VGO_darwin)
455 STRNCASECMP(VG_Z_DYLD,        strncasecmp)
456 #endif
457
458
459 #define STRCASECMP_L(soname, fnname) \
460    int VG_REPLACE_FUNCTION_ZU(soname,fnname) \
461           ( const char* s1, const char* s2, void* locale ); \
462    int VG_REPLACE_FUNCTION_ZU(soname,fnname) \
463           ( const char* s1, const char* s2, void* locale ) \
464    { \
465       extern int tolower_l(int, void*) __attribute__((weak));    \
466       register unsigned char c1; \
467       register unsigned char c2; \
468       while (True) { \
469          c1 = tolower_l(*(unsigned char *)s1, locale); \
470          c2 = tolower_l(*(unsigned char *)s2, locale); \
471          if (c1 != c2) break; \
472          if (c1 == 0) break; \
473          s1++; s2++; \
474       } \
475       if ((unsigned char)c1 < (unsigned char)c2) return -1; \
476       if ((unsigned char)c1 > (unsigned char)c2) return 1; \
477       return 0; \
478    }
479
480 STRCASECMP_L(VG_Z_LIBC_SONAME, strcasecmp_l)
481 #if defined(VGO_linux)
482 STRCASECMP_L(VG_Z_LIBC_SONAME, __GI_strcasecmp_l)
483 #endif
484
485
486 #define STRNCASECMP_L(soname, fnname) \
487    int VG_REPLACE_FUNCTION_ZU(soname,fnname) \
488           ( const char* s1, const char* s2, SizeT nmax, void* locale ); \
489    int VG_REPLACE_FUNCTION_ZU(soname,fnname) \
490           ( const char* s1, const char* s2, SizeT nmax, void* locale ) \
491    { \
492       extern int tolower_l(int, void*) __attribute__((weak));    \
493       SizeT n = 0; \
494       while (True) { \
495          if (n >= nmax) return 0; \
496          if (*s1 == 0 && *s2 == 0) return 0; \
497          if (*s1 == 0) return -1; \
498          if (*s2 == 0) return 1; \
499          \
500          if (tolower_l(*(unsigned char*)s1, locale) < tolower_l(*(unsigned char*)s2, locale)) return -1; \
501          if (tolower_l(*(unsigned char*)s1, locale) > tolower_l(*(unsigned char*)s2, locale)) return 1; \
502          \
503          s1++; s2++; n++; \
504       } \
505    }
506
507 STRNCASECMP_L(VG_Z_LIBC_SONAME, strncasecmp_l)
508 #if defined(VGO_linux)
509 STRNCASECMP_L(VG_Z_LIBC_SONAME, __GI_strncasecmp_l)
510 #elif defined(VGO_darwin)
511 STRNCASECMP_L(VG_Z_DYLD,        strncasecmp_l)
512 #endif
513
514
515 #define STRCMP(soname, fnname) \
516    int VG_REPLACE_FUNCTION_ZU(soname,fnname) \
517           ( const char* s1, const char* s2 ); \
518    int VG_REPLACE_FUNCTION_ZU(soname,fnname) \
519           ( const char* s1, const char* s2 ) \
520    { \
521       register unsigned char c1; \
522       register unsigned char c2; \
523       while (True) { \
524          c1 = *(unsigned char *)s1; \
525          c2 = *(unsigned char *)s2; \
526          if (c1 != c2) break; \
527          if (c1 == 0) break; \
528          s1++; s2++; \
529       } \
530       if ((unsigned char)c1 < (unsigned char)c2) return -1; \
531       if ((unsigned char)c1 > (unsigned char)c2) return 1; \
532       return 0; \
533    }
534
535 STRCMP(VG_Z_LIBC_SONAME,          strcmp)
536 #if defined(VGO_linux)
537 STRCMP(VG_Z_LIBC_SONAME,          __GI_strcmp)
538 STRCMP(VG_Z_LD_LINUX_X86_64_SO_2, strcmp)
539 STRCMP(VG_Z_LD64_SO_1,            strcmp)
540 #endif
541
542
543 #define MEMCHR(soname, fnname) \
544    void* VG_REPLACE_FUNCTION_ZU(soname,fnname) (const void *s, int c, SizeT n); \
545    void* VG_REPLACE_FUNCTION_ZU(soname,fnname) (const void *s, int c, SizeT n) \
546    { \
547       SizeT i; \
548       UChar c0 = (UChar)c; \
549       UChar* p = (UChar*)s; \
550       for (i = 0; i < n; i++) \
551          if (p[i] == c0) return (void*)(&p[i]); \
552       return NULL; \
553    }
554
555 MEMCHR(VG_Z_LIBC_SONAME, memchr)
556 #if defined(VGO_darwin)
557 MEMCHR(VG_Z_DYLD,        memchr)
558 #endif
559
560
561 #define MEMCPY(soname, fnname) \
562    void* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
563             ( void *dst, const void *src, SizeT len ); \
564    void* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
565             ( void *dst, const void *src, SizeT len ) \
566    { \
567       if (is_overlap(dst, src, len, len)) \
568          RECORD_OVERLAP_ERROR("memcpy", dst, src, len); \
569       \
570       const Addr WS = sizeof(UWord); /* 8 or 4 */ \
571       const Addr WM = WS - 1;        /* 7 or 3 */ \
572       \
573       if (dst < src) { \
574       \
575          /* Copying backwards. */ \
576          SizeT n = len; \
577          Addr  d = (Addr)dst; \
578          Addr  s = (Addr)src; \
579          \
580          if (((s^d) & WM) == 0) { \
581             /* s and d have same UWord alignment. */ \
582             /* Pull up to a UWord boundary. */ \
583             while ((s & WM) != 0 && n >= 1) \
584                { *(UChar*)d = *(UChar*)s; s += 1; d += 1; n -= 1; } \
585             /* Copy UWords. */ \
586             while (n >= WS) \
587                { *(UWord*)d = *(UWord*)s; s += WS; d += WS; n -= WS; } \
588             if (n == 0) \
589                return dst; \
590          } \
591          if (((s|d) & 1) == 0) { \
592             /* Both are 16-aligned; copy what we can thusly. */ \
593             while (n >= 2) \
594                { *(UShort*)d = *(UShort*)s; s += 2; d += 2; n -= 2; } \
595          } \
596          /* Copy leftovers, or everything if misaligned. */ \
597          while (n >= 1) \
598             { *(UChar*)d = *(UChar*)s; s += 1; d += 1; n -= 1; } \
599       \
600       } else if (dst > src) { \
601       \
602          SizeT n = len; \
603          Addr  d = ((Addr)dst) + n; \
604          Addr  s = ((Addr)src) + n; \
605          \
606          /* Copying forwards. */ \
607          if (((s^d) & WM) == 0) { \
608             /* s and d have same UWord alignment. */ \
609             /* Back down to a UWord boundary. */ \
610             while ((s & WM) != 0 && n >= 1) \
611                { s -= 1; d -= 1; *(UChar*)d = *(UChar*)s; n -= 1; } \
612             /* Copy UWords. */ \
613             while (n >= WS) \
614                { s -= WS; d -= WS; *(UWord*)d = *(UWord*)s; n -= WS; } \
615             if (n == 0) \
616                return dst; \
617          } \
618          if (((s|d) & 1) == 0) { \
619             /* Both are 16-aligned; copy what we can thusly. */ \
620             while (n >= 2) \
621                { s -= 2; d -= 2; *(UShort*)d = *(UShort*)s; n -= 2; } \
622          } \
623          /* Copy leftovers, or everything if misaligned. */ \
624          while (n >= 1) \
625             { s -= 1; d -= 1; *(UChar*)d = *(UChar*)s; n -= 1; } \
626          \
627       } \
628       \
629       return dst; \
630    }
631
632 MEMCPY(VG_Z_LIBC_SONAME, memcpy)
633 #if defined(VGO_linux)
634 MEMCPY(VG_Z_LD_SO_1,     memcpy) /* ld.so.1 */
635 MEMCPY(VG_Z_LD64_SO_1,   memcpy) /* ld64.so.1 */
636 #elif defined(VGO_darwin)
637 MEMCPY(VG_Z_DYLD,        memcpy)
638 #endif
639 /* icc9 blats these around all over the place.  Not only in the main
640    executable but various .so's.  They are highly tuned and read
641    memory beyond the source boundary (although work correctly and
642    never go across page boundaries), so give errors when run natively,
643    at least for misaligned source arg.  Just intercepting in the exe
644    only until we understand more about the problem.  See
645    http://bugs.kde.org/show_bug.cgi?id=139776
646  */
647 MEMCPY(NONE, _intel_fast_memcpy)
648
649
650 #define MEMCMP(soname, fnname) \
651    int VG_REPLACE_FUNCTION_ZU(soname,fnname) \
652           ( const void *s1V, const void *s2V, SizeT n ); \
653    int VG_REPLACE_FUNCTION_ZU(soname,fnname) \
654           ( const void *s1V, const void *s2V, SizeT n ) \
655    { \
656       int res; \
657       unsigned char a0; \
658       unsigned char b0; \
659       unsigned char* s1 = (unsigned char*)s1V; \
660       unsigned char* s2 = (unsigned char*)s2V; \
661       \
662       while (n != 0) { \
663          a0 = s1[0]; \
664          b0 = s2[0]; \
665          s1 += 1; \
666          s2 += 1; \
667          res = ((int)a0) - ((int)b0); \
668          if (res != 0) \
669             return res; \
670          n -= 1; \
671       } \
672       return 0; \
673    }
674
675 MEMCMP(VG_Z_LIBC_SONAME, memcmp)
676 MEMCMP(VG_Z_LIBC_SONAME, bcmp)
677 #if defined(VGO_linux)
678 MEMCMP(VG_Z_LD_SO_1,     bcmp)
679 #elif defined(VGO_darwin)
680 MEMCMP(VG_Z_DYLD,        memcmp)
681 MEMCMP(VG_Z_DYLD,        bcmp)
682 #endif
683
684
685 /* Copy SRC to DEST, returning the address of the terminating '\0' in
686    DEST. (minor variant of strcpy) */
687 #define STPCPY(soname, fnname) \
688    char* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( char* dst, const char* src ); \
689    char* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( char* dst, const char* src ) \
690    { \
691       const Char* src_orig = src; \
692             Char* dst_orig = dst; \
693       \
694       while (*src) *dst++ = *src++; \
695       *dst = 0; \
696       \
697       /* This checks for overlap after copying, unavoidable without */ \
698       /* pre-counting length... should be ok */ \
699       if (is_overlap(dst_orig,  \
700                      src_orig,  \
701                      (Addr)dst-(Addr)dst_orig+1,  \
702                      (Addr)src-(Addr)src_orig+1)) \
703          RECORD_OVERLAP_ERROR("stpcpy", dst_orig, src_orig, 0); \
704       \
705       return dst; \
706    }
707
708 STPCPY(VG_Z_LIBC_SONAME,          stpcpy)
709 #if defined(VGO_linux)
710 STPCPY(VG_Z_LIBC_SONAME,          __GI_stpcpy)
711 STPCPY(VG_Z_LD_LINUX_SO_2,        stpcpy)
712 STPCPY(VG_Z_LD_LINUX_X86_64_SO_2, stpcpy)
713 #elif defined(VGO_darwin)
714 STPCPY(VG_Z_DYLD,                 stpcpy)
715 #endif
716
717
718 #define MEMSET(soname, fnname) \
719    void* VG_REPLACE_FUNCTION_ZU(soname,fnname)(void *s, Int c, SizeT n); \
720    void* VG_REPLACE_FUNCTION_ZU(soname,fnname)(void *s, Int c, SizeT n) \
721    { \
722       Addr a  = (Addr)s;   \
723       UInt c4 = (c & 0xFF); \
724       c4 = (c4 << 8) | c4; \
725       c4 = (c4 << 16) | c4; \
726       while ((a & 3) != 0 && n >= 1) \
727          { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \
728       while (n >= 4) \
729          { *(UInt*)a = c4; a += 4; n -= 4; } \
730       while (n >= 1) \
731          { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \
732       return s; \
733    }
734
735 MEMSET(VG_Z_LIBC_SONAME, memset)
736 #if defined(VGO_darwin)
737 MEMSET(VG_Z_DYLD,        memset)
738 #endif
739
740
741 #define MEMMOVE(soname, fnname) \
742    void* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
743             (void *dstV, const void *srcV, SizeT n); \
744    void* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
745             (void *dstV, const void *srcV, SizeT n) \
746    { \
747       SizeT i; \
748       Char* dst = (Char*)dstV; \
749       Char* src = (Char*)srcV; \
750       if (dst < src) { \
751          for (i = 0; i < n; i++) \
752             dst[i] = src[i]; \
753       } \
754       else  \
755       if (dst > src) { \
756          for (i = 0; i < n; i++) \
757             dst[n-i-1] = src[n-i-1]; \
758       } \
759       return dst; \
760    }
761
762 MEMMOVE(VG_Z_LIBC_SONAME, memmove)
763 #if defined(VGO_darwin)
764 MEMMOVE(VG_Z_DYLD,        memmove)
765 #endif
766
767
768 #define BCOPY(soname, fnname) \
769    void VG_REPLACE_FUNCTION_ZU(soname,fnname) \
770             (const void *srcV, void *dstV, SizeT n); \
771    void VG_REPLACE_FUNCTION_ZU(soname,fnname) \
772             (const void *srcV, void *dstV, SizeT n) \
773    { \
774       SizeT i; \
775       Char* dst = (Char*)dstV; \
776       Char* src = (Char*)srcV; \
777       if (dst < src) { \
778          for (i = 0; i < n; i++) \
779             dst[i] = src[i]; \
780       } \
781       else  \
782       if (dst > src) { \
783          for (i = 0; i < n; i++) \
784             dst[n-i-1] = src[n-i-1]; \
785       } \
786    }
787
788 #if defined(VGO_darwin)
789 BCOPY(VG_Z_LIBC_SONAME, bcopy)
790 BCOPY(VG_Z_DYLD,        bcopy)
791 #endif
792
793
794 /* glibc 2.5 variant of memmove which checks the dest is big enough.
795    There is no specific part of glibc that this is copied from. */
796 #define GLIBC25___MEMMOVE_CHK(soname, fnname) \
797    void* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
798             (void *dstV, const void *srcV, SizeT n, SizeT destlen); \
799    void* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
800             (void *dstV, const void *srcV, SizeT n, SizeT destlen) \
801    { \
802       extern void _exit(int status); \
803       SizeT i; \
804       Char* dst = (Char*)dstV; \
805       Char* src = (Char*)srcV; \
806       if (destlen < n) \
807          goto badness; \
808       if (dst < src) { \
809          for (i = 0; i < n; i++) \
810             dst[i] = src[i]; \
811       } \
812       else  \
813       if (dst > src) { \
814          for (i = 0; i < n; i++) \
815             dst[n-i-1] = src[n-i-1]; \
816       } \
817       return dst; \
818      badness: \
819       VALGRIND_PRINTF_BACKTRACE( \
820          "*** memmove_chk: buffer overflow detected ***: " \
821          "program terminated\n"); \
822      _exit(127); \
823      /*NOTREACHED*/ \
824      return NULL; \
825    }
826
827 GLIBC25___MEMMOVE_CHK(VG_Z_LIBC_SONAME, __memmove_chk)
828
829
830 /* Find the first occurrence of C in S or the final NUL byte.  */
831 #define GLIBC232_STRCHRNUL(soname, fnname) \
832    char* VG_REPLACE_FUNCTION_ZU(soname,fnname) (const char* s, int c_in); \
833    char* VG_REPLACE_FUNCTION_ZU(soname,fnname) (const char* s, int c_in) \
834    { \
835       unsigned char  c        = (unsigned char) c_in; \
836       unsigned char* char_ptr = (unsigned char *)s; \
837       while (1) { \
838          if (*char_ptr == 0) return char_ptr; \
839          if (*char_ptr == c) return char_ptr; \
840          char_ptr++; \
841       } \
842    }
843
844 GLIBC232_STRCHRNUL(VG_Z_LIBC_SONAME, strchrnul)
845
846
847 /* Find the first occurrence of C in S.  */
848 #define GLIBC232_RAWMEMCHR(soname, fnname) \
849    char* VG_REPLACE_FUNCTION_ZU(soname,fnname) (const char* s, int c_in); \
850    char* VG_REPLACE_FUNCTION_ZU(soname,fnname) (const char* s, int c_in) \
851    { \
852       unsigned char  c        = (unsigned char) c_in; \
853       unsigned char* char_ptr = (unsigned char *)s; \
854       while (1) { \
855          if (*char_ptr == c) return char_ptr; \
856          char_ptr++; \
857       } \
858    }
859
860 GLIBC232_RAWMEMCHR(VG_Z_LIBC_SONAME, rawmemchr)
861 #if defined (VGO_linux)
862 GLIBC232_RAWMEMCHR(VG_Z_LIBC_SONAME, __GI___rawmemchr)
863 #endif
864
865 /* glibc variant of strcpy that checks the dest is big enough.
866    Copied from glibc-2.5/debug/test-strcpy_chk.c. */
867 #define GLIBC25___STRCPY_CHK(soname,fnname) \
868    char* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
869                                (char* dst, const char* src, SizeT len); \
870    char* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
871                                (char* dst, const char* src, SizeT len) \
872    { \
873       extern void _exit(int status); \
874       char* ret = dst; \
875       if (! len) \
876          goto badness; \
877       while ((*dst++ = *src++) != '\0') \
878          if (--len == 0) \
879             goto badness; \
880       return ret; \
881      badness: \
882       VALGRIND_PRINTF_BACKTRACE( \
883          "*** strcpy_chk: buffer overflow detected ***: " \
884          "program terminated\n"); \
885      _exit(127); \
886      /*NOTREACHED*/ \
887      return NULL; \
888    }
889
890 GLIBC25___STRCPY_CHK(VG_Z_LIBC_SONAME, __strcpy_chk)
891
892
893 /* glibc variant of stpcpy that checks the dest is big enough.
894    Copied from glibc-2.5/debug/test-stpcpy_chk.c. */
895 #define GLIBC25___STPCPY_CHK(soname,fnname) \
896    char* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
897                                (char* dst, const char* src, SizeT len); \
898    char* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
899                                (char* dst, const char* src, SizeT len) \
900    { \
901       extern void _exit(int status); \
902       if (! len) \
903          goto badness; \
904       while ((*dst++ = *src++) != '\0') \
905          if (--len == 0) \
906             goto badness; \
907       return dst - 1; \
908      badness: \
909       VALGRIND_PRINTF_BACKTRACE( \
910          "*** stpcpy_chk: buffer overflow detected ***: " \
911          "program terminated\n"); \
912      _exit(127); \
913      /*NOTREACHED*/ \
914      return NULL; \
915    }
916
917 GLIBC25___STPCPY_CHK(VG_Z_LIBC_SONAME, __stpcpy_chk)
918
919
920 /* mempcpy */
921 #define GLIBC25_MEMPCPY(soname, fnname) \
922    void* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
923             ( void *dst, const void *src, SizeT len ); \
924    void* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
925             ( void *dst, const void *src, SizeT len ) \
926    { \
927       register char *d; \
928       register char *s; \
929       SizeT len_saved = len; \
930       \
931       if (len == 0) \
932          return dst; \
933       \
934       if (is_overlap(dst, src, len, len)) \
935          RECORD_OVERLAP_ERROR("mempcpy", dst, src, len); \
936       \
937       if ( dst > src ) { \
938          d = (char *)dst + len - 1; \
939          s = (char *)src + len - 1; \
940          while ( len-- ) { \
941             *d-- = *s--; \
942          } \
943       } else if ( dst < src ) { \
944          d = (char *)dst; \
945          s = (char *)src; \
946          while ( len-- ) { \
947             *d++ = *s++; \
948          } \
949       } \
950       return (void*)( ((char*)dst) + len_saved ); \
951    }
952
953 GLIBC25_MEMPCPY(VG_Z_LIBC_SONAME, mempcpy)
954 #if defined(VGO_linux)
955 GLIBC25_MEMPCPY(VG_Z_LD_SO_1,     mempcpy) /* ld.so.1 */
956 #endif
957
958
959 #define GLIBC26___MEMCPY_CHK(soname, fnname) \
960    void* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
961             (void* dst, const void* src, SizeT len, SizeT dstlen ); \
962    void* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
963             (void* dst, const void* src, SizeT len, SizeT dstlen ) \
964    { \
965       extern void _exit(int status); \
966       register char *d; \
967       register char *s; \
968       \
969       if (dstlen < len) goto badness; \
970       \
971       if (len == 0) \
972          return dst; \
973       \
974       if (is_overlap(dst, src, len, len)) \
975          RECORD_OVERLAP_ERROR("memcpy_chk", dst, src, len); \
976       \
977       if ( dst > src ) { \
978          d = (char *)dst + len - 1; \
979          s = (char *)src + len - 1; \
980          while ( len-- ) { \
981             *d-- = *s--; \
982          } \
983       } else if ( dst < src ) { \
984          d = (char *)dst; \
985          s = (char *)src; \
986          while ( len-- ) { \
987             *d++ = *s++; \
988          } \
989       } \
990       return dst; \
991      badness: \
992       VALGRIND_PRINTF_BACKTRACE( \
993          "*** memcpy_chk: buffer overflow detected ***: " \
994          "program terminated\n"); \
995      _exit(127); \
996      /*NOTREACHED*/ \
997      return NULL; \
998    }
999
1000 GLIBC26___MEMCPY_CHK(VG_Z_LIBC_SONAME, __memcpy_chk)
1001
1002
1003 #define STRSTR(soname, fnname) \
1004    void* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
1005          (void* haystack, void* needle); \
1006    void* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
1007          (void* haystack, void* needle) \
1008    { \
1009       UChar* h = (UChar*)haystack; \
1010       UChar* n = (UChar*)needle; \
1011       \
1012       /* find the length of n, not including terminating zero */ \
1013       UWord nlen = 0; \
1014       while (n[nlen]) nlen++; \
1015       \
1016       /* if n is the empty string, match immediately. */ \
1017       if (nlen == 0) return h; \
1018       \
1019       /* assert(nlen >= 1); */ \
1020       UChar n0 = n[0]; \
1021       \
1022       while (1) { \
1023          UChar hh = *h; \
1024          if (hh == 0) return NULL; \
1025          if (hh != n0) { h++; continue; } \
1026          \
1027          UWord i; \
1028          for (i = 0; i < nlen; i++) { \
1029             if (n[i] != h[i]) \
1030                break; \
1031          } \
1032          /* assert(i >= 0 && i <= nlen); */ \
1033          if (i == nlen) \
1034             return h; \
1035          \
1036          h++; \
1037       } \
1038    }
1039
1040 #if defined(VGO_linux)
1041 STRSTR(VG_Z_LIBC_SONAME,          strstr)
1042 #endif
1043
1044
1045 #define STRPBRK(soname, fnname) \
1046    void* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
1047          (void* sV, void* acceptV); \
1048    void* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
1049          (void* sV, void* acceptV) \
1050    { \
1051       UChar* s = (UChar*)sV; \
1052       UChar* accept = (UChar*)acceptV; \
1053       \
1054       /*  find the length of 'accept', not including terminating zero */ \
1055       UWord nacc = 0; \
1056       while (accept[nacc]) nacc++; \
1057       \
1058       /* if n is the empty string, fail immediately. */ \
1059       if (nacc == 0) return NULL; \
1060       \
1061       /* assert(nacc >= 1); */ \
1062       while (1) { \
1063          UWord i; \
1064          UChar sc = *s; \
1065          if (sc == 0) \
1066             break; \
1067          for (i = 0; i < nacc; i++) { \
1068             if (sc == accept[i]) \
1069                return s; \
1070          } \
1071          s++; \
1072       } \
1073       \
1074       return NULL; \
1075    }
1076
1077 #if defined(VGO_linux)
1078 STRPBRK(VG_Z_LIBC_SONAME,          strpbrk)
1079 #endif
1080
1081
1082 #define STRCSPN(soname, fnname) \
1083    SizeT VG_REPLACE_FUNCTION_ZU(soname,fnname) \
1084          (void* sV, void* rejectV); \
1085    SizeT VG_REPLACE_FUNCTION_ZU(soname,fnname) \
1086          (void* sV, void* rejectV) \
1087    { \
1088       UChar* s = (UChar*)sV; \
1089       UChar* reject = (UChar*)rejectV; \
1090       \
1091       /* find the length of 'reject', not including terminating zero */ \
1092       UWord nrej = 0; \
1093       while (reject[nrej]) nrej++; \
1094       \
1095       UWord len = 0; \
1096       while (1) { \
1097          UWord i; \
1098          UChar sc = *s; \
1099          if (sc == 0) \
1100             break; \
1101          for (i = 0; i < nrej; i++) { \
1102             if (sc == reject[i]) \
1103                break; \
1104          } \
1105          /* assert(i >= 0 && i <= nrej); */ \
1106          if (i < nrej) \
1107             break; \
1108          s++; \
1109          len++; \
1110       } \
1111       \
1112       return len; \
1113    }
1114
1115 #if defined(VGO_linux)
1116 STRCSPN(VG_Z_LIBC_SONAME,          strcspn)
1117 #endif
1118
1119
1120 // And here's a validated strspn replacement, should it
1121 // become necessary.
1122 //UWord mystrspn( UChar* s, UChar* accept )
1123 //{
1124 //   /* find the length of 'accept', not including terminating zero */
1125 //   UWord nacc = 0;
1126 //   while (accept[nacc]) nacc++;
1127 //   if (nacc == 0) return 0;
1128 //
1129 //   UWord len = 0;
1130 //   while (1) {
1131 //      UWord i;
1132 //      UChar sc = *s;
1133 //      if (sc == 0)
1134 //         break;
1135 //      for (i = 0; i < nacc; i++) {
1136 //         if (sc == accept[i])
1137 //            break;
1138 //      }
1139 //      assert(i >= 0 && i <= nacc);
1140 //      if (i == nacc)
1141 //         break;
1142 //      s++;
1143 //      len++;
1144 //   }
1145 //
1146 //   return len;
1147 //}
1148
1149
1150 /*------------------------------------------------------------*/
1151 /*--- Improve definedness checking of process environment  ---*/
1152 /*------------------------------------------------------------*/
1153
1154 #if defined(VGO_linux)
1155
1156 /* putenv */
1157 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, putenv) (char* string);
1158 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, putenv) (char* string)
1159 {
1160     OrigFn fn;
1161     Word result;
1162     const char* p = string;
1163     VALGRIND_GET_ORIG_FN(fn);
1164     /* Now by walking over the string we magically produce
1165        traces when hitting undefined memory. */
1166     if (p)
1167         while (*p++)
1168             ;
1169     CALL_FN_W_W(result, fn, string);
1170     return result;
1171 }
1172
1173 /* unsetenv */
1174 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, unsetenv) (const char* name);
1175 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, unsetenv) (const char* name)
1176 {
1177     OrigFn fn;
1178     Word result;
1179     const char* p = name;
1180     VALGRIND_GET_ORIG_FN(fn);
1181     /* Now by walking over the string we magically produce
1182        traces when hitting undefined memory. */
1183     if (p)
1184         while (*p++)
1185             ;
1186     CALL_FN_W_W(result, fn, name);
1187     return result;
1188 }
1189
1190 /* setenv */
1191 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, setenv)
1192     (const char* name, const char* value, int overwrite);
1193 int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, setenv)
1194     (const char* name, const char* value, int overwrite)
1195 {
1196     OrigFn fn;
1197     Word result;
1198     const char* p;
1199     VALGRIND_GET_ORIG_FN(fn);
1200     /* Now by walking over the string we magically produce
1201        traces when hitting undefined memory. */
1202     if (name)
1203         for (p = name; *p; p++)
1204             ;
1205     if (value)
1206         for (p = value; *p; p++)
1207             ;
1208     VALGRIND_CHECK_VALUE_IS_DEFINED (overwrite);
1209     CALL_FN_W_WWW(result, fn, name, value, overwrite);
1210     return result;
1211 }
1212
1213 #endif /* defined(VGO_linux) */
1214
1215
1216 /*------------------------------------------------------------*/
1217 /*--- AIX stuff only after this point                      ---*/
1218 /*------------------------------------------------------------*/
1219
1220 /* Generate replacements for strcat, strncat, strcpy, strncpy, strcmp
1221    in the given soname. */
1222 #define Str5FNs(_soname)       \
1223     STRCAT(_soname, strcat)    \
1224    STRNCAT(_soname, strncat)   \
1225     STRCPY(_soname, strcpy)    \
1226    STRNCPY(_soname, strncpy)   \
1227     STRCMP(_soname, strcmp)
1228
1229 #if defined(VGP_ppc32_aix5)
1230 Str5FNs(NONE)                             /* in main exe */
1231 Str5FNs(libCZdaZLshrcoreZdoZR)            /* libC.a(shrcore.o) */
1232 Str5FNs(libX11ZdaZLshr4ZdoZR)             /* libX11.a(shr4.o) */
1233 Str5FNs(libXmZdaZLshrZaZdoZR)             /* libXm.a(shr*.o) */
1234 Str5FNs(libXtZdaZLshr4ZdoZR)              /* libXt.a(shr4.o) */
1235 Str5FNs(libppeZurZdaZLdynamicZdoZR)       /* libppe_r.a(dynamic.o) */
1236 Str5FNs(libodmZdaZLshrZdoZR)              /* libodm.a(shr.o) */
1237 Str5FNs(libmpiZurZdaZLmpicoreZurZdoZR)    /* libmpi_r.a(mpicore_r.o) */
1238 Str5FNs(libmpiZurZdaZLmpipoeZurZdoZR)     /* libmpi_r.a(mpipoe_r.o) */
1239 Str5FNs(libmpiZurZdaZLmpciZurZdoZR)       /* libmpi_r.a(mpci_r.o) */
1240 Str5FNs(libslurmZdso)                     /* libslurm.so */
1241 Str5FNs(libglibZdso)                      /* libglib.so */
1242 Str5FNs(libIMZdaZLshrZdoZR)               /* libIM.a(shr.o) */
1243 Str5FNs(libiconvZdaZLshr4ZdoZR)           /* libiconv.a(shr4.o) */
1244 Str5FNs(libGLZdaZLshrZdoZR)               /* libGL.a(shr.o) */
1245 Str5FNs(libgdkZdso)                       /* libgdk.so */
1246 Str5FNs(libcursesZdaZLshr42ZdoZR)         /* libcurses.a(shr42.o) */
1247 Str5FNs(libqtZda)                         /* libqt.a */
1248 Str5FNs(ZaZLlibglibZhZaZdsoZaZR)          /* *(libglib-*.so*) */
1249 Str5FNs(ZaZLlibfontconfigZdsoZaZR)        /* *(libfontconfig.so*) */
1250 Str5FNs(libQtZaa)                         /* libQt*.a */
1251 #endif
1252 #if defined(VGP_ppc64_aix5)
1253 Str5FNs(NONE)                             /* in main exe */
1254 Str5FNs(libX11ZdaZLshrZu64ZdoZR)          /* libX11.a(shr_64.o) */
1255 Str5FNs(libiconvZdaZLshr4Zu64ZdoZR)       /* libiconv.a(shr4_64.o) */
1256 Str5FNs(libGLZdaZLshrZu64ZdoZR)           /* libGL.a(shr_64.o) */
1257 Str5FNs(libppeZurZdaZLdynamic64ZdoZR)     /* libppe_r.a(dynamic64.o) */
1258 Str5FNs(libodmZdaZLshrZu64ZdoZR)          /* libodm.a(shr_64.o) */
1259 Str5FNs(libmpiZurZdaZLmpicore64ZurZdoZR)  /* libmpi_r.a(mpicore64_r.o) */
1260 Str5FNs(libmpiZurZdaZLmpipoe64ZurZdoZR)   /* libmpi_r.a(mpipoe64_r.o) */
1261 Str5FNs(libCZdaZLshrcoreZu64ZdoZR)        /* libC.a(shrcore_64.o) */
1262 Str5FNs(libmpiZurZdaZLmpci64ZurZdoZR)     /* libmpi_r.a(mpci64_r.o) */
1263 Str5FNs(libqtZda)                         /* libqt.a */
1264 Str5FNs(ZaZLlibglibZhZaZdsoZaZR)          /* *(libglib-*.so*) */
1265 Str5FNs(ZaZLlibfontconfigZdsoZaZR)        /* *(libfontconfig.so*) */
1266 Str5FNs(libQtZaa)                         /* libQt*.a */
1267 #endif
1268
1269
1270 /* AIX's libm contains a sqrt implementation which does a nasty thing:
1271    it loads the initial estimate of the root into a FP register, but
1272    only the upper half of the number is initialised data.  Hence the
1273    least significant 32 mantissa bits are undefined, and it then uses
1274    Newton-Raphson iteration to compute the final, defined result.
1275    This fools memcheck completely; the only solution I can think of is
1276    provide our own substitute.  The _FAST variant is almost right
1277    except the result is not correctly rounded.  The _EXACT variant,
1278    which is selected by default, is always right; but it's also pretty
1279    darn slow. */
1280
1281 #if defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
1282 #define SQRT_FAST(soname, fnname) \
1283    double VG_REPLACE_FUNCTION_ZU(soname,fnname)( double x ); \
1284    double VG_REPLACE_FUNCTION_ZU(soname,fnname)( double x ) \
1285    { \
1286       static UInt T1[32] =  \
1287          { 0,       1024,   3062,   5746,   9193,  13348, \
1288            18162,  23592,  29598,  36145,  43202,  50740, \
1289            58733,  67158,  75992,  85215,  83599,  71378, \
1290            60428,  50647,  41945,  34246,  27478,  21581, \
1291            16499,  12183,   8588,   5674,   3403,   1742, \
1292            661,    130 }; \
1293       UInt x0, x1, sign, expo, mant0, bIGENDIAN = 1; \
1294       union { UInt w[2]; double d; } u; \
1295       u.d   = x; \
1296       x0    = u.w[1 - bIGENDIAN]; /* high half */ \
1297       x1    = u.w[bIGENDIAN];  /* low half */ \
1298       sign  = x0 >> 31; \
1299       expo  = (x0 >> 20) & 0x7FF; \
1300       mant0 = x0 & 0xFFFFF; \
1301       if ( (sign == 0 && expo >= 1 && expo <= 0x7FE) /* +normal */ \
1302            || (sign == 0 && expo == 0  \
1303                          && (mant0 | x1) > 0) /* +denorm */) { \
1304          /* common case; do Newton-Raphson */ \
1305          /* technically k should be signed int32, but since we're \
1306             always entering here with x > 0, doesn't matter that it's \
1307             unsigned. */ \
1308          double y; \
1309          UInt k = (x0>>1) + 0x1ff80000; \
1310          u.w[1 - bIGENDIAN] = k - T1[31&(k>>15)]; \
1311          u.w[bIGENDIAN] = 0; \
1312          y = u.d; \
1313          y = (y+x/y)/2.0 ; \
1314          y = (y+x/y)/2.0 ; \
1315          y = y-(y-x/y)/2.0 ; \
1316          return y; \
1317       } \
1318       if ( (sign == 1 && expo >= 1 && expo <= 0x7FE) /* -normal */ \
1319            || (sign == 1 && expo == 0  \
1320                          && (mant0 | x1) > 0) /* -denorm */) { \
1321          u.w[1 - bIGENDIAN] = 0xFFF00000; \
1322          u.w[bIGENDIAN] = 0x1; \
1323          return u.d; /* -Inf -> NaN */ \
1324       } \
1325       if ((expo | mant0 | x1) == 0) \
1326          return x; /* +/-zero -> self */ \
1327       if (expo == 0x7FF && (mant0 | x1) == 0) { \
1328          if (sign == 0) \
1329             return x; /* +Inf -> self */ \
1330          u.w[1 - bIGENDIAN] = 0xFFF00000; \
1331          u.w[bIGENDIAN] = 0x1; \
1332          return u.d; /* -Inf -> NaN */ \
1333       } \
1334       /* must be +/- NaN */ \
1335       return x; /* +/-NaN -> self */ \
1336    }
1337
1338 #define SQRT_EXACT(soname, fnname) \
1339    /* \
1340     * ==================================================== \
1341     * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. \
1342     * \
1343     * Developed at SunPro, a Sun Microsystems, Inc. business. \
1344     * Permission to use, copy, modify, and distribute this \
1345     * software is freely granted, provided that this notice \
1346     * is preserved. \
1347     * ==================================================== \
1348     */ \
1349    /* \
1350     * Return correctly rounded sqrt. \
1351     *           ------------------------------------------ \
1352     *           |  Use the hardware sqrt if you have one | \
1353     *           ------------------------------------------ \
1354     * Method: \
1355     *   Bit by bit method using integer arithmetic. (Slow, but portable) \
1356     *   1. Normalization \
1357     *      Scale x to y in [1,4) with even powers of 2: \
1358     *      find an integer k such that  1 <= (y=x*2^(2k)) < 4, then \
1359     *              sqrt(x) = 2^k * sqrt(y) \
1360     *   2. Bit by bit computation \
1361     *      Let q  = sqrt(y) truncated to i bit after binary point (q = 1), \
1362     *           i                                                   0 \
1363     *                                     i+1         2 \
1364     *          s  = 2*q , and      y  =  2   * ( y - q  ).         (1) \
1365     *           i      i            i                 i \
1366     * \
1367     *      To compute q    from q , one checks whether \
1368     *                  i+1       i \
1369     * \
1370     *                            -(i+1) 2 \
1371     *                      (q + 2      ) <= y.                     (2) \
1372     *                        i \
1373     *                                                            -(i+1) \
1374     *      If (2) is false, then q   = q ; otherwise q   = q  + 2      . \
1375     *                             i+1   i             i+1   i \
1376     * \
1377     *      With some algebric manipulation, it is not difficult to see \
1378     *      that (2) is equivalent to \
1379     *                             -(i+1) \
1380     *                      s  +  2       <= y                      (3) \
1381     *                       i                i \
1382     * \
1383     *      The advantage of (3) is that s  and y  can be computed by \
1384     *                                    i      i \
1385     *      the following recurrence formula: \
1386     *          if (3) is false \
1387     * \
1388     *          s     =  s  ,       y    = y   ;                    (4) \
1389     *           i+1      i          i+1    i \
1390     * \
1391     *          otherwise, \
1392     *                         -i                     -(i+1) \
1393     *          s     =  s  + 2  ,  y    = y  -  s  - 2             (5) \
1394     *           i+1      i          i+1    i     i \
1395     * \
1396     * \
1397     *      One may easily use induction to prove (4) and (5). \
1398     *      Note. Since the left hand side of (3) contain only i+2 bits, \
1399     *            it does not necessary to do a full (53-bit) comparison \
1400     *            in (3). \
1401     *   3. Final rounding \
1402     *      After generating the 53 bits result, we compute one more bit. \
1403     *      Together with the remainder, we can decide whether the \
1404     *      result is exact, bigger than 1/2ulp, or less than 1/2ulp \
1405     *      (it will never equal to 1/2ulp). \
1406     *      The rounding mode can be detected by checking whether \
1407     *      huge + tiny is equal to huge, and whether huge - tiny is \
1408     *      equal to huge for some floating point number "huge" and "tiny". \
1409     * \
1410     * Special cases: \
1411     *      sqrt(+-0) = +-0         ... exact \
1412     *      sqrt(inf) = inf \
1413     *      sqrt(-ve) = NaN         ... with invalid signal \
1414     *      sqrt(NaN) = NaN         ... with invalid signal for signaling NaN \
1415     * \
1416     */ \
1417    double VG_REPLACE_FUNCTION_ZU(soname,fnname)( double x ); \
1418    double VG_REPLACE_FUNCTION_ZU(soname,fnname)( double x ) \
1419    {  \
1420       const Int    bIGENDIAN = 1; \
1421       const double one = 1.0, tiny=1.0e-300; \
1422       double z; \
1423       Int sign = (Int)0x80000000; \
1424       Int ix0,s0,q,m,t,i; \
1425       UInt r,t1,s1,ix1,q1; \
1426       union { UInt w[2]; double d; } u; \
1427       u.d = x; \
1428       ix0 = u.w[1-bIGENDIAN]; \
1429       ix1 = u.w[bIGENDIAN];    \
1430       \
1431       /* take care of Inf and NaN */ \
1432       if((ix0&0x7ff00000)==0x7ff00000) { \
1433          return x*x+x;               /* sqrt(NaN)=NaN, sqrt(+inf)=+inf \
1434                                         sqrt(-inf)=sNaN */ \
1435       } \
1436       /* take care of zero */ \
1437       if(ix0<=0) { \
1438          if(((ix0&(~sign))|ix1)==0) return x;/* sqrt(+-0) = +-0 */ \
1439          else if(ix0<0) \
1440               return (x-x)/(x-x);             /* sqrt(-ve) = sNaN */ \
1441       } \
1442       /* normalize x */ \
1443       m = (ix0>>20); \
1444       if(m==0) {                              /* subnormal x */ \
1445          while(ix0==0) { \
1446             m -= 21; \
1447             ix0 |= (ix1>>11); ix1 <<= 21; \
1448          } \
1449          for(i=0;(ix0&0x00100000)==0;i++) ix0<<=1; \
1450          m -= i-1; \
1451          ix0 |= (ix1>>(32-i)); \
1452          ix1 <<= i; \
1453       } \
1454       m -= 1023;      /* unbias exponent */ \
1455       ix0 = (ix0&0x000fffff)|0x00100000; \
1456       if(m&1){        /* odd m, double x to make it even */ \
1457          ix0 += ix0 + ((ix1&sign)>>31); \
1458          ix1 += ix1; \
1459       } \
1460       m >>= 1;        /* m = [m/2] */ \
1461       /* generate sqrt(x) bit by bit */ \
1462       ix0 += ix0 + ((ix1&sign)>>31); \
1463       ix1 += ix1; \
1464       q = q1 = s0 = s1 = 0;   /* [q,q1] = sqrt(x) */ \
1465       r = 0x00200000;         /* r = moving bit from right to left */ \
1466       while(r!=0) { \
1467          t = s0+r; \
1468          if(t<=ix0) { \
1469             s0   = t+r; \
1470             ix0 -= t; \
1471             q   += r; \
1472          } \
1473          ix0 += ix0 + ((ix1&sign)>>31); \
1474          ix1 += ix1; \
1475          r>>=1; \
1476       } \
1477       r = sign; \
1478       while(r!=0) { \
1479          t1 = s1+r; \
1480          t  = s0; \
1481          if((t<ix0)||((t==ix0)&&(t1<=ix1))) { \
1482             s1  = t1+r; \
1483             if(((t1&sign)==sign)&&(s1&sign)==0) s0 += 1; \
1484             ix0 -= t; \
1485             if (ix1 < t1) ix0 -= 1; \
1486             ix1 -= t1; \
1487             q1  += r; \
1488          } \
1489          ix0 += ix0 + ((ix1&sign)>>31); \
1490          ix1 += ix1; \
1491          r>>=1; \
1492       } \
1493       /* use floating add to find out rounding direction */ \
1494       if((ix0|ix1)!=0) { \
1495          z = one-tiny; /* trigger inexact flag */ \
1496          if (z>=one) { \
1497             z = one+tiny; \
1498             if (q1==(UInt)0xffffffff) { q1=0; q += 1;} \
1499             else if (z>one) { \
1500                     if (q1==(UInt)0xfffffffe) q+=1; \
1501                     q1+=2; \
1502                  } else \
1503                     q1 += (q1&1); \
1504          } \
1505       } \
1506       ix0 = (q>>1)+0x3fe00000; \
1507       ix1 = q1>>1; \
1508       if ((q&1)==1) ix1 |= sign; \
1509       ix0 += (m <<20); \
1510       ix0 = u.w[1-bIGENDIAN] = ix0; \
1511       ix1 = u.w[bIGENDIAN] = ix1;    \
1512       z = u.d; \
1513       return z; \
1514    }
1515
1516 #if 0
1517 SQRT_FAST(NONE, sqrt)  /* xlC generates these */
1518 SQRT_FAST(NONE, _sqrt) /* xlf generates these */
1519 #else
1520 SQRT_EXACT(NONE, sqrt)  /* xlC generates these */
1521 SQRT_EXACT(NONE, _sqrt) /* xlf generates these */
1522 #endif
1523
1524 #endif /* defined(VGP_ppc32_aix5) */
1525
1526 /*--------------------------------------------------------------------*/
1527 /*--- end                                                          ---*/
1528 /*--------------------------------------------------------------------*/