From: Paul Floyd Date: Tue, 2 Mar 2021 12:32:22 +0000 (+0100) Subject: Bug 388787 - Support for C++17 new/delete X-Git-Tag: VALGRIND_3_17_0~27 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e42badd060c789fe712a13d4c3ff8360a44d60f3;p=thirdparty%2Fvalgrind.git Bug 388787 - Support for C++17 new/delete These over-aligned new and delete operators were added in C++ 17. --- diff --git a/.gitignore b/.gitignore index c22c0315a2..b9fca3de32 100644 --- a/.gitignore +++ b/.gitignore @@ -794,6 +794,7 @@ /memcheck/tests/cond_ld_st /memcheck/tests/custom-overlap /memcheck/tests/custom_alloc +/memcheck/tests/cxx17_aligned_new /memcheck/tests/deep-backtrace /memcheck/tests/deep_templates /memcheck/tests/demangle diff --git a/NEWS b/NEWS index 43533fc1ad..fa7c4b0183 100644 --- a/NEWS +++ b/NEWS @@ -92,6 +92,7 @@ where XXXXXX is the bug number as listed below. 361770 Missing F_ADD_SEALS 369029 handle linux syscalls sched_getattr and sched_setattr 384729 __libc_freeres inhibits cross-platform valgrind +388787 Support for C++17 new/delete 391853 Makefile.all.am:L247 and @SOLARIS_UNDEF_LARGESOURCE@ being empty 397605 ioctl FICLONE mishandled 408663 Suppression file for musl libc diff --git a/configure.ac b/configure.ac index 595003b46d..be5d99ee0c 100755 --- a/configure.ac +++ b/configure.ac @@ -2327,6 +2327,29 @@ AC_LANG(C) AC_SUBST(FLAG_FSIZED_DEALLOCATION) AM_CONDITIONAL([HAVE_FSIZED_DEALLOCATION], [test x$ac_have_sized_deallocation = xyes]) +# does this compiler support C++17 aligned new/delete? +AC_MSG_CHECKING([if g++ supports aligned new and delete]) + +safe_CXXFLAGS=$CXXFLAGS +CXXFLAGS="-std=c++17" + +AC_LANG(C++) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include +#include +]], [[ + operator delete(nullptr, std::align_val_t(64U)); +]])], [ +ac_have_aligned_cxx_alloc=yes +AC_MSG_RESULT([yes]) +], [ +ac_have_aligned_cxx_alloc=no +AC_MSG_RESULT([no]) +]) +CXXFLAGS=$safe_CXXFLAGS +AC_LANG(C) + +AM_CONDITIONAL([HAVE_ALIGNED_CXX_ALLOC], [test x$ac_have_aligned_cxx_alloc = xyes]) # does this compiler support -fno-stack-protector ? AC_MSG_CHECKING([if gcc accepts -fno-stack-protector]) diff --git a/coregrind/m_replacemalloc/vg_replace_malloc.c b/coregrind/m_replacemalloc/vg_replace_malloc.c index c3be5c6a81..c1ade1f68b 100644 --- a/coregrind/m_replacemalloc/vg_replace_malloc.c +++ b/coregrind/m_replacemalloc/vg_replace_malloc.c @@ -261,6 +261,33 @@ extern int *__errno_location (void) __attribute__((weak)); return v; \ } +/* Generate a replacement for 'fnname' in object 'soname', which calls + 'vg_replacement' to allocate aligned memory. If that fails, return NULL. +*/ +#define ALLOC_or_NULL_ALIGNED(soname, fnname, vg_replacement) \ + \ + void* VG_REPLACE_FUNCTION_EZU(10010,soname,fnname) (SizeT n, SizeT alignment); \ + void* VG_REPLACE_FUNCTION_EZU(10010,soname,fnname) (SizeT n, SizeT alignment) \ + { \ + void* v; \ + \ + DO_INIT; \ + TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(n); \ + MALLOC_TRACE(#fnname "(size %llu, al %llu)", (ULong)n, (ULong)alignment ); \ + \ + /* Round up to minimum alignment if necessary. */ \ + if (alignment < VG_MIN_MALLOC_SZB) \ + alignment = VG_MIN_MALLOC_SZB; \ + \ + /* Round up to nearest power-of-two if necessary (like glibc). */ \ + while (0 != (alignment & (alignment - 1))) alignment++; \ + \ + v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_##vg_replacement, n, alignment ); \ + MALLOC_TRACE(" = %p\n", v ); \ + if (!v) SET_ERRNO_ENOMEM; \ + return v; \ + } + #define ZONEALLOC_or_NULL(soname, fnname, vg_replacement) \ \ void* VG_REPLACE_FUNCTION_EZU(10020,soname,fnname) (void *zone, SizeT n); \ @@ -306,6 +333,40 @@ extern int *__errno_location (void) __attribute__((weak)); return v; \ } +/* Generate a replacement for 'fnname' in object 'soname', which calls + 'vg_replacement' to allocate aligned memory. If that fails, it bombs the + system. +*/ +#define ALLOC_or_BOMB_ALIGNED(soname, fnname, vg_replacement) \ + \ + void* VG_REPLACE_FUNCTION_EZU(10030,soname,fnname) (SizeT n, SizeT alignment); \ + void* VG_REPLACE_FUNCTION_EZU(10030,soname,fnname) (SizeT n, SizeT alignment) \ + { \ + void* v; \ + \ + DO_INIT; \ + TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(n); \ + MALLOC_TRACE(#fnname "(size %llu, al %llu)", (ULong)n, (ULong)alignment ); \ + \ + /* Round up to minimum alignment if necessary. */ \ + if (alignment < VG_MIN_MALLOC_SZB) \ + alignment = VG_MIN_MALLOC_SZB; \ + \ + /* Round up to nearest power-of-two if necessary (like glibc). */ \ + while (0 != (alignment & (alignment - 1))) alignment++; \ + \ + v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_##vg_replacement, n, alignment ); \ + MALLOC_TRACE(" = %p\n", v ); \ + if (NULL == v) { \ + VALGRIND_PRINTF( \ + "new/new[] aligned failed and should throw an exception, but Valgrind\n"); \ + VALGRIND_PRINTF_BACKTRACE( \ + " cannot throw exceptions and so is aborting instead. Sorry.\n"); \ + my_exit(1); \ + } \ + return v; \ + } + // Each of these lines generates a replacement function: // (from_so, from_fn, v's replacement) // For some lines, we will also define a replacement function @@ -344,12 +405,14 @@ extern int *__errno_location (void) __attribute__((weak)); // operator new(unsigned int), GNU mangling #if VG_WORDSIZE == 4 ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znwj, __builtin_new); + ALLOC_or_BOMB(VG_Z_LIBCXX_SONAME, _Znwj, __builtin_new); ALLOC_or_BOMB(VG_Z_LIBC_SONAME, _Znwj, __builtin_new); ALLOC_or_BOMB(SO_SYN_MALLOC, _Znwj, __builtin_new); #endif // operator new(unsigned long), GNU mangling #if VG_WORDSIZE == 8 ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znwm, __builtin_new); + ALLOC_or_BOMB(VG_Z_LIBCXX_SONAME, _Znwm, __builtin_new); ALLOC_or_BOMB(VG_Z_LIBC_SONAME, _Znwm, __builtin_new); ALLOC_or_BOMB(SO_SYN_MALLOC, _Znwm, __builtin_new); #endif @@ -380,6 +443,41 @@ extern int *__errno_location (void) __attribute__((weak)); #endif +/*------------------- C++17 new aligned -------------------*/ + + #if defined(VGO_linux) + // operator new(unsigned int, std::align_val_t), GNU mangling + #if VG_WORDSIZE == 4 + ALLOC_or_BOMB_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZnwjSt11align_val_t, __builtin_new_aligned); + ALLOC_or_BOMB_ALIGNED(VG_Z_LIBCXX_SONAME, _ZnwjSt11align_val_t, __builtin_new_aligned); + ALLOC_or_BOMB_ALIGNED(VG_Z_LIBC_SONAME, _ZnwjSt11align_val_t, __builtin_new_aligned); + ALLOC_or_BOMB_ALIGNED(SO_SYN_MALLOC, _ZnwjSt11align_val_t, __builtin_new_aligned); + #endif + // operator new(unsigned long, std::align_val_t), GNU mangling + #if VG_WORDSIZE == 8 + ALLOC_or_BOMB_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZnwmSt11align_val_t, __builtin_new_aligned); + ALLOC_or_BOMB_ALIGNED(VG_Z_LIBCXX_SONAME, _ZnwmSt11align_val_t, __builtin_new_aligned); + ALLOC_or_BOMB_ALIGNED(VG_Z_LIBC_SONAME, _ZnwmSt11align_val_t, __builtin_new_aligned); + ALLOC_or_BOMB_ALIGNED(SO_SYN_MALLOC, _ZnwmSt11align_val_t, __builtin_new_aligned); + #endif + +#elif defined(VGO_darwin) + +#elif defined(VGO_solaris) + // operator new(unsigned int, std::align_val_t), GNU mangling + #if VG_WORDSIZE == 4 + ALLOC_or_BOMB_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZnwjSt11align_val_t, __builtin_new_aligned); + ALLOC_or_BOMB_ALIGNED(SO_SYN_MALLOC, _ZnwjSt11align_val_t, __builtin_new_aligned); + #endif + // operator new(unsigned long, std::align_val_t), GNU mangling + #if VG_WORDSIZE == 8 + ALLOC_or_BOMB_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZnwmSt11align_val_t, __builtin_new_aligned); + ALLOC_or_BOMB_ALIGNED(SO_SYN_MALLOC, _ZnwmSt11align_val_t, __builtin_new_aligned); + + #endif + +#endif + /*---------------------- new nothrow ----------------------*/ @@ -387,12 +485,14 @@ extern int *__errno_location (void) __attribute__((weak)); // operator new(unsigned, std::nothrow_t const&), GNU mangling #if VG_WORDSIZE == 4 ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnwjRKSt9nothrow_t, __builtin_new); + ALLOC_or_NULL(VG_Z_LIBCXX_SONAME, _ZnwjRKSt9nothrow_t, __builtin_new); ALLOC_or_NULL(VG_Z_LIBC_SONAME, _ZnwjRKSt9nothrow_t, __builtin_new); ALLOC_or_NULL(SO_SYN_MALLOC, _ZnwjRKSt9nothrow_t, __builtin_new); #endif // operator new(unsigned long, std::nothrow_t const&), GNU mangling #if VG_WORDSIZE == 8 ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnwmRKSt9nothrow_t, __builtin_new); + ALLOC_or_NULL(VG_Z_LIBCXX_SONAME, _ZnwmRKSt9nothrow_t, __builtin_new); ALLOC_or_NULL(VG_Z_LIBC_SONAME, _ZnwmRKSt9nothrow_t, __builtin_new); ALLOC_or_NULL(SO_SYN_MALLOC, _ZnwmRKSt9nothrow_t, __builtin_new); #endif @@ -423,6 +523,40 @@ extern int *__errno_location (void) __attribute__((weak)); #endif +/*----------------- C++17 new aligned nothrow -----------------*/ + +#if defined(VGO_linux) + // operator new(unsigned int, std::align_val_t, std::nothrow_t const&), GNU mangling + #if VG_WORDSIZE == 4 + ALLOC_or_NULL_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZnwjSt11align_val_tRKSt9nothrow_t, __builtin_new_aligned); + ALLOC_or_NULL_ALIGNED(VG_Z_LIBCXX_SONAME, _ZnwjSt11align_val_tRKSt9nothrow_t, __builtin_new_aligned); + ALLOC_or_NULL_ALIGNED(VG_Z_LIBC_SONAME, _ZnwjSt11align_val_tRKSt9nothrow_t, __builtin_new_aligned); + ALLOC_or_NULL_ALIGNED(SO_SYN_MALLOC, _ZnwjSt11align_val_tRKSt9nothrow_t, __builtin_new_aligned); + #endif + // operator new(unsigned long, std::align_val_t, std::nothrow_t const&), GNU mangling + #if VG_WORDSIZE == 8 + ALLOC_or_NULL_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZnwmSt11align_val_tRKSt9nothrow_t, __builtin_new_aligned); + ALLOC_or_NULL_ALIGNED(VG_Z_LIBCXX_SONAME, _ZnwmSt11align_val_tRKSt9nothrow_t, __builtin_new_aligned); + ALLOC_or_NULL_ALIGNED(VG_Z_LIBC_SONAME, _ZnwmSt11align_val_tRKSt9nothrow_t, __builtin_new_aligned); + ALLOC_or_NULL_ALIGNED(SO_SYN_MALLOC, _ZnwmSt11align_val_tRKSt9nothrow_t, __builtin_new_aligned); + #endif + +#elif defined(VGO_darwin) + +#elif defined(VGO_solaris) + // operator new(unsigned, std::align_val_t, std::nothrow_t const&), GNU mangling + #if VG_WORDSIZE == 4 + ALLOC_or_NULL_ALIGNED(VG_Z_LIBSTDCXX_SONAME, __ZnwjSt11align_val_tRKSt9nothrow_t, __builtin_new_aligned); + ALLOC_or_NULL_ALIGNED(SO_SYN_MALLOC, __ZnwjSt11align_val_tRKSt9nothrow_t, __builtin_new_aligned); + #endif + // operator new(unsigned long, std::align_val_t, std::nothrow_t const&), GNU mangling + #if VG_WORDSIZE == 8 + ALLOC_or_NULL_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZnwmSt11align_val_tRKSt9nothrow_t, __builtin_new_aligned); + ALLOC_or_NULL_ALIGNED(SO_SYN_MALLOC, _ZnwmSt11align_val_tRKSt9nothrow_t, __builtin_new_aligned); + #endif + +#endif + /*---------------------- new [] ----------------------*/ @@ -433,12 +567,14 @@ extern int *__errno_location (void) __attribute__((weak)); // operator new[](unsigned int), GNU mangling #if VG_WORDSIZE == 4 ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znaj, __builtin_vec_new ); + ALLOC_or_BOMB(VG_Z_LIBCXX_SONAME, _Znaj, __builtin_vec_new ); ALLOC_or_BOMB(VG_Z_LIBC_SONAME, _Znaj, __builtin_vec_new ); ALLOC_or_BOMB(SO_SYN_MALLOC, _Znaj, __builtin_vec_new ); #endif // operator new[](unsigned long), GNU mangling #if VG_WORDSIZE == 8 ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znam, __builtin_vec_new ); + ALLOC_or_BOMB(VG_Z_LIBCXX_SONAME, _Znam, __builtin_vec_new ); ALLOC_or_BOMB(VG_Z_LIBC_SONAME, _Znam, __builtin_vec_new ); ALLOC_or_BOMB(SO_SYN_MALLOC, _Znam, __builtin_vec_new ); #endif @@ -469,6 +605,41 @@ extern int *__errno_location (void) __attribute__((weak)); #endif +/*------------------ C++ 17 new aligned [] ------------------*/ + +#if defined(VGO_linux) + // operator new[](unsigned int, std::align_val_t), GNU mangling + #if VG_WORDSIZE == 4 + ALLOC_or_BOMB_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZnajSt11align_val_t, __builtin_vec_new_aligned ); + ALLOC_or_BOMB_ALIGNED(VG_Z_LIBCXX_SONAME, _ZnajSt11align_val_t, __builtin_vec_new_aligned ); + ALLOC_or_BOMB_ALIGNED(VG_Z_LIBC_SONAME, _ZnajSt11align_val_t, __builtin_vec_new_aligned ); + ALLOC_or_BOMB_ALIGNED(SO_SYN_MALLOC, _ZnajSt11align_val_t, __builtin_vec_new_aligned ); + #endif + // operator new[](unsigned long, std::align_val_t), GNU mangling + #if VG_WORDSIZE == 8 + ALLOC_or_BOMB_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZnamSt11align_val_t, __builtin_vec_new_aligned ); + ALLOC_or_BOMB_ALIGNED(VG_Z_LIBCXX_SONAME, _ZnamSt11align_val_t, __builtin_vec_new_aligned ); + ALLOC_or_BOMB_ALIGNED(VG_Z_LIBC_SONAME, _ZnamSt11align_val_t, __builtin_vec_new_aligned ); + ALLOC_or_BOMB_ALIGNED(SO_SYN_MALLOC, _ZnamSt11align_val_t, __builtin_vec_new_aligned ); + #endif + +#elif defined(VGO_darwin) + +#elif defined(VGO_solaris) + // operator new[](unsigned int, std::align_val_t), GNU mangling + #if VG_WORDSIZE == 4 + ALLOC_or_BOMB_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZnajSt11align_val_t, __builtin_vec_new_aligned ); + ALLOC_or_BOMB_ALIGNED(SO_SYN_MALLOC, _ZnajSt11align_val_t, __builtin_vec_new_aligned ); + #endif + // operator new[](unsigned long, std::align_val_t), GNU mangling + #if VG_WORDSIZE == 8 + ALLOC_or_BOMB_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZnamSt11align_val_t, __builtin_vec_new_aligned ); + ALLOC_or_BOMB_ALIGNED(VG_Z_STDCXX_SONAME, _ZnamSt11align_val_t, __builtin_vec_new_aligned ); + ALLOC_or_BOMB_ALIGNED(SO_SYN_MALLOC, _ZnamSt11align_val_t, __builtin_vec_new_aligned ); + #endif + +#endif + /*---------------------- new [] nothrow ----------------------*/ @@ -476,12 +647,14 @@ extern int *__errno_location (void) __attribute__((weak)); // operator new[](unsigned, std::nothrow_t const&), GNU mangling #if VG_WORDSIZE == 4 ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnajRKSt9nothrow_t, __builtin_vec_new ); + ALLOC_or_NULL(VG_Z_LIBCXX_SONAME, _ZnajRKSt9nothrow_t, __builtin_vec_new ); ALLOC_or_NULL(VG_Z_LIBC_SONAME, _ZnajRKSt9nothrow_t, __builtin_vec_new ); ALLOC_or_NULL(SO_SYN_MALLOC, _ZnajRKSt9nothrow_t, __builtin_vec_new ); #endif // operator new[](unsigned long, std::nothrow_t const&), GNU mangling #if VG_WORDSIZE == 8 ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnamRKSt9nothrow_t, __builtin_vec_new ); + ALLOC_or_NULL(VG_Z_LIBCXX_SONAME, _ZnamRKSt9nothrow_t, __builtin_vec_new ); ALLOC_or_NULL(VG_Z_LIBC_SONAME, _ZnamRKSt9nothrow_t, __builtin_vec_new ); ALLOC_or_NULL(SO_SYN_MALLOC, _ZnamRKSt9nothrow_t, __builtin_vec_new ); #endif @@ -512,6 +685,39 @@ extern int *__errno_location (void) __attribute__((weak)); #endif +/*----------------- C++17 new aligned [] nothrow -----------------*/ + +#if defined(VGO_linux) + // operator new[](unsigned int, std::align_val_t, std::nothrow_t const&), GNU mangling + #if VG_WORDSIZE == 4 + ALLOC_or_NULL_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZnajSt11align_val_tRKSt9nothrow_t, __builtin_vec_new_aligned ); + ALLOC_or_NULL_ALIGNED(VG_Z_LIBCXX_SONAME, _ZnajSt11align_val_tRKSt9nothrow_t, __builtin_vec_new_aligned ); + ALLOC_or_NULL_ALIGNED(VG_Z_LIBC_SONAME, _ZnajSt11align_val_tRKSt9nothrow_t, __builtin_vec_new_aligned ); + ALLOC_or_NULL_ALIGNED(SO_SYN_MALLOC, _ZnajSt11align_val_tRKSt9nothrow_t, __builtin_vec_new_aligned ); + #endif + // operator new[](unsigned long, std::align_val_t, std::nothrow_t const&), GNU mangling + #if VG_WORDSIZE == 8 + ALLOC_or_NULL_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZnamSt11align_val_tRKSt9nothrow_t, __builtin_vec_new_aligned ); + ALLOC_or_NULL_ALIGNED(VG_Z_LIBCXX_SONAME, _ZnamSt11align_val_tRKSt9nothrow_t, __builtin_vec_new_aligned ); + ALLOC_or_NULL_ALIGNED(VG_Z_LIBC_SONAME, _ZnamSt11align_val_tRKSt9nothrow_t, __builtin_vec_new_aligned ); + ALLOC_or_NULL_ALIGNED(SO_SYN_MALLOC, _ZnamSt11align_val_tRKSt9nothrow_t, __builtin_vec_new_aligned ); + #endif + +#elif defined(VGO_darwin) + +#elif defined(VGO_solaris) + // operator new[](unsigned int, std::align_val_t, std::nothrow_t const&), GNU mangling + #if VG_WORDSIZE == 4 + ALLOC_or_NULL_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZnajSt11align_val_tRKSt9nothrow_t, __builtin_vec_new_aligned ); + ALLOC_or_NULL_ALIGNED(SO_SYN_MALLOC, _ZnajSt11align_val_tRKSt9nothrow_t, __builtin_vec_new_aligned ); + #endif + // operator new[](unsigned long, std::align_val_t, std::nothrow_t const&), GNU mangling + #if VG_WORDSIZE == 8 + ALLOC_or_NULL_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZnamSt11align_val_tRKSt9nothrow_t, __builtin_vec_new_aligned ); + ALLOC_or_NULL_ALIGNED(SO_SYN_MALLOC, _ZnamSt11align_val_tRKSt9nothrow_t, __builtin_vec_new_aligned ); + #endif + +#endif /*---------------------- free ----------------------*/ @@ -592,15 +798,19 @@ extern int *__errno_location (void) __attribute__((weak)); FREE(VG_Z_LIBC_SONAME, __builtin_delete, __builtin_delete ); // operator delete(void*), GNU mangling FREE(VG_Z_LIBSTDCXX_SONAME, _ZdlPv, __builtin_delete ); + FREE(VG_Z_LIBCXX_SONAME, _ZdlPv, __builtin_delete ); FREE(VG_Z_LIBC_SONAME, _ZdlPv, __builtin_delete ); FREE(SO_SYN_MALLOC, _ZdlPv, __builtin_delete ); - // operator delete(void*, unsigned long), C++14, GNU mangling + // operator delete(void*, unsigned int), C++14, GNU mangling #if __SIZEOF_SIZE_T__ == 4 FREE(VG_Z_LIBSTDCXX_SONAME, _ZdlPvj, __builtin_delete ); + FREE(VG_Z_LIBCXX_SONAME, _ZdlPvj, __builtin_delete ); FREE(VG_Z_LIBC_SONAME, _ZdlPvj, __builtin_delete ); FREE(SO_SYN_MALLOC, _ZdlPvj, __builtin_delete ); + // operator delete(void*, unsigned long), C++14, GNU mangling #elif __SIZEOF_SIZE_T__ == 8 FREE(VG_Z_LIBSTDCXX_SONAME, _ZdlPvm, __builtin_delete ); + FREE(VG_Z_LIBCXX_SONAME, _ZdlPvm, __builtin_delete ); FREE(VG_Z_LIBC_SONAME, _ZdlPvm, __builtin_delete ); FREE(SO_SYN_MALLOC, _ZdlPvm, __builtin_delete ); #endif @@ -626,6 +836,50 @@ extern int *__errno_location (void) __attribute__((weak)); #endif +#endif + + /*------------------- C++17 delete aligned -------------------*/ + +#if defined(VGO_linux) + // operator delete(void*, std::align_val_t), GNU mangling + FREE(VG_Z_LIBSTDCXX_SONAME, _ZdlPvSt11align_val_t, __builtin_delete_aligned ); + FREE(VG_Z_LIBCXX_SONAME, _ZdlPvSt11align_val_t, __builtin_delete_aligned ); + FREE(VG_Z_LIBC_SONAME, _ZdlPvSt11align_val_t, __builtin_delete_aligned ); + FREE(SO_SYN_MALLOC, _ZdlPvSt11align_val_t, __builtin_delete_aligned ); + + // operator delete(void*, unsigned int, std::align_val_t), GNU mangling +#if __SIZEOF_SIZE_T__ == 4 + FREE(VG_Z_LIBSTDCXX_SONAME, _ZdlPvjSt11align_val_t, __builtin_delete_aligned ); + FREE(VG_Z_LIBCXX_SONAME, _ZdlPvjSt11align_val_t, __builtin_delete_aligned ); + FREE(VG_Z_LIBC_SONAME, _ZdlPvjSt11align_val_t, __builtin_delete_aligned ); + FREE(SO_SYN_MALLOC, _ZdlPvjSt11align_val_t, __builtin_delete_aligned ); + // operator delete(void*, unsigned long, std::align_val_t), GNU mangling +#elif __SIZEOF_SIZE_T__ == 8 + FREE(VG_Z_LIBSTDCXX_SONAME, _ZdlPvmSt11align_val_t, __builtin_delete_aligned ); + FREE(VG_Z_LIBCXX_SONAME, _ZdlPvmSt11align_val_t, __builtin_delete_aligned ); + FREE(VG_Z_LIBC_SONAME, _ZdlPvmSt11align_val_t, __builtin_delete_aligned ); + FREE(SO_SYN_MALLOC, _ZdlPvmSt11align_val_t, __builtin_delete_aligned ); +#endif + + +#elif defined(VGO_darwin) + +#elif defined(VGO_solaris) + + // operator delete(void*, std::align_val_t) + FREE(VG_Z_LIBSTDCXX_SONAME, _ZdlPvSt11align_val_t, __builtin_delete_aligned ); + FREE(SO_SYN_MALLOC, _ZdlPvSt11align_val_t, __builtin_delete_aligned ); + + // operator delete(void*, unsigned int, std::align_val_t) +#if __SIZEOF_SIZE_T__ == 4 + FREE(VG_Z_LIBSTDCXX_SONAME, _ZdlPvjSt11align_val_t, __builtin_delete_aligned ); + FREE(SO_SYN_MALLOC, _ZdlPvjSt11align_val_t, __builtin_delete_aligned ); + // operator delete(void*, unsigned long, std::align_val_t) + #elif __SIZEOF_SIZE_T__ == 8 + FREE(VG_Z_LIBSTDCXX_SONAME, _ZdlPvmSt11align_val_t, __builtin_delete_aligned ); + FREE(SO_SYN_MALLOC, _ZdlPvmSt11align_val_t, __builtin_delete_aligned ); +#endif + #endif /*---------------------- delete nothrow ----------------------*/ @@ -633,6 +887,7 @@ extern int *__errno_location (void) __attribute__((weak)); #if defined(VGO_linux) // operator delete(void*, std::nothrow_t const&), GNU mangling FREE(VG_Z_LIBSTDCXX_SONAME, _ZdlPvRKSt9nothrow_t, __builtin_delete ); + FREE(VG_Z_LIBCXX_SONAME, _ZdlPvRKSt9nothrow_t, __builtin_delete ); FREE(VG_Z_LIBC_SONAME, _ZdlPvRKSt9nothrow_t, __builtin_delete ); FREE(SO_SYN_MALLOC, _ZdlPvRKSt9nothrow_t, __builtin_delete ); @@ -646,6 +901,28 @@ extern int *__errno_location (void) __attribute__((weak)); FREE(VG_Z_LIBSTDCXX_SONAME, _ZdlPvRKSt9nothrow_t, __builtin_delete ); FREE(SO_SYN_MALLOC, _ZdlPvRKSt9nothrow_t, __builtin_delete ); +#endif + + /*---------------------- C++17 delete aligned nothrow ----------------------*/ + +#if defined(VGO_linux) + // operator delete(void*, std::align_val_t, std::nothrow_t const&), GNU mangling + FREE(VG_Z_LIBSTDCXX_SONAME, _ZdlPvSt11align_val_tRKSt9nothrow_t, __builtin_delete_aligned ); + FREE(VG_Z_LIBCXX_SONAME, _ZdlPvSt11align_val_tRKSt9nothrow_t, __builtin_delete_aligned ); + FREE(VG_Z_LIBC_SONAME, _ZdlPvSt11align_val_tRKSt9nothrow_t, __builtin_delete_aligned ); + FREE(SO_SYN_MALLOC, _ZdlPvSt11align_val_tRKSt9nothrow_t, __builtin_delete_aligned ); + + // no sized version of this operator + +#elif defined(VGO_darwin) + +#elif defined(VGO_solaris) + // operator delete(void*, std::align_val_t, std::nothrow_t const&), GNU mangling + FREE(VG_Z_LIBSTDCXX_SONAME, _ZdlPvSt11align_val_tRKSt9nothrow_t, __builtin_delete_aligned ); + FREE(SO_SYN_MALLOC, _ZdlPvSt11align_val_tRKSt9nothrow_t, __builtin_delete_aligned ); + + // no sized version of this operator + #endif @@ -657,17 +934,20 @@ extern int *__errno_location (void) __attribute__((weak)); FREE(VG_Z_LIBC_SONAME, __builtin_vec_delete, __builtin_vec_delete ); // operator delete[](void*), GNU mangling FREE(VG_Z_LIBSTDCXX_SONAME, _ZdaPv, __builtin_vec_delete ); + FREE(VG_Z_LIBCXX_SONAME, _ZdaPv, __builtin_vec_delete ); FREE(VG_Z_LIBC_SONAME, _ZdaPv, __builtin_vec_delete ); FREE(SO_SYN_MALLOC, _ZdaPv, __builtin_vec_delete ); // operator delete[](void*, unsigned long), C++14, GNU mangling #if __SIZEOF_SIZE_T__ == 4 FREE(VG_Z_LIBSTDCXX_SONAME, _ZdaPvj, __builtin_vec_delete ); + FREE(VG_Z_LIBCXX_SONAME, _ZdaPvj, __builtin_vec_delete ); FREE(VG_Z_LIBC_SONAME, _ZdaPvj, __builtin_vec_delete ); FREE(SO_SYN_MALLOC, _ZdaPvj, __builtin_vec_delete ); #elif __SIZEOF_SIZE_T__ == 8 FREE(VG_Z_LIBSTDCXX_SONAME, _ZdaPvm, __builtin_vec_delete ); + FREE(VG_Z_LIBCXX_SONAME, _ZdaPvm, __builtin_vec_delete ); FREE(VG_Z_LIBC_SONAME, _ZdaPvm, __builtin_vec_delete ); FREE(SO_SYN_MALLOC, _ZdaPvm, __builtin_vec_delete ); #endif @@ -685,10 +965,11 @@ extern int *__errno_location (void) __attribute__((weak)); FREE(VG_Z_LIBSTDCXX_SONAME, _ZdaPv, __builtin_vec_delete ); FREE(SO_SYN_MALLOC, _ZdaPv, __builtin_vec_delete ); - // operator delete[](void*, unsigned long), C++14, GNU mangling + // operator delete[](void*, unsigned int), C++14, GNU mangling #if __SIZEOF_SIZE_T__ == 4 FREE(VG_Z_LIBSTDCXX_SONAME, _ZdaPvj, __builtin_vec_delete ); FREE(SO_SYN_MALLOC, _ZdaPvj, __builtin_vec_delete ); + // operator delete[](void*, unsigned long), C++14, GNU mangling #elif __SIZEOF_SIZE_T__ == 8 FREE(VG_Z_LIBSTDCXX_SONAME, _ZdaPvm, __builtin_vec_delete ); FREE(SO_SYN_MALLOC, _ZdaPvm, __builtin_vec_delete ); @@ -696,12 +977,54 @@ extern int *__errno_location (void) __attribute__((weak)); #endif +/*---------------------- C++17 delete aligned [] ----------------------*/ + +#if defined(VGO_linux) + // operator delete[](void*, std::align_val_t), GNU mangling + FREE(VG_Z_LIBSTDCXX_SONAME, _ZdaPvSt11align_val_t, __builtin_vec_delete_aligned ); + FREE(VG_Z_LIBCXX_SONAME, _ZdaPvSt11align_val_t, __builtin_vec_delete_aligned ); + FREE(VG_Z_LIBC_SONAME, _ZdaPvSt11align_val_t, __builtin_vec_delete_aligned ); + FREE(SO_SYN_MALLOC, _ZdaPvSt11align_val_t, __builtin_vec_delete_aligned ); + + // operator delete[](void*, unsigned int, std::align_val_t), GNU mangling + #if __SIZEOF_SIZE_T__ == 4 + FREE(VG_Z_LIBSTDCXX_SONAME, _ZdaPvjSt11align_val_t, __builtin_vec_delete_aligned ); + FREE(VG_Z_LIBCXX_SONAME, _ZdaPvjSt11align_val_t, __builtin_vec_delete_aligned ); + FREE(VG_Z_LIBC_SONAME, _ZdaPvjSt11align_val_t, __builtin_vec_delete_aligned ); + FREE(SO_SYN_MALLOC, _ZdaPvjSt11align_val_t, __builtin_vec_delete_aligned ); + // operator delete[](void*, unsigned long, std::align_val_t), GNU mangling + #elif __SIZEOF_SIZE_T__ == 8 + FREE(VG_Z_LIBSTDCXX_SONAME, _ZdaPvmSt11align_val_t, __builtin_vec_delete_aligned ); + FREE(VG_Z_LIBCXX_SONAME, _ZdaPvmSt11align_val_t, __builtin_vec_delete_aligned ); + FREE(VG_Z_LIBC_SONAME, _ZdaPvmSt11align_val_t, __builtin_vec_delete_aligned ); + FREE(SO_SYN_MALLOC, _ZdaPvmSt11align_val_t, __builtin_vec_delete_aligned ); +#endif + +#elif defined(VGO_darwin) + +#elif defined(VGO_solaris) + // operator delete[](void*, std::align_val_t), GNU mangling + FREE(VG_Z_LIBSTDCXX_SONAME, _ZdaPvSt11align_val_t, __builtin_vec_delete_aligned ); + FREE(SO_SYN_MALLOC, _ZdaPvSt11align_val_t, __builtin_vec_delete_aligned ); + + // operator delete[](void*, unsigned int, std::align_val_t) + #if __SIZEOF_SIZE_T__ == 4 + FREE(VG_Z_LIBSTDCXX_SONAME, _ZdaPvjSt11align_val_t, __builtin_vec_delete_aligned ); + FREE(SO_SYN_MALLOC, _ZdaPvjSt11align_val_t, __builtin_vec_delete_aligned ); + // operator delete[](void*, unsigned long), GNU mangling + #elif __SIZEOF_SIZE_T__ == 8 + FREE(VG_Z_LIBSTDCXX_SONAME, _ZdaPvmSt11align_val_t, __builtin_vec_delete_aligned ); + FREE(SO_SYN_MALLOC, _ZdaPvmSt11align_val_t, __builtin_vec_delete_aligned ); +#endif + +#endif /*---------------------- delete [] nothrow ----------------------*/ #if defined(VGO_linux) // operator delete[](void*, std::nothrow_t const&), GNU mangling FREE(VG_Z_LIBSTDCXX_SONAME, _ZdaPvRKSt9nothrow_t, __builtin_vec_delete ); + FREE(VG_Z_LIBCXX_SONAME, _ZdaPvRKSt9nothrow_t, __builtin_vec_delete ); FREE(VG_Z_LIBC_SONAME, _ZdaPvRKSt9nothrow_t, __builtin_vec_delete ); FREE(SO_SYN_MALLOC, _ZdaPvRKSt9nothrow_t, __builtin_vec_delete ); @@ -715,6 +1038,28 @@ extern int *__errno_location (void) __attribute__((weak)); FREE(VG_Z_LIBSTDCXX_SONAME, _ZdaPvRKSt9nothrow_t, __builtin_vec_delete ); FREE(SO_SYN_MALLOC, _ZdaPvRKSt9nothrow_t, __builtin_vec_delete ); +#endif + + /*---------------------- C+17 delete aligned [] nothrow ----------------------*/ + +#if defined(VGO_linux) + // operator delete[](void*, std::align_val_t, std::nothrow_t const&), GNU mangling + FREE(VG_Z_LIBSTDCXX_SONAME, _ZdaPvSt11align_val_tRKSt9nothrow_t, __builtin_vec_delete_aligned ); + FREE(VG_Z_LIBCXX_SONAME, _ZdaPvSt11align_val_tRKSt9nothrow_t, __builtin_vec_delete_aligned ); + FREE(VG_Z_LIBC_SONAME, _ZdaPvSt11align_val_tRKSt9nothrow_t, __builtin_vec_delete_aligned ); + FREE(SO_SYN_MALLOC, _ZdaPvSt11align_val_tRKSt9nothrow_t, __builtin_vec_delete_aligned ); + + // no sized version of this operator + +#elif defined(VGO_darwin) + +#elif defined(VGO_solaris) + // operator delete[](void*, std::align_val_t, std::nothrow_t const&), GNU mangling + FREE(VG_Z_LIBSTDCXX_SONAME, _ZdaPvSt11align_val_tRKSt9nothrow_t, __builtin_vec_delete_aligned ); + FREE(SO_SYN_MALLOC, _ZdaPvSt11align_val_tRKSt9nothrow_t, __builtin_vec_delete_aligned ); + + // no sized version of this operator + #endif diff --git a/coregrind/m_scheduler/scheduler.c b/coregrind/m_scheduler/scheduler.c index dc22dca176..4420a22d71 100644 --- a/coregrind/m_scheduler/scheduler.c +++ b/coregrind/m_scheduler/scheduler.c @@ -2071,11 +2071,15 @@ void do_client_request ( ThreadId tid ) info->tl_realloc = VG_(tdict).tool_realloc; info->tl_memalign = VG_(tdict).tool_memalign; info->tl___builtin_new = VG_(tdict).tool___builtin_new; + info->tl___builtin_new_aligned = VG_(tdict).tool___builtin_new_aligned; info->tl___builtin_vec_new = VG_(tdict).tool___builtin_vec_new; + info->tl___builtin_vec_new_aligned = VG_(tdict).tool___builtin_vec_new_aligned; info->tl_free = VG_(tdict).tool_free; info->tl___builtin_delete = VG_(tdict).tool___builtin_delete; + info->tl___builtin_delete_aligned = VG_(tdict).tool___builtin_delete_aligned; info->tl___builtin_vec_delete = VG_(tdict).tool___builtin_vec_delete; - info->tl_malloc_usable_size = VG_(tdict).tool_malloc_usable_size; + info->tl___builtin_vec_delete_aligned = VG_(tdict).tool___builtin_vec_delete_aligned; + info->tl_malloc_usable_size = VG_(tdict).tool_malloc_usable_size; info->mallinfo = VG_(mallinfo); info->clo_trace_malloc = VG_(clo_trace_malloc); diff --git a/coregrind/m_tooliface.c b/coregrind/m_tooliface.c index cbafe47c52..0c33498dbc 100644 --- a/coregrind/m_tooliface.c +++ b/coregrind/m_tooliface.c @@ -336,12 +336,16 @@ void VG_(needs_info_location) ( void VG_(needs_malloc_replacement)( void* (*malloc) ( ThreadId, SizeT ), void* (*__builtin_new) ( ThreadId, SizeT ), + void* (*__builtin_new_aligned)( ThreadId, SizeT, SizeT ), void* (*__builtin_vec_new) ( ThreadId, SizeT ), + void* (*__builtin_vec_new_aligned)( ThreadId, SizeT, SizeT ), void* (*memalign) ( ThreadId, SizeT, SizeT ), void* (*calloc) ( ThreadId, SizeT, SizeT ), void (*free) ( ThreadId, void* ), void (*__builtin_delete) ( ThreadId, void* ), + void (*__builtin_delete_aligned) ( ThreadId, void*, SizeT ), void (*__builtin_vec_delete) ( ThreadId, void* ), + void (*__builtin_vec_delete_aligned) ( ThreadId, void*, SizeT ), void* (*realloc) ( ThreadId, void*, SizeT ), SizeT (*malloc_usable_size) ( ThreadId, void* ), SizeT client_malloc_redzone_szB @@ -350,12 +354,16 @@ void VG_(needs_malloc_replacement)( VG_(needs).malloc_replacement = True; VG_(tdict).tool_malloc = malloc; VG_(tdict).tool___builtin_new = __builtin_new; + VG_(tdict).tool___builtin_new_aligned = __builtin_new_aligned; VG_(tdict).tool___builtin_vec_new = __builtin_vec_new; + VG_(tdict).tool___builtin_vec_new_aligned = __builtin_vec_new_aligned; VG_(tdict).tool_memalign = memalign; VG_(tdict).tool_calloc = calloc; VG_(tdict).tool_free = free; VG_(tdict).tool___builtin_delete = __builtin_delete; + VG_(tdict).tool___builtin_delete_aligned = __builtin_delete_aligned; VG_(tdict).tool___builtin_vec_delete = __builtin_vec_delete; + VG_(tdict).tool___builtin_vec_delete_aligned = __builtin_vec_delete_aligned; VG_(tdict).tool_realloc = realloc; VG_(tdict).tool_malloc_usable_size = malloc_usable_size; VG_(tdict).tool_client_redzone_szB = client_malloc_redzone_szB; diff --git a/coregrind/pub_core_replacemalloc.h b/coregrind/pub_core_replacemalloc.h index d9408c2695..cbf7f8ecdd 100644 --- a/coregrind/pub_core_replacemalloc.h +++ b/coregrind/pub_core_replacemalloc.h @@ -41,12 +41,16 @@ struct vg_mallocfunc_info { void* (*tl_malloc) (ThreadId tid, SizeT n); void* (*tl___builtin_new) (ThreadId tid, SizeT n); + void* (*tl___builtin_new_aligned) (ThreadId tid, SizeT n, SizeT align); void* (*tl___builtin_vec_new) (ThreadId tid, SizeT n); + void* (*tl___builtin_vec_new_aligned) (ThreadId tid, SizeT n, SizeT align); void* (*tl_memalign) (ThreadId tid, SizeT align, SizeT n); void* (*tl_calloc) (ThreadId tid, SizeT nmemb, SizeT n); void (*tl_free) (ThreadId tid, void* p); void (*tl___builtin_delete) (ThreadId tid, void* p); + void (*tl___builtin_delete_aligned) (ThreadId tid, void* p, SizeT n); void (*tl___builtin_vec_delete)(ThreadId tid, void* p); + void (*tl___builtin_vec_delete_aligned)(ThreadId tid, void* p, SizeT n); void* (*tl_realloc) (ThreadId tid, void* p, SizeT size); SizeT (*tl_malloc_usable_size) (ThreadId tid, void* payload); void (*mallinfo) (ThreadId tid, struct vg_mallinfo* mi); diff --git a/coregrind/pub_core_tooliface.h b/coregrind/pub_core_tooliface.h index 5f75d49972..6b42cc07ec 100644 --- a/coregrind/pub_core_tooliface.h +++ b/coregrind/pub_core_tooliface.h @@ -159,12 +159,16 @@ typedef struct { // VG_(needs).malloc_replacement void* (*tool_malloc) (ThreadId, SizeT); void* (*tool___builtin_new) (ThreadId, SizeT); + void* (*tool___builtin_new_aligned) (ThreadId, SizeT, SizeT); void* (*tool___builtin_vec_new) (ThreadId, SizeT); + void* (*tool___builtin_vec_new_aligned) (ThreadId, SizeT, SizeT); void* (*tool_memalign) (ThreadId, SizeT, SizeT); void* (*tool_calloc) (ThreadId, SizeT, SizeT); void (*tool_free) (ThreadId, void*); void (*tool___builtin_delete) (ThreadId, void*); + void (*tool___builtin_delete_aligned) (ThreadId, void*, SizeT); void (*tool___builtin_vec_delete)(ThreadId, void*); + void (*tool___builtin_vec_delete_aligned)(ThreadId, void*, SizeT); void* (*tool_realloc) (ThreadId, void*, SizeT); SizeT (*tool_malloc_usable_size) (ThreadId, void*); SizeT tool_client_redzone_szB; diff --git a/dhat/dh_main.c b/dhat/dh_main.c index 90b1a965ac..69e6fb6d01 100644 --- a/dhat/dh_main.c +++ b/dhat/dh_main.c @@ -747,11 +747,21 @@ static void* dh___builtin_new ( ThreadId tid, SizeT szB ) return new_block( tid, NULL, szB, VG_(clo_alignment), /*is_zeroed*/False ); } +static void* dh___builtin_new_aligned ( ThreadId tid, SizeT szB, SizeT alignB ) +{ + return new_block( tid, NULL, szB, alignB, /*is_zeroed*/False ); +} + static void* dh___builtin_vec_new ( ThreadId tid, SizeT szB ) { return new_block( tid, NULL, szB, VG_(clo_alignment), /*is_zeroed*/False ); } +static void* dh___builtin_vec_new_aligned ( ThreadId tid, SizeT szB, SizeT alignB ) +{ + return new_block( tid, NULL, szB, alignB, /*is_zeroed*/False ); +} + static void* dh_calloc ( ThreadId tid, SizeT m, SizeT szB ) { return new_block( tid, NULL, m*szB, VG_(clo_alignment), /*is_zeroed*/True ); @@ -772,11 +782,21 @@ static void dh___builtin_delete ( ThreadId tid, void* p ) die_block(p); } +static void dh___builtin_delete_aligned ( ThreadId tid, void* p, SizeT align ) +{ + die_block(p); +} + static void dh___builtin_vec_delete ( ThreadId tid, void* p ) { die_block(p); } +static void dh___builtin_vec_delete_aligned ( ThreadId tid, void* p, SizeT align ) +{ + die_block(p); +} + static void* dh_realloc ( ThreadId tid, void* p_old, SizeT new_szB ) { if (p_old == NULL) { @@ -1774,12 +1794,16 @@ static void dh_pre_clo_init(void) // dh_expensive_sanity_check); VG_(needs_malloc_replacement)(dh_malloc, dh___builtin_new, + dh___builtin_new_aligned, dh___builtin_vec_new, + dh___builtin_vec_new_aligned, dh_memalign, dh_calloc, dh_free, dh___builtin_delete, + dh___builtin_delete_aligned, dh___builtin_vec_delete, + dh___builtin_vec_delete_aligned, dh_realloc, dh_malloc_usable_size, 0 ); diff --git a/drd/drd_malloc_wrappers.c b/drd/drd_malloc_wrappers.c index c8d293ccd7..991fb845a0 100644 --- a/drd/drd_malloc_wrappers.c +++ b/drd/drd_malloc_wrappers.c @@ -253,24 +253,48 @@ static void* drd___builtin_new(ThreadId tid, SizeT n) return new_block(tid, n, VG_(clo_alignment), /*is_zeroed*/False); } +/** Wrapper for __builtin_new_aligned(). */ +static void* drd___builtin_new_aligned(ThreadId tid, SizeT n, SizeT align) +{ + return new_block(tid, n, align, /*is_zeroed*/False); +} + /** Wrapper for __builtin_delete(). */ static void drd___builtin_delete(ThreadId tid, void* p) { handle_free(tid, p); } +/** Wrapper for __builtin_delete_aligned(). */ +static void drd___builtin_delete_aligned(ThreadId tid, void* p, SizeT align) +{ + handle_free(tid, p); +} + /** Wrapper for __builtin_vec_new(). */ static void* drd___builtin_vec_new(ThreadId tid, SizeT n) { return new_block(tid, n, VG_(clo_alignment), /*is_zeroed*/False); } +/** Wrapper for __builtin_vec_new_aligned(). */ +static void* drd___builtin_vec_new_aligned(ThreadId tid, SizeT n, SizeT align) +{ + return new_block(tid, n, align, /*is_zeroed*/False); +} + /** Wrapper for __builtin_vec_delete(). */ static void drd___builtin_vec_delete(ThreadId tid, void* p) { handle_free(tid, p); } +/** Wrapper for __builtin_vec_delete_aligned(). */ +static void drd___builtin_vec_delete_aligned(ThreadId tid, void* p, SizeT align) +{ + handle_free(tid, p); +} + /** * Wrapper for malloc_usable_size() / malloc_size(). This function takes * a pointer to a block allocated by `malloc' and returns the amount of space @@ -299,12 +323,16 @@ void DRD_(register_malloc_wrappers)(const StartUsingMem start_callback, VG_(needs_malloc_replacement)(drd_malloc, drd___builtin_new, + drd___builtin_new_aligned, drd___builtin_vec_new, + drd___builtin_vec_new_aligned, drd_memalign, drd_calloc, drd_free, drd___builtin_delete, + drd___builtin_delete_aligned, drd___builtin_vec_delete, + drd___builtin_vec_delete_aligned, drd_realloc, drd_malloc_usable_size, 0); diff --git a/helgrind/hg_main.c b/helgrind/hg_main.c index 26b0c5a123..490fc38fef 100644 --- a/helgrind/hg_main.c +++ b/helgrind/hg_main.c @@ -4237,11 +4237,21 @@ static void* hg_cli____builtin_new ( ThreadId tid, SizeT n ) { return handle_alloc ( tid, n, VG_(clo_alignment), /*is_zeroed*/False ); } +static void* hg_cli____builtin_new_aligned ( ThreadId tid, SizeT n, SizeT align ) { + if (((SSizeT)n) < 0) return NULL; + return handle_alloc ( tid, n, align, + /*is_zeroed*/False ); +} static void* hg_cli____builtin_vec_new ( ThreadId tid, SizeT n ) { if (((SSizeT)n) < 0) return NULL; return handle_alloc ( tid, n, VG_(clo_alignment), /*is_zeroed*/False ); } +static void* hg_cli____builtin_vec_new_aligned ( ThreadId tid, SizeT n, SizeT align ) { + if (((SSizeT)n) < 0) return NULL; + return handle_alloc ( tid, n, align, + /*is_zeroed*/False ); +} static void* hg_cli__memalign ( ThreadId tid, SizeT align, SizeT n ) { if (((SSizeT)n) < 0) return NULL; return handle_alloc ( tid, n, align, @@ -4294,10 +4304,15 @@ static void hg_cli__free ( ThreadId tid, void* p ) { static void hg_cli____builtin_delete ( ThreadId tid, void* p ) { handle_free(tid, p); } +static void hg_cli____builtin_delete_aligned ( ThreadId tid, void* p, SizeT align ) { + handle_free(tid, p); +} static void hg_cli____builtin_vec_delete ( ThreadId tid, void* p ) { handle_free(tid, p); } - +static void hg_cli____builtin_vec_delete_aligned ( ThreadId tid, void* p, SizeT align ) { + handle_free(tid, p); +} static void* hg_cli__realloc ( ThreadId tid, void* payloadV, SizeT new_size ) { @@ -6033,12 +6048,16 @@ static void hg_pre_clo_init ( void ) VG_(needs_malloc_replacement) (hg_cli__malloc, hg_cli____builtin_new, + hg_cli____builtin_new_aligned, hg_cli____builtin_vec_new, + hg_cli____builtin_vec_new_aligned, hg_cli__memalign, hg_cli__calloc, hg_cli__free, hg_cli____builtin_delete, + hg_cli____builtin_delete_aligned, hg_cli____builtin_vec_delete, + hg_cli____builtin_vec_delete_aligned, hg_cli__realloc, hg_cli_malloc_usable_size, HG_CLI__DEFAULT_MALLOC_REDZONE_SZB ); diff --git a/include/pub_tool_redir.h b/include/pub_tool_redir.h index 7c7a76b7dd..2e0365438e 100644 --- a/include/pub_tool_redir.h +++ b/include/pub_tool_redir.h @@ -274,6 +274,11 @@ // Valid on all platforms(?) #define VG_Z_LIBSTDCXX_SONAME libstdcZpZpZa // libstdc++* +/* --- Soname of the clang C++ library. --- */ + +#define VG_Z_LIBCXX_SONAME libcZpZpZa // libc++* + + /* --- Soname of the pthreads library. --- */ #if defined(VGO_linux) diff --git a/include/pub_tool_tooliface.h b/include/pub_tool_tooliface.h index 62c9969612..34e577fce6 100644 --- a/include/pub_tool_tooliface.h +++ b/include/pub_tool_tooliface.h @@ -474,12 +474,16 @@ extern void VG_(needs_var_info) ( void ); extern void VG_(needs_malloc_replacement)( void* (*pmalloc) ( ThreadId tid, SizeT n ), void* (*p__builtin_new) ( ThreadId tid, SizeT n ), + void* (*p__builtin_new_aligned)( ThreadId tid, SizeT n, SizeT align ), void* (*p__builtin_vec_new) ( ThreadId tid, SizeT n ), + void* (*p__builtin_vec_new_aligned)( ThreadId tid, SizeT n, SizeT align ), void* (*pmemalign) ( ThreadId tid, SizeT align, SizeT n ), void* (*pcalloc) ( ThreadId tid, SizeT nmemb, SizeT size1 ), void (*pfree) ( ThreadId tid, void* p ), void (*p__builtin_delete) ( ThreadId tid, void* p ), + void (*p__builtin_delete_aligned) ( ThreadId tid, void* p, SizeT align ), void (*p__builtin_vec_delete) ( ThreadId tid, void* p ), + void (*p__builtin_vec_delete_aligned) ( ThreadId tid, void* p, SizeT align ), void* (*prealloc) ( ThreadId tid, void* p, SizeT new_size ), SizeT (*pmalloc_usable_size) ( ThreadId tid, void* p), SizeT client_malloc_redzone_szB diff --git a/massif/ms_main.c b/massif/ms_main.c index f022621eac..1ebbe4f29f 100644 --- a/massif/ms_main.c +++ b/massif/ms_main.c @@ -1393,11 +1393,21 @@ static void* ms___builtin_new ( ThreadId tid, SizeT szB ) return alloc_and_record_block( tid, szB, VG_(clo_alignment), /*is_zeroed*/False ); } +static void* ms___builtin_new_aligned ( ThreadId tid, SizeT szB, SizeT alignB ) +{ + return alloc_and_record_block( tid, szB, alignB, /*is_zeroed*/False ); +} + static void* ms___builtin_vec_new ( ThreadId tid, SizeT szB ) { return alloc_and_record_block( tid, szB, VG_(clo_alignment), /*is_zeroed*/False ); } +static void* ms___builtin_vec_new_aligned ( ThreadId tid, SizeT szB, SizeT alignB ) +{ + return alloc_and_record_block( tid, szB, alignB, /*is_zeroed*/False ); +} + static void* ms_calloc ( ThreadId tid, SizeT m, SizeT szB ) { return alloc_and_record_block( tid, m*szB, VG_(clo_alignment), /*is_zeroed*/True ); @@ -1420,12 +1430,24 @@ static void ms___builtin_delete ( ThreadId tid, void* p ) VG_(cli_free)(p); } +static void ms___builtin_delete_aligned ( ThreadId tid, void* p, SizeT align ) +{ + unrecord_block(p, /*maybe_snapshot*/True, /*exclude_first_entry*/True); + VG_(cli_free)(p); +} + static void ms___builtin_vec_delete ( ThreadId tid, void* p ) { unrecord_block(p, /*maybe_snapshot*/True, /*exclude_first_entry*/True); VG_(cli_free)(p); } +static void ms___builtin_vec_delete_aligned ( ThreadId tid, void* p, SizeT align ) +{ + unrecord_block(p, /*maybe_snapshot*/True, /*exclude_first_entry*/True); + VG_(cli_free)(p); +} + static void* ms_realloc ( ThreadId tid, void* p_old, SizeT new_szB ) { return realloc_block(tid, p_old, new_szB); @@ -2110,12 +2132,16 @@ static void ms_pre_clo_init(void) VG_(needs_print_stats) (ms_print_stats); VG_(needs_malloc_replacement) (ms_malloc, ms___builtin_new, + ms___builtin_new_aligned, ms___builtin_vec_new, + ms___builtin_vec_new_aligned, ms_memalign, ms_calloc, ms_free, ms___builtin_delete, + ms___builtin_delete_aligned, ms___builtin_vec_delete, + ms___builtin_vec_delete_aligned, ms_realloc, ms_malloc_usable_size, 0 ); diff --git a/memcheck/mc_include.h b/memcheck/mc_include.h index 0abbee60de..035c2276cf 100644 --- a/memcheck/mc_include.h +++ b/memcheck/mc_include.h @@ -150,12 +150,16 @@ SizeT MC_(get_cmalloc_n_frees) ( void ); void* MC_(malloc) ( ThreadId tid, SizeT n ); void* MC_(__builtin_new) ( ThreadId tid, SizeT n ); +void* MC_(__builtin_new_aligned)( ThreadId tid, SizeT n, SizeT alignB ); void* MC_(__builtin_vec_new) ( ThreadId tid, SizeT n ); +void* MC_(__builtin_vec_new_aligned) ( ThreadId tid, SizeT n, SizeT alignB ); void* MC_(memalign) ( ThreadId tid, SizeT align, SizeT n ); void* MC_(calloc) ( ThreadId tid, SizeT nmemb, SizeT size1 ); void MC_(free) ( ThreadId tid, void* p ); void MC_(__builtin_delete) ( ThreadId tid, void* p ); +void MC_(__builtin_delete_aligned) ( ThreadId tid, void* p, SizeT alignB ); void MC_(__builtin_vec_delete) ( ThreadId tid, void* p ); +void MC_(__builtin_vec_delete_aligned) ( ThreadId tid, void* p, SizeT alignB ); void* MC_(realloc) ( ThreadId tid, void* p, SizeT new_size ); SizeT MC_(malloc_usable_size) ( ThreadId tid, void* p ); diff --git a/memcheck/mc_main.c b/memcheck/mc_main.c index 436ee46b4f..d268d7e52b 100644 --- a/memcheck/mc_main.c +++ b/memcheck/mc_main.c @@ -8127,12 +8127,16 @@ static void mc_pre_clo_init(void) VG_(needs_info_location) (MC_(pp_describe_addr)); VG_(needs_malloc_replacement) (MC_(malloc), MC_(__builtin_new), + MC_(__builtin_new_aligned), MC_(__builtin_vec_new), + MC_(__builtin_vec_new_aligned), MC_(memalign), MC_(calloc), MC_(free), MC_(__builtin_delete), + MC_(__builtin_delete_aligned), MC_(__builtin_vec_delete), + MC_(__builtin_vec_delete_aligned), MC_(realloc), MC_(malloc_usable_size), MC_MALLOC_DEFAULT_REDZONE_SZB ); diff --git a/memcheck/mc_malloc_wrappers.c b/memcheck/mc_malloc_wrappers.c index 3e1665e675..d6775bd1d3 100644 --- a/memcheck/mc_malloc_wrappers.c +++ b/memcheck/mc_malloc_wrappers.c @@ -417,6 +417,16 @@ void* MC_(__builtin_new) ( ThreadId tid, SizeT n ) } } +void* MC_(__builtin_new_aligned) ( ThreadId tid, SizeT n, SizeT alignB ) +{ + if (MC_(record_fishy_value_error)(tid, "__builtin_new_aligned", "size", n)) { + return NULL; + } else { + return MC_(new_block) ( tid, 0, n, alignB, + /*is_zeroed*/False, MC_AllocNew, MC_(malloc_list)); + } +} + void* MC_(__builtin_vec_new) ( ThreadId tid, SizeT n ) { if (MC_(record_fishy_value_error)(tid, "__builtin_vec_new", "size", n)) { @@ -427,6 +437,16 @@ void* MC_(__builtin_vec_new) ( ThreadId tid, SizeT n ) } } +void* MC_(__builtin_vec_new_aligned) ( ThreadId tid, SizeT n, SizeT alignB ) +{ + if (MC_(record_fishy_value_error)(tid, "__builtin_vec_new_aligned", "size", n)) { + return NULL; + } else { + return MC_(new_block) ( tid, 0, n, alignB, + /*is_zeroed*/False, MC_AllocNewVec, MC_(malloc_list)); + } +} + void* MC_(memalign) ( ThreadId tid, SizeT alignB, SizeT n ) { if (MC_(record_fishy_value_error)(tid, "memalign", "size", n)) { @@ -523,12 +543,26 @@ void MC_(__builtin_delete) ( ThreadId tid, void* p ) tid, (Addr)p, MC_(Malloc_Redzone_SzB), MC_AllocNew); } + +void MC_(__builtin_delete_aligned) ( ThreadId tid, void* p, SizeT alignB ) +{ + MC_(handle_free)( + tid, (Addr)p, MC_(Malloc_Redzone_SzB), MC_AllocNew); +} + void MC_(__builtin_vec_delete) ( ThreadId tid, void* p ) { MC_(handle_free)( tid, (Addr)p, MC_(Malloc_Redzone_SzB), MC_AllocNewVec); } +void MC_(__builtin_vec_delete_aligned) ( ThreadId tid, void* p, SizeT alignB ) +{ + MC_(handle_free)( + tid, (Addr)p, MC_(Malloc_Redzone_SzB), MC_AllocNewVec); +} + + void* MC_(realloc) ( ThreadId tid, void* p_old, SizeT new_szB ) { MC_Chunk* old_mc; diff --git a/memcheck/tests/Makefile.am b/memcheck/tests/Makefile.am index e24bcc24d9..38a087cdfc 100644 --- a/memcheck/tests/Makefile.am +++ b/memcheck/tests/Makefile.am @@ -70,7 +70,8 @@ dist_noinst_SCRIPTS = \ filter_varinfo3 \ filter_memcheck \ filter_overlaperror \ - filter_sized_delete + filter_malloc_free \ + filter_sized_delete noinst_HEADERS = leak.h @@ -123,6 +124,9 @@ EXTRA_DIST = \ custom_alloc.stderr.exp custom_alloc.vgtest \ custom_alloc.stderr.exp-s390x-mvc \ custom-overlap.stderr.exp custom-overlap.vgtest \ + cxx17_aligned_new.stderr.exp cxx17_aligned_new.vgtest \ + cxx17_aligned_new.stderr.exp_32 \ + cxx17_aligned_new.stdout.exp \ deep-backtrace.vgtest deep-backtrace.stderr.exp \ demangle.stderr.exp demangle.vgtest \ big_debuginfo_symbol.stderr.exp big_debuginfo_symbol.vgtest \ @@ -654,3 +658,9 @@ else endif xml1_CFLAGS = $(AM_CFLAGS) -D_GNU_SOURCE + +if HAVE_ALIGNED_CXX_ALLOC +check_PROGRAMS += cxx17_aligned_new +cxx17_aligned_new_SOURCES = cxx17_aligned_new.cpp +cxx17_aligned_new_CXXFLAGS = -std=c++17 +endif diff --git a/memcheck/tests/cxx17_aligned_new.cpp b/memcheck/tests/cxx17_aligned_new.cpp new file mode 100644 index 0000000000..ad5dae866b --- /dev/null +++ b/memcheck/tests/cxx17_aligned_new.cpp @@ -0,0 +1,48 @@ +#include +#include +#include + +class alignas(64) MyClass { +public: + int i; +}; + +class OrdinaryClass { +public: + int i; +}; + +int main() { + // unsized versions + MyClass* myClass = new MyClass; + operator delete(myClass, std::align_val_t(64U)); + + MyClass* myClass5 = new MyClass[5]; + operator delete [](myClass5, std::align_val_t(64U)); + + // sized versions + myClass = new MyClass(); + operator delete(myClass, 64U, std::align_val_t(64U)); + + myClass5 = new MyClass[5]; + operator delete [](myClass5, 320U, std::align_val_t(64U)); + + MyClass* myClassNt = new (std::nothrow) MyClass; + operator delete(myClassNt, std::align_val_t(64U), std::nothrow); + + MyClass* myClass5Nt = new (std::nothrow) MyClass[5]; + operator delete [](myClass5Nt, std::align_val_t(64U), std::nothrow); + + OrdinaryClass* oClass = new OrdinaryClass; + // this is a limitation, VG does not use enough bits + // to tell apart aligned and unaligned allocations + // so new/aligned delete is not a mismatch + operator delete(oClass, std::align_val_t(64U)); + oClass = new (std::nothrow) OrdinaryClass; + delete oClass; + oClass = new OrdinaryClass[5]; + delete [] oClass; + oClass = new (std::nothrow) OrdinaryClass[5]; + delete [] oClass; +} + diff --git a/memcheck/tests/cxx17_aligned_new.stderr.exp b/memcheck/tests/cxx17_aligned_new.stderr.exp new file mode 100644 index 0000000000..54659a4dba --- /dev/null +++ b/memcheck/tests/cxx17_aligned_new.stderr.exp @@ -0,0 +1,30 @@ + +_ZnwmSt11align_val_t(size 64, al 64) = 0x........ +_ZdlPvSt11align_val_t(0x........) +_ZnamSt11align_val_t(size 320, al 64) = 0x........ +_ZdaPvSt11align_val_t(0x........) +_ZnwmSt11align_val_t(size 64, al 64) = 0x........ +_ZdlPvmSt11align_val_t(0x........) +_ZnamSt11align_val_t(size 320, al 64) = 0x........ +_ZdaPvmSt11align_val_t(0x........) +_ZnwmSt11align_val_tRKSt9nothrow_t(size 64, al 64) = 0x........ +_ZdlPvSt11align_val_tRKSt9nothrow_t(0x........) +_ZnamSt11align_val_tRKSt9nothrow_t(size 320, al 64) = 0x........ +_ZdaPvSt11align_val_tRKSt9nothrow_t(0x........) +_Znwm(4) = 0x........ +_ZdlPvSt11align_val_t(0x........) +_ZnwmRKSt9nothrow_t(4) = 0x........ +_ZdlPvm(0x........) +_Znam(20) = 0x........ +_ZdaPv(0x........) +_ZnamRKSt9nothrow_t(20) = 0x........ +_ZdaPv(0x........) + +HEAP SUMMARY: + in use at exit: ... bytes in ... blocks + total heap usage: ... allocs, ... frees, ... bytes allocated + +For a detailed leak analysis, rerun with: --leak-check=full + +For lists of detected and suppressed errors, rerun with: -s +ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) diff --git a/memcheck/tests/cxx17_aligned_new.stderr.exp_32 b/memcheck/tests/cxx17_aligned_new.stderr.exp_32 new file mode 100644 index 0000000000..22fe31f50c --- /dev/null +++ b/memcheck/tests/cxx17_aligned_new.stderr.exp_32 @@ -0,0 +1,30 @@ + +_ZnwjSt11align_val_t(size 64, al 64) = 0x........ +_ZdlPvSt11align_val_t(0x........) +_ZnajSt11align_val_t(size 320, al 64) = 0x........ +_ZdaPvSt11align_val_t(0x........) +_ZnwjSt11align_val_t(size 64, al 64) = 0x........ +_ZdlPvjSt11align_val_t(0x........) +_ZnajSt11align_val_t(size 320, al 64) = 0x........ +_ZdaPvjSt11align_val_t(0x........) +_ZnwjSt11align_val_tRKSt9nothrow_t(size 64, al 64) = 0x........ +_ZdlPvSt11align_val_tRKSt9nothrow_t(0x........) +_ZnajSt11align_val_tRKSt9nothrow_t(size 320, al 64) = 0x........ +_ZdaPvSt11align_val_tRKSt9nothrow_t(0x........) +_Znwj(4) = 0x........ +_ZdlPvSt11align_val_t(0x........) +_ZnwjRKSt9nothrow_t(4) = 0x........ +_ZdlPvj(0x........) +_Znaj(20) = 0x........ +_ZdaPv(0x........) +_ZnajRKSt9nothrow_t(20) = 0x........ +_ZdaPv(0x........) + +HEAP SUMMARY: + in use at exit: ... bytes in ... blocks + total heap usage: ... allocs, ... frees, ... bytes allocated + +For a detailed leak analysis, rerun with: --leak-check=full + +For lists of detected and suppressed errors, rerun with: -s +ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) diff --git a/memcheck/tests/cxx17_aligned_new.stdout.exp b/memcheck/tests/cxx17_aligned_new.stdout.exp new file mode 100644 index 0000000000..e69de29bb2 diff --git a/memcheck/tests/cxx17_aligned_new.vgtest b/memcheck/tests/cxx17_aligned_new.vgtest new file mode 100644 index 0000000000..986bcc2c8b --- /dev/null +++ b/memcheck/tests/cxx17_aligned_new.vgtest @@ -0,0 +1,4 @@ +prog: cxx17_aligned_new +prereq: test -e ./cxx17_aligned_new +vgopts: --trace-malloc=yes --show-mismatched-frees=yes +stderr_filter: filter_malloc_free diff --git a/memcheck/tests/filter_malloc_free b/memcheck/tests/filter_malloc_free new file mode 100755 index 0000000000..0f43cf2e1d --- /dev/null +++ b/memcheck/tests/filter_malloc_free @@ -0,0 +1,6 @@ +#! /bin/sh + +./filter_stderr "$@" | +./filter_allocs | +sed -e '/^malloc/d;/^free/d' +