Index: valgrind/memcheck/mc_replace_strmem.c =================================================================== --- valgrind/memcheck/mc_replace_strmem.c (revision 13016) +++ valgrind/memcheck/mc_replace_strmem.c (working copy) @@ -97,6 +97,10 @@ 20350 STRCASESTR 20360 MEMRCHR 20370 WCSLEN + 20380 WCSCMP + 20390 WCSCPY + 20400 WCSCHR + 20410 WCSRCHR */ @@ -1570,7 +1574,115 @@ #endif +/*---------------------- wcscmp ----------------------*/ +// This is a wchar_t equivalent to strcmp. We don't +// have wchar_t available here, but in the GNU C Library +// wchar_t is always 32 bits wide and wcscmp uses signed +// comparison, not unsigned as in strcmp function. + +#define WCSCMP(soname, fnname) \ + int VG_REPLACE_FUNCTION_EZU(20380,soname,fnname) \ + ( const Int* s1, const Int* s2 ); \ + int VG_REPLACE_FUNCTION_EZU(20380,soname,fnname) \ + ( const Int* s1, const Int* s2 ) \ + { \ + register Int c1; \ + register Int c2; \ + while (True) { \ + c1 = *s1; \ + c2 = *s2; \ + if (c1 != c2) break; \ + if (c1 == 0) break; \ + s1++; s2++; \ + } \ + if (c1 < c2) return -1; \ + if (c1 > c2) return 1; \ + return 0; \ + } + +#if defined(VGO_linux) + WCSCMP(VG_Z_LIBC_SONAME, wcscmp) +#endif + +/*---------------------- wcscpy ----------------------*/ + +// This is a wchar_t equivalent to strcpy. We don't +// have wchar_t available here, but in the GNU C Library +// wchar_t is always 32 bits wide. + +#define WCSCPY(soname, fnname) \ + Int* VG_REPLACE_FUNCTION_EZU(20390,soname,fnname) \ + ( Int* dst, const Int* src ); \ + Int* VG_REPLACE_FUNCTION_EZU(20390,soname,fnname) \ + ( Int* dst, const Int* src ) \ + { \ + const Int* src_orig = src; \ + Int* dst_orig = dst; \ + \ + while (*src) *dst++ = *src++; \ + *dst = 0; \ + \ + /* This checks for overlap after copying, unavoidable without */ \ + /* pre-counting length... should be ok */ \ + if (is_overlap(dst_orig, \ + src_orig, \ + (Addr)dst-(Addr)dst_orig+1, \ + (Addr)src-(Addr)src_orig+1)) \ + RECORD_OVERLAP_ERROR("wcscpy", dst_orig, src_orig, 0); \ + \ + return dst_orig; \ + } + +#if defined(VGO_linux) + WCSCPY(VG_Z_LIBC_SONAME, wcscpy) +#endif + + +/*---------------------- wcschr ----------------------*/ + +// This is a wchar_t equivalent to strchr. We don't +// have wchar_t available here, but in the GNU C Library +// wchar_t is always 32 bits wide. + +#define WCSCHR(soname, fnname) \ + Int* VG_REPLACE_FUNCTION_EZU(20400,soname,fnname) ( const Int* s, Int c ); \ + Int* VG_REPLACE_FUNCTION_EZU(20400,soname,fnname) ( const Int* s, Int c ) \ + { \ + Int* p = (Int*)s; \ + while (True) { \ + if (*p == c) return p; \ + if (*p == 0) return NULL; \ + p++; \ + } \ + } + +#if defined(VGO_linux) + WCSCHR(VG_Z_LIBC_SONAME, wcschr) +#endif +/*---------------------- wcsrchr ----------------------*/ + +// This is a wchar_t equivalent to strrchr. We don't +// have wchar_t available here, but in the GNU C Library +// wchar_t is always 32 bits wide. + +#define WCSRCHR(soname, fnname) \ + Int* VG_REPLACE_FUNCTION_EZU(20410,soname,fnname)( const Int* s, Int c ); \ + Int* VG_REPLACE_FUNCTION_EZU(20410,soname,fnname)( const Int* s, Int c ) \ + { \ + Int* p = (Int*) s; \ + Int* last = NULL; \ + while (True) { \ + if (*p == c) last = p; \ + if (*p == 0) return last; \ + p++; \ + } \ + } + +#if defined(VGO_linux) + WCSRCHR(VG_Z_LIBC_SONAME, wcsrchr) +#endif + /*------------------------------------------------------------*/ /*--- Improve definedness checking of process environment ---*/ /*------------------------------------------------------------*/ Index: valgrind/memcheck/tests/Makefile.am =================================================================== --- valgrind/memcheck/tests/Makefile.am (revision 13016) +++ valgrind/memcheck/tests/Makefile.am (working copy) @@ -216,6 +217,7 @@ vcpu_fbench.stdout.exp vcpu_fbench.stderr.exp vcpu_fbench.vgtest \ vcpu_fnfns.stdout.exp vcpu_fnfns.stdout.exp-glibc28-amd64 \ vcpu_fnfns.stdout.exp-darwin vcpu_fnfns.stderr.exp vcpu_fnfns.vgtest \ + wcs.vgtest wcs.stderr.exp \ wrap1.vgtest wrap1.stdout.exp wrap1.stderr.exp \ wrap2.vgtest wrap2.stdout.exp wrap2.stderr.exp \ wrap3.vgtest wrap3.stdout.exp wrap3.stderr.exp \ @@ -292,6 +294,7 @@ varinfo1 varinfo2 varinfo3 varinfo4 \ varinfo5 varinfo5so.so varinfo6 \ vcpu_fbench vcpu_fnfns \ + wcs \ xml1 \ wrap1 wrap2 wrap3 wrap4 wrap5 wrap6 wrap7 wrap7so.so wrap8 \ writev1 Index: valgrind/memcheck/tests/wcs.c =================================================================== --- valgrind/memcheck/tests/wcs.c (revision 0) +++ valgrind/memcheck/tests/wcs.c (working copy) @@ -0,0 +1,29 @@ +// Uses various wchar_t * functions that have hand written SSE assembly +// implementations in glibc. wcslen, wcscpy, wcscmp, wcsrchr, wcschr. + +#include +#include +#include + +int main(int argc, char **argv) +{ + wchar_t a[] = L"The spazzy orange tiger jumped over the tawny jaguar."; + wchar_t *b, *c; + wchar_t *d, *e; + + size_t l = wcslen (a); + fprintf (stderr, "wcslen: %zd\n", l); // wcslen: 53 + + b = (wchar_t *) malloc((l + 1) * sizeof (wchar_t)); + c = wcscpy (b, a); + + fprintf (stderr, "wcscmp equal: %d\n", wcscmp (a, b)); // wcscmp equal: 0 + + d = wcsrchr (a, L'd'); + e = wcschr (a, L'd'); + + fprintf (stderr, "wcsrchr == wcschr: %d\n", d == e); // wcsrchr == wcschr: 1 + + free (c); // b == c + return 0; +} Index: valgrind/memcheck/tests/wcs.stderr.exp =================================================================== --- valgrind/memcheck/tests/wcs.stderr.exp (revision 0) +++ valgrind/memcheck/tests/wcs.stderr.exp (working copy) @@ -0,0 +1,3 @@ +wcslen: 53 +wcscmp equal: 0 +wcsrchr == wcschr: 1 Index: valgrind/memcheck/tests/wcs.vgtest =================================================================== --- valgrind/memcheck/tests/wcs.vgtest (revision 0) +++ valgrind/memcheck/tests/wcs.vgtest (working copy) @@ -0,0 +1,2 @@ +prog: wcs +vgopts: -q --- valgrind-3.8.1/memcheck/tests/Makefile.in.orig 2012-10-04 22:27:31.879093431 +0200 +++ valgrind-3.8.1/memcheck/tests/Makefile.in 2012-10-04 22:28:55.381301338 +0200 @@ -114,7 +114,7 @@ unit_oset$(EXEEXT) varinfo1$(EXEEXT) varinfo2$(EXEEXT) \ varinfo3$(EXEEXT) varinfo4$(EXEEXT) varinfo5$(EXEEXT) \ varinfo5so.so$(EXEEXT) varinfo6$(EXEEXT) vcpu_fbench$(EXEEXT) \ - vcpu_fnfns$(EXEEXT) xml1$(EXEEXT) wrap1$(EXEEXT) \ + vcpu_fnfns$(EXEEXT) wcs$(EXEEXT) xml1$(EXEEXT) wrap1$(EXEEXT) \ wrap2$(EXEEXT) wrap3$(EXEEXT) wrap4$(EXEEXT) wrap5$(EXEEXT) \ wrap6$(EXEEXT) wrap7$(EXEEXT) wrap7so.so$(EXEEXT) \ wrap8$(EXEEXT) writev1$(EXEEXT) $(am__EXEEXT_1) @@ -530,6 +530,9 @@ vcpu_fnfns_DEPENDENCIES = vcpu_fnfns_LINK = $(CCLD) $(vcpu_fnfns_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ +wcs_SOURCES = wcs.c +wcs_OBJECTS = wcs.$(OBJEXT) +wcs_LDADD = $(LDADD) wrap1_SOURCES = wrap1.c wrap1_OBJECTS = wrap1.$(OBJEXT) wrap1_LDADD = $(LDADD) @@ -610,9 +613,9 @@ suppfree.c test-plo.c trivialleak.c unit_libcbase.c \ unit_oset.c varinfo1.c varinfo2.c varinfo3.c varinfo4.c \ $(varinfo5_SOURCES) $(varinfo5so_so_SOURCES) varinfo6.c \ - vcpu_fbench.c vcpu_fnfns.c wrap1.c wrap2.c wrap3.c wrap4.c \ - wrap5.c wrap6.c $(wrap7_SOURCES) $(wrap7so_so_SOURCES) wrap8.c \ - writev1.c xml1.c + vcpu_fbench.c vcpu_fnfns.c wcs.c wrap1.c wrap2.c wrap3.c \ + wrap4.c wrap5.c wrap6.c $(wrap7_SOURCES) $(wrap7so_so_SOURCES) \ + wrap8.c writev1.c xml1.c DIST_SOURCES = accounting.c addressable.c atomic_incs.c badaddrvalue.c \ badfree.c badjump.c badjump2.c badloop.c badpoll.c badrw.c \ big_blocks_freed_list.c brk2.c buflen_check.c bug287260.c \ @@ -641,9 +644,9 @@ suppfree.c test-plo.c trivialleak.c unit_libcbase.c \ unit_oset.c varinfo1.c varinfo2.c varinfo3.c varinfo4.c \ $(varinfo5_SOURCES) $(varinfo5so_so_SOURCES) varinfo6.c \ - vcpu_fbench.c vcpu_fnfns.c wrap1.c wrap2.c wrap3.c wrap4.c \ - wrap5.c wrap6.c $(wrap7_SOURCES) $(wrap7so_so_SOURCES) wrap8.c \ - writev1.c xml1.c + vcpu_fbench.c vcpu_fnfns.c wcs.c wrap1.c wrap2.c wrap3.c \ + wrap4.c wrap5.c wrap6.c $(wrap7_SOURCES) $(wrap7so_so_SOURCES) \ + wrap8.c writev1.c xml1.c RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ html-recursive info-recursive install-data-recursive \ install-dvi-recursive install-exec-recursive \ @@ -1142,6 +1145,7 @@ vcpu_fbench.stdout.exp vcpu_fbench.stderr.exp vcpu_fbench.vgtest \ vcpu_fnfns.stdout.exp vcpu_fnfns.stdout.exp-glibc28-amd64 \ vcpu_fnfns.stdout.exp-darwin vcpu_fnfns.stderr.exp vcpu_fnfns.vgtest \ + wcs.vgtest wcs.stderr.exp \ wrap1.vgtest wrap1.stdout.exp wrap1.stderr.exp \ wrap2.vgtest wrap2.stdout.exp wrap2.stderr.exp \ wrap3.vgtest wrap3.stdout.exp wrap3.stderr.exp \ @@ -1629,6 +1633,9 @@ vcpu_fnfns$(EXEEXT): $(vcpu_fnfns_OBJECTS) $(vcpu_fnfns_DEPENDENCIES) @rm -f vcpu_fnfns$(EXEEXT) $(vcpu_fnfns_LINK) $(vcpu_fnfns_OBJECTS) $(vcpu_fnfns_LDADD) $(LIBS) +wcs$(EXEEXT): $(wcs_OBJECTS) $(wcs_DEPENDENCIES) + @rm -f wcs$(EXEEXT) + $(LINK) $(wcs_OBJECTS) $(wcs_LDADD) $(LIBS) wrap1$(EXEEXT): $(wrap1_OBJECTS) $(wrap1_DEPENDENCIES) @rm -f wrap1$(EXEEXT) $(LINK) $(wrap1_OBJECTS) $(wrap1_LDADD) $(LIBS) @@ -1784,6 +1791,7 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/varinfo6-varinfo6.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vcpu_fbench-vcpu_fbench.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vcpu_fnfns-vcpu_fnfns.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wcs.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wrap1.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wrap2.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wrap3.Po@am__quote@