From: Julian Seward Date: Thu, 18 Aug 2011 13:09:55 +0000 (+0000) Subject: Extend the behavioural-equivalence-class mechanism for redirection X-Git-Tag: svn/VALGRIND_3_7_0~246 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e1567da7c5198b384e4c12f8904d87ec392ec39a;p=thirdparty%2Fvalgrind.git 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 --- diff --git a/coregrind/m_demangle/demangle.c b/coregrind/m_demangle/demangle.c index ccc59267ad..5fc47f3e5d 100644 --- a/coregrind/m_demangle/demangle.c +++ b/coregrind/m_demangle/demangle.c @@ -100,7 +100,7 @@ void VG_(demangle) ( Bool do_cxx_demangling, Bool do_z_demangling, 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 @@ Bool VG_(maybe_Z_demangle) ( const HChar* sym, /*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 @@ Bool VG_(maybe_Z_demangle) ( const HChar* sym, 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 @@ Bool VG_(maybe_Z_demangle) ( const HChar* sym, 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 f22088b629..5b59144054 100644 --- a/coregrind/m_redir.c +++ b/coregrind/m_redir.c @@ -233,6 +233,9 @@ typedef 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 @@ typedef 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 @@ static void free_symname_array ( UChar** names, UChar** twoslots ) 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 @@ void VG_(redir_notify_new_DebugInfo)( DebugInfo* newdi ) 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 @@ void VG_(redir_notify_new_DebugInfo)( DebugInfo* newdi ) 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 @@ void VG_(redir_notify_new_DebugInfo)( DebugInfo* newdi ) 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 @@ void generate_and_add_actives ( 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 @@ void generate_and_add_actives ( 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 @@ static void maybe_add_active ( Active act ) 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 @@ static void maybe_add_active ( Active act ) 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 @@ static void add_hardwired_active ( Addr from, Addr to ) 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 @@ void handle_maybe_load_notifier( const UChar* soname, 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 handle_require_text_symbols ( DebugInfo* di ) 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 @@ static void show_active ( HChar* left, Active* act ) 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 53170d8c4d..38553ec8cd 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 @@ static void init(void); */ #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 @@ static void init(void); #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 @@ static void init(void); */ #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 @@ ALLOC_or_BOMB(VG_Z_LIBC_SONAME, __builtin_vec_new, __builtin_vec_new ); */ #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 @@ ALLOC_or_BOMB(VG_Z_LIBC_SONAME, __builtin_vec_new, __builtin_vec_new ); #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 @@ FREE(VG_Z_LIBC_SONAME, _ZdaPvRKSt9nothrow_t, __builtin_vec_delete ); #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 @@ FREE(VG_Z_LIBC_SONAME, _ZdaPvRKSt9nothrow_t, __builtin_vec_delete ); #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 @@ ZONECALLOC(VG_Z_LIBC_SONAME, malloc_zone_calloc); #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 @@ ZONECALLOC(VG_Z_LIBC_SONAME, malloc_zone_calloc); 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 @@ ZONECALLOC(VG_Z_LIBC_SONAME, malloc_zone_calloc); #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 @@ ZONECALLOC(VG_Z_LIBC_SONAME, malloc_zone_calloc); 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 @@ ZONEREALLOC(VG_Z_LIBC_SONAME, malloc_zone_realloc); #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 @@ ZONEREALLOC(VG_Z_LIBC_SONAME, malloc_zone_realloc); #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 @@ ZONEMEMALIGN(VG_Z_LIBC_SONAME, malloc_zone_memalign); #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 @@ ZONEVALLOC(VG_Z_LIBC_SONAME, malloc_zone_valloc); #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 @@ MALLOPT(VG_Z_LIBC_SONAME, mallopt); // 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 @@ MALLOC_TRIM(VG_Z_LIBC_SONAME, malloc_trim); #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 @@ MALLOC_TRIM(VG_Z_LIBC_SONAME, malloc_trim); || (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 @@ POSIX_MEMALIGN(VG_Z_LIBC_SONAME, posix_memalign); #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 @@ static void panic(const char *str) #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 @@ PANIC(VG_Z_LIBC_SONAME, malloc_set_state); #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 @@ MALLOC_STATS(VG_Z_LIBC_SONAME, malloc_stats); // 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 @@ static vki_malloc_zone_t vg_default_zone = { 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 @@ static vki_malloc_zone_t vg_default_zone = { #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 @@ DEFAULT_ZONE(VG_Z_LIBC_SONAME, malloc_default_zone); // 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 fc621340c8..39bb4adcfe 100644 --- a/coregrind/pub_core_demangle.h +++ b/coregrind/pub_core_demangle.h @@ -60,7 +60,8 @@ Bool VG_(maybe_Z_demangle) ( const HChar* sym, /*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 15894e3999..4ca8358350 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. - - The tag is mandatory and must comprise 4 decimal digits. The tag - 0000 is special and means "does not have behaviour identical to any + 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. + + 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 cac4490c00..0603aeea15 100644 --- a/include/valgrind.h +++ b/include/valgrind.h @@ -689,10 +689,10 @@ typedef #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 1570de36e0..42f8eceae5 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 @@ static inline void my_exit ( int x ) #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 @@ STRRCHR(VG_Z_DYLD, rindex) #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 @@ STRCHR(VG_Z_DYLD, index) #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 @@ STRCAT(VG_Z_LIBC_SONAME, __GI_strcat) #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 @@ STRNCAT(VG_Z_DYLD, strncat) 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 @@ STRLCAT(VG_Z_DYLD, strlcat) #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 @@ STRNLEN(VG_Z_LIBC_SONAME, __GI_strnlen) // 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 @@ STRLEN(VG_Z_LIBC_SONAME, __GI_strlen) #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 @@ STRCPY(VG_Z_DYLD, strcpy) #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 @@ STRNCPY(VG_Z_DYLD, strncpy) /* 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 @@ STRLCPY(VG_Z_DYLD, strlcpy) #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 @@ STRNCMP(VG_Z_DYLD, strncmp) #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 @@ STRCASECMP(VG_Z_LIBC_SONAME, __GI_strcasecmp) #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 @@ STRNCASECMP(VG_Z_DYLD, strncasecmp) #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 @@ STRCASECMP_L(VG_Z_LIBC_SONAME, __GI___strcasecmp_l) #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 @@ STRNCASECMP_L(VG_Z_DYLD, strncasecmp_l) #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 @@ STRCMP(VG_Z_LD64_SO_1, strcmp) #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 @@ MEMCHR(VG_Z_DYLD, memchr) } #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 @@ MEMCPY(NONE, ZuintelZufastZumemcpy) #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 @@ MEMCMP(VG_Z_DYLD, bcmp) /* 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 @@ STPCPY(VG_Z_DYLD, stpcpy) #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 @@ MEMSET(VG_Z_DYLD, memset) #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 @@ MEMMOVE(VG_Z_DYLD, memmove) #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 @@ BCOPY(VG_Z_DYLD, bcopy) /* 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 @@ GLIBC25___MEMMOVE_CHK(VG_Z_LIBC_SONAME, __memmove_chk) /* 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 @@ GLIBC232_STRCHRNUL(VG_Z_LIBC_SONAME, strchrnul) /* 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 @@ GLIBC232_RAWMEMCHR(VG_Z_LIBC_SONAME, __GI___rawmemchr) /* 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 @@ GLIBC25___STRCPY_CHK(VG_Z_LIBC_SONAME, __strcpy_chk) /* 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 @@ GLIBC25___STPCPY_CHK(VG_Z_LIBC_SONAME, __stpcpy_chk) /* 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 @@ GLIBC25_MEMPCPY(VG_Z_LD_SO_1, mempcpy) /* ld.so.1 */ #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 @@ GLIBC26___MEMCPY_CHK(VG_Z_LIBC_SONAME, __memcpy_chk) #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 @@ STRSTR(VG_Z_LIBC_SONAME, strstr) #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 @@ STRPBRK(VG_Z_LIBC_SONAME, strpbrk) #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 @@ STRCSPN(VG_Z_LIBC_SONAME, strcspn) #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; \