mirror of https://git.tukaani.org/xz.git
liblzma: Fix false Valgrind error report with GCC.
With GCC and a certain combination of flags, Valgrind will falsely trigger an invalid write. This appears to be due to the omission of instructions to properly save, set up, and restore the frame pointer. The IFUNC resolver is a leaf function since it only calls a function that is inlined. So sometimes GCC omits the frame pointer instructions in the resolver unless this optimization is explictly disabled. This fixes https://bugzilla.redhat.com/show_bug.cgi?id=2267598.
This commit is contained in:
parent
6e97b299f1
commit
651a1545c8
|
@ -135,15 +135,12 @@ typedef uint32_t (*crc32_func_type)(
|
||||||
// This resolver is shared between all three dispatch methods. It serves as
|
// This resolver is shared between all three dispatch methods. It serves as
|
||||||
// the ifunc resolver if ifunc is supported, otherwise it is called as a
|
// the ifunc resolver if ifunc is supported, otherwise it is called as a
|
||||||
// regular function by the constructor or first call resolution methods.
|
// regular function by the constructor or first call resolution methods.
|
||||||
// The __no_profile_instrument_function__ attribute support is checked when
|
// The funcion attributes are needed for safe IFUNC resolver usage with GCC.
|
||||||
// determining if ifunc can be used, so it is safe to use here.
|
lzma_resolver_attributes
|
||||||
#ifdef CRC_USE_IFUNC
|
|
||||||
__attribute__((__no_profile_instrument_function__))
|
|
||||||
#endif
|
|
||||||
static crc32_func_type
|
static crc32_func_type
|
||||||
crc32_resolve(void)
|
crc32_resolve(void)
|
||||||
{
|
{
|
||||||
return is_arch_extension_supported()
|
return is_arch_extension_supported()
|
||||||
? &crc32_arch_optimized : &crc32_generic;
|
? &crc32_arch_optimized : &crc32_generic;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -98,13 +98,12 @@ typedef uint64_t (*crc64_func_type)(
|
||||||
# pragma GCC diagnostic ignored "-Wunused-function"
|
# pragma GCC diagnostic ignored "-Wunused-function"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CRC_USE_IFUNC
|
// The funcion attributes are needed for safe IFUNC resolver usage with GCC.
|
||||||
__attribute__((__no_profile_instrument_function__))
|
lzma_resolver_attributes
|
||||||
#endif
|
|
||||||
static crc64_func_type
|
static crc64_func_type
|
||||||
crc64_resolve(void)
|
crc64_resolve(void)
|
||||||
{
|
{
|
||||||
return is_arch_extension_supported()
|
return is_arch_extension_supported()
|
||||||
? &crc64_arch_optimized : &crc64_generic;
|
? &crc64_arch_optimized : &crc64_generic;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -128,6 +128,31 @@
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef CRC_USE_IFUNC
|
||||||
|
// Two function attributes are needed to make IFUNC safe with GCC.
|
||||||
|
//
|
||||||
|
// no-omit-frame-pointer prevents false Valgrind issues when combined with
|
||||||
|
// a few other compiler flags. The optimize attribute is supported on
|
||||||
|
// GCC >= 4.4 and is not supported with Clang.
|
||||||
|
# if TUKLIB_GNUC_REQ(4,4) && !defined(__clang__)
|
||||||
|
# define no_omit_frame_pointer \
|
||||||
|
__attribute__((optimize("no-omit-frame-pointer")))
|
||||||
|
# else
|
||||||
|
# define no_omit_frame_pointer
|
||||||
|
# endif
|
||||||
|
|
||||||
|
// The __no_profile_instrument_function__ attribute support is checked when
|
||||||
|
// determining if ifunc can be used, so it is safe to use unconditionally.
|
||||||
|
// This attribute is needed because GCC can add profiling to the IFUNC
|
||||||
|
// resolver, which calls functions that have not yet been relocated leading
|
||||||
|
// to a crash on liblzma start up.
|
||||||
|
# define lzma_resolver_attributes \
|
||||||
|
__attribute__((__no_profile_instrument_function__)) \
|
||||||
|
no_omit_frame_pointer
|
||||||
|
#else
|
||||||
|
# define lzma_resolver_attributes
|
||||||
|
#endif
|
||||||
|
|
||||||
// For CRC32 use the generic slice-by-eight implementation if no optimized
|
// For CRC32 use the generic slice-by-eight implementation if no optimized
|
||||||
// version is available.
|
// version is available.
|
||||||
#if !defined(CRC32_ARCH_OPTIMIZED) && !defined(CRC32_GENERIC)
|
#if !defined(CRC32_ARCH_OPTIMIZED) && !defined(CRC32_GENERIC)
|
||||||
|
|
Loading…
Reference in New Issue