This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Emit .note.GNU-stack section on linux arches which by default need executable stack
- From: Jakub Jelinek <jakub at redhat dot com>
- To: Richard Henderson <rth at redhat dot com>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Wed, 4 Jun 2003 08:38:46 +0200
- Subject: [PATCH] Emit .note.GNU-stack section on linux arches which by default need executable stack
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
Hi!
This patch emits a .note.GNU-stack non-SHF_ALLOC section on
linux targets which have stack executable by default.
If code uses trampolines, it sets SHF_EXECINSTR bit, otherwise
leaves it clear.
This information is then collected by recent GNU ld to compute
default stack permissions for the PT_GNU_STACK segment header
which tells the kernel whether an executable or library needs
executable stack or not (it can be overridden from the command
line).
Ok to commit?
2003-06-04 Jakub Jelinek <jakub@redhat.com>
* function.c (trampolines_created): New variable.
(expand_function_end): Set it when doing INITIALIZE_TRAMPOLINE.
* function.h (trampolines_created): Add.
* config/s390/linux.h (ASM_FILE_END): Define.
* config/alpha/linux-elf.h (ASM_FILE_END): Define.
* config/rs6000/linux.h (ASM_FILE_END): Define.
* config/rs6000/linux64.h (ASM_FILE_END): Define.
* config/sparc/linux.h (ASM_FILE_END): Define.
* config/sparc/linux64.h (ASM_FILE_END): Define.
* config/i386/i386.c (ix86_asm_file_end): Use SUBTARGET_FILE_END.
* config/i386/linux.h (SUBTARGET_FILE_END): Define.
* config/i386/linux64.h (SUBTARGET_FILE_END): Define.
--- gcc/function.c.jj 2003-05-31 15:38:26.000000000 -0400
+++ gcc/function.c 2003-06-03 19:05:24.000000000 -0400
@@ -129,6 +129,9 @@ int current_function_uses_only_leaf_regs
post-instantiation libcalls. */
int virtuals_instantiated;
+/* Nonzero if at least one trampoline has been created. */
+int trampolines_created;
+
/* Assign unique numbers to labels generated for profiling, debugging, etc. */
static GTY(()) int funcdef_no;
@@ -6959,6 +6962,7 @@ expand_function_end (filename, line, end
emit_block_move (blktramp, initial_trampoline,
GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
#endif
+ trampolines_created = 1;
INITIALIZE_TRAMPOLINE (tramp, XEXP (DECL_RTL (function), 0), context);
seq = get_insns ();
end_sequence ();
--- gcc/function.h.jj 2003-05-16 05:54:50.000000000 -0400
+++ gcc/function.h 2003-06-03 19:05:51.000000000 -0400
@@ -513,6 +513,9 @@ extern GTY(()) struct function *cfun;
/* Nonzero if we've already converted virtual regs to hard regs. */
extern int virtuals_instantiated;
+/* Nonzero if at least one trampoline has been created. */
+extern int trampolines_created;
+
/* For backward compatibility... eventually these should all go away. */
#define current_function_name (cfun->name)
#define current_function_pops_args (cfun->pops_args)
--- gcc/config/s390/linux.h.jj 2003-05-21 06:24:42.000000000 -0400
+++ gcc/config/s390/linux.h 2003-06-03 19:20:03.000000000 -0400
@@ -121,6 +121,12 @@ Boston, MA 02111-1307, USA. */
{ "link_arch31", LINK_ARCH31_SPEC }, \
{ "link_arch64", LINK_ARCH64_SPEC }, \
+#define ASM_FILE_END(FILE) \
+ do { \
+ named_section_flags (".note.GNU-stack", \
+ SECTION_DEBUG \
+ | (trampolines_created ? SECTION_CODE : 0)); \
+ } while (0)
/* Do code reading to identify a signal frame, and set the frame
state data appropriately. See unwind-dw2.c for the structs. */
--- gcc/config/alpha/linux-elf.h.jj 2003-05-16 05:55:32.000000000 -0400
+++ gcc/config/alpha/linux-elf.h 2003-06-03 19:24:21.000000000 -0400
@@ -41,3 +41,10 @@ Boston, MA 02111-1307, USA. */
#undef LIB_SPEC
#define LIB_SPEC \
"%{pthread:-lpthread} %{shared:-lc}%{!shared:%{profile:-lc_p}%{!profile:-lc}} "
+
+#define ASM_FILE_END(FILE) \
+ do { \
+ named_section_flags (".note.GNU-stack", \
+ SECTION_DEBUG \
+ | (trampolines_created ? SECTION_CODE : 0)); \
+ } while (0)
--- gcc/config/i386/linux.h.jj 2003-06-01 09:50:37.000000000 -0400
+++ gcc/config/i386/linux.h 2003-06-03 19:13:33.000000000 -0400
@@ -219,6 +219,13 @@ Boston, MA 02111-1307, USA. */
: "=d"(BASE))
#endif
+#define SUBTARGET_FILE_END(FILE) \
+ do { \
+ named_section_flags (".note.GNU-stack", \
+ SECTION_DEBUG \
+ | (trampolines_created ? SECTION_CODE : 0)); \
+ } while (0)
+
/* Do code reading to identify a signal frame, and set the frame
state data appropriately. See unwind-dw2.c for the structs. */
--- gcc/config/i386/linux64.h.jj 2003-06-03 05:03:11.000000000 -0400
+++ gcc/config/i386/linux64.h 2003-06-03 19:13:56.000000000 -0400
@@ -67,6 +67,13 @@ Boston, MA 02111-1307, USA. */
#define MULTILIB_DEFAULTS { "m64" }
+#define SUBTARGET_FILE_END(FILE) \
+ do { \
+ named_section_flags (".note.GNU-stack", \
+ SECTION_DEBUG \
+ | (trampolines_created ? SECTION_CODE : 0)); \
+ } while (0)
+
/* Do code reading to identify a signal frame, and set the frame
state data appropriately. See unwind-dw2.c for the structs.
Don't use this at all if inhibit_libc is used. */
--- gcc/config/i386/i386.c.jj 2003-05-26 17:04:25.000000000 -0400
+++ gcc/config/i386/i386.c 2003-06-03 19:14:27.000000000 -0400
@@ -4727,6 +4727,10 @@ ix86_asm_file_end (file)
output_asm_insn ("mov{l}\t{%1, %0|%0, %1}", xops);
output_asm_insn ("ret", xops);
}
+
+#ifdef SUBTARGET_FILE_END
+ SUBTARGET_FILE_END (file);
+#endif
}
/* Emit code for the SET_GOT patterns. */
--- gcc/config/rs6000/linux.h.jj 2003-06-01 09:50:37.000000000 -0400
+++ gcc/config/rs6000/linux.h 2003-06-03 19:16:46.000000000 -0400
@@ -78,6 +78,13 @@
#undef DRAFT_V4_STRUCT_RET
#define DRAFT_V4_STRUCT_RET 1
+#define ASM_FILE_END(FILE) \
+ do { \
+ named_section_flags (".note.GNU-stack", \
+ SECTION_DEBUG \
+ | (trampolines_created ? SECTION_CODE : 0)); \
+ } while (0)
+
/* Do code reading to identify a signal frame, and set the frame
state data appropriately. See unwind-dw2.c for the structs. */
--- gcc/config/rs6000/linux64.h.jj 2003-06-03 05:03:11.000000000 -0400
+++ gcc/config/rs6000/linux64.h 2003-06-03 19:19:23.000000000 -0400
@@ -411,3 +411,12 @@ while (0)
#undef ASM_PREFERRED_EH_DATA_FORMAT
#define ASM_PREFERRED_EH_DATA_FORMAT(CODE, GLOBAL) \
(((GLOBAL) ? DW_EH_PE_indirect : 0) | DW_EH_PE_pcrel | DW_EH_PE_udata8)
+
+#define ASM_FILE_END(FILE) \
+ do { \
+ if (! TARGET_64BIT) \
+ named_section_flags (".note.GNU-stack", \
+ SECTION_DEBUG \
+ | (trampolines_created ? SECTION_CODE : 0)); \
+ } while (0)
+
--- gcc/config/sparc/linux.h.jj 2003-06-03 05:03:11.000000000 -0400
+++ gcc/config/sparc/linux.h 2003-06-03 19:22:02.000000000 -0400
@@ -259,6 +259,13 @@ do { \
#undef CTORS_SECTION_ASM_OP
#undef DTORS_SECTION_ASM_OP
+#define ASM_FILE_END(FILE) \
+ do { \
+ named_section_flags (".note.GNU-stack", \
+ SECTION_DEBUG \
+ | (trampolines_created ? SECTION_CODE : 0)); \
+ } while (0)
+
/* Do code reading to identify a signal frame, and set the frame
state data appropriately. See unwind-dw2.c for the structs. */
--- gcc/config/sparc/linux64.h.jj 2003-06-03 05:03:11.000000000 -0400
+++ gcc/config/sparc/linux64.h 2003-06-03 19:22:47.000000000 -0400
@@ -324,6 +324,13 @@ do { \
#undef CTORS_SECTION_ASM_OP
#undef DTORS_SECTION_ASM_OP
+#define ASM_FILE_END(FILE) \
+ do { \
+ named_section_flags (".note.GNU-stack", \
+ SECTION_DEBUG \
+ | (trampolines_created ? SECTION_CODE : 0)); \
+ } while (0)
+
/* Do code reading to identify a signal frame, and set the frame
state data appropriately. See unwind-dw2.c for the structs. */
Jakub