]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
PowerPC64 doesn't need an executable stack and therefore doesn't need
authorRyan Arnold <ryanarn@etna.rchland.ibm.com>
Mon, 1 Nov 2010 20:38:51 +0000 (15:38 -0500)
committerRyan Arnold <ryanarn@etna.rchland.ibm.com>
Mon, 1 Nov 2010 20:38:51 +0000 (15:38 -0500)
PT_GNU_STACK to make the stack no-exec.  This change abstracts the stack
permissions settings into a macro defined in a header.

17 files changed:
ChangeLog
config.h.in
elf/Makefile
elf/dl-load.c
elf/dl-support.c
elf/rtld.c
sysdeps/generic/stackinfo.h
sysdeps/i386/stackinfo.h
sysdeps/ia64/stackinfo.h
sysdeps/powerpc/powerpc64/check-execstack.c [new file with mode: 0644]
sysdeps/powerpc/powerpc64/configure
sysdeps/powerpc/powerpc64/configure.in
sysdeps/powerpc/stackinfo.h
sysdeps/s390/stackinfo.h
sysdeps/sh/stackinfo.h
sysdeps/sparc/stackinfo.h
sysdeps/x86_64/stackinfo.h

index dd1cbecc0c15f245dfcc7acd32e39a0d5a54ad24..93f6ed4ec90b6549ea3fa56501076ecaedfd210e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,35 @@
+2010-10-26  Ryan S. Arnold  <rsa@us.ibm.com>
+
+       * config.h.in: Added HAVE_PPC64_PT_GNU_STACK which is set during a
+       configure test to determine whether the the $(CC) compiler defaults to
+       PT_GNU_STACK support for PPC64.
+       * elf/Makefile (($objpfx)check-execstac:): Replaced $(native-compile)
+       with an operation which does the same thing but searches sysdeps/ for
+       the testcase before settling on elf/check-execstack.c.  This allows
+       overriding in sysdeps/powerpc/powerpc64/check-execstack.c.
+       * elf/dl-load.c (_dl_map_object_from_fd): Replace PF_R|RF_W|PF_X with
+       _STACK_FLAGS, defined in stackinfo.h.
+       * elf/dl-support.c (_dl_stack_flags): Likewise.
+       * elf/rtld.c (_rtld_global): Likewise.
+       * sysdeps/generic/stackinfo.h: Define _STACK_FLAGS = PF_R|PF_W|PF_X.
+       Define _STACKINFO_H.
+       * sysdeps/i386/stackinfo.h: Include <sysdeps/generic/stackinfo.h> and
+       remove #define _STACKINFO_H.
+       * sysdeps/ia64/stackinfo.h: Likewise.
+       * sysdeps/s390/stackinfo.h: Likewise.
+       * sysdeps/sh/stackinfo.h: Likewise.
+       * sysdeps/sparc/stackinfo.h: Likewise.
+       * sysdeps/x86_64/stackinfo.h: Likewise.
+       * sysdeps/powerpc/stackinfo.h: Define _STACK_FLAGS as PF_R|PF_W, i.e.,
+       nonexecutable, on PowerPC64, but PF_R|PF_W|PF_X on PowerPC32.
+       * sysdeps/powerpc/powerpc64/check-execstack.c: New file which checks
+       the test executable to make sure it doesn't have PT_GNU_STACK set and
+       then checks the executable to see if the mapfile indicates that
+       the [stack] is nonexecutable.
+       * sysdeps/powerpc/powerpc64/configure: Regenerated.
+       * sysdeps/powerpc/powerpc64/configure.in: Added fragment to test for
+       PT_GNU_STACK default in the compiler.  It sets HAVE_PPC64_PT_GNU_STACK.
+
 2010-10-16  Jakub Jelinek  <jakub@redhat.com>
 
        [BZ #3268]
index 18bf01a38c227175d5795160009bdee7b1155a63..6cd3dc17439aace281c9f97acabfaa5402a77203 100644 (file)
 /* Define if your compiler defaults to -msecure-plt mode on ppc.  */
 #undef HAVE_PPC_SECURE_PLT
 
+/* Define if your compiler emits a PT_GNU_STACK header for ppc64.  */
+#undef HAVE_PPC64_PT_GNU_STACK
+
 /* Define if __stack_chk_guard canary should be randomized at program startup.  */
 #undef ENABLE_STACKGUARD_RANDOMIZE
 
index e600cc39827b11d58bdcb57b37df7f8aa4643461..50c46c6de2a2485f8d88685bac10bada55c61b88 100644 (file)
@@ -899,8 +899,13 @@ $(objpfx)check-textrel: check-textrel.c
        $(native-compile)
 
 check-execstack-CFLAGS = -O -Wall -D_XOPEN_SOURCE=600 -D_BSD_SOURCE -std=gnu99
+# Perform the same operation as $(native-compile) but search sysdeps/ for a
+# matching testcase file before settling for the testcase in elf/.
 $(objpfx)check-execstack: check-execstack.c
-       $(native-compile)
+       $(make-target-directory)
+       $(patsubst %/,cd % &&,$(objpfx)) \
+       $(BUILD_CC) $($(basename $(<F))-CFLAGS) $(ALL_BUILD_CFLAGS) \
+       $(firstword $(wildcard $(addsuffix /$<,$(addprefix $(shell pwd)/,$(sysdirs)) $(shell pwd)))) -o $(@F)
 
 check-localplt-CFLAGS = -O -Wall -D_GNU_SOURCE -std=gnu99
 $(objpfx)check-localplt: check-localplt.c
index 0adddf5aaa2008c5c2ee91fd4b96489605581baa..899973c24c58df40a0bf7fee931e098cbf17e770 100644 (file)
@@ -999,8 +999,10 @@ _dl_map_object_from_fd (const char *name, int fd, struct filebuf *fbp,
        }
     }
 
-  /* Presumed absent PT_GNU_STACK.  */
-  uint_fast16_t stack_flags = PF_R|PF_W|PF_X;
+  /* On most architectures presume that PT_GNU_STACK is absent and the stack is
+   * executable.  Other architectures default to a nonexecutable stack and don't
+   * need PT_GNU_STACK to do so.  */
+  uint_fast16_t stack_flags = _STACK_FLAGS;
 
   {
     /* Scan the program header table, collecting its load commands.  */
index f94d2c4c6e0e095755a53eed217a361b7b6e9806..0e2cccfecd13fcb82de2d5f6fbac0c0c7f8205cd 100644 (file)
@@ -32,6 +32,7 @@
 #include <dl-procinfo.h>
 #include <unsecvars.h>
 #include <hp-timing.h>
+#include <stackinfo.h>
 
 extern char *__progname;
 char **_dl_argv = &__progname; /* This is checked for some error messages.  */
@@ -134,8 +135,9 @@ uint64_t _dl_hwcap __attribute__ ((nocommon));
    setting _dl_hwcap nonzero below, but we do anyway.  */
 uint64_t _dl_hwcap_mask __attribute__ ((nocommon));
 
-/* Prevailing state of the stack, PF_X indicating it's executable.  */
-ElfW(Word) _dl_stack_flags = PF_R|PF_W|PF_X;
+/* Prevailing state of the stack.  Generally this includes PF_X, indicating it's
+ * executable but this isn't true for all architectures.  */
+ElfW(Word) _dl_stack_flags = _STACK_FLAGS;
 
 /* If loading a shared object requires that we make the stack executable
    when it was not, we do it by calling this function.
index d03aa04f33177238d6df62a856bcb591b69766d0..f03c6c00577fe234b60091d72d1e3237a82613ab 100644 (file)
@@ -40,6 +40,7 @@
 #include <dl-osinfo.h>
 #include <dl-procinfo.h>
 #include <tls.h>
+#include <stackinfo.h>
 
 #include <assert.h>
 
@@ -122,8 +123,9 @@ INTVARDEF(_dl_starting_up)
    (except those which cannot be added for some reason).  */
 struct rtld_global _rtld_global =
   {
-    /* Default presumption without further information is executable stack.  */
-    ._dl_stack_flags = PF_R|PF_W|PF_X,
+    /* Generally the default presumption without further information is an
+     * executable stack but this is not true on all architectures.  */
+    ._dl_stack_flags = _STACK_FLAGS,
 #ifdef _LIBC_REENTRANT
     ._dl_load_lock = _RTLD_LOCK_RECURSIVE_INITIALIZER,
     ._dl_load_write_lock = _RTLD_LOCK_RECURSIVE_INITIALIZER,
index 7c43801e6382a3327010efc1b65412ec99204bd2..af613f99b1061985bc303a4bc5d9b3e0959482bd 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1999 Free Software Foundation, Inc.
+/* Copyright (C) 1999, 2010 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    02111-1307 USA.  */
 
-/* This file contains a bit of information about the stack allocation
-   of the processor.  Since there is no general truth we can't say
-   anything here.  */
+/* This file contains generic information about the stack allocation.  */
+
+#ifndef _STACKINFO_H
+#define _STACKINFO_H   1
+#include <elf.h>
+
+/* Default to an executable stack.  PF_X can be overridden if PT_GNU_STACK is
+ * present, but it is presumed absent.  */
+#define _STACK_FLAGS   (PF_R|PF_W|PF_X)
+
+#endif /* stackinfo.h  */
index 2530ea72348d080b15976f5d54dfa8279f98600b..38fd1f1cfdf459fee3383ab1637c2bb03613d420 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1999, 2009 Free Software Foundation, Inc.
+/* Copyright (C) 1999, 2009, 2010 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -20,7 +20,9 @@
    of the processor.  */
 
 #ifndef _STACKINFO_H
-#define _STACKINFO_H   1
+
+/* Pick up the default definition for _STACK_FLAGS and define _STACKINFO_H.  */
+#include <sysdeps/generic/stackinfo.h>
 
 /* On x86 the stack grows down.  */
 #define _STACK_GROWS_DOWN      1
index b7dc5d91dde23ac6f5540a7d5ea04b7001966c66..4d3f827b01f67ec457fb4e65b7714387375cbb06 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001 Free Software Foundation, Inc.
+/* Copyright (C) 2001, 2010 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -20,7 +20,9 @@
    of the processor.  */
 
 #ifndef _STACKINFO_H
-#define _STACKINFO_H   1
+
+/* Pick up the default definition for _STACK_FLAGS and define _STACKINFO_H.  */
+#include <sysdeps/generic/stackinfo.h>
 
 /* On IA-64 the stack grows down.  The register stack is of no concern
    here.  */
diff --git a/sysdeps/powerpc/powerpc64/check-execstack.c b/sysdeps/powerpc/powerpc64/check-execstack.c
new file mode 100644 (file)
index 0000000..8194789
--- /dev/null
@@ -0,0 +1,195 @@
+/* Verify nonexecutable stack in test app when linked against GLIBC.
+   Copyright (C) 2010 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contribute by Ryan S. Arnold <rsa@us.ibm.com>. 2010.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#if defined HAVE_PPC64_PT_GNU_STACK
+
+/* If the compiler defaults to emitting PT_GNU_STACK for PPC64 then we should
+ * use the standard check-execstack.c test case which checks the shared objects
+ * generated by GLIBC for the GNU_STACK header.  */
+#include "../../../elf/check-execstack.c"
+
+#else
+
+/* The original test in elf/check-execstack.c supposedly checks for no-exec
+ * stack but what it really does is check if the compiler used to to build GLIBC
+ * creates a PT_GNU_STACK header in the elf info for each shared object.  The
+ * only way to check whether the stack is executable is to build and link an app
+ * with the recently built GLIBC and check the exec bits.  */
+
+#include <stdio.h>
+#include <byteswap.h>
+#include <elf.h>
+#include <endian.h>
+#include <linux/limits.h> /* Pick up PATH_MAX.  */
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <alloca.h>
+
+/* Macros taken from elf/check-execstack.c because it works.  */
+# define BITS 64
+# define E(name) _E (name, BITS)
+# define _E(name, bits) __E (name, bits)
+# define __E(name, bits) Elf##bits##_##name
+# define SWAP(val) \
+  ({ __typeof (val) __res;                                                   \
+     if (((ehdr.e_ident[EI_DATA] == ELFDATA2MSB                                      \
+          && BYTE_ORDER == LITTLE_ENDIAN)                                    \
+         || (ehdr.e_ident[EI_DATA] == ELFDATA2LSB                            \
+             && BYTE_ORDER == BIG_ENDIAN))                                   \
+        && sizeof (val) != 1)                                                \
+       {                                                                     \
+        if (sizeof (val) == 2)                                               \
+          __res = bswap_16 (val);                                            \
+        else if (sizeof (val) == 4)                                          \
+          __res = bswap_32 (val);                                            \
+        else                                                                 \
+          __res = bswap_64 (val);                                            \
+       }                                                                     \
+     else                                                                    \
+       __res = (val);                                                        \
+     __res; })
+
+/* Make sure this binary doesn't have PT_GNU_STACK set (which it shouldn't if
+ * the configure test which left HAVE_PPC64_PT_GNU_STACK unset was correct) and
+ * make sure that this test case didn't inherit PT_GNU_STACK, and that the stack
+ * defaults to non-executable anyway.  */
+
+int
+main (int argc, char *argv[])
+{
+
+  char *argv0 = argv[0]; /* testcase binary.  */
+  int fd = open (argv0, O_RDONLY);
+
+  if (fd == -1)
+    {
+      printf("Cannot open file image %s for reading.\n", argv0);
+    }
+
+  /* Read whats is supposed to be the ELF header.  Read the initial
+     bytes to determine whether this is a 32 or 64 bit file.  */
+  char ident[EI_NIDENT];
+  if (read (fd, ident, EI_NIDENT) != EI_NIDENT)
+    {
+    read_error:
+      printf("%s: read error\n", argv0);
+      close (fd);
+      return 1;
+    }
+
+  if (memcmp (&ident[EI_MAG0], ELFMAG, SELFMAG) != 0)
+    {
+      printf("%s: not an ELF file\n", argv0);
+      close (fd);
+      return 1;
+    }
+
+  /* Only operate on a 64-bit file.  */
+  if (ident[EI_CLASS] == ELFCLASS32)
+    {
+      printf("%s is not a 64-bit binary.\n",argv0);
+      close (fd);
+      return 1;
+  }
+
+  /* Now verify that this binary doesn't have a PT_GNU_STACK header.  */
+  E(Ehdr) ehdr;
+
+  if (pread (fd, &ehdr, sizeof (ehdr), 0) != sizeof (ehdr))
+    goto read_error;
+
+  const size_t phnum = SWAP (ehdr.e_phnum);
+  const size_t phentsize = SWAP (ehdr.e_phentsize);
+
+  /* Read the program header.  */
+  E(Phdr) *phdr = alloca (phentsize * phnum);
+  if (pread (fd, phdr, phentsize * phnum, SWAP (ehdr.e_phoff))
+      != phentsize * phnum)
+    goto read_error;
+
+  /* Search for an unwanted PT_GNU_STACK entry.  */
+  for (size_t cnt = 0; cnt < phnum; ++cnt)
+    if (SWAP (phdr[cnt].p_type) == PT_GNU_STACK)
+      {
+       printf("%s: Found unwanted PT_GNU_STACK header.\n", argv0);
+       close (fd);
+       return 1;
+      }
+
+  close(fd);
+
+  /* Now make sure the stack is marked non-executable by reading
+   * /proc/self/maps and looking for the memory permissions on the [stack]
+   * region.  */
+
+  FILE *mapfd = fopen ("/proc/self/maps", "r");
+  if (mapfd == NULL)
+    {
+      /* We don't have a solution for older systems that don't support
+       * /proc/self/maps.  Just return a false success since the situation is
+       * kind of ridiculous (really old kernel + glibc 2.13+).  */
+      printf("fopen of /proc/self/maps failed.\n");
+      return 0;
+    }
+
+  char line[PATH_MAX + 128];
+  const char delimiters[] = " ";
+  char *token;
+  const char stack[] = "[stack]";
+  while ((fgets(line, PATH_MAX + 128, mapfd)) != NULL)
+    {
+      char *perms = NULL;
+      int field = 0;
+      token = strtok(line,delimiters);
+      while(token != NULL) {
+       if (field == 1) /* The second field is the perms field.  */
+         perms = token; /* Save this until we find [stack].  */
+       if (field == 5) /* The sixth field is the pathname field.  */
+         {
+           /* If we find "[stack]" as the pathname check the permissions.  */
+           if (!strncmp(stack,token,strlen(stack)))
+             {
+               if (perms[2] == 'x')
+                 {
+                   printf("found executable stack for %s.\n", argv0);
+                   printf("%s %s %s\n",line,perms,token);
+                   fclose(mapfd);
+                   return 1;
+                 }
+               else
+                 {
+                   printf("found noexec stack in:\n");
+                   printf("%s %s %s\n",line,perms,token);
+                   fclose(mapfd);
+                   return 0;
+                 }
+             }
+           break;
+         }
+       token = strtok(NULL,delimiters);
+       field++;
+      }
+    }
+  printf("didn't find [stack] pathname for %s in /proc/self/maps.\n", argv0);
+  fclose(mapfd);
+  return 1;
+}
+#endif
index a9b6722c11953f83a5315a0954720afdf9d36001..8976d34ca0c61ef507b304407e586e80c51b22e5 100644 (file)
@@ -3,10 +3,10 @@
 
 # The Aix ld uses global .symbol_names instead of symbol_names
 # and unfortunately early Linux PPC64 linkers use it as well.
-{ $as_echo "$as_me:$LINENO: checking for support for omitting dot symbols" >&5
-$as_echo_n "checking for support for omitting dot symbols... " >&6; }
+{ echo "$as_me:$LINENO: checking for support for omitting dot symbols" >&5
+echo $ECHO_N "checking for support for omitting dot symbols... $ECHO_C" >&6; }
 if test "${libc_cv_omit_dot_syms+set}" = set; then
-  $as_echo_n "(cached) " >&6
+  echo $ECHO_N "(cached) $ECHO_C" >&6
 else
   libc_cv_omit_dot_syms=no
 echo 'void foo (void) {}' > conftest.c
@@ -14,7 +14,7 @@ if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS -S conftest.c -o conftest.s 1>&5'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
-  $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
   if grep -w '\.foo' conftest.s > /dev/null; then
     :
@@ -25,8 +25,8 @@ fi
 rm -f conftest.c conftest.s
 
 fi
-{ $as_echo "$as_me:$LINENO: result: $libc_cv_omit_dot_syms" >&5
-$as_echo "$libc_cv_omit_dot_syms" >&6; }
+{ echo "$as_me:$LINENO: result: $libc_cv_omit_dot_syms" >&5
+echo "${ECHO_T}$libc_cv_omit_dot_syms" >&6; }
 if test x$libc_cv_omit_dot_syms != xyes; then
   cat >>confdefs.h <<\_ACEOF
 #define HAVE_ASM_GLOBAL_DOT_NAME 1
@@ -34,10 +34,10 @@ _ACEOF
 
 fi
 
-{ $as_echo "$as_me:$LINENO: checking for linker support for overlapping .opd entries" >&5
-$as_echo_n "checking for linker support for overlapping .opd entries... " >&6; }
+{ echo "$as_me:$LINENO: checking for linker support for overlapping .opd entries" >&5
+echo $ECHO_N "checking for linker support for overlapping .opd entries... $ECHO_C" >&6; }
 if test "${libc_cv_overlapping_opd+set}" = set; then
-  $as_echo_n "(cached) " >&6
+  echo $ECHO_N "(cached) $ECHO_C" >&6
 else
   libc_cv_overlapping_opd=no
 echo 'void foo (void) {}' > conftest.c
@@ -45,7 +45,7 @@ if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS -S conftest.c -o conftest.s 1>&5'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
-  $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
   if grep '\.TOC\.@tocbase' conftest.s > /dev/null; then
     if grep '\.TOC\.@tocbase[  ]*,[    ]*0' conftest.s > /dev/null; then
@@ -58,11 +58,45 @@ fi
 rm -f conftest.c conftest.s
 
 fi
-{ $as_echo "$as_me:$LINENO: result: $libc_cv_overlapping_opd" >&5
-$as_echo "$libc_cv_overlapping_opd" >&6; }
+{ echo "$as_me:$LINENO: result: $libc_cv_overlapping_opd" >&5
+echo "${ECHO_T}$libc_cv_overlapping_opd" >&6; }
 if test x$libc_cv_overlapping_opd = xyes; then
   cat >>confdefs.h <<\_ACEOF
 #define USE_PPC64_OVERLAPPING_OPD 1
 _ACEOF
 
 fi
+
+# Some compilers have been configured to emit PT_GNU_STACK on PowerPC64 even
+# though this isn't necessary.  If it is present then which check-execstack is
+# tested should be changed.
+{ echo "$as_me:$LINENO: checking if PT_GNU_STACK ELF program header is emitted by the compiler on PowerPC64" >&5
+echo $ECHO_N "checking if PT_GNU_STACK ELF program header is emitted by the compiler on PowerPC64... $ECHO_C" >&6; }
+if test "${libc_cv_ppc64_pt_gnu_stack+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  echo 'int main (void) { return 0; }' > conftest.c
+libc_cv_ppc64_pt_gnu_stack=no
+  if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS -o conftest
+                    conftest.c 1>&5'
+  { (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); }; }
+  then
+    if readelf -l conftest | fgrep GNU_STACK > /dev/null; then
+      libc_cv_ppc64_pt_gnu_stack=yes
+    fi
+  fi
+  rm -f conftest*
+fi
+{ echo "$as_me:$LINENO: result: $libc_cv_ppc64_pt_gnu_stack" >&5
+echo "${ECHO_T}$libc_cv_ppc64_pt_gnu_stack" >&6; }
+#AC_SUBST(libc_cv_ppc64_pt_gnu_stack)
+if test $libc_cv_ppc64_pt_gnu_stack = yes; then
+  cat >>confdefs.h <<\_ACEOF
+#define HAVE_PPC64_PT_GNU_STACK 1
+_ACEOF
+
+fi
index 67aac663d8f1d0fa1c18ac2e4332b1b0fe23bbce..9c236adbc4a25eb0a4970baf159ffd3d156e25c1 100644 (file)
@@ -40,3 +40,22 @@ rm -f conftest.c conftest.s
 if test x$libc_cv_overlapping_opd = xyes; then
   AC_DEFINE(USE_PPC64_OVERLAPPING_OPD)
 fi
+
+# Some compilers have been configured to emit PT_GNU_STACK on PowerPC64 even
+# though this isn't necessary.  If it is present then which check-execstack is
+# tested should be changed.
+AC_CACHE_CHECK(if PT_GNU_STACK ELF program header is emitted by the compiler on PowerPC64, libc_cv_ppc64_pt_gnu_stack, [dnl
+echo 'int main (void) { return 0; }' > conftest.c
+libc_cv_ppc64_pt_gnu_stack=no
+  if AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS -o conftest
+                    conftest.c 1>&AS_MESSAGE_LOG_FD])
+  then
+    if readelf -l conftest | fgrep GNU_STACK > /dev/null; then
+      libc_cv_ppc64_pt_gnu_stack=yes
+    fi
+  fi
+  rm -f conftest*])
+#AC_SUBST(libc_cv_ppc64_pt_gnu_stack)
+if test $libc_cv_ppc64_pt_gnu_stack = yes; then
+  AC_DEFINE(HAVE_PPC64_PT_GNU_STACK)
+fi
index 839758a4e35afb062322402f8fcdf02e6a854c33..c46ec7cc52138733c018e78f0a8f2896c191cc4d 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1999 Free Software Foundation, Inc.
+/* Copyright (C) 1999, 2010 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
 /* On PPC the stack grows down.  */
 #define _STACK_GROWS_DOWN      1
 
+#if __WORDSIZE == 64
+/* PPC64 doesn't need an executable stack and doesn't need PT_GNU_STACK
+ * to make the stack nonexecutable.  */
+# define _STACK_FLAGS  (PF_R|PF_W)
+#else
+/* PF_X can be overridden if PT_GNU_STACK is present but is presumed absent.  */
+# define _STACK_FLAGS  (PF_R|PF_W|PF_X)
+#endif
+
 #endif /* stackinfo.h */
index 7e09c85b9b6cdf1393835783ce47a3870260aa6d..b41a6f487b8147ab706df657e99c8e1706fec583 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 Free Software Foundation, Inc.
+/* Copyright (C) 2000, 2010 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -20,7 +20,9 @@
    of the processor.  */
 
 #ifndef _STACKINFO_H
-#define _STACKINFO_H   1
+
+/* Pick up the default definition for _STACK_FLAGS and define _STACKINFO_H.  */
+#include <sysdeps/generic/stackinfo.h>
 
 /* On s390 the stack grows down.  */
 #define _STACK_GROWS_DOWN      1
index e65338f25643f057bf3627a0b8ad0af98a1ea5a6..4b0eb9599ddea265cf8e5103c40a60e58e31aae4 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001 Free Software Foundation, Inc.
+/* Copyright (C) 2001, 2010 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -20,7 +20,9 @@
    of the processor.  */
 
 #ifndef _STACKINFO_H
-#define _STACKINFO_H   1
+
+/* Pick up the default definition for _STACK_FLAGS and define _STACKINFO_H.  */
+#include <sysdeps/generic/stackinfo.h>
 
 /* On SH the stack grows down.  */
 #define _STACK_GROWS_DOWN      1
index fd34e2deb007b11f628c305a5eff1d669d24bcf8..5f02a2b04f3f9409033ae9856028377ab21a7209 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001 Free Software Foundation, Inc.
+/* Copyright (C) 2001, 2010 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -20,7 +20,9 @@
    of the processor.  */
 
 #ifndef _STACKINFO_H
-#define _STACKINFO_H   1
+
+/* Pick up the default definition for _STACK_FLAGS and define _STACKINFO_H.  */
+#include <sysdeps/generic/stackinfo.h>
 
 /* On sparc the stack grows down.  */
 #define _STACK_GROWS_DOWN      1
index b11849d9ab1ddcb39dde95cc55530eb64849fa48..3f090196582fefa87b0d9fb7cb6a353854bb8e61 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001, 2009 Free Software Foundation, Inc.
+/* Copyright (C) 2001, 2009, 2010 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -20,7 +20,9 @@
    of the processor.  */
 
 #ifndef _STACKINFO_H
-#define _STACKINFO_H   1
+
+/* Pick up the default definition for _STACK_FLAGS and define _STACKINFO_H.  */
+#include <sysdeps/generic/stackinfo.h>
 
 /* On x86_64 the stack grows down.  */
 #define _STACK_GROWS_DOWN      1