aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/liblzma/check/crc32_fast.c9
-rw-r--r--src/liblzma/check/crc64_fast.c7
-rw-r--r--src/liblzma/check/crc_common.h25
3 files changed, 31 insertions, 10 deletions
diff --git a/src/liblzma/check/crc32_fast.c b/src/liblzma/check/crc32_fast.c
index 079051f1..719d696c 100644
--- a/src/liblzma/check/crc32_fast.c
+++ b/src/liblzma/check/crc32_fast.c
@@ -135,15 +135,12 @@ typedef uint32_t (*crc32_func_type)(
// 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
// regular function by the constructor or first call resolution methods.
-// The __no_profile_instrument_function__ attribute support is checked when
-// determining if ifunc can be used, so it is safe to use here.
-#ifdef CRC_USE_IFUNC
-__attribute__((__no_profile_instrument_function__))
-#endif
+// The funcion attributes are needed for safe IFUNC resolver usage with GCC.
+lzma_resolver_attributes
static crc32_func_type
crc32_resolve(void)
{
- return is_arch_extension_supported()
+ return is_arch_extension_supported()
? &crc32_arch_optimized : &crc32_generic;
}
diff --git a/src/liblzma/check/crc64_fast.c b/src/liblzma/check/crc64_fast.c
index 5728b45e..330a5016 100644
--- a/src/liblzma/check/crc64_fast.c
+++ b/src/liblzma/check/crc64_fast.c
@@ -98,13 +98,12 @@ typedef uint64_t (*crc64_func_type)(
# pragma GCC diagnostic ignored "-Wunused-function"
#endif
-#ifdef CRC_USE_IFUNC
-__attribute__((__no_profile_instrument_function__))
-#endif
+// The funcion attributes are needed for safe IFUNC resolver usage with GCC.
+lzma_resolver_attributes
static crc64_func_type
crc64_resolve(void)
{
- return is_arch_extension_supported()
+ return is_arch_extension_supported()
? &crc64_arch_optimized : &crc64_generic;
}
diff --git a/src/liblzma/check/crc_common.h b/src/liblzma/check/crc_common.h
index 856665db..5a86556f 100644
--- a/src/liblzma/check/crc_common.h
+++ b/src/liblzma/check/crc_common.h
@@ -128,6 +128,31 @@
# 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
// version is available.
#if !defined(CRC32_ARCH_OPTIMIZED) && !defined(CRC32_GENERIC)