From: Paul Floyd Date: Sat, 17 Feb 2024 10:56:32 +0000 (+0100) Subject: Bug 466762 - Add redirs for C23 free_sized() and free_aligned_sized() X-Git-Tag: VALGRIND_3_23_0~155 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=9903f2fe0b82b49467157adb6ac087bf49c1dead;p=thirdparty%2Fvalgrind.git Bug 466762 - Add redirs for C23 free_sized() and free_aligned_sized() No testcase for the moment - I still need to link with a non-system to be able to test --- diff --git a/NEWS b/NEWS index c7fe3df936..f0ec723c28 100644 --- a/NEWS +++ b/NEWS @@ -32,6 +32,7 @@ are not entered into bugzilla tend to get forgotten about or ignored. 437790 valgrind reports "Conditional jump or move depends on uninitialised value" in memchr of macOS 10.12-10.15 460616 disInstr(arm64): unhandled instruction 0x4E819402 (dotprod/ASIMDDP) +466762 Add redirs for C23 free_sized() and free_aligned_sized() 466884 Missing writev uninit padding suppression for _XSend 471036 disInstr_AMD64: disInstr miscalculated next %rip on RORX imm8, m32/64, r32/6 475498 Add reallocarray wrapper diff --git a/configure.ac b/configure.ac index 2aa11f29fd..858405ef67 100755 --- a/configure.ac +++ b/configure.ac @@ -4968,7 +4968,8 @@ AC_CHECK_FUNCS([ \ memrchr \ strndup \ close_range \ - wcsncpy + wcsncpy \ + free_aligned_sized ]) # AC_CHECK_LIB adds any library found to the variable LIBS, and links these @@ -5006,6 +5007,8 @@ AM_CONDITIONAL([HAVE_STRLCAT], [test x$ac_cv_func_strlcat = xyes]) AM_CONDITIONAL([HAVE_STRLCPY], [test x$ac_cv_func_strlcpy = xyes]) +AM_CONDITIONAL([HAVE_FREE_ALIGNED_SIZED], + [test x$ac_cv_func_free_aligned_sized = xyes]) if test x$VGCONF_PLATFORM_PRI_CAPS = xMIPS32_LINUX \ -o x$VGCONF_PLATFORM_PRI_CAPS = xMIPS64_LINUX \ diff --git a/coregrind/m_replacemalloc/vg_replace_malloc.c b/coregrind/m_replacemalloc/vg_replace_malloc.c index 1e6764aee9..c8f93bc42d 100644 --- a/coregrind/m_replacemalloc/vg_replace_malloc.c +++ b/coregrind/m_replacemalloc/vg_replace_malloc.c @@ -83,6 +83,8 @@ 10030 ALLOC_or_BOMB 10040 ZONEFREE 10050 FREE + 10051 FREE_SIZED + 10052 FREE_ALIGNED_SIZED 10060 ZONECALLOC 10070 CALLOC 10080 ZONEREALLOC @@ -1003,7 +1005,83 @@ extern int * __error(void) __attribute__((weak)); #endif + /*------------------- free_sized -------------------*/ + /* Generate a replacement for 'fnname' in object 'soname', which calls + 'vg_replacement' to free previously allocated memory. + */ + +#define FREE_SIZED(soname, fnname, vg_replacement, tag) \ + \ + void VG_REPLACE_FUNCTION_EZU(10051,soname,fnname) (void *p, SizeT size); \ + void VG_REPLACE_FUNCTION_EZU(10051,soname,fnname) (void *p, SizeT size) \ + { \ + struct AlignedAllocInfo aligned_alloc_info = { .size=size, .mem=p, .alloc_kind=AllocKind##tag }; \ + \ + DO_INIT; \ + TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED((UWord)size); \ + VERIFY_ALIGNMENT(&aligned_alloc_info); \ + MALLOC_TRACE(#fnname "(%p)\n", p ); \ + if (p == NULL) \ + return; \ + (void)VALGRIND_NON_SIMD_CALL1( info.tl_##vg_replacement, p ); \ + } + + +#if defined(VGO_linux) + FREE_SIZED(VG_Z_LIBC_SONAME, free_sized, free, FreeSized ); + FREE_SIZED(SO_SYN_MALLOC, free_sized, free, FreeSized ); + +#elif defined(VGO_freebsd) + FREE_SIZED(VG_Z_LIBC_SONAME, free_sized, free, FreeSized ); + FREE_SIZED(SO_SYN_MALLOC, free_sized, free, FreeSized ); + +#elif defined(VGO_darwin) + FREE_SIZED(VG_Z_LIBC_SONAME, free_sized, free, FreeSized ); + FREE_SIZED(SO_SYN_MALLOC, free_sized, free, FreeSized ); + +#elif defined(VGO_solaris) + FREE_SIZED(VG_Z_LIBC_SONAME, free_sized, free, FreeSized ); + FREE_SIZED(SO_SYN_MALLOC, free_sized, free, FreeSized ); + +#endif + + + /*--------------- free_aligned_sized ---------------*/ + + /* Generate a replacement for 'fnname' in object 'soname', which calls + 'vg_replacement' to free previously allocated memory. + */ + +#define FREE_ALIGNED_SIZED(soname, fnname, vg_replacement, tag) \ + \ + void VG_REPLACE_FUNCTION_EZU(10052,soname,fnname) (void *p, SizeT alignment, SizeT size); \ + void VG_REPLACE_FUNCTION_EZU(10052,soname,fnname) (void *p, SizeT alignment, SizeT size) \ + { \ + struct AlignedAllocInfo aligned_alloc_info = { .orig_alignment=alignment, .size=size, .mem=p, .alloc_kind=AllocKind##tag }; \ + \ + DO_INIT; \ + TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED((UWord)alignment); \ + TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED((UWord)size); \ + VERIFY_ALIGNMENT(&aligned_alloc_info); \ + MALLOC_TRACE(#fnname "(%p)\n", p ); \ + if (p == NULL) \ + return; \ + (void)VALGRIND_NON_SIMD_CALL1( info.tl_##vg_replacement, p ); \ + } + + +#if defined(VGO_linux) + +#elif defined(VGO_freebsd) + FREE_ALIGNED_SIZED(VG_Z_LIBC_SONAME, free_aligned_sized, free, FreeAlignedSized ); + FREE_ALIGNED_SIZED(SO_SYN_MALLOC, free_aligned_sized, free, FreeAlignedSized ); + +#elif defined(VGO_darwin) + +#elif defined(VGO_solaris) + +#endif /*---------------------- cfree ----------------------*/ // cfree diff --git a/include/pub_tool_replacemalloc.h b/include/pub_tool_replacemalloc.h index 4bddaa8943..914f9a823c 100644 --- a/include/pub_tool_replacemalloc.h +++ b/include/pub_tool_replacemalloc.h @@ -103,7 +103,9 @@ typedef enum { AllocKindDeleteAligned, AllocKindVecDeleteAligned, AllocKindDeleteSizedAligned, - AllocKindVecDeleteSizedAligned + AllocKindVecDeleteSizedAligned, + AllocKindFreeSized, + AllocKindFreeAlignedSized } AlignedAllocKind; struct AlignedAllocInfo { diff --git a/memcheck/mc_main.c b/memcheck/mc_main.c index ea5637e561..ba8ff34c52 100644 --- a/memcheck/mc_main.c +++ b/memcheck/mc_main.c @@ -7272,6 +7272,32 @@ static Bool mc_handle_client_request ( ThreadId tid, UWord* arg, UWord* ret ) MC_(record_size_mismatch_error) ( tid, mc, aligned_alloc_info->size, "new[][/delete[]" ); } break; + case AllocKindFreeSized: + mc = VG_(HT_lookup) ( MC_(malloc_list), (UWord)aligned_alloc_info->mem ); + if (mc && mc->szB != aligned_alloc_info->size) { + MC_(record_size_mismatch_error) ( tid, mc, aligned_alloc_info->size, "aligned_alloc/free_sized" ); + } + break; + case AllocKindFreeAlignedSized: + // same alignment checks as aligned_alloc + if ((aligned_alloc_info->orig_alignment & (aligned_alloc_info->orig_alignment - 1)) != 0) { + MC_(record_bad_alignment) ( tid, aligned_alloc_info->orig_alignment , 0U, " (should be a power of 2)" ); + } + if (aligned_alloc_info->orig_alignment && + aligned_alloc_info->size % aligned_alloc_info->orig_alignment != 0U) { + MC_(record_bad_alignment) ( tid, aligned_alloc_info->orig_alignment , aligned_alloc_info->size, " (size should be a multiple of alignment)" ); + } + if (aligned_alloc_info->size == 0) { + MC_(record_bad_size) ( tid, aligned_alloc_info->size, "free_aligned_sized()" ); + } + mc = VG_(HT_lookup) ( MC_(malloc_list), (UWord)aligned_alloc_info->mem ); + if (mc && aligned_alloc_info->orig_alignment != mc->alignB) { + MC_(record_align_mismatch_error) ( tid, mc, aligned_alloc_info->orig_alignment, False, "aligned_alloc/free_aligned_sized"); + } + if (mc && mc->szB != aligned_alloc_info->size) { + MC_(record_size_mismatch_error) ( tid, mc, aligned_alloc_info->size, "aligned_alloc/free_aligned_sized" ); + } + break; case AllocKindNewAligned: if (aligned_alloc_info->orig_alignment == 0 || (aligned_alloc_info->orig_alignment & (aligned_alloc_info->orig_alignment - 1)) != 0) {