diff --git a/aclocal.m4 b/aclocal.m4 index ee6c4db..7be8d3b 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/configure.ac b/configure.ac index c367454..2b0d146 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 3d89a60..15c18f5 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 bec6ebd..635eb72 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 +