aboutsummaryrefslogtreecommitdiff
blob: db76acb5928cea9357f290cd5ff514a93f75895d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
gcc/

2010-05-06	Magnus Granberg		<zorry@gentoo.org>, Kevin F. Quinn <kevquinn@gentoo.org>

		* builtins.c:  (expand_builtin_init_trampoline):	if warn_trampolines make a warning.
		* common.opt:	Add -Wtrampolines.
		* varasm.c:		(file_end_indicate_exec_stack): if warn_trampolines make a warning.

gcc/doc

2010-05-06	Magnus Granberg		<zorry@gentoo.org>

		* invoke.texi:	Add -Wtrampolines.

gcc/testsuite/

2010-05-06	Magnus Granberg		<zorry@gentoo.org>

		* gcc.dg/Wtrampolines.c:	New.

--- gcc/builtins.c.zorry	2010-04-13 15:47:11.000000000 +0200
+++ gcc/builtins.c			2010-06-16 12:33:54.000000000 +0200
@@ -5150,6 +5150,10 @@
   targetm.calls.trampoline_init (m_tramp, t_func, r_chain);
 
   trampolines_created = 1;
+
+  if (warn_trampolines)
+    warning (OPT_Wtrampolines, "trampoline generated for nested function %s", (IDENTIFIER_POINTER(DECL_NAME(t_func))));
+
   return const0_rtx;
 }
 
--- gcc/common.opt.zorry	2010-03-18 04:01:09.000000000 +0100
+++ gcc/common.opt			2010-05-06 00:44:18.000000000 +0200
@@ -192,6 +192,10 @@
 Common Var(warn_system_headers) Warning
 Do not suppress warnings from system headers
 
+Wtrampolines
+Common Var(warn_trampolines) Warnings
+Warn whenever a trampoline is generated and warn if it requires executable stack to
+
 Wtype-limits
 Common Var(warn_type_limits) Init(-1) Warning
 Warn if a comparison is always true or always false due to the limited range of the data type
--- gcc/varasm.c.zorry	2010-03-27 12:56:30.000000000 +0100
+++ gcc/varasm.c		2010-05-29 15:06:33.000000000 +0200
@@ -6768,7 +6768,11 @@
 {
   unsigned int flags = SECTION_DEBUG;
   if (trampolines_created)
+    {
     flags |= SECTION_CODE;
+    if (warn_trampolines)
+      warning (OPT_Wtrampolines, "setting the stack as executable stack");
+	 }
 
   switch_to_section (get_section (".note.GNU-stack", flags, NULL));
 }
--- gcc/doc/invoke.texi.zorry	2010-04-06 16:02:22.000000000 +0200
+++ gcc/doc/invoke.texi			2010-05-06 00:20:25.000000000 +0200
@@ -258,8 +258,8 @@
 -Wstrict-aliasing -Wstrict-aliasing=n @gol
 -Wstrict-overflow -Wstrict-overflow=@var{n} @gol
 -Wswitch  -Wswitch-default  -Wswitch-enum -Wsync-nand @gol
--Wsystem-headers  -Wtrigraphs  -Wtype-limits  -Wundef  -Wuninitialized @gol
--Wunknown-pragmas  -Wno-pragmas @gol
+-Wsystem-headers  -Wtrampolines  -Wtrigraphs  -Wtype-limits  -Wundef @gol
+-Wuninitialized  -Wunknown-pragmas  -Wno-pragmas @gol
 -Wunsuffixed-float-constants  -Wunused  -Wunused-function @gol
 -Wunused-label  -Wunused-parameter -Wno-unused-result -Wunused-value  -Wunused-variable @gol
 -Wvariadic-macros -Wvla @gol
@@ -3603,6 +3603,19 @@
 option will @emph{not} warn about unknown pragmas in system
 headers---for that, @option{-Wunknown-pragmas} must also be used.
 
+@item -Wtrampolines
+@opindex Wtrampolines
+@opindex Wno-trampolines
+ Warn about trampolines generated for pointers to nested functions.
+ Warn when the trampoline requires the stack to be made executable.
+ 
+ A trampoline is a small piece of data or code that is created at run
+ time on the stack when the address of a nested function is taken, and
+ is used to call the nested function indirectly.  For some targets, it
+ is made up of data only and thus requires no special treatment.  But,
+ for most targets, it is made up of code and thus requires the stack
+ to be made executable in order for the program to work properly.
+
 @item -Wfloat-equal
 @opindex Wfloat-equal
 @opindex Wno-float-equal
--- gcc/testsuite/gcc.dg/Wtrampolines.c.zorry	2010-05-05 12:53:11.000000000 +0200
+++ gcc/testsuite/gcc.dg/Wtrampolines.c			2010-05-06 00:26:05.000000000 +0200
@@ -0,0 +1,59 @@
+/* Origin: trampoline-1.c Waldek Hebisch <hebisch@math.uni.wroc.pl> */
+/* Ported to test -Wtrampolines Magnus Granberg <zorry@gentoo.org> */
+
+/* { dg-do compile } */
+/* { dg-require-effective-target trampolines } */
+/* { dg-options "-O2 -Wtrampolines" } */
+/* { dg-warning "trampoline" "" { target *-*-* } 31 } */
+/* { dg-prune-output "stack" } */
+
+#ifndef NO_TRAMPOLINES
+
+/* This used to fail on various versions of Solaris 2 because the
+   trampoline couldn't be made executable.  */
+
+extern void abort(void);
+extern double fabs(double);
+
+void foo (void)
+{
+  const int correct[1100] = {1, 0, -2, 0, 1, 0, 1, -1, -10, -30, -67};
+  int i;
+
+  double x1 (void) {return 1; }
+  double x2 (void) {return -1;}
+  double x3 (void) {return -1;}
+  double x4 (void) {return 1; }
+  double x5 (void) {return 0; }
+
+  typedef double pfun(void);
+
+  double a (int k, pfun x1, pfun x2, pfun x3, pfun x4, pfun x5)
+  {
+    double b (void)
+    {
+      k = k - 1;
+      return a (k, b, x1, x2, x3, x4 );
+    }
+
+    if (k <= 0)
+      return x4 () + x5 ();
+    else
+      return b ();
+  }
+
+  for (i=0; i<=10; i++)
+  {
+    if (fabs(a( i, x1, x2, x3, x4, x5 ) - correct [i]) > 0.1)
+      abort();
+  }
+}
+#endif
+
+int main (void)
+{
+#ifndef NO_TRAMPOLINES
+  foo ();
+#endif
+  return 0;
+}