aboutsummaryrefslogtreecommitdiffstats
path: root/community/gcc6/0013-i386-Don-t-generate-alias-for-function-return-thunk.patch
blob: d846ac77d9f7bf9de3b4a66becec7cc342eec06e (plain) (blame)
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
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
From e7fbaebc8ff650df76f43e92cb9ca59d5174ebe7 Mon Sep 17 00:00:00 2001
From: hjl <hjl@138bc75d-0d04-0410-961f-82ee72b054a4>
Date: Thu, 15 Mar 2018 17:54:40 +0000
Subject: [PATCH 13/13] i386: Don't generate alias for function return thunk

Function return thunks shouldn't be aliased to indirect branch thunks
since indirect branch thunks are placed in COMDAT section and a COMDAT
section with indirect branch may not have function return thunk.  This
patch generates function return thunks directly.

gcc/

	Backport from mainline
	PR target/84574
	* config/i386/i386.c (indirect_thunk_needed): Update comments.
	(indirect_thunk_bnd_needed): Likewise.
	(indirect_thunks_used): Likewise.
	(indirect_thunks_bnd_used): Likewise.
	(indirect_return_needed): New.
	(indirect_return_bnd_needed): Likewise.
	(output_indirect_thunk_function): Add a bool argument for
	function return.
	(output_indirect_thunk_function): Don't generate alias for
	function return thunk.
	(ix86_code_end): Call output_indirect_thunk_function to generate
	function return thunks.
	(ix86_output_function_return): Set indirect_return_bnd_needed
	and indirect_return_needed instead of indirect_thunk_bnd_needed
	and indirect_thunk_needed.

gcc/testsuite/

	Backport from mainline
	PR target/84574
	* gcc.target/i386/ret-thunk-9.c: Expect __x86_return_thunk
	label instead of __x86_indirect_thunk label.
---
 gcc/config/i386/i386.c                      | 92 ++++++++++-------------------
 gcc/testsuite/gcc.target/i386/ret-thunk-9.c |  2 +-
 2 files changed, 33 insertions(+), 61 deletions(-)

diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 21c3c18bd3c..f4cd1c6f4e9 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -11067,19 +11067,23 @@ ix86_setup_frame_addresses (void)
    labels in call and return thunks.  */
 static int indirectlabelno;
 
-/* True if call and return thunk functions are needed.  */
+/* True if call thunk function is needed.  */
 static bool indirect_thunk_needed = false;
-/* True if call and return thunk functions with the BND prefix are
-   needed.  */
+/* True if call thunk function with the BND prefix is needed.  */
 static bool indirect_thunk_bnd_needed = false;
 
 /* Bit masks of integer registers, which contain branch target, used
-   by call and return thunks functions.  */
+   by call thunk functions.  */
 static int indirect_thunks_used;
 /* Bit masks of integer registers, which contain branch target, used
-   by call and return thunks functions with the BND prefix.  */
+   by call thunk functions with the BND prefix.  */
 static int indirect_thunks_bnd_used;
 
+/* True if return thunk function is needed.  */
+static bool indirect_return_needed = false;
+/* True if return thunk function with the BND prefix is needed.  */
+static bool indirect_return_bnd_needed = false;
+
 /* True if return thunk function via CX is needed.  */
 static bool indirect_return_via_cx;
 /* True if return thunk function via CX with the BND prefix is
@@ -11226,16 +11230,18 @@ output_indirect_thunk (bool need_bnd_p, unsigned int regno)
 /* Output a funtion with a call and return thunk for indirect branch.
    If BND_P is true, the BND prefix is needed.  If REGNO != INVALID_REGNUM,
    the function address is in REGNO.  Otherwise, the function address is
-   on the top of stack.  */
+   on the top of stack.  Thunk is used for function return if RET_P is
+   true.  */
 
 static void
-output_indirect_thunk_function (bool need_bnd_p, unsigned int regno)
+output_indirect_thunk_function (bool need_bnd_p, unsigned int regno,
+				bool ret_p)
 {
   char name[32];
   tree decl;
 
   /* Create __x86_indirect_thunk/__x86_indirect_thunk_bnd.  */
-  indirect_thunk_name (name, regno, need_bnd_p, false);
+  indirect_thunk_name (name, regno, need_bnd_p, ret_p);
   decl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL,
 		     get_identifier (name),
 		     build_function_type_list (void_type_node, NULL_TREE));
@@ -11278,50 +11284,6 @@ output_indirect_thunk_function (bool need_bnd_p, unsigned int regno)
 	ASM_OUTPUT_LABEL (asm_out_file, name);
       }
 
-  /* Create alias for __x86_return_thunk/__x86_return_thunk_bnd or
-     __x86_return_thunk_ecx/__x86_return_thunk_ecx_bnd.  */
-  bool need_alias;
-  if (regno == INVALID_REGNUM)
-    need_alias = true;
-  else if (regno == CX_REG)
-    {
-      if (need_bnd_p)
-	need_alias = indirect_return_via_cx_bnd;
-      else
-	need_alias = indirect_return_via_cx;
-    }
-  else
-    need_alias = false;
-
-  if (need_alias)
-    {
-      char alias[32];
-
-      indirect_thunk_name (alias, regno, need_bnd_p, true);
-#if TARGET_MACHO
-      if (TARGET_MACHO)
-	{
-	  fputs ("\t.weak_definition\t", asm_out_file);
-	  assemble_name (asm_out_file, alias);
-	  fputs ("\n\t.private_extern\t", asm_out_file);
-	  assemble_name (asm_out_file, alias);
-	  putc ('\n', asm_out_file);
-	  ASM_OUTPUT_LABEL (asm_out_file, alias);
-	}
-#else
-      ASM_OUTPUT_DEF (asm_out_file, alias, name);
-      if (USE_HIDDEN_LINKONCE)
-	{
-	  fputs ("\t.globl\t", asm_out_file);
-	  assemble_name (asm_out_file, alias);
-	  putc ('\n', asm_out_file);
-	  fputs ("\t.hidden\t", asm_out_file);
-	  assemble_name (asm_out_file, alias);
-	  putc ('\n', asm_out_file);
-	}
-#endif
-    }
-
   DECL_INITIAL (decl) = make_node (BLOCK);
   current_function_decl = decl;
   allocate_struct_function (decl, false);
@@ -11368,19 +11330,29 @@ ix86_code_end (void)
   rtx xops[2];
   unsigned int regno;
 
+  if (indirect_return_needed)
+    output_indirect_thunk_function (false, INVALID_REGNUM, true);
+  if (indirect_return_bnd_needed)
+    output_indirect_thunk_function (true, INVALID_REGNUM, true);
+
+  if (indirect_return_via_cx)
+    output_indirect_thunk_function (false, CX_REG, true);
+  if (indirect_return_via_cx_bnd)
+    output_indirect_thunk_function (true, CX_REG, true);
+
   if (indirect_thunk_needed)
-    output_indirect_thunk_function (false, INVALID_REGNUM);
+    output_indirect_thunk_function (false, INVALID_REGNUM, false);
   if (indirect_thunk_bnd_needed)
-    output_indirect_thunk_function (true, INVALID_REGNUM);
+    output_indirect_thunk_function (true, INVALID_REGNUM, false);
 
   for (regno = FIRST_REX_INT_REG; regno <= LAST_REX_INT_REG; regno++)
     {
       unsigned int i = regno - FIRST_REX_INT_REG + LAST_INT_REG + 1;
       if ((indirect_thunks_used & (1 << i)))
-	output_indirect_thunk_function (false, regno);
+	output_indirect_thunk_function (false, regno, false);
 
       if ((indirect_thunks_bnd_used & (1 << i)))
-	output_indirect_thunk_function (true, regno);
+	output_indirect_thunk_function (true, regno, false);
     }
 
   for (regno = AX_REG; regno <= SP_REG; regno++)
@@ -11389,10 +11361,10 @@ ix86_code_end (void)
       tree decl;
 
       if ((indirect_thunks_used & (1 << regno)))
-	output_indirect_thunk_function (false, regno);
+	output_indirect_thunk_function (false, regno, false);
 
       if ((indirect_thunks_bnd_used & (1 << regno)))
-	output_indirect_thunk_function (true, regno);
+	output_indirect_thunk_function (true, regno, false);
 
       if (!(pic_labels_used & (1 << regno)))
 	continue;
@@ -28077,12 +28049,12 @@ ix86_output_function_return (bool long_p)
 			       true);
 	  if (need_bnd_p)
 	    {
-	      indirect_thunk_bnd_needed |= need_thunk;
+	      indirect_return_bnd_needed |= need_thunk;
 	      fprintf (asm_out_file, "\tbnd jmp\t%s\n", thunk_name);
 	    }
 	  else
 	    {
-	      indirect_thunk_needed |= need_thunk;
+	      indirect_return_needed |= need_thunk;
 	      fprintf (asm_out_file, "\tjmp\t%s\n", thunk_name);
 	    }
 	}
diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-9.c b/gcc/testsuite/gcc.target/i386/ret-thunk-9.c
index d2df8b874e0..eee230ca2f6 100644
--- a/gcc/testsuite/gcc.target/i386/ret-thunk-9.c
+++ b/gcc/testsuite/gcc.target/i386/ret-thunk-9.c
@@ -13,7 +13,7 @@ foo (void)
 /* { dg-final { scan-assembler "jmp\[ \t\]*__x86_return_thunk" } } */
 /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
 /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
-/* { dg-final { scan-assembler "__x86_indirect_thunk:" } } */
+/* { dg-final { scan-assembler "__x86_return_thunk:" } } */
 /* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?bar" { target *-*-linux* } } } */
 /* { dg-final { scan-assembler-times {\tpause} 2 } } */
 /* { dg-final { scan-assembler-times {\tlfence} 2 } } */
-- 
2.16.3