diff --git a/ChangeLog b/ChangeLog index 8155c7584..f2da11503 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2008-09-19 Christian Franke + + * aclocal.m4 (grub_CHECK_ENABLE_EXECUTE_STACK): New function. + * configure.ac: Call grub_CHECK_ENABLE_EXECUTE_STACK. + * include/grub/misc.h [NEED_ENABLE_EXECUTE_STACK]: + Export __enable_execute_stack() to modules. + * kern/misc.c [NEED_ENABLE_EXECUTE_STACK] (__enable_execute_stack): + New function. + 2008-09-09 Felix Zielcke * Makefile.in (RMKFILES): Add `i386.rmk' and `x86_64-efi.rmk'. diff --git a/aclocal.m4 b/aclocal.m4 index ee6c4db13..7be8d3b2f 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -379,6 +379,33 @@ dnl So use regparm 2 until a better test is found. [Catch gcc bug]) fi ]) + +dnl Check if the C compiler generates calls to `__enable_execute_stack()'. +AC_DEFUN(grub_CHECK_ENABLE_EXECUTE_STACK,[ +AC_MSG_CHECKING([whether `$CC' generates calls to `__enable_execute_stack()']) +AC_LANG_CONFTEST([[ +void f (int (*p) (void)); +void g (int i) +{ + int nestedfunc (void) { return i; } + f (nestedfunc); +} +]]) +if AC_TRY_COMMAND([${CC-cc} ${CFLAGS} -S conftest.c]) && test -s conftest.s; then + true +else + AC_MSG_ERROR([${CC-cc} failed to produce assembly code]) +fi +if grep __enable_execute_stack conftest.s >/dev/null 2>&1; then + AC_DEFINE([NEED_ENABLE_EXECUTE_STACK], 1, + [Define to 1 if GCC generates calls to __enable_execute_stack()]) + AC_MSG_RESULT([yes]) +else + AC_MSG_RESULT([no]) +fi +rm -f conftest* +]) + dnl Check if the C compiler supports `-fstack-protector'. AC_DEFUN(grub_CHECK_STACK_PROTECTOR,[ diff --git a/config.h.in b/config.h.in index 044e81ee9..dbd87d992 100644 --- a/config.h.in +++ b/config.h.in @@ -79,6 +79,9 @@ /* Define to 1 if you enable memory manager debugging. */ #undef MM_DEBUG +/* Define to 1 if GCC generates calls to __enable_execute_stack() */ +#undef NEED_ENABLE_EXECUTE_STACK + /* Catch gcc bug */ #undef NESTED_FUNC_ATTR diff --git a/configure b/configure index 818204d8e..6af424a27 100644 --- a/configure +++ b/configure @@ -6775,6 +6775,47 @@ fi # Compiler features. # +# Need __enable_execute_stack() for nested function trampolines? + +{ echo "$as_me:$LINENO: checking whether \`$CC' generates calls to \`__enable_execute_stack()'" >&5 +echo $ECHO_N "checking whether \`$CC' generates calls to \`__enable_execute_stack()'... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF + +void f (int (*p) (void)); +void g (int i) +{ + int nestedfunc (void) { return i; } + f (nestedfunc); +} + +_ACEOF +if { ac_try='${CC-cc} ${CFLAGS} -S conftest.c' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && test -s conftest.s; then + true +else + { { echo "$as_me:$LINENO: error: ${CC-cc} failed to produce assembly code" >&5 +echo "$as_me: error: ${CC-cc} failed to produce assembly code" >&2;} + { (exit 1); exit 1; }; } +fi +if grep __enable_execute_stack conftest.s >/dev/null 2>&1; then + +cat >>confdefs.h <<\_ACEOF +#define NEED_ENABLE_EXECUTE_STACK 1 +_ACEOF + + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi +rm -f conftest* + + # Smashing stack protector. # Smashing stack protector. diff --git a/configure.ac b/configure.ac index c36745413..2b0d1467f 100644 --- a/configure.ac +++ b/configure.ac @@ -305,6 +305,9 @@ fi # Compiler features. # +# Need __enable_execute_stack() for nested function trampolines? +grub_CHECK_ENABLE_EXECUTE_STACK + # Smashing stack protector. grub_CHECK_STACK_PROTECTOR # Need that, because some distributions ship compilers that include diff --git a/include/grub/misc.h b/include/grub/misc.h index 3d89a6080..15c18f534 100644 --- a/include/grub/misc.h +++ b/include/grub/misc.h @@ -82,6 +82,10 @@ grub_ssize_t EXPORT_FUNC(grub_utf8_to_ucs4) (grub_uint32_t *dest, grub_uint64_t EXPORT_FUNC(grub_divmod64) (grub_uint64_t n, grub_uint32_t d, grub_uint32_t *r); +#ifdef NEED_ENABLE_EXECUTE_STACK +void EXPORT_FUNC(__enable_execute_stack) (void *addr); +#endif + /* Inline functions. */ static inline unsigned int diff --git a/kern/misc.c b/kern/misc.c index bec6ebd33..635eb7227 100644 --- a/kern/misc.c +++ b/kern/misc.c @@ -1036,3 +1036,12 @@ grub_abort (void) } /* GCC emits references to abort(). */ void abort (void) __attribute__ ((alias ("grub_abort"))); + +#ifdef NEED_ENABLE_EXECUTE_STACK +/* Some gcc versions generate a call to this function + in trampolines for nested functions. */ +__enable_execute_stack (void *addr __attribute__ ((unused))) +{ +} +#endif +