#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
*/
#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; \
\
#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; \
\
*/
#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; \
\
*/
#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 ); \
#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 ); \
#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; \
\
#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; \
\
#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; \
\
#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; \
\
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; \
} \
#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; \
\
#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; \
\
#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) \
#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 */ \
// 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 */ \
#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; \
\
|| (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; \
#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; \
\
#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); \
}
#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. */ \
}
// 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(); \
#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; \
}
// 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; \
}
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].
#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; \
#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; \
#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; \
#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; \
/* 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); \
\
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. */ \
(Addr)dst-(Addr)dst_orig+1, \
(Addr)src-(Addr)src_orig+1)) \
RECORD_OVERLAP_ERROR("strlcat", dst_orig, src_orig, n); \
-\
+ \
return m; \
}
#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++; \
// 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++; \
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; \
/* 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); \
\
#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; \
/* 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, */ \
#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; \
#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); \
#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); \
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++; \
} \
#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)); \
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)); \
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++; \
} \
#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; \
#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; \
#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 */ \
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
#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; \
/* 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; \
#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); \
#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)
#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; \
/* 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; \
/* 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; \
/* 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; \
/* 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) \
/* 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; \
/* 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; \
#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; \
#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; \
#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; \
#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; \
#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
/*------------------------------------------------------------*/
#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)