diff options
author | Ryan Arnold <ryanarn@etna.rchland.ibm.com> | 2010-11-01 15:38:51 -0500 |
---|---|---|
committer | Ryan Arnold <ryanarn@etna.rchland.ibm.com> | 2010-11-01 15:38:51 -0500 |
commit | ac02cf3af6f46706a29f21fc762f7099a7a546cc (patch) | |
tree | 24db7cec0b9a210d3c7c80716b295a35bd91e720 | |
parent | fbe0f55169e6ce50fd2eef1a84f64bbe7aa0592d (diff) | |
download | glibc-ac02cf3af6f46706a29f21fc762f7099a7a546cc.tar.gz glibc-ac02cf3af6f46706a29f21fc762f7099a7a546cc.tar.xz glibc-ac02cf3af6f46706a29f21fc762f7099a7a546cc.zip |
PowerPC64 doesn't need an executable stack and therefore doesn't need
PT_GNU_STACK to make the stack no-exec. This change abstracts the stack permissions settings into a macro defined in a header.
-rw-r--r-- | ChangeLog | 32 | ||||
-rw-r--r-- | config.h.in | 3 | ||||
-rw-r--r-- | elf/Makefile | 7 | ||||
-rw-r--r-- | elf/dl-load.c | 6 | ||||
-rw-r--r-- | elf/dl-support.c | 6 | ||||
-rw-r--r-- | elf/rtld.c | 6 | ||||
-rw-r--r-- | sysdeps/generic/stackinfo.h | 16 | ||||
-rw-r--r-- | sysdeps/i386/stackinfo.h | 6 | ||||
-rw-r--r-- | sysdeps/ia64/stackinfo.h | 6 | ||||
-rw-r--r-- | sysdeps/powerpc/powerpc64/check-execstack.c | 195 | ||||
-rw-r--r-- | sysdeps/powerpc/powerpc64/configure | 58 | ||||
-rw-r--r-- | sysdeps/powerpc/powerpc64/configure.in | 19 | ||||
-rw-r--r-- | sysdeps/powerpc/stackinfo.h | 11 | ||||
-rw-r--r-- | sysdeps/s390/stackinfo.h | 6 | ||||
-rw-r--r-- | sysdeps/sh/stackinfo.h | 6 | ||||
-rw-r--r-- | sysdeps/sparc/stackinfo.h | 6 | ||||
-rw-r--r-- | sysdeps/x86_64/stackinfo.h | 6 |
17 files changed, 359 insertions, 36 deletions
diff --git a/ChangeLog b/ChangeLog index dd1cbecc0c..93f6ed4ec9 100644 --- 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] diff --git a/config.h.in b/config.h.in index 18bf01a38c..6cd3dc1743 100644 --- a/config.h.in +++ b/config.h.in @@ -195,6 +195,9 @@ /* 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 diff --git a/elf/Makefile b/elf/Makefile index e600cc3982..50c46c6de2 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -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 diff --git a/elf/dl-load.c b/elf/dl-load.c index 0adddf5aaa..899973c24c 100644 --- a/elf/dl-load.c +++ b/elf/dl-load.c @@ -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. */ diff --git a/elf/dl-support.c b/elf/dl-support.c index f94d2c4c6e..0e2cccfecd 100644 --- a/elf/dl-support.c +++ b/elf/dl-support.c @@ -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. diff --git a/elf/rtld.c b/elf/rtld.c index d03aa04f33..f03c6c0057 100644 --- a/elf/rtld.c +++ b/elf/rtld.c @@ -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, diff --git a/sysdeps/generic/stackinfo.h b/sysdeps/generic/stackinfo.h index 7c43801e63..af613f99b1 100644 --- a/sysdeps/generic/stackinfo.h +++ b/sysdeps/generic/stackinfo.h @@ -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 @@ -16,6 +16,14 @@ 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 */ diff --git a/sysdeps/i386/stackinfo.h b/sysdeps/i386/stackinfo.h index 2530ea7234..38fd1f1cfd 100644 --- a/sysdeps/i386/stackinfo.h +++ b/sysdeps/i386/stackinfo.h @@ -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 diff --git a/sysdeps/ia64/stackinfo.h b/sysdeps/ia64/stackinfo.h index b7dc5d91dd..4d3f827b01 100644 --- a/sysdeps/ia64/stackinfo.h +++ b/sysdeps/ia64/stackinfo.h @@ -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 index 0000000000..81947894cc --- /dev/null +++ b/sysdeps/powerpc/powerpc64/check-execstack.c @@ -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 diff --git a/sysdeps/powerpc/powerpc64/configure b/sysdeps/powerpc/powerpc64/configure index a9b6722c11..8976d34ca0 100644 --- a/sysdeps/powerpc/powerpc64/configure +++ b/sysdeps/powerpc/powerpc64/configure @@ -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 diff --git a/sysdeps/powerpc/powerpc64/configure.in b/sysdeps/powerpc/powerpc64/configure.in index 67aac663d8..9c236adbc4 100644 --- a/sysdeps/powerpc/powerpc64/configure.in +++ b/sysdeps/powerpc/powerpc64/configure.in @@ -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 diff --git a/sysdeps/powerpc/stackinfo.h b/sysdeps/powerpc/stackinfo.h index 839758a4e3..c46ec7cc52 100644 --- a/sysdeps/powerpc/stackinfo.h +++ b/sysdeps/powerpc/stackinfo.h @@ -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 @@ -25,4 +25,13 @@ /* 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 */ diff --git a/sysdeps/s390/stackinfo.h b/sysdeps/s390/stackinfo.h index 7e09c85b9b..b41a6f487b 100644 --- a/sysdeps/s390/stackinfo.h +++ b/sysdeps/s390/stackinfo.h @@ -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 diff --git a/sysdeps/sh/stackinfo.h b/sysdeps/sh/stackinfo.h index e65338f256..4b0eb9599d 100644 --- a/sysdeps/sh/stackinfo.h +++ b/sysdeps/sh/stackinfo.h @@ -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 diff --git a/sysdeps/sparc/stackinfo.h b/sysdeps/sparc/stackinfo.h index fd34e2deb0..5f02a2b04f 100644 --- a/sysdeps/sparc/stackinfo.h +++ b/sysdeps/sparc/stackinfo.h @@ -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 diff --git a/sysdeps/x86_64/stackinfo.h b/sysdeps/x86_64/stackinfo.h index b11849d9ab..3f09019658 100644 --- a/sysdeps/x86_64/stackinfo.h +++ b/sysdeps/x86_64/stackinfo.h @@ -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 |