From aed6c8b994f256afee66146f7a4b4e003b7f7d5f Mon Sep 17 00:00:00 2001 From: Tommi Rantala Date: Thu, 30 Aug 2012 14:18:33 +0300 Subject: [PATCH] Check __builtin___clear_cache() at configuration time Fixup commit 39b83981 ("Flush icache with __builtin___clear_cache() in tests when compiling with GCC") to fix compilation with older GCC versions that do not provide __builtin___clear_cache(). --- configure.in | 11 +++++++++++ tests/Gtest-dyn1.c | 10 ++-------- tests/Makefile.am | 7 ++++--- tests/flush-cache.S | 6 +++++- tests/flush-cache.h | 38 ++++++++++++++++++++++++++++++++++++++ tests/ia64-test-dyn1.c | 10 ++-------- 6 files changed, 62 insertions(+), 20 deletions(-) create mode 100644 tests/flush-cache.h diff --git a/configure.in b/configure.in index 081cceea..f577bc71 100644 --- a/configure.in +++ b/configure.in @@ -277,6 +277,17 @@ if test x$intel_compiler = xyes; then AC_MSG_RESULT([$have_static_libcxa]) fi +AC_MSG_CHECKING([for __builtin___clear_cache]) +AC_LINK_IFELSE( + [AC_LANG_PROGRAM([[]], [[__builtin___clear_cache(0, 0)]])], + [have__builtin___clear_cache=yes], + [have__builtin___clear_cache=no]) +if test x$have__builtin___clear_cache = xyes; then + AC_DEFINE([HAVE__BUILTIN___CLEAR_CACHE], [1], + [Defined if __builtin___clear_cache() is available]) +fi +AC_MSG_RESULT([$have__builtin___clear_cache]) + CCASFLAGS="${CCASFLAGS} ${CPPFLAGS}" arch="$target_arch" diff --git a/tests/Gtest-dyn1.c b/tests/Gtest-dyn1.c index df2ab4a0..96eb7067 100644 --- a/tests/Gtest-dyn1.c +++ b/tests/Gtest-dyn1.c @@ -25,6 +25,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* This file tests dynamic code-generation via function-cloning. */ +#include "flush-cache.h" + #include #include #include @@ -86,10 +88,6 @@ struct fdesc # define get_gp(fdesc) (0) #endif -#ifndef __GNUC__ -extern void flush_cache (void *addr, size_t len); -#endif - void template (int i, template_t self, int (*printer)(const char *, ...), const char *fmt, const char **arr) @@ -187,11 +185,7 @@ main (int argc, char *argv[] __attribute__((unused))) mprotect ((void *) ((long) mem & ~(getpagesize () - 1)), 2*getpagesize(), PROT_READ | PROT_WRITE | PROT_EXEC); -#ifdef __GNUC__ - __builtin___clear_cache(mem, mem + MAX_FUNC_SIZE); -#else flush_cache (mem, MAX_FUNC_SIZE); -#endif signal (SIGSEGV, sighandler); diff --git a/tests/Makefile.am b/tests/Makefile.am index f4f6f3ed..987f22b1 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -101,15 +101,16 @@ Lia64_test_rbs_SOURCES = Lia64-test-rbs.c ia64-test-rbs-asm.S ia64-test-rbs.h Gia64_test_rbs_SOURCES = Gia64-test-rbs.c ia64-test-rbs-asm.S ia64-test-rbs.h Lia64_test_nat_SOURCES = Lia64-test-nat.c ia64-test-nat-asm.S Gia64_test_nat_SOURCES = Gia64-test-nat.c ia64-test-nat-asm.S -ia64_test_dyn1_SOURCES = ia64-test-dyn1.c ia64-dyn-asm.S flush-cache.S +ia64_test_dyn1_SOURCES = ia64-test-dyn1.c ia64-dyn-asm.S flush-cache.S \ + flush-cache.h ppc64_test_altivec_SOURCES = ppc64-test-altivec.c ppc64-test-altivec-utils.c ppc64_test_wchar_SOURCES = ppc64-test-wchar.c Gtest_init_SOURCES = Gtest-init.cxx Ltest_init_SOURCES = Ltest-init.cxx Ltest_cxx_exceptions_SOURCES = Ltest-cxx-exceptions.cxx -Gtest_dyn1_SOURCES = Gtest-dyn1.c flush-cache.S -Ltest_dyn1_SOURCES = Ltest-dyn1.c flush-cache.S +Gtest_dyn1_SOURCES = Gtest-dyn1.c flush-cache.S flush-cache.h +Ltest_dyn1_SOURCES = Ltest-dyn1.c flush-cache.S flush-cache.h test_static_link_SOURCES = test-static-link-loc.c test-static-link-gen.c test_static_link_LDFLAGS = -static forker_LDFLAGS = -static diff --git a/tests/flush-cache.S b/tests/flush-cache.S index f441a74c..6d514499 100644 --- a/tests/flush-cache.S +++ b/tests/flush-cache.S @@ -1,4 +1,8 @@ -#ifndef __GNUC__ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#ifndef HAVE__BUILTIN___CLEAR_CACHE #if defined(__ia64__) diff --git a/tests/flush-cache.h b/tests/flush-cache.h new file mode 100644 index 00000000..8227d85b --- /dev/null +++ b/tests/flush-cache.h @@ -0,0 +1,38 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2012 Tommi Rantala + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef FLUSH_CACHE_H +#define FLUSH_CACHE_H + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#ifdef HAVE__BUILTIN___CLEAR_CACHE +#define flush_cache(ADDR, LEN) \ + __builtin___clear_cache((ADDR), (ADDR) + (LEN)) +#else +#include +extern void flush_cache (void *addr, size_t len); +#endif + +#endif /* FLUSH_CACHE_H */ diff --git a/tests/ia64-test-dyn1.c b/tests/ia64-test-dyn1.c index 83319130..90127dd5 100644 --- a/tests/ia64-test-dyn1.c +++ b/tests/ia64-test-dyn1.c @@ -1,3 +1,5 @@ +#include "flush-cache.h" + #include #include #include @@ -20,10 +22,6 @@ int verbose; # define EXTRA 0 #endif -#ifndef __GNUC__ -extern void flush_cache (void *addr, size_t len); -#endif - int make_executable (void *addr, size_t len) { @@ -33,11 +31,7 @@ make_executable (void *addr, size_t len) perror ("mprotect"); return -1; } -#ifdef __GNUC__ - __builtin___clear_cache(addr, addr + len); -#else flush_cache (addr, len); -#endif return 0; }