|
From: <sv...@va...> - 2011-08-16 21:50:18
|
Author: sewardj
Date: 2011-08-16 22:45:28 +0100 (Tue, 16 Aug 2011)
New Revision: 11985
Log:
Fix for #275284 (initial fix, at least). Will break OSX; fix
to follow.
* add behavioural eclass tags for most functions in
mc_replace_strmem.c and vg_replace_malloc.c.
* add a wrapper for strspn() (see bug 270925)
* coregrind/m_redir.c: add logic to use eclass tags for
resolving conflicting redirections. Improve debug
printing in that situation.
* mc_replace_strmem.c: add a wrapper for "__GI___strcasecmp_l".
Gark. Is this correct? Does __GI___strcasecmp_l behave the
same as __GI_strcasecmp_l and strcasecmp_l ?
Modified:
trunk/coregrind/m_redir.c
trunk/coregrind/m_replacemalloc/vg_replace_malloc.c
trunk/memcheck/mc_replace_strmem.c
Modified: trunk/coregrind/m_redir.c
===================================================================
--- trunk/coregrind/m_redir.c 2011-08-16 09:54:00 UTC (rev 11984)
+++ trunk/coregrind/m_redir.c 2011-08-16 21:45:28 UTC (rev 11985)
@@ -708,7 +708,7 @@
static void maybe_add_active ( Active act )
{
HChar* what = NULL;
- Active* old;
+ Active* old = NULL;
/* Complain and ignore manifestly bogus 'from' addresses.
@@ -735,10 +735,24 @@
/* Dodgy. Conflicting binding. */
vg_assert(old->from_addr == act.from_addr);
if (old->to_addr != act.to_addr) {
- /* we have to ignore it -- otherwise activeSet would contain
- conflicting bindings. */
- what = "new redirection conflicts with existing -- ignoring it";
- goto bad;
+ /* We've got a conflicting binding -- that is, from_addr is
+ specified to redirect to two different destinations,
+ old->to_addr and act.to_addr. If we can prove that they
+ are behaviourally equivalent then that's no problem. So
+ we can look at the behavioural eclass tags for both
+ functions to see if that's so. If they are equal, and
+ nonzero, then that's fine. But if not, we can't show they
+ are equivalent, so we have to complain, and ignore the new
+ binding. */
+ vg_assert(old->becTag >= 0 && old->becTag <= 9999);
+ vg_assert(act.becTag >= 0 && act.becTag <= 9999);
+ if (old->becTag != 0 && act.becTag != 0 && old->becTag == act.becTag) {
+ /* the replacements are behaviourally equivalent, so we can
+ safely ignore this conflict, and not add the new one. */
+ } else {
+ what = "new redirection conflicts with existing -- ignoring it";
+ goto bad;
+ }
} else {
/* This appears to be a duplicate of an existing binding.
Safe(ish) -- ignore. */
@@ -765,6 +779,9 @@
vg_assert(what);
if (VG_(clo_verbosity) > 1) {
VG_(message)(Vg_UserMsg, "WARNING: %s\n", what);
+ if (old) {
+ show_active( " old: ", old);
+ }
show_active( " new: ", &act);
}
}
Modified: trunk/coregrind/m_replacemalloc/vg_replace_malloc.c
===================================================================
--- trunk/coregrind/m_replacemalloc/vg_replace_malloc.c 2011-08-16 09:54:00 UTC (rev 11984)
+++ trunk/coregrind/m_replacemalloc/vg_replace_malloc.c 2011-08-16 21:45:28 UTC (rev 11985)
@@ -70,7 +70,33 @@
#include "pub_core_redir.h" // for VG_REPLACE_FUNCTION_*
#include "pub_core_replacemalloc.h"
+/* Assignment of behavioural equivalence class tags: 1NNN is intended
+ to be reserved for the Valgrind core. Current usage:
+ 1001 ALLOC_or_NULL
+ 1002 ZONEALLOC_or_NULL
+ 1003 ALLOC_or_BOMB
+ 1004 ZONEFREE
+ 1005 FREE
+ 1006 ZONECALLOC
+ 1007 CALLOC
+ 1008 ZONEREALLOC
+ 1009 REALLOC
+ 1010 ZONEMEMALIGN
+ 1011 MEMALIGN
+ 1012 VALLOC
+ 1013 ZONEVALLOC
+ 1014 MALLOPT
+ 1015 MALLOC_TRIM
+ 1016 POSIX_MEMALIGN
+ 1017 MALLOC_USABLE_SIZE
+ 1018 PANIC
+ 1019 MALLOC_STATS
+ 1020 MALLINFO
+ 1021 DEFAULT_ZONE
+ 1022 ZONE_CHECK
+*/
+
/* 2 Apr 05: the Portland Group compiler, which uses cfront/ARM style
mangling, could be supported properly by the redirects in this
module. Except we can't because it doesn't put its allocation
@@ -172,8 +198,8 @@
*/
#define ALLOC_or_NULL(soname, fnname, vg_replacement) \
\
- void* VG_REPLACE_FUNCTION_ZU(soname,fnname) (SizeT n); \
- void* VG_REPLACE_FUNCTION_ZU(soname,fnname) (SizeT n) \
+ void* VG_REPLACE_FUNCTION_EZU(1001,soname,fnname) (SizeT n); \
+ void* VG_REPLACE_FUNCTION_EZU(1001,soname,fnname) (SizeT n) \
{ \
void* v; \
\
@@ -187,8 +213,8 @@
#define ZONEALLOC_or_NULL(soname, fnname, vg_replacement) \
\
- void* VG_REPLACE_FUNCTION_ZU(soname,fnname) (void *zone, SizeT n); \
- void* VG_REPLACE_FUNCTION_ZU(soname,fnname) (void *zone, SizeT n) \
+ void* VG_REPLACE_FUNCTION_EZU(1002,soname,fnname) (void *zone, SizeT n); \
+ void* VG_REPLACE_FUNCTION_EZU(1002,soname,fnname) (void *zone, SizeT n) \
{ \
void* v; \
\
@@ -207,8 +233,8 @@
*/
#define ALLOC_or_BOMB(soname, fnname, vg_replacement) \
\
- void* VG_REPLACE_FUNCTION_ZU(soname,fnname) (SizeT n); \
- void* VG_REPLACE_FUNCTION_ZU(soname,fnname) (SizeT n) \
+ void* VG_REPLACE_FUNCTION_EZU(1003,soname,fnname) (SizeT n); \
+ void* VG_REPLACE_FUNCTION_EZU(1003,soname,fnname) (SizeT n) \
{ \
void* v; \
\
@@ -316,8 +342,8 @@
*/
#define ZONEFREE(soname, fnname, vg_replacement) \
\
- void VG_REPLACE_FUNCTION_ZU(soname,fnname) (void *zone, void *p); \
- void VG_REPLACE_FUNCTION_ZU(soname,fnname) (void *zone, void *p) \
+ void VG_REPLACE_FUNCTION_EZU(1004,soname,fnname) (void *zone, void *p); \
+ void VG_REPLACE_FUNCTION_EZU(1004,soname,fnname) (void *zone, void *p) \
{ \
if (!init_done) init(); \
MALLOC_TRACE(#vg_replacement "(%p, %p)\n", zone, p ); \
@@ -328,8 +354,8 @@
#define FREE(soname, fnname, vg_replacement) \
\
- void VG_REPLACE_FUNCTION_ZU(soname,fnname) (void *p); \
- void VG_REPLACE_FUNCTION_ZU(soname,fnname) (void *p) \
+ void VG_REPLACE_FUNCTION_EZU(1005,soname,fnname) (void *p); \
+ void VG_REPLACE_FUNCTION_EZU(1005,soname,fnname) (void *p) \
{ \
if (!init_done) init(); \
MALLOC_TRACE(#vg_replacement "(%p)\n", p ); \
@@ -391,8 +417,10 @@
#define ZONECALLOC(soname, fnname) \
\
- void* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( void *zone, SizeT nmemb, SizeT size ); \
- void* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( void *zone, SizeT nmemb, SizeT size ) \
+ void* VG_REPLACE_FUNCTION_EZU(1006,soname,fnname) \
+ ( void *zone, SizeT nmemb, SizeT size ); \
+ void* VG_REPLACE_FUNCTION_EZU(1006,soname,fnname) \
+ ( void *zone, SizeT nmemb, SizeT size ) \
{ \
void* v; \
\
@@ -406,8 +434,10 @@
#define CALLOC(soname, fnname) \
\
- void* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( SizeT nmemb, SizeT size ); \
- void* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( SizeT nmemb, SizeT size ) \
+ void* VG_REPLACE_FUNCTION_EZU(1007,soname,fnname) \
+ ( SizeT nmemb, SizeT size ); \
+ void* VG_REPLACE_FUNCTION_EZU(1007,soname,fnname) \
+ ( SizeT nmemb, SizeT size ) \
{ \
void* v; \
\
@@ -439,8 +469,10 @@
#define ZONEREALLOC(soname, fnname) \
\
- void* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( void *zone, void* ptrV, SizeT new_size );\
- void* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( void *zone, void* ptrV, SizeT new_size ) \
+ void* VG_REPLACE_FUNCTION_EZU(1008,soname,fnname) \
+ ( void *zone, void* ptrV, SizeT new_size ); \
+ void* VG_REPLACE_FUNCTION_EZU(1008,soname,fnname) \
+ ( void *zone, void* ptrV, SizeT new_size ) \
{ \
void* v; \
\
@@ -463,8 +495,10 @@
#define REALLOC(soname, fnname) \
\
- void* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( void* ptrV, SizeT new_size );\
- void* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( void* ptrV, SizeT new_size ) \
+ void* VG_REPLACE_FUNCTION_EZU(1009,soname,fnname) \
+ ( void* ptrV, SizeT new_size );\
+ void* VG_REPLACE_FUNCTION_EZU(1009,soname,fnname) \
+ ( void* ptrV, SizeT new_size ) \
{ \
void* v; \
\
@@ -474,9 +508,10 @@
if (ptrV == NULL) \
/* We need to call a malloc-like function; so let's use \
one which we know exists. */ \
- return VG_REPLACE_FUNCTION_ZU(VG_Z_LIBC_SONAME,malloc) (new_size); \
+ return VG_REPLACE_FUNCTION_EZU(1001,VG_Z_LIBC_SONAME,malloc) \
+ (new_size); \
if (new_size <= 0) { \
- VG_REPLACE_FUNCTION_ZU(VG_Z_LIBC_SONAME,free)(ptrV); \
+ VG_REPLACE_FUNCTION_EZU(1005,VG_Z_LIBC_SONAME,free)(ptrV); \
MALLOC_TRACE(" = 0\n"); \
return NULL; \
} \
@@ -495,8 +530,10 @@
#define ZONEMEMALIGN(soname, fnname) \
\
- void* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( void *zone, SizeT alignment, SizeT n ); \
- void* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( void *zone, SizeT alignment, SizeT n ) \
+ void* VG_REPLACE_FUNCTION_EZU(1010,soname,fnname) \
+ ( void *zone, SizeT alignment, SizeT n ); \
+ void* VG_REPLACE_FUNCTION_EZU(1010,soname,fnname) \
+ ( void *zone, SizeT alignment, SizeT n ) \
{ \
void* v; \
\
@@ -518,8 +555,10 @@
#define MEMALIGN(soname, fnname) \
\
- void* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( SizeT alignment, SizeT n ); \
- void* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( SizeT alignment, SizeT n ) \
+ void* VG_REPLACE_FUNCTION_EZU(1011,soname,fnname) \
+ ( SizeT alignment, SizeT n ); \
+ void* VG_REPLACE_FUNCTION_EZU(1011,soname,fnname) \
+ ( SizeT alignment, SizeT n ) \
{ \
void* v; \
\
@@ -549,20 +588,22 @@
#define VALLOC(soname, fnname) \
\
- void* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( SizeT size ); \
- void* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( SizeT size ) \
+ void* VG_REPLACE_FUNCTION_EZU(1012,soname,fnname) ( SizeT size ); \
+ void* VG_REPLACE_FUNCTION_EZU(1012,soname,fnname) ( SizeT size ) \
{ \
static int pszB = 0; \
if (pszB == 0) \
pszB = my_getpagesize(); \
- return VG_REPLACE_FUNCTION_ZU(VG_Z_LIBC_SONAME,memalign) \
+ return VG_REPLACE_FUNCTION_EZU(1011,VG_Z_LIBC_SONAME,memalign) \
((SizeT)pszB, size); \
}
#define ZONEVALLOC(soname, fnname) \
\
- void* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( void *zone, SizeT size ); \
- void* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( void *zone, SizeT size ) \
+ void* VG_REPLACE_FUNCTION_EZU(1013,soname,fnname) \
+ ( void *zone, SizeT size ); \
+ void* VG_REPLACE_FUNCTION_EZU(1013,soname,fnname) \
+ ( void *zone, SizeT size ) \
{ \
static int pszB = 0; \
if (pszB == 0) \
@@ -583,8 +624,8 @@
#define MALLOPT(soname, fnname) \
\
- int VG_REPLACE_FUNCTION_ZU(soname, fnname) ( int cmd, int value ); \
- int VG_REPLACE_FUNCTION_ZU(soname, fnname) ( int cmd, int value ) \
+ int VG_REPLACE_FUNCTION_EZU(1014,soname,fnname) ( int cmd, int value ); \
+ int VG_REPLACE_FUNCTION_EZU(1014,soname,fnname) ( int cmd, int value ) \
{ \
/* In glibc-2.2.4, 1 denotes a successful return value for \
mallopt */ \
@@ -619,8 +660,8 @@
// For simplicity, we always return 0.
#define MALLOC_TRIM(soname, fnname) \
\
- int VG_REPLACE_FUNCTION_ZU(soname, fnname) ( SizeT pad ); \
- int VG_REPLACE_FUNCTION_ZU(soname, fnname) ( SizeT pad ) \
+ int VG_REPLACE_FUNCTION_EZU(1015,soname,fnname) ( SizeT pad ); \
+ int VG_REPLACE_FUNCTION_EZU(1015,soname,fnname) ( SizeT pad ) \
{ \
/* 0 denotes that malloc_trim() either wasn't able \
to do anything, or was not implemented */ \
@@ -634,10 +675,10 @@
#define POSIX_MEMALIGN(soname, fnname) \
\
- int VG_REPLACE_FUNCTION_ZU(soname, fnname) ( void **memptr, \
- SizeT alignment, SizeT size ); \
- int VG_REPLACE_FUNCTION_ZU(soname, fnname) ( void **memptr, \
- SizeT alignment, SizeT size ) \
+ int VG_REPLACE_FUNCTION_EZU(1016,soname,fnname) \
+ ( void **memptr, SizeT alignment, SizeT size ); \
+ int VG_REPLACE_FUNCTION_EZU(1016,soname,fnname) \
+ ( void **memptr, SizeT alignment, SizeT size ) \
{ \
void *mem; \
\
@@ -647,7 +688,8 @@
|| (alignment & (alignment - 1)) != 0) \
return VKI_EINVAL; \
\
- mem = VG_REPLACE_FUNCTION_ZU(VG_Z_LIBC_SONAME,memalign)(alignment, size); \
+ mem = VG_REPLACE_FUNCTION_EZU(1011,VG_Z_LIBC_SONAME,memalign) \
+ (alignment, size); \
\
if (mem != NULL) { \
*memptr = mem; \
@@ -664,8 +706,8 @@
#define MALLOC_USABLE_SIZE(soname, fnname) \
\
- SizeT VG_REPLACE_FUNCTION_ZU(soname, fnname) ( void* p ); \
- SizeT VG_REPLACE_FUNCTION_ZU(soname, fnname) ( void* p ) \
+ SizeT VG_REPLACE_FUNCTION_EZU(1017,soname,fnname) ( void* p ); \
+ SizeT VG_REPLACE_FUNCTION_EZU(1017,soname,fnname) ( void* p ) \
{ \
SizeT pszB; \
\
@@ -697,8 +739,8 @@
#define PANIC(soname, fnname) \
\
- void VG_REPLACE_FUNCTION_ZU(soname, fnname) ( void ); \
- void VG_REPLACE_FUNCTION_ZU(soname, fnname) ( void ) \
+ void VG_REPLACE_FUNCTION_EZU(1018,soname,fnname) ( void ); \
+ void VG_REPLACE_FUNCTION_EZU(1018,soname,fnname) ( void ) \
{ \
panic(#fnname); \
}
@@ -709,8 +751,8 @@
#define MALLOC_STATS(soname, fnname) \
\
- void VG_REPLACE_FUNCTION_ZU(soname, fnname) ( void ); \
- void VG_REPLACE_FUNCTION_ZU(soname, fnname) ( void ) \
+ void VG_REPLACE_FUNCTION_EZU(1019,soname,fnname) ( void ); \
+ void VG_REPLACE_FUNCTION_EZU(1019,soname,fnname) ( void ) \
{ \
/* Valgrind's malloc_stats implementation does nothing. */ \
}
@@ -725,8 +767,8 @@
// doesn't know that the call to mallinfo fills in mi.
#define MALLINFO(soname, fnname) \
\
- struct vg_mallinfo VG_REPLACE_FUNCTION_ZU(soname, fnname) ( void ); \
- struct vg_mallinfo VG_REPLACE_FUNCTION_ZU(soname, fnname) ( void ) \
+ struct vg_mallinfo VG_REPLACE_FUNCTION_EZU(1020,soname,fnname) ( void ); \
+ struct vg_mallinfo VG_REPLACE_FUNCTION_EZU(1020,soname,fnname) ( void ) \
{ \
static struct vg_mallinfo mi; \
if (!init_done) init(); \
@@ -763,8 +805,8 @@
#define DEFAULT_ZONE(soname, fnname) \
\
- void *VG_REPLACE_FUNCTION_ZU(soname, fnname) ( void ); \
- void *VG_REPLACE_FUNCTION_ZU(soname, fnname) ( void ) \
+ void *VG_REPLACE_FUNCTION_EZU(1021,soname,fnname) ( void ); \
+ void *VG_REPLACE_FUNCTION_EZU(1021,soname,fnname) ( void ) \
{ \
return &vg_default_zone; \
}
@@ -776,9 +818,9 @@
// GrP fixme bypass libc's use of zone->introspect->check
#define ZONE_CHECK(soname, fnname) \
- \
- int VG_REPLACE_FUNCTION_ZU(soname, fnname)(void* zone); \
- int VG_REPLACE_FUNCTION_ZU(soname, fnname)(void* zone) \
+ \
+ int VG_REPLACE_FUNCTION_EZU(1022,soname,fnname)(void* zone); \
+ int VG_REPLACE_FUNCTION_EZU(1022,soname,fnname)(void* zone) \
{ \
return 1; \
}
Modified: trunk/memcheck/mc_replace_strmem.c
===================================================================
--- trunk/memcheck/mc_replace_strmem.c 2011-08-16 09:54:00 UTC (rev 11984)
+++ trunk/memcheck/mc_replace_strmem.c 2011-08-16 21:45:28 UTC (rev 11985)
@@ -53,7 +53,46 @@
THEY RUN ON THE SIMD CPU!
------------------------------------------------------------------ */
+/* Assignment of behavioural equivalence class tags: 2NNN is intended
+ to be reserved for Memcheck. Current usage:
+ 2001 STRRCHR
+ 2002 STRCHR
+ 2003 STRCAT
+ 2004 STRNCAT
+ 2005 STRLCAT
+ 2006 STRNLEN
+ 2007 STRLEN
+ 2008 STRCPY
+ 2009 STRNCPY
+ 2010 STRLCPY
+ 2011 STRNCMP
+ 2012 STRCASECMP
+ 2013 STRNCASECMP
+ 2014 STRCASECMP_L
+ 2015 STRNCASECMP_L
+ 2016 STRCMP
+ 2017 MEMCHR
+ 2018 MEMMOVE
+ 2019 MEMCMP
+ 2020 STPCPY
+ 2021 MEMSET
+ 2022 MEMCPY
+ 2023 BCOPY
+ 2024 GLIBC25___MEMMOVE_CHK
+ 2025 GLIBC232_STRCHRNUL
+ 2026 GLIBC232_RAWMEMCHR
+ 2027 GLIBC25___STRCPY_CHK
+ 2028 GLIBC25___STPCPY_CHK
+ 2029 GLIBC25_MEMPCPY
+ 2030 GLIBC26___MEMCPY_CHK
+ 2031 STRSTR
+ 2032 STRPBRK
+ 2033 STRCSPN
+ 2034 STRSPN
+*/
+
+
/* Figure out if [dst .. dst+dstlen-1] overlaps with
[src .. src+srclen-1].
We assume that the address ranges do not wrap around
@@ -113,8 +152,8 @@
#define STRRCHR(soname, fnname) \
- char* VG_REPLACE_FUNCTION_ZU(soname,fnname)( const char* s, int c ); \
- char* VG_REPLACE_FUNCTION_ZU(soname,fnname)( const char* s, int c ) \
+ char* VG_REPLACE_FUNCTION_EZU(2001,soname,fnname)( const char* s, int c ); \
+ char* VG_REPLACE_FUNCTION_EZU(2001,soname,fnname)( const char* s, int c ) \
{ \
UChar ch = (UChar)((UInt)c); \
UChar* p = (UChar*)s; \
@@ -139,8 +178,8 @@
#define STRCHR(soname, fnname) \
- char* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( const char* s, int c ); \
- char* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( const char* s, int c ) \
+ char* VG_REPLACE_FUNCTION_EZU(2002,soname,fnname) ( const char* s, int c ); \
+ char* VG_REPLACE_FUNCTION_EZU(2002,soname,fnname) ( const char* s, int c ) \
{ \
UChar ch = (UChar)((UInt)c); \
UChar* p = (UChar*)s; \
@@ -167,8 +206,10 @@
#define STRCAT(soname, fnname) \
- char* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( char* dst, const char* src ); \
- char* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( char* dst, const char* src ) \
+ char* VG_REPLACE_FUNCTION_EZU(2003,soname,fnname) \
+ ( char* dst, const char* src ); \
+ char* VG_REPLACE_FUNCTION_EZU(2003,soname,fnname) \
+ ( char* dst, const char* src ) \
{ \
const Char* src_orig = src; \
Char* dst_orig = dst; \
@@ -193,9 +234,9 @@
#endif
#define STRNCAT(soname, fnname) \
- char* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
+ char* VG_REPLACE_FUNCTION_EZU(2004,soname,fnname) \
( char* dst, const char* src, SizeT n ); \
- char* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
+ char* VG_REPLACE_FUNCTION_EZU(2004,soname,fnname) \
( char* dst, const char* src, SizeT n ) \
{ \
const Char* src_orig = src; \
@@ -210,7 +251,7 @@
/* pre-counting lengths... should be ok */ \
if (is_overlap(dst_orig, \
src_orig, \
- (Addr)dst-(Addr)dst_orig+1, \
+ (Addr)dst-(Addr)dst_orig+1, \
(Addr)src-(Addr)src_orig+1)) \
RECORD_OVERLAP_ERROR("strncat", dst_orig, src_orig, n); \
\
@@ -229,15 +270,15 @@
Truncation occurred if retval >= n.
*/
#define STRLCAT(soname, fnname) \
- SizeT VG_REPLACE_FUNCTION_ZU(soname,fnname) \
+ SizeT VG_REPLACE_FUNCTION_EZU(2005,soname,fnname) \
( char* dst, const char* src, SizeT n ); \
- SizeT VG_REPLACE_FUNCTION_ZU(soname,fnname) \
+ SizeT VG_REPLACE_FUNCTION_EZU(2005,soname,fnname) \
( char* dst, const char* src, SizeT n ) \
{ \
const Char* src_orig = src; \
Char* dst_orig = dst; \
SizeT m = 0; \
-\
+ \
while (m < n && *dst) { m++; dst++; } \
if (m < n) { \
/* Fill as far as dst_orig[n-2], then nul-terminate. */ \
@@ -255,7 +296,7 @@
(Addr)dst-(Addr)dst_orig+1, \
(Addr)src-(Addr)src_orig+1)) \
RECORD_OVERLAP_ERROR("strlcat", dst_orig, src_orig, n); \
-\
+ \
return m; \
}
@@ -266,8 +307,10 @@
#define STRNLEN(soname, fnname) \
- SizeT VG_REPLACE_FUNCTION_ZU(soname,fnname) ( const char* str, SizeT n ); \
- SizeT VG_REPLACE_FUNCTION_ZU(soname,fnname) ( const char* str, SizeT n ) \
+ SizeT VG_REPLACE_FUNCTION_EZU(2006,soname,fnname) \
+ ( const char* str, SizeT n ); \
+ SizeT VG_REPLACE_FUNCTION_EZU(2006,soname,fnname) \
+ ( const char* str, SizeT n ) \
{ \
SizeT i = 0; \
while (i < n && str[i] != 0) i++; \
@@ -285,8 +328,10 @@
// confusing if you aren't expecting it. Other small functions in this file
// may also be inline by gcc.
#define STRLEN(soname, fnname) \
- SizeT VG_REPLACE_FUNCTION_ZU(soname,fnname)( const char* str ); \
- SizeT VG_REPLACE_FUNCTION_ZU(soname,fnname)( const char* str ) \
+ SizeT VG_REPLACE_FUNCTION_EZU(2007,soname,fnname) \
+ ( const char* str ); \
+ SizeT VG_REPLACE_FUNCTION_EZU(2007,soname,fnname) \
+ ( const char* str ) \
{ \
SizeT i = 0; \
while (str[i] != 0) i++; \
@@ -296,14 +341,14 @@
STRLEN(VG_Z_LIBC_SONAME, strlen)
#if defined(VGO_linux)
STRLEN(VG_Z_LIBC_SONAME, __GI_strlen)
-STRLEN(VG_Z_LD_LINUX_SO_2, strlen)
-STRLEN(VG_Z_LD_LINUX_X86_64_SO_2, strlen)
#endif
#define STRCPY(soname, fnname) \
- char* VG_REPLACE_FUNCTION_ZU(soname, fnname) ( char* dst, const char* src ); \
- char* VG_REPLACE_FUNCTION_ZU(soname, fnname) ( char* dst, const char* src ) \
+ char* VG_REPLACE_FUNCTION_EZU(2008,soname,fnname) \
+ ( char* dst, const char* src ); \
+ char* VG_REPLACE_FUNCTION_EZU(2008,soname,fnname) \
+ ( char* dst, const char* src ) \
{ \
const Char* src_orig = src; \
Char* dst_orig = dst; \
@@ -315,7 +360,7 @@
/* pre-counting length... should be ok */ \
if (is_overlap(dst_orig, \
src_orig, \
- (Addr)dst-(Addr)dst_orig+1, \
+ (Addr)dst-(Addr)dst_orig+1, \
(Addr)src-(Addr)src_orig+1)) \
RECORD_OVERLAP_ERROR("strcpy", dst_orig, src_orig, 0); \
\
@@ -331,9 +376,9 @@
#define STRNCPY(soname, fnname) \
- char* VG_REPLACE_FUNCTION_ZU(soname, fnname) \
+ char* VG_REPLACE_FUNCTION_EZU(2009,soname,fnname) \
( char* dst, const char* src, SizeT n ); \
- char* VG_REPLACE_FUNCTION_ZU(soname, fnname) \
+ char* VG_REPLACE_FUNCTION_EZU(2009,soname,fnname) \
( char* dst, const char* src, SizeT n ) \
{ \
const Char* src_orig = src; \
@@ -361,15 +406,15 @@
/* Copy up to n-1 bytes from src to dst. Then nul-terminate dst if n > 0.
Returns strlen(src). Does not zero-fill the remainder of dst. */
#define STRLCPY(soname, fnname) \
- SizeT VG_REPLACE_FUNCTION_ZU(soname, fnname) \
+ SizeT VG_REPLACE_FUNCTION_EZU(2010,soname,fnname) \
( char* dst, const char* src, SizeT n ); \
- SizeT VG_REPLACE_FUNCTION_ZU(soname, fnname) \
+ SizeT VG_REPLACE_FUNCTION_EZU(2010,soname,fnname) \
( char* dst, const char* src, SizeT n ) \
{ \
const char* src_orig = src; \
char* dst_orig = dst; \
SizeT m = 0; \
-\
+ \
while (m < n-1 && *src) { m++; *dst++ = *src++; } \
/* m non-nul bytes have now been copied, and m <= n-1. */ \
/* Check for overlap after copying; all n bytes of dst are relevant, */ \
@@ -390,9 +435,9 @@
#define STRNCMP(soname, fnname) \
- int VG_REPLACE_FUNCTION_ZU(soname,fnname) \
+ int VG_REPLACE_FUNCTION_EZU(2011,soname,fnname) \
( const char* s1, const char* s2, SizeT nmax ); \
- int VG_REPLACE_FUNCTION_ZU(soname,fnname) \
+ int VG_REPLACE_FUNCTION_EZU(2011,soname,fnname) \
( const char* s1, const char* s2, SizeT nmax ) \
{ \
SizeT n = 0; \
@@ -418,9 +463,9 @@
#define STRCASECMP(soname, fnname) \
- int VG_REPLACE_FUNCTION_ZU(soname,fnname) \
+ int VG_REPLACE_FUNCTION_EZU(2012,soname,fnname) \
( const char* s1, const char* s2 ); \
- int VG_REPLACE_FUNCTION_ZU(soname,fnname) \
+ int VG_REPLACE_FUNCTION_EZU(2012,soname,fnname) \
( const char* s1, const char* s2 ) \
{ \
extern int tolower(int); \
@@ -447,9 +492,9 @@
#define STRNCASECMP(soname, fnname) \
- int VG_REPLACE_FUNCTION_ZU(soname,fnname) \
+ int VG_REPLACE_FUNCTION_EZU(2013,soname,fnname) \
( const char* s1, const char* s2, SizeT nmax ); \
- int VG_REPLACE_FUNCTION_ZU(soname,fnname) \
+ int VG_REPLACE_FUNCTION_EZU(2013,soname,fnname) \
( const char* s1, const char* s2, SizeT nmax ) \
{ \
extern int tolower(int); \
@@ -460,8 +505,10 @@
if (*s1 == 0) return -1; \
if (*s2 == 0) return 1; \
\
- if (tolower(*(unsigned char*)s1) < tolower(*(unsigned char*)s2)) return -1; \
- if (tolower(*(unsigned char*)s1) > tolower(*(unsigned char*)s2)) return 1; \
+ if (tolower(*(unsigned char*)s1) \
+ < tolower(*(unsigned char*)s2)) return -1; \
+ if (tolower(*(unsigned char*)s1) \
+ > tolower(*(unsigned char*)s2)) return 1; \
\
s1++; s2++; n++; \
} \
@@ -478,9 +525,9 @@
#define STRCASECMP_L(soname, fnname) \
- int VG_REPLACE_FUNCTION_ZU(soname,fnname) \
+ int VG_REPLACE_FUNCTION_EZU(2014,soname,fnname) \
( const char* s1, const char* s2, void* locale ); \
- int VG_REPLACE_FUNCTION_ZU(soname,fnname) \
+ int VG_REPLACE_FUNCTION_EZU(2014,soname,fnname) \
( const char* s1, const char* s2, void* locale ) \
{ \
extern int tolower_l(int, void*) __attribute__((weak)); \
@@ -501,13 +548,14 @@
STRCASECMP_L(VG_Z_LIBC_SONAME, strcasecmp_l)
#if defined(VGO_linux)
STRCASECMP_L(VG_Z_LIBC_SONAME, __GI_strcasecmp_l)
+STRCASECMP_L(VG_Z_LIBC_SONAME, __GI___strcasecmp_l)
#endif
#define STRNCASECMP_L(soname, fnname) \
- int VG_REPLACE_FUNCTION_ZU(soname,fnname) \
+ int VG_REPLACE_FUNCTION_EZU(2015,soname,fnname) \
( const char* s1, const char* s2, SizeT nmax, void* locale ); \
- int VG_REPLACE_FUNCTION_ZU(soname,fnname) \
+ int VG_REPLACE_FUNCTION_EZU(2015,soname,fnname) \
( const char* s1, const char* s2, SizeT nmax, void* locale ) \
{ \
extern int tolower_l(int, void*) __attribute__((weak)); \
@@ -518,8 +566,10 @@
if (*s1 == 0) return -1; \
if (*s2 == 0) return 1; \
\
- if (tolower_l(*(unsigned char*)s1, locale) < tolower_l(*(unsigned char*)s2, locale)) return -1; \
- if (tolower_l(*(unsigned char*)s1, locale) > tolower_l(*(unsigned char*)s2, locale)) return 1; \
+ if (tolower_l(*(unsigned char*)s1, locale) \
+ < tolower_l(*(unsigned char*)s2, locale)) return -1; \
+ if (tolower_l(*(unsigned char*)s1, locale) \
+ > tolower_l(*(unsigned char*)s2, locale)) return 1; \
\
s1++; s2++; n++; \
} \
@@ -534,9 +584,9 @@
#define STRCMP(soname, fnname) \
- int VG_REPLACE_FUNCTION_ZU(soname,fnname) \
+ int VG_REPLACE_FUNCTION_EZU(2016,soname,fnname) \
( const char* s1, const char* s2 ); \
- int VG_REPLACE_FUNCTION_ZU(soname,fnname) \
+ int VG_REPLACE_FUNCTION_EZU(2016,soname,fnname) \
( const char* s1, const char* s2 ) \
{ \
register unsigned char c1; \
@@ -562,8 +612,10 @@
#define MEMCHR(soname, fnname) \
- void* VG_REPLACE_FUNCTION_ZU(soname,fnname) (const void *s, int c, SizeT n); \
- void* VG_REPLACE_FUNCTION_ZU(soname,fnname) (const void *s, int c, SizeT n) \
+ void* VG_REPLACE_FUNCTION_EZU(2017,soname,fnname) \
+ (const void *s, int c, SizeT n); \
+ void* VG_REPLACE_FUNCTION_EZU(2017,soname,fnname) \
+ (const void *s, int c, SizeT n) \
{ \
SizeT i; \
UChar c0 = (UChar)c; \
@@ -579,13 +631,13 @@
#endif
-#define MEMCPY(soname, fnname) \
- void* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
+#define MEMMOVE_OR_MEMCPY(becTag, soname, fnname, do_ol_check) \
+ void* VG_REPLACE_FUNCTION_EZU(becTag,soname,fnname) \
( void *dst, const void *src, SizeT len ); \
- void* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
+ void* VG_REPLACE_FUNCTION_EZU(becTag,soname,fnname) \
( void *dst, const void *src, SizeT len ) \
{ \
- if (is_overlap(dst, src, len, len)) \
+ if (do_ol_check && is_overlap(dst, src, len, len)) \
RECORD_OVERLAP_ERROR("memcpy", dst, src, len); \
\
const Addr WS = sizeof(UWord); /* 8 or 4 */ \
@@ -650,11 +702,20 @@
return dst; \
}
-MEMCPY(VG_Z_LIBC_SONAME, memcpy)
+#define MEMMOVE(soname, fnname) \
+ MEMMOVE_OR_MEMCPY(2018, soname, fnname, 0)
+
+#define MEMCPY(soname, fnname) \
+ MEMMOVE_OR_MEMCPY(2022, soname, fnname, 1)
+
#if defined(VGO_linux)
-MEMCPY(VG_Z_LD_SO_1, memcpy) /* ld.so.1 */
-MEMCPY(VG_Z_LD64_SO_1, memcpy) /* ld64.so.1 */
+/* For older memcpy we have to use memmove-like semantics and skip the
+ overlap check; sigh; see #275284. */
+MEMMOVE(VG_Z_LIBC_SONAME, memcpy)
+MEMMOVE(VG_Z_LD_SO_1, memcpy) /* ld.so.1 */
+MEMMOVE(VG_Z_LD64_SO_1, memcpy) /* ld64.so.1 */
#elif defined(VGO_darwin)
+MEMCPY(VG_Z_LIBC_SONAME, memcpy)
MEMCPY(VG_Z_DYLD, memcpy)
#endif
/* icc9 blats these around all over the place. Not only in the main
@@ -669,10 +730,10 @@
#define MEMCMP(soname, fnname) \
- int VG_REPLACE_FUNCTION_ZU(soname,fnname) \
+ int VG_REPLACE_FUNCTION_EZU(2019,soname,fnname) \
( const void *s1V, const void *s2V, SizeT n ); \
- int VG_REPLACE_FUNCTION_ZU(soname,fnname) \
- ( const void *s1V, const void *s2V, SizeT n ) \
+ int VG_REPLACE_FUNCTION_EZU(2019,soname,fnname) \
+ ( const void *s1V, const void *s2V, SizeT n ) \
{ \
int res; \
unsigned char a0; \
@@ -706,8 +767,10 @@
/* Copy SRC to DEST, returning the address of the terminating '\0' in
DEST. (minor variant of strcpy) */
#define STPCPY(soname, fnname) \
- char* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( char* dst, const char* src ); \
- char* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( char* dst, const char* src ) \
+ char* VG_REPLACE_FUNCTION_EZU(2020,soname,fnname) \
+ ( char* dst, const char* src ); \
+ char* VG_REPLACE_FUNCTION_EZU(2020,soname,fnname) \
+ ( char* dst, const char* src ) \
{ \
const Char* src_orig = src; \
Char* dst_orig = dst; \
@@ -737,8 +800,10 @@
#define MEMSET(soname, fnname) \
- void* VG_REPLACE_FUNCTION_ZU(soname,fnname)(void *s, Int c, SizeT n); \
- void* VG_REPLACE_FUNCTION_ZU(soname,fnname)(void *s, Int c, SizeT n) \
+ void* VG_REPLACE_FUNCTION_EZU(2021,soname,fnname) \
+ (void *s, Int c, SizeT n); \
+ void* VG_REPLACE_FUNCTION_EZU(2021,soname,fnname) \
+ (void *s, Int c, SizeT n) \
{ \
Addr a = (Addr)s; \
UInt c4 = (c & 0xFF); \
@@ -759,27 +824,7 @@
#endif
-#define MEMMOVE(soname, fnname) \
- void* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
- (void *dstV, const void *srcV, SizeT n); \
- void* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
- (void *dstV, const void *srcV, SizeT n) \
- { \
- SizeT i; \
- Char* dst = (Char*)dstV; \
- Char* src = (Char*)srcV; \
- if (dst < src) { \
- for (i = 0; i < n; i++) \
- dst[i] = src[i]; \
- } \
- else \
- if (dst > src) { \
- for (i = 0; i < n; i++) \
- dst[n-i-1] = src[n-i-1]; \
- } \
- return dst; \
- }
-
+/* memmove -- use the MEMMOVE defn which also serves for memcpy. */
MEMMOVE(VG_Z_LIBC_SONAME, memmove)
#if defined(VGO_darwin)
MEMMOVE(VG_Z_DYLD, memmove)
@@ -787,9 +832,9 @@
#define BCOPY(soname, fnname) \
- void VG_REPLACE_FUNCTION_ZU(soname,fnname) \
+ void VG_REPLACE_FUNCTION_EZU(2023,soname,fnname) \
(const void *srcV, void *dstV, SizeT n); \
- void VG_REPLACE_FUNCTION_ZU(soname,fnname) \
+ void VG_REPLACE_FUNCTION_EZU(2023,soname,fnname) \
(const void *srcV, void *dstV, SizeT n) \
{ \
SizeT i; \
@@ -815,9 +860,9 @@
/* glibc 2.5 variant of memmove which checks the dest is big enough.
There is no specific part of glibc that this is copied from. */
#define GLIBC25___MEMMOVE_CHK(soname, fnname) \
- void* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
+ void* VG_REPLACE_FUNCTION_EZU(2024,soname,fnname) \
(void *dstV, const void *srcV, SizeT n, SizeT destlen); \
- void* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
+ void* VG_REPLACE_FUNCTION_EZU(2024,soname,fnname) \
(void *dstV, const void *srcV, SizeT n, SizeT destlen) \
{ \
SizeT i; \
@@ -849,8 +894,10 @@
/* Find the first occurrence of C in S or the final NUL byte. */
#define GLIBC232_STRCHRNUL(soname, fnname) \
- char* VG_REPLACE_FUNCTION_ZU(soname,fnname) (const char* s, int c_in); \
- char* VG_REPLACE_FUNCTION_ZU(soname,fnname) (const char* s, int c_in) \
+ char* VG_REPLACE_FUNCTION_EZU(2025,soname,fnname) \
+ (const char* s, int c_in); \
+ char* VG_REPLACE_FUNCTION_EZU(2025,soname,fnname) \
+ (const char* s, int c_in) \
{ \
unsigned char c = (unsigned char) c_in; \
unsigned char* char_ptr = (unsigned char *)s; \
@@ -866,8 +913,10 @@
/* Find the first occurrence of C in S. */
#define GLIBC232_RAWMEMCHR(soname, fnname) \
- char* VG_REPLACE_FUNCTION_ZU(soname,fnname) (const char* s, int c_in); \
- char* VG_REPLACE_FUNCTION_ZU(soname,fnname) (const char* s, int c_in) \
+ char* VG_REPLACE_FUNCTION_EZU(2026,soname,fnname) \
+ (const char* s, int c_in); \
+ char* VG_REPLACE_FUNCTION_EZU(2026,soname,fnname) \
+ (const char* s, int c_in) \
{ \
unsigned char c = (unsigned char) c_in; \
unsigned char* char_ptr = (unsigned char *)s; \
@@ -885,10 +934,10 @@
/* glibc variant of strcpy that checks the dest is big enough.
Copied from glibc-2.5/debug/test-strcpy_chk.c. */
#define GLIBC25___STRCPY_CHK(soname,fnname) \
- char* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
- (char* dst, const char* src, SizeT len); \
- char* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
- (char* dst, const char* src, SizeT len) \
+ char* VG_REPLACE_FUNCTION_EZU(2027,soname,fnname) \
+ (char* dst, const char* src, SizeT len); \
+ char* VG_REPLACE_FUNCTION_EZU(2027,soname,fnname) \
+ (char* dst, const char* src, SizeT len) \
{ \
char* ret = dst; \
if (! len) \
@@ -912,10 +961,10 @@
/* glibc variant of stpcpy that checks the dest is big enough.
Copied from glibc-2.5/debug/test-stpcpy_chk.c. */
#define GLIBC25___STPCPY_CHK(soname,fnname) \
- char* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
- (char* dst, const char* src, SizeT len); \
- char* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
- (char* dst, const char* src, SizeT len) \
+ char* VG_REPLACE_FUNCTION_EZU(2028,soname,fnname) \
+ (char* dst, const char* src, SizeT len); \
+ char* VG_REPLACE_FUNCTION_EZU(2028,soname,fnname) \
+ (char* dst, const char* src, SizeT len) \
{ \
if (! len) \
goto badness; \
@@ -937,9 +986,9 @@
/* mempcpy */
#define GLIBC25_MEMPCPY(soname, fnname) \
- void* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
+ void* VG_REPLACE_FUNCTION_EZU(2029,soname,fnname) \
( void *dst, const void *src, SizeT len ); \
- void* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
+ void* VG_REPLACE_FUNCTION_EZU(2029,soname,fnname) \
( void *dst, const void *src, SizeT len ) \
{ \
register char *d; \
@@ -975,9 +1024,9 @@
#define GLIBC26___MEMCPY_CHK(soname, fnname) \
- void* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
+ void* VG_REPLACE_FUNCTION_EZU(2030,soname,fnname) \
(void* dst, const void* src, SizeT len, SizeT dstlen ); \
- void* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
+ void* VG_REPLACE_FUNCTION_EZU(2030,soname,fnname) \
(void* dst, const void* src, SizeT len, SizeT dstlen ) \
{ \
register char *d; \
@@ -1018,9 +1067,9 @@
#define STRSTR(soname, fnname) \
- void* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
+ void* VG_REPLACE_FUNCTION_EZU(2031,soname,fnname) \
(void* haystack, void* needle); \
- void* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
+ void* VG_REPLACE_FUNCTION_EZU(2031,soname,fnname) \
(void* haystack, void* needle) \
{ \
UChar* h = (UChar*)haystack; \
@@ -1060,9 +1109,9 @@
#define STRPBRK(soname, fnname) \
- void* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
+ void* VG_REPLACE_FUNCTION_EZU(2032,soname,fnname) \
(void* sV, void* acceptV); \
- void* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
+ void* VG_REPLACE_FUNCTION_EZU(2032,soname,fnname) \
(void* sV, void* acceptV) \
{ \
UChar* s = (UChar*)sV; \
@@ -1097,9 +1146,9 @@
#define STRCSPN(soname, fnname) \
- SizeT VG_REPLACE_FUNCTION_ZU(soname,fnname) \
+ SizeT VG_REPLACE_FUNCTION_EZU(2033,soname,fnname) \
(void* sV, void* rejectV); \
- SizeT VG_REPLACE_FUNCTION_ZU(soname,fnname) \
+ SizeT VG_REPLACE_FUNCTION_EZU(2033,soname,fnname) \
(void* sV, void* rejectV) \
{ \
UChar* s = (UChar*)sV; \
@@ -1134,42 +1183,55 @@
#endif
-// And here's a validated strspn replacement, should it
-// become necessary.
-//UWord mystrspn( UChar* s, UChar* accept )
-//{
-// /* find the length of 'accept', not including terminating zero */
-// UWord nacc = 0;
-// while (accept[nacc]) nacc++;
-// if (nacc == 0) return 0;
-//
-// UWord len = 0;
-// while (1) {
-// UWord i;
-// UChar sc = *s;
-// if (sc == 0)
-// break;
-// for (i = 0; i < nacc; i++) {
-// if (sc == accept[i])
-// break;
-// }
-// assert(i >= 0 && i <= nacc);
-// if (i == nacc)
-// break;
-// s++;
-// len++;
-// }
-//
-// return len;
-//}
+#define STRSPN(soname, fnname) \
+ SizeT VG_REPLACE_FUNCTION_EZU(2034,soname,fnname) \
+ (void* sV, void* acceptV); \
+ SizeT VG_REPLACE_FUNCTION_EZU(2034,soname,fnname) \
+ (void* sV, void* acceptV) \
+ { \
+ UChar* s = (UChar*)sV; \
+ UChar* accept = (UChar*)acceptV; \
+ \
+ /* find the length of 'accept', not including terminating zero */ \
+ UWord nacc = 0; \
+ while (accept[nacc]) nacc++; \
+ if (nacc == 0) return 0; \
+ \
+ UWord len = 0; \
+ while (1) { \
+ UWord i; \
+ UChar sc = *s; \
+ if (sc == 0) \
+ break; \
+ for (i = 0; i < nacc; i++) { \
+ if (sc == accept[i]) \
+ break; \
+ } \
+ /* assert(i >= 0 && i <= nacc); */ \
+ if (i == nacc) \
+ break; \
+ s++; \
+ len++; \
+ } \
+ \
+ return len; \
+ }
+#if defined(VGO_linux)
+STRSPN(VG_Z_LIBC_SONAME, strspn)
+#endif
+
/*------------------------------------------------------------*/
/*--- Improve definedness checking of process environment ---*/
/*------------------------------------------------------------*/
#if defined(VGO_linux)
+/* If these wind up getting generated via a macro, so that multiple
+ versions of each function exist (as above), use the _EZU variants
+ to assign equivalance class tags. */
+
/* putenv */
int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, putenv) (char* string);
int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, putenv) (char* string)
|