Extend the behavioural-equivalence-class mechanism for redirection
functions to include the ability to give a priority to each function,
as well as a tag indicating its behavioural class. Add logic in
m_redir.c to resolve conflicting redirections with the same eclass but
different priorities by preferring the redirection with the higher
priority. Use all of the above in mc_replace_strmem.c, to cause a
conflict between redirections for "memcpy" and "memcpy@GLIBC_2.2.5" to
be resolved in favour of the latter (the non-overlap-checking
version).
This is all related to the massive swamp that is #275284.
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@11991 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/coregrind/m_demangle/demangle.c b/coregrind/m_demangle/demangle.c
index ccc5926..5fc47f3 100644
--- a/coregrind/m_demangle/demangle.c
+++ b/coregrind/m_demangle/demangle.c
@@ -100,7 +100,7 @@
interested in that). */
if (do_z_demangling) {
if (VG_(maybe_Z_demangle)( orig, NULL,0,/*soname*/
- z_demangled, N_ZBUF, NULL, NULL )) {
+ z_demangled, N_ZBUF, NULL, NULL, NULL )) {
orig = z_demangled;
}
}
@@ -147,7 +147,8 @@
/*OUT*/HChar* so, Int soLen,
/*OUT*/HChar* fn, Int fnLen,
/*OUT*/Bool* isWrap,
- /*OUT*/Int* eclassTag )
+ /*OUT*/Int* eclassTag,
+ /*OUT*/Int* eclassPrio )
{
# define EMITSO(ch) \
do { \
@@ -181,24 +182,28 @@
valid = sym[0] == '_'
&& sym[1] == 'v'
&& sym[2] == 'g'
- && (sym[3] == 'r' || sym[3] == 'w' || sym[3] == 'n')
+ && (sym[3] == 'r' || sym[3] == 'w')
&& VG_(isdigit)(sym[4])
&& VG_(isdigit)(sym[5])
&& VG_(isdigit)(sym[6])
&& VG_(isdigit)(sym[7])
- && sym[8] == 'Z'
- && (sym[9] == 'Z' || sym[9] == 'U')
- && sym[10] == '_';
- if (valid && sym[3] == 'n') {
- /* for _vgn (notify-on-load symbols), the equivalence class has
- no meaning; hence ensure it is the default 0000 value. */
- if (sym[4] != '0' || sym[5] != '0' || sym[6] != '0' || sym[7] != '0')
- valid = False;
+ && VG_(isdigit)(sym[8])
+ && sym[9] == 'Z'
+ && (sym[10] == 'Z' || sym[10] == 'U')
+ && sym[11] == '_';
+
+ if (valid
+ && sym[4] == '0' && sym[5] == '0' && sym[6] == '0' && sym[7] == '0'
+ && sym[8] != '0') {
+ /* If the eclass tag is 0000 (meaning "no eclass"), the priority
+ must be 0 too. */
+ valid = False;
}
+
if (!valid)
return False;
- fn_is_encoded = sym[9] == 'Z';
+ fn_is_encoded = sym[10] == 'Z';
if (isWrap)
*isWrap = sym[3] == 'w';
@@ -211,21 +216,26 @@
vg_assert(*eclassTag >= 0 && *eclassTag <= 9999);
}
+ if (eclassPrio) {
+ *eclassPrio = ((Int)sym[8]) - '0';
+ vg_assert(*eclassPrio >= 0 && *eclassPrio <= 9);
+ }
+
/* Now check the soname prefix isn't "VG_Z_", as described in
pub_tool_redir.h. */
is_VG_Z_prefixed =
- sym[11] == 'V' &&
- sym[12] == 'G' &&
- sym[13] == '_' &&
- sym[14] == 'Z' &&
- sym[15] == '_';
+ sym[12] == 'V' &&
+ sym[13] == 'G' &&
+ sym[14] == '_' &&
+ sym[15] == 'Z' &&
+ sym[16] == '_';
if (is_VG_Z_prefixed) {
vg_assert2(0, "symbol with a 'VG_Z_' prefix: %s.\n"
"see pub_tool_redir.h for an explanation.", sym);
}
/* Now scan the Z-encoded soname. */
- i = 11;
+ i = 12;
while (True) {
if (sym[i] == '_')
diff --git a/coregrind/m_redir.c b/coregrind/m_redir.c
index f22088b..5b59144 100644
--- a/coregrind/m_redir.c
+++ b/coregrind/m_redir.c
@@ -233,6 +233,9 @@
Int becTag; /* 0 through 9999. Behavioural equivalance class tag.
If two wrappers have the same (non-zero) tag, they
are promising that they behave identically. */
+ Int becPrio; /* 0 through 9. Behavioural equivalence class prio.
+ Used to choose between competing wrappers with
+ the same (non-zero) tag. */
const HChar** mandatory; /* non-NULL ==> abort V and print the
strings if from_sopatt is loaded but
from_fnpatt cannot be found */
@@ -278,6 +281,7 @@
TopSpec* parent_spec; /* the TopSpec which supplied the Spec */
TopSpec* parent_sym; /* the TopSpec which supplied the symbol */
Int becTag; /* behavioural eclass tag for ::to_addr */
+ Int becPrio; /* and its priority */
Bool isWrap; /* wrap or replacement? */
Bool isIFunc; /* indirect function? */
}
@@ -371,7 +375,7 @@
void VG_(redir_notify_new_DebugInfo)( DebugInfo* newdi )
{
Bool ok, isWrap;
- Int i, nsyms, becTag;
+ Int i, nsyms, becTag, becPrio;
Spec* specList;
Spec* spec;
TopSpec* ts;
@@ -416,7 +420,7 @@
ok = VG_(maybe_Z_demangle)( *names,
demangled_sopatt, N_DEMANGLED,
demangled_fnpatt, N_DEMANGLED,
- &isWrap, &becTag );
+ &isWrap, &becTag, &becPrio );
/* ignore data symbols */
if (!isText)
continue;
@@ -442,6 +446,7 @@
spec->to_addr = sym_addr;
spec->isWrap = isWrap;
spec->becTag = becTag;
+ spec->becPrio = becPrio;
/* check we're not adding manifestly stupid destinations */
vg_assert(is_plausible_guest_addr(sym_addr));
spec->next = specList;
@@ -465,7 +470,7 @@
ok = isText
&& VG_(maybe_Z_demangle)(
*names, demangled_sopatt, N_DEMANGLED,
- demangled_fnpatt, N_DEMANGLED, &isWrap, NULL );
+ demangled_fnpatt, N_DEMANGLED, &isWrap, NULL, NULL );
if (!ok)
/* not a redirect. Ignore. */
continue;
@@ -640,6 +645,7 @@
act.parent_spec = parent_spec;
act.parent_sym = parent_sym;
act.becTag = sp->becTag;
+ act.becPrio = sp->becPrio;
act.isWrap = sp->isWrap;
act.isIFunc = isIFunc;
sp->done = True;
@@ -707,8 +713,9 @@
conflicting bindings. */
static void maybe_add_active ( Active act )
{
- HChar* what = NULL;
- Active* old = NULL;
+ HChar* what = NULL;
+ Active* old = NULL;
+ Bool add_act = False;
/* Complain and ignore manifestly bogus 'from' addresses.
@@ -744,26 +751,63 @@
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. */
+ vg_assert(old->becTag >= 0 && old->becTag <= 9999);
+ vg_assert(old->becPrio >= 0 && old->becPrio <= 9);
+ vg_assert(act.becTag >= 0 && act.becTag <= 9999);
+ vg_assert(act.becPrio >= 0 && act.becPrio <= 9);
+ if (old->becTag == 0)
+ vg_assert(old->becPrio == 0);
+ if (act.becTag == 0)
+ vg_assert(act.becPrio == 0);
+
+ if (old->becTag == 0 || act.becTag == 0 || old->becTag != act.becTag) {
+ /* We can't show that they are equivalent. Complain and
+ ignore. */
+ what = "new redirection conflicts with existing -- ignoring it";
+ goto bad;
+ }
+ /* They have the same eclass tag. Use the priorities to
+ resolve the ambiguity. */
+ if (act.becPrio <= old->becPrio) {
+ /* The new one doesn't have a higher priority, so just
+ ignore it. */
if (VG_(clo_verbosity) > 2) {
- VG_(message)(Vg_UserMsg, "Ignoring duplicate redirection:\n");
+ VG_(message)(Vg_UserMsg, "Ignoring %s redirection:\n",
+ act.becPrio < old->becPrio ? "lower priority"
+ : "duplicate");
show_active( " old: ", old);
show_active( " new: ", &act);
}
} else {
- what = "new redirection conflicts with existing -- ignoring it";
- goto bad;
+ /* The tricky case. The new one has a higher priority, so
+ we need to get the old one out of the OSet and install
+ this one in its place. */
+ if (VG_(clo_verbosity) > 1) {
+ VG_(message)(Vg_UserMsg,
+ "Preferring higher priority redirection:\n");
+ show_active( " old: ", old);
+ show_active( " new: ", &act);
+ }
+ add_act = True;
+ void* oldNd = VG_(OSetGen_Remove)( activeSet, &act.from_addr );
+ vg_assert(oldNd == old);
+ VG_(OSetGen_FreeNode)( activeSet, old );
+ old = NULL;
}
} else {
/* This appears to be a duplicate of an existing binding.
Safe(ish) -- ignore. */
/* XXXXXXXXXXX COMPLAIN if new and old parents differ */
}
+
} else {
+ /* There's no previous binding for this from_addr, so we must
+ add 'act' to the active set. */
+ add_act = True;
+ }
+
+ /* So, finally, actually add it. */
+ if (add_act) {
Active* a = VG_(OSetGen_AllocNode)(activeSet, sizeof(Active));
vg_assert(a);
*a = act;
@@ -786,6 +830,7 @@
bad:
vg_assert(what);
+ vg_assert(!add_act);
if (VG_(clo_verbosity) > 1) {
VG_(message)(Vg_UserMsg, "WARNING: %s\n", what);
if (old) {
@@ -936,6 +981,7 @@
act.parent_spec = NULL;
act.parent_sym = NULL;
act.becTag = 0; /* "not equivalent to any other fn" */
+ act.becPrio = 0; /* mandatory when becTag == 0 */
act.isWrap = False;
act.isIFunc = False;
maybe_add_active( act );
@@ -1248,7 +1294,8 @@
if (VG_(strcmp)(symbol, VG_STRINGIFY(VG_NOTIFY_ON_LOAD(freeres))) == 0)
VG_(client___libc_freeres_wrapper) = addr;
- else if (VG_(strcmp)(symbol, VG_STRINGIFY(VG_NOTIFY_ON_LOAD(ifunc_wrapper))) == 0)
+ else
+ if (VG_(strcmp)(symbol, VG_STRINGIFY(VG_NOTIFY_ON_LOAD(ifunc_wrapper))) == 0)
iFuncWrapper = addr;
else
vg_assert2(0, "unrecognised load notification function: %s", symbol);
@@ -1381,11 +1428,11 @@
static void show_spec ( HChar* left, Spec* spec )
{
VG_(message)( Vg_DebugMsg,
- "%s%25s %30s %s-> (%04d) 0x%08llx\n",
+ "%s%25s %30s %s-> (%04d.%d) 0x%08llx\n",
left,
spec->from_sopatt, spec->from_fnpatt,
spec->isWrap ? "W" : "R",
- spec->becTag,
+ spec->becTag, spec->becPrio,
(ULong)spec->to_addr );
}
@@ -1400,11 +1447,12 @@
ok = VG_(get_fnname_w_offset)(act->to_addr, name2, 64);
if (!ok) VG_(strcpy)(name2, "???");
- VG_(message)(Vg_DebugMsg, "%s0x%08llx (%20s) %s-> (%04d) 0x%08llx %s\n",
+ VG_(message)(Vg_DebugMsg, "%s0x%08llx (%20s) %s-> (%04d.%d) 0x%08llx %s\n",
left,
(ULong)act->from_addr, name1,
act->isWrap ? "W" : "R",
- act->becTag, (ULong)act->to_addr, name2 );
+ act->becTag, act->becPrio,
+ (ULong)act->to_addr, name2 );
}
static void show_redir_state ( HChar* who )
diff --git a/coregrind/m_replacemalloc/vg_replace_malloc.c b/coregrind/m_replacemalloc/vg_replace_malloc.c
index 53170d8..38553ec 100644
--- a/coregrind/m_replacemalloc/vg_replace_malloc.c
+++ b/coregrind/m_replacemalloc/vg_replace_malloc.c
@@ -73,28 +73,28 @@
/* 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
+ 10010 ALLOC_or_NULL
+ 10020 ZONEALLOC_or_NULL
+ 10030 ALLOC_or_BOMB
+ 10040 ZONEFREE
+ 10050 FREE
+ 10060 ZONECALLOC
+ 10070 CALLOC
+ 10080 ZONEREALLOC
+ 10090 REALLOC
+ 10100 ZONEMEMALIGN
+ 10110 MEMALIGN
+ 10120 VALLOC
+ 10130 ZONEVALLOC
+ 10140 MALLOPT
+ 10150 MALLOC_TRIM
+ 10160 POSIX_MEMALIGN
+ 10170 MALLOC_USABLE_SIZE
+ 10180 PANIC
+ 10190 MALLOC_STATS
+ 10200 MALLINFO
+ 10210 DEFAULT_ZONE
+ 10220 ZONE_CHECK
*/
/* 2 Apr 05: the Portland Group compiler, which uses cfront/ARM style
@@ -198,8 +198,8 @@
*/
#define ALLOC_or_NULL(soname, fnname, vg_replacement) \
\
- void* VG_REPLACE_FUNCTION_EZU(1001,soname,fnname) (SizeT n); \
- void* VG_REPLACE_FUNCTION_EZU(1001,soname,fnname) (SizeT n) \
+ void* VG_REPLACE_FUNCTION_EZU(10010,soname,fnname) (SizeT n); \
+ void* VG_REPLACE_FUNCTION_EZU(10010,soname,fnname) (SizeT n) \
{ \
void* v; \
\
@@ -213,8 +213,8 @@
#define ZONEALLOC_or_NULL(soname, fnname, vg_replacement) \
\
- 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* VG_REPLACE_FUNCTION_EZU(10020,soname,fnname) (void *zone, SizeT n); \
+ void* VG_REPLACE_FUNCTION_EZU(10020,soname,fnname) (void *zone, SizeT n) \
{ \
void* v; \
\
@@ -233,8 +233,8 @@
*/
#define ALLOC_or_BOMB(soname, fnname, vg_replacement) \
\
- void* VG_REPLACE_FUNCTION_EZU(1003,soname,fnname) (SizeT n); \
- void* VG_REPLACE_FUNCTION_EZU(1003,soname,fnname) (SizeT n) \
+ void* VG_REPLACE_FUNCTION_EZU(10030,soname,fnname) (SizeT n); \
+ void* VG_REPLACE_FUNCTION_EZU(10030,soname,fnname) (SizeT n) \
{ \
void* v; \
\
@@ -342,8 +342,8 @@
*/
#define ZONEFREE(soname, fnname, vg_replacement) \
\
- void VG_REPLACE_FUNCTION_EZU(1004,soname,fnname) (void *zone, void *p); \
- void VG_REPLACE_FUNCTION_EZU(1004,soname,fnname) (void *zone, void *p) \
+ void VG_REPLACE_FUNCTION_EZU(10040,soname,fnname) (void *zone, void *p); \
+ void VG_REPLACE_FUNCTION_EZU(10040,soname,fnname) (void *zone, void *p) \
{ \
if (!init_done) init(); \
MALLOC_TRACE(#vg_replacement "(%p, %p)\n", zone, p ); \
@@ -354,8 +354,8 @@
#define FREE(soname, fnname, vg_replacement) \
\
- void VG_REPLACE_FUNCTION_EZU(1005,soname,fnname) (void *p); \
- void VG_REPLACE_FUNCTION_EZU(1005,soname,fnname) (void *p) \
+ void VG_REPLACE_FUNCTION_EZU(10050,soname,fnname) (void *p); \
+ void VG_REPLACE_FUNCTION_EZU(10050,soname,fnname) (void *p) \
{ \
if (!init_done) init(); \
MALLOC_TRACE(#vg_replacement "(%p)\n", p ); \
@@ -417,9 +417,9 @@
#define ZONECALLOC(soname, fnname) \
\
- void* VG_REPLACE_FUNCTION_EZU(1006,soname,fnname) \
+ void* VG_REPLACE_FUNCTION_EZU(10060,soname,fnname) \
( void *zone, SizeT nmemb, SizeT size ); \
- void* VG_REPLACE_FUNCTION_EZU(1006,soname,fnname) \
+ void* VG_REPLACE_FUNCTION_EZU(10060,soname,fnname) \
( void *zone, SizeT nmemb, SizeT size ) \
{ \
void* v; \
@@ -434,9 +434,9 @@
#define CALLOC(soname, fnname) \
\
- void* VG_REPLACE_FUNCTION_EZU(1007,soname,fnname) \
+ void* VG_REPLACE_FUNCTION_EZU(10070,soname,fnname) \
( SizeT nmemb, SizeT size ); \
- void* VG_REPLACE_FUNCTION_EZU(1007,soname,fnname) \
+ void* VG_REPLACE_FUNCTION_EZU(10070,soname,fnname) \
( SizeT nmemb, SizeT size ) \
{ \
void* v; \
@@ -469,9 +469,9 @@
#define ZONEREALLOC(soname, fnname) \
\
- void* VG_REPLACE_FUNCTION_EZU(1008,soname,fnname) \
+ void* VG_REPLACE_FUNCTION_EZU(10080,soname,fnname) \
( void *zone, void* ptrV, SizeT new_size ); \
- void* VG_REPLACE_FUNCTION_EZU(1008,soname,fnname) \
+ void* VG_REPLACE_FUNCTION_EZU(10080,soname,fnname) \
( void *zone, void* ptrV, SizeT new_size ) \
{ \
void* v; \
@@ -482,10 +482,10 @@
if (ptrV == NULL) \
/* We need to call a malloc-like function; so let's use \
one which we know exists. GrP fixme use zonemalloc instead? */ \
- return VG_REPLACE_FUNCTION_EZU(1001,VG_Z_LIBC_SONAME,malloc) \
+ return VG_REPLACE_FUNCTION_EZU(10010,VG_Z_LIBC_SONAME,malloc) \
(new_size); \
if (new_size <= 0) { \
- VG_REPLACE_FUNCTION_EZU(1005,VG_Z_LIBC_SONAME,free)(ptrV); \
+ VG_REPLACE_FUNCTION_EZU(10050,VG_Z_LIBC_SONAME,free)(ptrV); \
MALLOC_TRACE(" = 0\n"); \
return NULL; \
} \
@@ -496,9 +496,9 @@
#define REALLOC(soname, fnname) \
\
- void* VG_REPLACE_FUNCTION_EZU(1009,soname,fnname) \
+ void* VG_REPLACE_FUNCTION_EZU(10090,soname,fnname) \
( void* ptrV, SizeT new_size );\
- void* VG_REPLACE_FUNCTION_EZU(1009,soname,fnname) \
+ void* VG_REPLACE_FUNCTION_EZU(10090,soname,fnname) \
( void* ptrV, SizeT new_size ) \
{ \
void* v; \
@@ -509,10 +509,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_EZU(1001,VG_Z_LIBC_SONAME,malloc) \
+ return VG_REPLACE_FUNCTION_EZU(10010,VG_Z_LIBC_SONAME,malloc) \
(new_size); \
if (new_size <= 0) { \
- VG_REPLACE_FUNCTION_EZU(1005,VG_Z_LIBC_SONAME,free)(ptrV); \
+ VG_REPLACE_FUNCTION_EZU(10050,VG_Z_LIBC_SONAME,free)(ptrV); \
MALLOC_TRACE(" = 0\n"); \
return NULL; \
} \
@@ -531,9 +531,9 @@
#define ZONEMEMALIGN(soname, fnname) \
\
- void* VG_REPLACE_FUNCTION_EZU(1010,soname,fnname) \
+ void* VG_REPLACE_FUNCTION_EZU(10100,soname,fnname) \
( void *zone, SizeT alignment, SizeT n ); \
- void* VG_REPLACE_FUNCTION_EZU(1010,soname,fnname) \
+ void* VG_REPLACE_FUNCTION_EZU(10100,soname,fnname) \
( void *zone, SizeT alignment, SizeT n ) \
{ \
void* v; \
@@ -556,9 +556,9 @@
#define MEMALIGN(soname, fnname) \
\
- void* VG_REPLACE_FUNCTION_EZU(1011,soname,fnname) \
+ void* VG_REPLACE_FUNCTION_EZU(10110,soname,fnname) \
( SizeT alignment, SizeT n ); \
- void* VG_REPLACE_FUNCTION_EZU(1011,soname,fnname) \
+ void* VG_REPLACE_FUNCTION_EZU(10110,soname,fnname) \
( SizeT alignment, SizeT n ) \
{ \
void* v; \
@@ -589,27 +589,27 @@
#define VALLOC(soname, fnname) \
\
- void* VG_REPLACE_FUNCTION_EZU(1012,soname,fnname) ( SizeT size ); \
- void* VG_REPLACE_FUNCTION_EZU(1012,soname,fnname) ( SizeT size ) \
+ void* VG_REPLACE_FUNCTION_EZU(10120,soname,fnname) ( SizeT size ); \
+ void* VG_REPLACE_FUNCTION_EZU(10120,soname,fnname) ( SizeT size ) \
{ \
static int pszB = 0; \
if (pszB == 0) \
pszB = my_getpagesize(); \
- return VG_REPLACE_FUNCTION_EZU(1011,VG_Z_LIBC_SONAME,memalign) \
+ return VG_REPLACE_FUNCTION_EZU(10110,VG_Z_LIBC_SONAME,memalign) \
((SizeT)pszB, size); \
}
#define ZONEVALLOC(soname, fnname) \
\
- void* VG_REPLACE_FUNCTION_EZU(1013,soname,fnname) \
+ void* VG_REPLACE_FUNCTION_EZU(10130,soname,fnname) \
( void *zone, SizeT size ); \
- void* VG_REPLACE_FUNCTION_EZU(1013,soname,fnname) \
+ void* VG_REPLACE_FUNCTION_EZU(10130,soname,fnname) \
( void *zone, SizeT size ) \
{ \
static int pszB = 0; \
if (pszB == 0) \
pszB = my_getpagesize(); \
- return VG_REPLACE_FUNCTION_EZU(1011,VG_Z_LIBC_SONAME,memalign) \
+ return VG_REPLACE_FUNCTION_EZU(10110,VG_Z_LIBC_SONAME,memalign) \
((SizeT)pszB, size); \
}
@@ -625,8 +625,8 @@
#define MALLOPT(soname, fnname) \
\
- int VG_REPLACE_FUNCTION_EZU(1014,soname,fnname) ( int cmd, int value ); \
- int VG_REPLACE_FUNCTION_EZU(1014,soname,fnname) ( int cmd, int value ) \
+ int VG_REPLACE_FUNCTION_EZU(10140,soname,fnname) ( int cmd, int value ); \
+ int VG_REPLACE_FUNCTION_EZU(10140,soname,fnname) ( int cmd, int value ) \
{ \
/* In glibc-2.2.4, 1 denotes a successful return value for \
mallopt */ \
@@ -661,8 +661,8 @@
// For simplicity, we always return 0.
#define MALLOC_TRIM(soname, fnname) \
\
- int VG_REPLACE_FUNCTION_EZU(1015,soname,fnname) ( SizeT pad ); \
- int VG_REPLACE_FUNCTION_EZU(1015,soname,fnname) ( SizeT pad ) \
+ int VG_REPLACE_FUNCTION_EZU(10150,soname,fnname) ( SizeT pad ); \
+ int VG_REPLACE_FUNCTION_EZU(10150,soname,fnname) ( SizeT pad ) \
{ \
/* 0 denotes that malloc_trim() either wasn't able \
to do anything, or was not implemented */ \
@@ -676,9 +676,9 @@
#define POSIX_MEMALIGN(soname, fnname) \
\
- int VG_REPLACE_FUNCTION_EZU(1016,soname,fnname) \
+ int VG_REPLACE_FUNCTION_EZU(10160,soname,fnname) \
( void **memptr, SizeT alignment, SizeT size ); \
- int VG_REPLACE_FUNCTION_EZU(1016,soname,fnname) \
+ int VG_REPLACE_FUNCTION_EZU(10160,soname,fnname) \
( void **memptr, SizeT alignment, SizeT size ) \
{ \
void *mem; \
@@ -689,7 +689,7 @@
|| (alignment & (alignment - 1)) != 0) \
return VKI_EINVAL; \
\
- mem = VG_REPLACE_FUNCTION_EZU(1011,VG_Z_LIBC_SONAME,memalign) \
+ mem = VG_REPLACE_FUNCTION_EZU(10110,VG_Z_LIBC_SONAME,memalign) \
(alignment, size); \
\
if (mem != NULL) { \
@@ -707,8 +707,8 @@
#define MALLOC_USABLE_SIZE(soname, fnname) \
\
- SizeT VG_REPLACE_FUNCTION_EZU(1017,soname,fnname) ( void* p ); \
- SizeT VG_REPLACE_FUNCTION_EZU(1017,soname,fnname) ( void* p ) \
+ SizeT VG_REPLACE_FUNCTION_EZU(10170,soname,fnname) ( void* p ); \
+ SizeT VG_REPLACE_FUNCTION_EZU(10170,soname,fnname) ( void* p ) \
{ \
SizeT pszB; \
\
@@ -740,8 +740,8 @@
#define PANIC(soname, fnname) \
\
- void VG_REPLACE_FUNCTION_EZU(1018,soname,fnname) ( void ); \
- void VG_REPLACE_FUNCTION_EZU(1018,soname,fnname) ( void ) \
+ void VG_REPLACE_FUNCTION_EZU(10180,soname,fnname) ( void ); \
+ void VG_REPLACE_FUNCTION_EZU(10180,soname,fnname) ( void ) \
{ \
panic(#fnname); \
}
@@ -752,8 +752,8 @@
#define MALLOC_STATS(soname, fnname) \
\
- void VG_REPLACE_FUNCTION_EZU(1019,soname,fnname) ( void ); \
- void VG_REPLACE_FUNCTION_EZU(1019,soname,fnname) ( void ) \
+ void VG_REPLACE_FUNCTION_EZU(10190,soname,fnname) ( void ); \
+ void VG_REPLACE_FUNCTION_EZU(10190,soname,fnname) ( void ) \
{ \
/* Valgrind's malloc_stats implementation does nothing. */ \
}
@@ -768,8 +768,8 @@
// doesn't know that the call to mallinfo fills in mi.
#define MALLINFO(soname, fnname) \
\
- struct vg_mallinfo VG_REPLACE_FUNCTION_EZU(1020,soname,fnname) ( void ); \
- struct vg_mallinfo VG_REPLACE_FUNCTION_EZU(1020,soname,fnname) ( void ) \
+ struct vg_mallinfo VG_REPLACE_FUNCTION_EZU(10200,soname,fnname) ( void ); \
+ struct vg_mallinfo VG_REPLACE_FUNCTION_EZU(10200,soname,fnname) ( void ) \
{ \
static struct vg_mallinfo mi; \
if (!init_done) init(); \
@@ -787,11 +787,11 @@
NULL, // reserved
NULL, // reserved
NULL, // GrP fixme malloc_size
- (void*)VG_REPLACE_FUNCTION_EZU(1002,VG_Z_LIBC_SONAME,malloc_zone_malloc),
- (void*)VG_REPLACE_FUNCTION_EZU(1006,VG_Z_LIBC_SONAME,malloc_zone_calloc),
- (void*)VG_REPLACE_FUNCTION_EZU(1013,VG_Z_LIBC_SONAME,malloc_zone_valloc),
- (void*)VG_REPLACE_FUNCTION_EZU(1004,VG_Z_LIBC_SONAME,malloc_zone_free),
- (void*)VG_REPLACE_FUNCTION_EZU(1008,VG_Z_LIBC_SONAME,malloc_zone_realloc),
+ (void*)VG_REPLACE_FUNCTION_EZU(10020,VG_Z_LIBC_SONAME,malloc_zone_malloc),
+ (void*)VG_REPLACE_FUNCTION_EZU(10060,VG_Z_LIBC_SONAME,malloc_zone_calloc),
+ (void*)VG_REPLACE_FUNCTION_EZU(10130,VG_Z_LIBC_SONAME,malloc_zone_valloc),
+ (void*)VG_REPLACE_FUNCTION_EZU(10040,VG_Z_LIBC_SONAME,malloc_zone_free),
+ (void*)VG_REPLACE_FUNCTION_EZU(10080,VG_Z_LIBC_SONAME,malloc_zone_realloc),
NULL, // GrP fixme destroy
"ValgrindMallocZone",
NULL, // batch_malloc
@@ -806,8 +806,8 @@
#define DEFAULT_ZONE(soname, fnname) \
\
- void *VG_REPLACE_FUNCTION_EZU(1021,soname,fnname) ( void ); \
- void *VG_REPLACE_FUNCTION_EZU(1021,soname,fnname) ( void ) \
+ void *VG_REPLACE_FUNCTION_EZU(10210,soname,fnname) ( void ); \
+ void *VG_REPLACE_FUNCTION_EZU(10210,soname,fnname) ( void ) \
{ \
return &vg_default_zone; \
}
@@ -820,8 +820,8 @@
// GrP fixme bypass libc's use of zone->introspect->check
#define ZONE_CHECK(soname, fnname) \
\
- int VG_REPLACE_FUNCTION_EZU(1022,soname,fnname)(void* zone); \
- int VG_REPLACE_FUNCTION_EZU(1022,soname,fnname)(void* zone) \
+ int VG_REPLACE_FUNCTION_EZU(10220,soname,fnname)(void* zone); \
+ int VG_REPLACE_FUNCTION_EZU(10220,soname,fnname)(void* zone) \
{ \
return 1; \
}
diff --git a/coregrind/pub_core_demangle.h b/coregrind/pub_core_demangle.h
index fc62134..39bb4ad 100644
--- a/coregrind/pub_core_demangle.h
+++ b/coregrind/pub_core_demangle.h
@@ -60,7 +60,8 @@
/*OUT*/HChar* so, Int soLen,
/*OUT*/HChar* fn, Int fnLen,
/*OUT*/Bool* isWrap,
- /*OUT*/Int* eclassTag );
+ /*OUT*/Int* eclassTag,
+ /*OUT*/Int* eclassPrio );
#endif // __PUB_CORE_DEMANGLE_H
diff --git a/include/pub_tool_redir.h b/include/pub_tool_redir.h
index 15894e3..4ca8358 100644
--- a/include/pub_tool_redir.h
+++ b/include/pub_tool_redir.h
@@ -51,24 +51,31 @@
sure you use the VG_REPLACE_FN_ macros and not the VG_WRAP_FN_
macros.
- Finally there is the concept of behavioural equivalence tags. A
- tag is a 4-digit decimal number (0001 to 9999) encoded in the name.
- If two replacement functions have the same tag then the redirect
- mechanism will assume that they have identical behaviour. If, when
- processing redirections at library load time, the set of available
- specifications yields more than one replacement or wrapper function
- for a given address, the system will try to resolve the situation
- by examining the tags on the replacements/wrappers. In particular,
- if all of them have the same tag, then they are all claiming to
- behave identically, so any of them may be chosen to be the actual
- redirection target. Of course if not all of them have the same tag
- then the redirection is ambiguous and the system will have to stop.
+ Finally there is the concept of prioritised behavioural equivalence
+ tags. A tag is a 5-digit decimal number (00000 to 99999) encoded
+ in the name. The top 4 digits are the equivalence class number,
+ and the last digit is a priority.
- The tag is mandatory and must comprise 4 decimal digits. The tag
- 0000 is special and means "does not have behaviour identical to any
+ When processing redirections at library load time, if the set of
+ available specifications yields more than one replacement or
+ wrapper function for a given address, the system will try to
+ resolve the situation by examining the tags on the
+ replacements/wrappers.
+
+ If two replacement/wrapper functions have the same tag and
+ priority, then the redirection machinery will assume they have
+ identical behaviour and can choose between them arbitrarily. If
+ they have the same tag but different priorities, then the one with
+ higher priority will be chosen. If neither case holds, then the
+ redirection is ambiguous and the system will ignore one of them
+ arbitrarily, but print a warning when running at -v or above.
+
+ The tag is mandatory and must comprise 5 decimal digits. The tag
+ 00000 is special and means "does not have behaviour identical to any
other replacement/wrapper function". Hence if you wish to write a
wrap/replacement function that is not subject to the above
- resolution rules, use 0000 for the tag.
+ resolution rules, use 00000 for the tag. Tags 00001 through 00009
+ may not be used for any purpose.
Replacement
@@ -83,12 +90,12 @@
zEncodedSoname should be a Z-encoded soname (see below for
Z-encoding details) and fnname should be an unencoded fn name. A
- default-safe equivalence tag of 0000 is assumed (see comments
+ default-safe equivalence tag of 00000 is assumed (see comments
above). The resulting name is
- _vgr0000ZU_zEncodedSoname_fnname
+ _vgr00000ZU_zEncodedSoname_fnname
- The "_vgr0000ZU_" is a prefix that gets discarded upon decoding.
+ The "_vgr00000ZU_" is a prefix that gets discarded upon decoding.
It identifies this function as a replacement and specifies its
equivalence tag.
@@ -104,7 +111,7 @@
Z-encoded. This can sometimes be necessary. In this case the
resulting function name is
- _vgr0000ZZ_zEncodedSoname_zEncodedFnname
+ _vgr00000ZZ_zEncodedSoname_zEncodedFnname
When it sees this either such name, the core's symbol-table reading
machinery and redirection machinery first Z-decode the soname and
@@ -138,12 +145,12 @@
To write function names which explicitly state the equivalence class
tag, use
- VG_REPLACE_FUNCTION_EZU(4-digit-tag,zEncodedSoname,fnname)
+ VG_REPLACE_FUNCTION_EZU(5-digit-tag,zEncodedSoname,fnname)
or
- VG_REPLACE_FUNCTION_EZZ(4-digit-tag,zEncodedSoname,zEncodedFnname)
+ VG_REPLACE_FUNCTION_EZZ(5-digit-tag,zEncodedSoname,zEncodedFnname)
- As per comments above, the tag must be a 4 digit decimal number,
- padded with leading zeroes, in the range 0001 to 9999 inclusive.
+ As per comments above, the tag must be a 5 digit decimal number,
+ padded with leading zeroes, in the range 00010 to 99999 inclusive.
Wrapping
@@ -206,16 +213,16 @@
/* Convenience macros defined in terms of the above 4. */
#define VG_REPLACE_FUNCTION_ZU(_soname,_fnname) \
- VG_CONCAT6(_vgr,0000,ZU_,_soname,_,_fnname)
+ VG_CONCAT6(_vgr,00000,ZU_,_soname,_,_fnname)
#define VG_REPLACE_FUNCTION_ZZ(_soname,_fnname) \
- VG_CONCAT6(_vgr,0000,ZZ_,_soname,_,_fnname)
+ VG_CONCAT6(_vgr,00000,ZZ_,_soname,_,_fnname)
#define VG_WRAP_FUNCTION_ZU(_soname,_fnname) \
- VG_CONCAT6(_vgw,0000,ZU_,_soname,_,_fnname)
+ VG_CONCAT6(_vgw,00000,ZU_,_soname,_,_fnname)
#define VG_WRAP_FUNCTION_ZZ(_soname,_fnname) \
- VG_CONCAT6(_vgw,0000,ZZ_,_soname,_,_fnname)
+ VG_CONCAT6(_vgw,00000,ZZ_,_soname,_,_fnname)
/* --------- Some handy Z-encoded names. --------- */
diff --git a/include/valgrind.h b/include/valgrind.h
index cac4490..0603aee 100644
--- a/include/valgrind.h
+++ b/include/valgrind.h
@@ -689,10 +689,10 @@
#define VG_CONCAT4(_aa,_bb,_cc,_dd) _aa##_bb##_cc##_dd
#define I_WRAP_SONAME_FNNAME_ZU(soname,fnname) \
- VG_CONCAT4(_vgw0000ZU_,soname,_,fnname)
+ VG_CONCAT4(_vgw00000ZU_,soname,_,fnname)
#define I_WRAP_SONAME_FNNAME_ZZ(soname,fnname) \
- VG_CONCAT4(_vgw0000ZZ_,soname,_,fnname)
+ VG_CONCAT4(_vgw00000ZZ_,soname,_,fnname)
/* Use this macro from within a wrapper function to collect the
context (address and possibly other info) of the original function.
diff --git a/memcheck/mc_replace_strmem.c b/memcheck/mc_replace_strmem.c
index 1570de3..42f8ece 100644
--- a/memcheck/mc_replace_strmem.c
+++ b/memcheck/mc_replace_strmem.c
@@ -53,43 +53,46 @@
THEY RUN ON THE SIMD CPU!
------------------------------------------------------------------ */
-/* Assignment of behavioural equivalence class tags: 2NNN is intended
+/* Assignment of behavioural equivalence class tags: 2NNNP 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
+ 20010 STRRCHR
+ 20020 STRCHR
+ 20030 STRCAT
+ 20040 STRNCAT
+ 20050 STRLCAT
+ 20060 STRNLEN
+ 20070 STRLEN
+ 20080 STRCPY
+ 20090 STRNCPY
+ 20100 STRLCPY
+ 20110 STRNCMP
+ 20120 STRCASECMP
+ 20130 STRNCASECMP
+ 20140 STRCASECMP_L
+ 20150 STRNCASECMP_L
+ 20160 STRCMP
+ 20170 MEMCHR
+
+ 20180 MEMCPY if there's a conflict between memcpy and
+ 20181 MEMMOVE memmove, prefer memmove
+
+ 20190 MEMCMP
+ 20200 STPCPY
+ 20210 MEMSET
+ 2022P unused (was previously MEMMOVE)
+ 20230 BCOPY
+ 20240 GLIBC25___MEMMOVE_CHK
+ 20250 GLIBC232_STRCHRNUL
+ 20260 GLIBC232_RAWMEMCHR
+ 20270 GLIBC25___STRCPY_CHK
+ 20280 GLIBC25___STPCPY_CHK
+ 20290 GLIBC25_MEMPCPY
+ 20300 GLIBC26___MEMCPY_CHK
+ 20310 STRSTR
+ 20320 STRPBRK
+ 20330 STRCSPN
+ 20340 STRSPN
*/
@@ -152,8 +155,8 @@
#define STRRCHR(soname, fnname) \
- 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 ) \
+ char* VG_REPLACE_FUNCTION_EZU(20010,soname,fnname)( const char* s, int c ); \
+ char* VG_REPLACE_FUNCTION_EZU(20010,soname,fnname)( const char* s, int c ) \
{ \
UChar ch = (UChar)((UInt)c); \
UChar* p = (UChar*)s; \
@@ -178,8 +181,8 @@
#define STRCHR(soname, fnname) \
- 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 ) \
+ char* VG_REPLACE_FUNCTION_EZU(20020,soname,fnname) ( const char* s, int c ); \
+ char* VG_REPLACE_FUNCTION_EZU(20020,soname,fnname) ( const char* s, int c ) \
{ \
UChar ch = (UChar)((UInt)c); \
UChar* p = (UChar*)s; \
@@ -206,9 +209,9 @@
#define STRCAT(soname, fnname) \
- char* VG_REPLACE_FUNCTION_EZU(2003,soname,fnname) \
+ char* VG_REPLACE_FUNCTION_EZU(20030,soname,fnname) \
( char* dst, const char* src ); \
- char* VG_REPLACE_FUNCTION_EZU(2003,soname,fnname) \
+ char* VG_REPLACE_FUNCTION_EZU(20030,soname,fnname) \
( char* dst, const char* src ) \
{ \
const Char* src_orig = src; \
@@ -234,9 +237,9 @@
#endif
#define STRNCAT(soname, fnname) \
- char* VG_REPLACE_FUNCTION_EZU(2004,soname,fnname) \
+ char* VG_REPLACE_FUNCTION_EZU(20040,soname,fnname) \
( char* dst, const char* src, SizeT n ); \
- char* VG_REPLACE_FUNCTION_EZU(2004,soname,fnname) \
+ char* VG_REPLACE_FUNCTION_EZU(20040,soname,fnname) \
( char* dst, const char* src, SizeT n ) \
{ \
const Char* src_orig = src; \
@@ -270,9 +273,9 @@
Truncation occurred if retval >= n.
*/
#define STRLCAT(soname, fnname) \
- SizeT VG_REPLACE_FUNCTION_EZU(2005,soname,fnname) \
+ SizeT VG_REPLACE_FUNCTION_EZU(20050,soname,fnname) \
( char* dst, const char* src, SizeT n ); \
- SizeT VG_REPLACE_FUNCTION_EZU(2005,soname,fnname) \
+ SizeT VG_REPLACE_FUNCTION_EZU(20050,soname,fnname) \
( char* dst, const char* src, SizeT n ) \
{ \
const Char* src_orig = src; \
@@ -307,9 +310,9 @@
#define STRNLEN(soname, fnname) \
- SizeT VG_REPLACE_FUNCTION_EZU(2006,soname,fnname) \
+ SizeT VG_REPLACE_FUNCTION_EZU(20060,soname,fnname) \
( const char* str, SizeT n ); \
- SizeT VG_REPLACE_FUNCTION_EZU(2006,soname,fnname) \
+ SizeT VG_REPLACE_FUNCTION_EZU(20060,soname,fnname) \
( const char* str, SizeT n ) \
{ \
SizeT i = 0; \
@@ -328,9 +331,9 @@
// 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_EZU(2007,soname,fnname) \
+ SizeT VG_REPLACE_FUNCTION_EZU(20070,soname,fnname) \
( const char* str ); \
- SizeT VG_REPLACE_FUNCTION_EZU(2007,soname,fnname) \
+ SizeT VG_REPLACE_FUNCTION_EZU(20070,soname,fnname) \
( const char* str ) \
{ \
SizeT i = 0; \
@@ -345,9 +348,9 @@
#define STRCPY(soname, fnname) \
- char* VG_REPLACE_FUNCTION_EZU(2008,soname,fnname) \
+ char* VG_REPLACE_FUNCTION_EZU(20080,soname,fnname) \
( char* dst, const char* src ); \
- char* VG_REPLACE_FUNCTION_EZU(2008,soname,fnname) \
+ char* VG_REPLACE_FUNCTION_EZU(20080,soname,fnname) \
( char* dst, const char* src ) \
{ \
const Char* src_orig = src; \
@@ -376,9 +379,9 @@
#define STRNCPY(soname, fnname) \
- char* VG_REPLACE_FUNCTION_EZU(2009,soname,fnname) \
+ char* VG_REPLACE_FUNCTION_EZU(20090,soname,fnname) \
( char* dst, const char* src, SizeT n ); \
- char* VG_REPLACE_FUNCTION_EZU(2009,soname,fnname) \
+ char* VG_REPLACE_FUNCTION_EZU(20090,soname,fnname) \
( char* dst, const char* src, SizeT n ) \
{ \
const Char* src_orig = src; \
@@ -406,9 +409,9 @@
/* 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_EZU(2010,soname,fnname) \
+ SizeT VG_REPLACE_FUNCTION_EZU(20100,soname,fnname) \
( char* dst, const char* src, SizeT n ); \
- SizeT VG_REPLACE_FUNCTION_EZU(2010,soname,fnname) \
+ SizeT VG_REPLACE_FUNCTION_EZU(20100,soname,fnname) \
( char* dst, const char* src, SizeT n ) \
{ \
const char* src_orig = src; \
@@ -435,9 +438,9 @@
#define STRNCMP(soname, fnname) \
- int VG_REPLACE_FUNCTION_EZU(2011,soname,fnname) \
+ int VG_REPLACE_FUNCTION_EZU(20110,soname,fnname) \
( const char* s1, const char* s2, SizeT nmax ); \
- int VG_REPLACE_FUNCTION_EZU(2011,soname,fnname) \
+ int VG_REPLACE_FUNCTION_EZU(20110,soname,fnname) \
( const char* s1, const char* s2, SizeT nmax ) \
{ \
SizeT n = 0; \
@@ -463,9 +466,9 @@
#define STRCASECMP(soname, fnname) \
- int VG_REPLACE_FUNCTION_EZU(2012,soname,fnname) \
+ int VG_REPLACE_FUNCTION_EZU(20120,soname,fnname) \
( const char* s1, const char* s2 ); \
- int VG_REPLACE_FUNCTION_EZU(2012,soname,fnname) \
+ int VG_REPLACE_FUNCTION_EZU(20120,soname,fnname) \
( const char* s1, const char* s2 ) \
{ \
extern int tolower(int); \
@@ -492,9 +495,9 @@
#define STRNCASECMP(soname, fnname) \
- int VG_REPLACE_FUNCTION_EZU(2013,soname,fnname) \
+ int VG_REPLACE_FUNCTION_EZU(20130,soname,fnname) \
( const char* s1, const char* s2, SizeT nmax ); \
- int VG_REPLACE_FUNCTION_EZU(2013,soname,fnname) \
+ int VG_REPLACE_FUNCTION_EZU(20130,soname,fnname) \
( const char* s1, const char* s2, SizeT nmax ) \
{ \
extern int tolower(int); \
@@ -525,9 +528,9 @@
#define STRCASECMP_L(soname, fnname) \
- int VG_REPLACE_FUNCTION_EZU(2014,soname,fnname) \
+ int VG_REPLACE_FUNCTION_EZU(20140,soname,fnname) \
( const char* s1, const char* s2, void* locale ); \
- int VG_REPLACE_FUNCTION_EZU(2014,soname,fnname) \
+ int VG_REPLACE_FUNCTION_EZU(20140,soname,fnname) \
( const char* s1, const char* s2, void* locale ) \
{ \
extern int tolower_l(int, void*) __attribute__((weak)); \
@@ -553,9 +556,9 @@
#define STRNCASECMP_L(soname, fnname) \
- int VG_REPLACE_FUNCTION_EZU(2015,soname,fnname) \
+ int VG_REPLACE_FUNCTION_EZU(20150,soname,fnname) \
( const char* s1, const char* s2, SizeT nmax, void* locale ); \
- int VG_REPLACE_FUNCTION_EZU(2015,soname,fnname) \
+ int VG_REPLACE_FUNCTION_EZU(20150,soname,fnname) \
( const char* s1, const char* s2, SizeT nmax, void* locale ) \
{ \
extern int tolower_l(int, void*) __attribute__((weak)); \
@@ -584,9 +587,9 @@
#define STRCMP(soname, fnname) \
- int VG_REPLACE_FUNCTION_EZU(2016,soname,fnname) \
+ int VG_REPLACE_FUNCTION_EZU(20160,soname,fnname) \
( const char* s1, const char* s2 ); \
- int VG_REPLACE_FUNCTION_EZU(2016,soname,fnname) \
+ int VG_REPLACE_FUNCTION_EZU(20160,soname,fnname) \
( const char* s1, const char* s2 ) \
{ \
register unsigned char c1; \
@@ -612,9 +615,9 @@
#define MEMCHR(soname, fnname) \
- void* VG_REPLACE_FUNCTION_EZU(2017,soname,fnname) \
+ void* VG_REPLACE_FUNCTION_EZU(20170,soname,fnname) \
(const void *s, int c, SizeT n); \
- void* VG_REPLACE_FUNCTION_EZU(2017,soname,fnname) \
+ void* VG_REPLACE_FUNCTION_EZU(20170,soname,fnname) \
(const void *s, int c, SizeT n) \
{ \
SizeT i; \
@@ -705,16 +708,17 @@
}
#define MEMMOVE(soname, fnname) \
- MEMMOVE_OR_MEMCPY(2018, soname, fnname, 0)
+ MEMMOVE_OR_MEMCPY(20181, soname, fnname, 0)
#define MEMCPY(soname, fnname) \
- MEMMOVE_OR_MEMCPY(2022, soname, fnname, 1)
+ MEMMOVE_OR_MEMCPY(20180, soname, fnname, 1)
#if defined(VGO_linux)
/* For older memcpy we have to use memmove-like semantics and skip the
overlap check; sigh; see #275284. */
MEMMOVE(VG_Z_LIBC_SONAME, memcpyZAGLIBCZu2Zd2Zd5) /* memcpy@GLIBC_2.2.5 */
MEMCPY(VG_Z_LIBC_SONAME, memcpyZAZAGLIBCZu2Zd14) /* memcpy@@GLIBC_2.14 */
+MEMCPY(VG_Z_LIBC_SONAME, memcpy) /* fallback case */
MEMCPY(VG_Z_LD_SO_1, memcpy) /* ld.so.1 */
MEMCPY(VG_Z_LD64_SO_1, memcpy) /* ld64.so.1 */
#elif defined(VGO_darwin)
@@ -733,9 +737,9 @@
#define MEMCMP(soname, fnname) \
- int VG_REPLACE_FUNCTION_EZU(2019,soname,fnname) \
+ int VG_REPLACE_FUNCTION_EZU(20190,soname,fnname) \
( const void *s1V, const void *s2V, SizeT n ); \
- int VG_REPLACE_FUNCTION_EZU(2019,soname,fnname) \
+ int VG_REPLACE_FUNCTION_EZU(20190,soname,fnname) \
( const void *s1V, const void *s2V, SizeT n ) \
{ \
int res; \
@@ -770,9 +774,9 @@
/* 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_EZU(2020,soname,fnname) \
+ char* VG_REPLACE_FUNCTION_EZU(20200,soname,fnname) \
( char* dst, const char* src ); \
- char* VG_REPLACE_FUNCTION_EZU(2020,soname,fnname) \
+ char* VG_REPLACE_FUNCTION_EZU(20200,soname,fnname) \
( char* dst, const char* src ) \
{ \
const Char* src_orig = src; \
@@ -803,9 +807,9 @@
#define MEMSET(soname, fnname) \
- void* VG_REPLACE_FUNCTION_EZU(2021,soname,fnname) \
+ void* VG_REPLACE_FUNCTION_EZU(20210,soname,fnname) \
(void *s, Int c, SizeT n); \
- void* VG_REPLACE_FUNCTION_EZU(2021,soname,fnname) \
+ void* VG_REPLACE_FUNCTION_EZU(20210,soname,fnname) \
(void *s, Int c, SizeT n) \
{ \
Addr a = (Addr)s; \
@@ -827,7 +831,7 @@
#endif
-/* memmove -- use the MEMMOVE defn which also serves for memcpy. */
+/* memmove -- use the MEMMOVE defn above. */
MEMMOVE(VG_Z_LIBC_SONAME, memmove)
#if defined(VGO_darwin)
MEMMOVE(VG_Z_DYLD, memmove)
@@ -835,9 +839,9 @@
#define BCOPY(soname, fnname) \
- void VG_REPLACE_FUNCTION_EZU(2023,soname,fnname) \
+ void VG_REPLACE_FUNCTION_EZU(20230,soname,fnname) \
(const void *srcV, void *dstV, SizeT n); \
- void VG_REPLACE_FUNCTION_EZU(2023,soname,fnname) \
+ void VG_REPLACE_FUNCTION_EZU(20230,soname,fnname) \
(const void *srcV, void *dstV, SizeT n) \
{ \
SizeT i; \
@@ -863,9 +867,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_EZU(2024,soname,fnname) \
+ void* VG_REPLACE_FUNCTION_EZU(20240,soname,fnname) \
(void *dstV, const void *srcV, SizeT n, SizeT destlen); \
- void* VG_REPLACE_FUNCTION_EZU(2024,soname,fnname) \
+ void* VG_REPLACE_FUNCTION_EZU(20240,soname,fnname) \
(void *dstV, const void *srcV, SizeT n, SizeT destlen) \
{ \
SizeT i; \
@@ -897,9 +901,9 @@
/* Find the first occurrence of C in S or the final NUL byte. */
#define GLIBC232_STRCHRNUL(soname, fnname) \
- char* VG_REPLACE_FUNCTION_EZU(2025,soname,fnname) \
+ char* VG_REPLACE_FUNCTION_EZU(20250,soname,fnname) \
(const char* s, int c_in); \
- char* VG_REPLACE_FUNCTION_EZU(2025,soname,fnname) \
+ char* VG_REPLACE_FUNCTION_EZU(20250,soname,fnname) \
(const char* s, int c_in) \
{ \
unsigned char c = (unsigned char) c_in; \
@@ -916,9 +920,9 @@
/* Find the first occurrence of C in S. */
#define GLIBC232_RAWMEMCHR(soname, fnname) \
- char* VG_REPLACE_FUNCTION_EZU(2026,soname,fnname) \
+ char* VG_REPLACE_FUNCTION_EZU(20260,soname,fnname) \
(const char* s, int c_in); \
- char* VG_REPLACE_FUNCTION_EZU(2026,soname,fnname) \
+ char* VG_REPLACE_FUNCTION_EZU(20260,soname,fnname) \
(const char* s, int c_in) \
{ \
unsigned char c = (unsigned char) c_in; \
@@ -937,9 +941,9 @@
/* 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_EZU(2027,soname,fnname) \
+ char* VG_REPLACE_FUNCTION_EZU(20270,soname,fnname) \
(char* dst, const char* src, SizeT len); \
- char* VG_REPLACE_FUNCTION_EZU(2027,soname,fnname) \
+ char* VG_REPLACE_FUNCTION_EZU(20270,soname,fnname) \
(char* dst, const char* src, SizeT len) \
{ \
char* ret = dst; \
@@ -964,9 +968,9 @@
/* 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_EZU(2028,soname,fnname) \
+ char* VG_REPLACE_FUNCTION_EZU(20280,soname,fnname) \
(char* dst, const char* src, SizeT len); \
- char* VG_REPLACE_FUNCTION_EZU(2028,soname,fnname) \
+ char* VG_REPLACE_FUNCTION_EZU(20280,soname,fnname) \
(char* dst, const char* src, SizeT len) \
{ \
if (! len) \
@@ -989,9 +993,9 @@
/* mempcpy */
#define GLIBC25_MEMPCPY(soname, fnname) \
- void* VG_REPLACE_FUNCTION_EZU(2029,soname,fnname) \
+ void* VG_REPLACE_FUNCTION_EZU(20290,soname,fnname) \
( void *dst, const void *src, SizeT len ); \
- void* VG_REPLACE_FUNCTION_EZU(2029,soname,fnname) \
+ void* VG_REPLACE_FUNCTION_EZU(20290,soname,fnname) \
( void *dst, const void *src, SizeT len ) \
{ \
register char *d; \
@@ -1027,9 +1031,9 @@
#define GLIBC26___MEMCPY_CHK(soname, fnname) \
- void* VG_REPLACE_FUNCTION_EZU(2030,soname,fnname) \
+ void* VG_REPLACE_FUNCTION_EZU(20300,soname,fnname) \
(void* dst, const void* src, SizeT len, SizeT dstlen ); \
- void* VG_REPLACE_FUNCTION_EZU(2030,soname,fnname) \
+ void* VG_REPLACE_FUNCTION_EZU(20300,soname,fnname) \
(void* dst, const void* src, SizeT len, SizeT dstlen ) \
{ \
register char *d; \
@@ -1070,9 +1074,9 @@
#define STRSTR(soname, fnname) \
- void* VG_REPLACE_FUNCTION_EZU(2031,soname,fnname) \
+ void* VG_REPLACE_FUNCTION_EZU(20310,soname,fnname) \
(void* haystack, void* needle); \
- void* VG_REPLACE_FUNCTION_EZU(2031,soname,fnname) \
+ void* VG_REPLACE_FUNCTION_EZU(20310,soname,fnname) \
(void* haystack, void* needle) \
{ \
UChar* h = (UChar*)haystack; \
@@ -1112,9 +1116,9 @@
#define STRPBRK(soname, fnname) \
- void* VG_REPLACE_FUNCTION_EZU(2032,soname,fnname) \
+ void* VG_REPLACE_FUNCTION_EZU(20320,soname,fnname) \
(void* sV, void* acceptV); \
- void* VG_REPLACE_FUNCTION_EZU(2032,soname,fnname) \
+ void* VG_REPLACE_FUNCTION_EZU(20320,soname,fnname) \
(void* sV, void* acceptV) \
{ \
UChar* s = (UChar*)sV; \
@@ -1149,9 +1153,9 @@
#define STRCSPN(soname, fnname) \
- SizeT VG_REPLACE_FUNCTION_EZU(2033,soname,fnname) \
+ SizeT VG_REPLACE_FUNCTION_EZU(20330,soname,fnname) \
(void* sV, void* rejectV); \
- SizeT VG_REPLACE_FUNCTION_EZU(2033,soname,fnname) \
+ SizeT VG_REPLACE_FUNCTION_EZU(20330,soname,fnname) \
(void* sV, void* rejectV) \
{ \
UChar* s = (UChar*)sV; \
@@ -1187,9 +1191,9 @@
#define STRSPN(soname, fnname) \
- SizeT VG_REPLACE_FUNCTION_EZU(2034,soname,fnname) \
+ SizeT VG_REPLACE_FUNCTION_EZU(20340,soname,fnname) \
(void* sV, void* acceptV); \
- SizeT VG_REPLACE_FUNCTION_EZU(2034,soname,fnname) \
+ SizeT VG_REPLACE_FUNCTION_EZU(20340,soname,fnname) \
(void* sV, void* acceptV) \
{ \
UChar* s = (UChar*)sV; \