]>
Commit | Line | Data |
---|---|---|
2f9a3f2d | 1 | Date: Wed, 4 May 2005 21:52:46 -0700 |
fbb03002 | 2 | From: "H dot J dot Lu" <hjl at lucon dot org> |
2f9a3f2d | 3 | Subject: PATCH: PR middle-end/20218: Can't use __attribute__ ((visibility ("hidden"))) to hide a symbol |
fbb03002 | 4 | |
2f9a3f2d | 5 | Here is the updated patch. It works for me on ia32, ia64 and x86_64. |
fbb03002 | 6 | |
2f9a3f2d | 7 | 2005-05-04 H.J. Lu <hongjiu.lu@intel.com> |
fbb03002 PS |
8 | |
9 | PR middle-end/20218 | |
10 | * config/elfos.h (ASM_OUTPUT_EXTERNAL): New. | |
11 | (TARGET_ASM_FILE_END): New. | |
2f9a3f2d | 12 | |
fbb03002 | 13 | * config/i386/i386-protos.h (ix86_elf_file_end): New. |
2f9a3f2d | 14 | |
fbb03002 | 15 | * config/i386/i386.c (ix86_elf_file_end): New. |
2f9a3f2d | 16 | |
fbb03002 PS |
17 | * config/i386/linux.h (TARGET_ASM_FILE_END): Defined. |
18 | * config/i386/linux64.h (TARGET_ASM_FILE_END): Likewise. | |
2f9a3f2d | 19 | |
fbb03002 | 20 | * config/ia64/hpux.h (TARGET_ASM_FILE_END): Removed. |
2f9a3f2d | 21 | |
fbb03002 PS |
22 | * config/ia64/ia64.c (ia64_hpux_add_extern_decl): Removed. |
23 | (ia64_hpux_file_end): Renamed to ... | |
24 | (ia64_file_end): This. Handle symbol with non-default | |
25 | visibility. | |
26 | (TARGET_ASM_FILE_END): Defined. | |
27 | (ia64_asm_output_external): Rewritten. | |
28 | (extern_func_list): Removed. | |
29 | (extern_func_head): Likewise. | |
2f9a3f2d PS |
30 | |
31 | * output.h (default_elf_asm_output_external): New. | |
fbb03002 PS |
32 | (default_elf_asm_output_external_1): New. |
33 | (default_elf_asm_file_end): New. | |
34 | (maybe_assemble_visibility): New. | |
2f9a3f2d PS |
35 | |
36 | * tree.h (extern_symbol_list): New. | |
37 | (extern_symbol_head): New. | |
38 | ||
fbb03002 PS |
39 | * varasm.c (maybe_assemble_visibility): Make it extern and |
40 | return int. | |
41 | (extern_symbol_head): New. | |
42 | (default_elf_asm_output_external_1): New. | |
43 | (default_elf_asm_output_external): New. | |
44 | (default_elf_asm_file_end): New. | |
45 | ||
2f9a3f2d PS |
46 | --- gcc/config/elfos.h.global 2005-04-14 14:57:02.000000000 -0700 |
47 | +++ gcc/config/elfos.h 2005-05-04 20:35:06.000000000 -0700 | |
fbb03002 PS |
48 | @@ -487,3 +487,17 @@ Boston, MA 02111-1307, USA. */ |
49 | fprintf ((FILE), "\"\n"); \ | |
50 | } \ | |
51 | while (0) | |
52 | + | |
53 | +/* A C statement (sans semicolon) to output to the stdio stream STREAM | |
54 | + any text necessary for declaring the name of an external symbol | |
55 | + named NAME whch is referenced in this compilation but not defined. | |
56 | + It is needed to properly support non-default visibility. */ | |
57 | + | |
58 | +#ifndef ASM_OUTPUT_EXTERNAL | |
59 | +#define ASM_OUTPUT_EXTERNAL(FILE, DECL, NAME) \ | |
60 | + default_elf_asm_output_external (FILE, DECL, NAME) | |
61 | +#endif | |
62 | + | |
63 | +#ifndef TARGET_ASM_FILE_END | |
64 | +#define TARGET_ASM_FILE_END default_elf_asm_file_end | |
65 | +#endif | |
2f9a3f2d PS |
66 | --- gcc/config/i386/i386-protos.h.global 2005-04-24 11:06:02.000000000 -0700 |
67 | +++ gcc/config/i386/i386-protos.h 2005-05-04 20:35:06.000000000 -0700 | |
fbb03002 PS |
68 | @@ -28,6 +28,7 @@ extern int ix86_frame_pointer_required ( |
69 | extern void ix86_setup_frame_addresses (void); | |
70 | ||
71 | extern void ix86_file_end (void); | |
72 | +extern void ix86_elf_file_end (void); | |
73 | extern HOST_WIDE_INT ix86_initial_elimination_offset (int, int); | |
74 | extern void ix86_expand_prologue (void); | |
75 | extern void ix86_expand_epilogue (int); | |
2f9a3f2d PS |
76 | --- gcc/config/i386/i386.c.global 2005-05-04 20:35:05.000000000 -0700 |
77 | +++ gcc/config/i386/i386.c 2005-05-04 20:35:06.000000000 -0700 | |
78 | @@ -4103,6 +4103,13 @@ ix86_file_end (void) | |
fbb03002 PS |
79 | file_end_indicate_exec_stack (); |
80 | } | |
81 | ||
82 | +void | |
83 | +ix86_elf_file_end (void) | |
84 | +{ | |
85 | + ix86_file_end (); | |
86 | + default_elf_asm_file_end (); | |
87 | +} | |
88 | + | |
89 | /* Emit code for the SET_GOT patterns. */ | |
90 | ||
91 | const char * | |
92 | --- gcc/config/i386/linux.h.global 2004-11-28 17:04:42.000000000 -0800 | |
2f9a3f2d | 93 | +++ gcc/config/i386/linux.h 2005-05-04 20:35:06.000000000 -0700 |
fbb03002 PS |
94 | @@ -185,3 +185,6 @@ Boston, MA 02111-1307, USA. */ |
95 | ||
96 | /* This macro may be overridden in i386/k*bsd-gnu.h. */ | |
97 | #define REG_NAME(reg) reg | |
98 | + | |
99 | +#undef TARGET_ASM_FILE_END | |
100 | +#define TARGET_ASM_FILE_END ix86_elf_file_end | |
101 | --- gcc/config/i386/linux64.h.global 2004-11-28 17:04:42.000000000 -0800 | |
2f9a3f2d | 102 | +++ gcc/config/i386/linux64.h 2005-05-04 20:35:06.000000000 -0700 |
fbb03002 PS |
103 | @@ -73,3 +73,6 @@ Boston, MA 02111-1307, USA. */ |
104 | ||
105 | /* This macro may be overridden in i386/k*bsd-gnu.h. */ | |
106 | #define REG_NAME(reg) reg | |
107 | + | |
108 | +#undef TARGET_ASM_FILE_END | |
109 | +#define TARGET_ASM_FILE_END ix86_elf_file_end | |
2f9a3f2d PS |
110 | --- gcc/config/ia64/hpux.h.global 2005-03-17 13:05:06.000000000 -0800 |
111 | +++ gcc/config/ia64/hpux.h 2005-05-04 20:35:06.000000000 -0700 | |
112 | @@ -147,10 +147,6 @@ do { \ | |
fbb03002 PS |
113 | definitions, so do not use them in gthr-posix.h. */ |
114 | #define GTHREAD_USE_WEAK 0 | |
115 | ||
116 | -/* Put out the needed function declarations at the end. */ | |
117 | - | |
118 | -#define TARGET_ASM_FILE_END ia64_hpux_file_end | |
119 | - | |
120 | #undef CTORS_SECTION_ASM_OP | |
121 | #define CTORS_SECTION_ASM_OP "\t.section\t.init_array,\t\"aw\",\"init_array\"" | |
122 | ||
2f9a3f2d PS |
123 | --- gcc/config/ia64/ia64.c.global 2005-04-28 16:11:38.000000000 -0700 |
124 | +++ gcc/config/ia64/ia64.c 2005-05-04 21:07:52.000000000 -0700 | |
125 | @@ -234,6 +234,7 @@ static void bundling (FILE *, int, rtx, | |
fbb03002 PS |
126 | static void ia64_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, |
127 | HOST_WIDE_INT, tree); | |
128 | static void ia64_file_start (void); | |
129 | +static void ia64_file_end (void); | |
130 | ||
131 | static void ia64_select_rtx_section (enum machine_mode, rtx, | |
132 | unsigned HOST_WIDE_INT); | |
2f9a3f2d | 133 | @@ -245,10 +246,6 @@ static void ia64_rwreloc_select_rtx_sect |
fbb03002 PS |
134 | unsigned HOST_WIDE_INT) |
135 | ATTRIBUTE_UNUSED; | |
136 | static unsigned int ia64_section_type_flags (tree, const char *, int); | |
137 | -static void ia64_hpux_add_extern_decl (tree decl) | |
138 | - ATTRIBUTE_UNUSED; | |
139 | -static void ia64_hpux_file_end (void) | |
140 | - ATTRIBUTE_UNUSED; | |
141 | static void ia64_init_libfuncs (void) | |
142 | ATTRIBUTE_UNUSED; | |
143 | static void ia64_hpux_init_libfuncs (void) | |
2f9a3f2d | 144 | @@ -360,6 +357,9 @@ static const struct attribute_spec ia64_ |
fbb03002 PS |
145 | #undef TARGET_ASM_FILE_START |
146 | #define TARGET_ASM_FILE_START ia64_file_start | |
147 | ||
148 | +#undef TARGET_ASM_FILE_END | |
149 | +#define TARGET_ASM_FILE_END ia64_file_end | |
150 | + | |
151 | #undef TARGET_RTX_COSTS | |
152 | #define TARGET_RTX_COSTS ia64_rtx_costs | |
153 | #undef TARGET_ADDRESS_COST | |
2f9a3f2d PS |
154 | @@ -4493,43 +4493,24 @@ ia64_secondary_reload_class (enum reg_cl |
155 | the Intel assembler does not support undefined externals. */ | |
156 | ||
fbb03002 | 157 | void |
2f9a3f2d PS |
158 | -ia64_asm_output_external (FILE *file, tree decl, const char *name) |
159 | +ia64_asm_output_external (FILE *file ATTRIBUTE_UNUSED, tree decl, | |
160 | + const char *name) | |
fbb03002 PS |
161 | { |
162 | - int save_referenced; | |
163 | - | |
164 | - /* GNU as does not need anything here, but the HP linker does need | |
165 | - something for external functions. */ | |
166 | - | |
167 | - if (TARGET_GNU_AS | |
168 | - && (!TARGET_HPUX_LD | |
169 | - || TREE_CODE (decl) != FUNCTION_DECL | |
170 | - || strstr (name, "__builtin_") == name)) | |
171 | - return; | |
172 | - | |
173 | /* ??? The Intel assembler creates a reference that needs to be satisfied by | |
174 | the linker when we do this, so we need to be careful not to do this for | |
175 | builtin functions which have no library equivalent. Unfortunately, we | |
176 | can't tell here whether or not a function will actually be called by | |
177 | expand_expr, so we pull in library functions even if we may not need | |
178 | them later. */ | |
179 | - if (! strcmp (name, "__builtin_next_arg") | |
180 | - || ! strcmp (name, "alloca") | |
181 | - || ! strcmp (name, "__builtin_constant_p") | |
182 | - || ! strcmp (name, "__builtin_args_info")) | |
183 | + if (TREE_CODE (decl) == FUNCTION_DECL | |
184 | + && ((TARGET_GNU_AS && strstr (name, "__builtin_") == name) | |
185 | + || (!strcmp (name, "__builtin_next_arg") | |
186 | + || ! strcmp (name, "alloca") | |
187 | + || ! strcmp (name, "__builtin_constant_p") | |
188 | + || ! strcmp (name, "__builtin_args_info")))) | |
189 | return; | |
190 | ||
191 | - if (TARGET_HPUX_LD) | |
192 | - ia64_hpux_add_extern_decl (decl); | |
193 | - else | |
194 | - { | |
195 | - /* assemble_name will set TREE_SYMBOL_REFERENCED, so we must save and | |
196 | - restore it. */ | |
197 | - save_referenced = TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)); | |
198 | - if (TREE_CODE (decl) == FUNCTION_DECL) | |
199 | - ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function"); | |
200 | - (*targetm.asm_out.globalize_label) (file, name); | |
201 | - TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)) = save_referenced; | |
202 | - } | |
203 | + default_elf_asm_output_external_1 (decl); | |
204 | } | |
205 | \f | |
206 | /* Parse the -mfixed-range= option string. */ | |
2f9a3f2d | 207 | @@ -7902,36 +7883,16 @@ ia64_hpux_function_arg_padding (enum mac |
fbb03002 PS |
208 | return DEFAULT_FUNCTION_ARG_PADDING (mode, type); |
209 | } | |
210 | ||
211 | -/* Linked list of all external functions that are to be emitted by GCC. | |
212 | - We output the name if and only if TREE_SYMBOL_REFERENCED is set in | |
213 | - order to avoid putting out names that are never really used. */ | |
214 | - | |
215 | -struct extern_func_list GTY(()) | |
216 | -{ | |
217 | - struct extern_func_list *next; | |
218 | - tree decl; | |
219 | -}; | |
220 | - | |
221 | -static GTY(()) struct extern_func_list *extern_func_head; | |
222 | - | |
223 | -static void | |
224 | -ia64_hpux_add_extern_decl (tree decl) | |
225 | -{ | |
226 | - struct extern_func_list *p = ggc_alloc (sizeof (struct extern_func_list)); | |
227 | - | |
228 | - p->decl = decl; | |
229 | - p->next = extern_func_head; | |
230 | - extern_func_head = p; | |
231 | -} | |
232 | - | |
233 | /* Print out the list of used global functions. */ | |
234 | ||
235 | static void | |
236 | -ia64_hpux_file_end (void) | |
237 | +ia64_file_end (void) | |
238 | { | |
239 | - struct extern_func_list *p; | |
240 | + struct extern_symbol_list *p; | |
241 | + int hpld = TARGET_HPUX_LD; | |
242 | + int gas = TARGET_GNU_AS; | |
243 | ||
244 | - for (p = extern_func_head; p; p = p->next) | |
245 | + for (p = extern_symbol_head; p; p = p->next) | |
246 | { | |
247 | tree decl = p->decl; | |
248 | tree id = DECL_ASSEMBLER_NAME (decl); | |
2f9a3f2d PS |
249 | @@ -7939,18 +7900,28 @@ ia64_hpux_file_end (void) |
250 | gcc_assert (id); | |
fbb03002 PS |
251 | |
252 | if (!TREE_ASM_WRITTEN (decl) && TREE_SYMBOL_REFERENCED (id)) | |
253 | - { | |
254 | + { | |
2f9a3f2d PS |
255 | + int vis = ((*targetm.binds_local_p) (decl) |
256 | + && maybe_assemble_visibility (decl)); | |
fbb03002 PS |
257 | const char *name = XSTR (XEXP (DECL_RTL (decl), 0), 0); |
258 | ||
259 | + /* GNU as does not need anything here, but the HP linker | |
260 | + does need something for external functions. */ | |
261 | + if ((hpld || !gas) | |
262 | + && TREE_CODE (decl) == FUNCTION_DECL) | |
263 | + { | |
264 | + ASM_OUTPUT_TYPE_DIRECTIVE (asm_out_file, name, | |
265 | + "function"); | |
266 | + (*targetm.asm_out.globalize_label) (asm_out_file, name); | |
267 | + } | |
268 | + else if (vis && !gas) | |
269 | + (*targetm.asm_out.globalize_label) (asm_out_file, name); | |
270 | + | |
271 | TREE_ASM_WRITTEN (decl) = 1; | |
272 | - (*targetm.asm_out.globalize_label) (asm_out_file, name); | |
273 | - fputs (TYPE_ASM_OP, asm_out_file); | |
274 | - assemble_name (asm_out_file, name); | |
275 | - fprintf (asm_out_file, "," TYPE_OPERAND_FMT "\n", "function"); | |
276 | } | |
277 | } | |
278 | ||
279 | - extern_func_head = 0; | |
280 | + extern_symbol_head = 0; | |
281 | } | |
282 | ||
283 | /* Set SImode div/mod functions, init_integral_libfuncs only initializes | |
2f9a3f2d PS |
284 | --- gcc/output.h.global 2005-04-28 16:11:31.000000000 -0700 |
285 | +++ gcc/output.h 2005-05-04 20:35:06.000000000 -0700 | |
286 | @@ -543,6 +543,12 @@ extern void default_file_start (void); | |
fbb03002 PS |
287 | extern void file_end_indicate_exec_stack (void); |
288 | extern bool default_valid_pointer_mode (enum machine_mode); | |
289 | ||
2f9a3f2d PS |
290 | +extern void default_elf_asm_output_external (FILE *file, tree, |
291 | + const char *); | |
292 | +extern void default_elf_asm_output_external_1 (tree); | |
293 | +extern void default_elf_asm_file_end (void); | |
294 | +extern int maybe_assemble_visibility (tree); | |
295 | + | |
296 | extern int default_address_cost (rtx); | |
297 | ||
298 | /* When performing hot/cold basic block partitioning, insert note in | |
299 | --- gcc/tree.h.global 2005-05-04 11:20:53.000000000 -0700 | |
300 | +++ gcc/tree.h 2005-05-04 20:35:06.000000000 -0700 | |
301 | @@ -3769,6 +3769,17 @@ extern void process_pending_assemble_ext | |
302 | extern void finish_aliases_1 (void); | |
303 | extern void finish_aliases_2 (void); | |
304 | ||
fbb03002 PS |
305 | +/* Linked list of all external symbols that are to be emitted by |
306 | + GCC. */ | |
307 | + | |
308 | +struct extern_symbol_list GTY(()) | |
309 | +{ | |
310 | + struct extern_symbol_list *next; | |
311 | + tree decl; | |
312 | +}; | |
313 | + | |
314 | +extern GTY(()) struct extern_symbol_list *extern_symbol_head; | |
315 | + | |
2f9a3f2d PS |
316 | /* In stmt.c */ |
317 | extern void expand_computed_goto (tree); | |
318 | extern bool parse_output_constraint (const char **, int, int, int, | |
319 | --- gcc/varasm.c.global 2005-05-04 20:35:05.000000000 -0700 | |
320 | +++ gcc/varasm.c 2005-05-04 20:35:06.000000000 -0700 | |
321 | @@ -123,7 +123,6 @@ static unsigned HOST_WIDE_INT array_size | |
fbb03002 PS |
322 | static unsigned min_align (unsigned, unsigned); |
323 | static void output_constructor (tree, unsigned HOST_WIDE_INT, unsigned int); | |
324 | static void globalize_decl (tree); | |
325 | -static void maybe_assemble_visibility (tree); | |
326 | static int in_named_entry_eq (const void *, const void *); | |
327 | static hashval_t in_named_entry_hash (const void *); | |
2f9a3f2d PS |
328 | static void initialize_cold_section_name (void); |
329 | @@ -4664,13 +4663,18 @@ default_assemble_visibility (tree decl, | |
fbb03002 PS |
330 | |
331 | /* A helper function to call assemble_visibility when needed for a decl. */ | |
332 | ||
333 | -static void | |
334 | +int | |
335 | maybe_assemble_visibility (tree decl) | |
336 | { | |
337 | enum symbol_visibility vis = DECL_VISIBILITY (decl); | |
338 | ||
339 | if (vis != VISIBILITY_DEFAULT) | |
340 | - targetm.asm_out.visibility (decl, vis); | |
341 | + { | |
342 | + targetm.asm_out.visibility (decl, vis); | |
343 | + return 1; | |
344 | + } | |
345 | + else | |
346 | + return 0; | |
347 | } | |
348 | ||
349 | /* Returns 1 if the target configuration supports defining public symbols | |
2f9a3f2d | 350 | @@ -5496,4 +5500,64 @@ file_end_indicate_exec_stack (void) |
fbb03002 PS |
351 | named_section_flags (".note.GNU-stack", flags); |
352 | } | |
353 | ||
354 | +struct extern_symbol_list *extern_symbol_head; | |
355 | + | |
356 | +void | |
357 | +default_elf_asm_output_external_1 (tree decl) | |
358 | +{ | |
359 | + struct extern_symbol_list *p | |
360 | + = ggc_alloc (sizeof (struct extern_symbol_list)); | |
361 | + | |
362 | + p->decl = decl; | |
363 | + p->next = extern_symbol_head; | |
364 | + extern_symbol_head = p; | |
365 | +} | |
366 | + | |
367 | +/* Emit text to declare externally defined symbols. It is needed to | |
368 | + properly support non-default visibility. */ | |
369 | + | |
370 | +void | |
371 | +default_elf_asm_output_external (FILE *file ATTRIBUTE_UNUSED, | |
372 | + tree decl, | |
373 | + const char *name) | |
374 | +{ | |
375 | + /* Ignore builtin functions. */ | |
376 | + if (TREE_CODE (decl) == FUNCTION_DECL | |
377 | + && strstr (name, "__builtin_") == name) | |
378 | + return; | |
379 | + else | |
380 | + default_elf_asm_output_external_1 (decl); | |
381 | +} | |
382 | + | |
383 | +/* Print out the list of referenced global symbols with non-default | |
384 | + visibility. */ | |
385 | + | |
386 | +void | |
387 | +default_elf_asm_file_end (void) | |
388 | +{ | |
389 | + struct extern_symbol_list *p; | |
390 | + | |
391 | + for (p = extern_symbol_head; p; p = p->next) | |
392 | + { | |
393 | + tree decl = p->decl; | |
394 | + tree id = DECL_ASSEMBLER_NAME (decl); | |
395 | + | |
396 | + if (!id) | |
397 | + abort (); | |
398 | + | |
399 | + /* We output the name if and only if TREE_SYMBOL_REFERENCED is | |
400 | + set in order to avoid putting out names that are never really | |
401 | + used. */ | |
2f9a3f2d PS |
402 | + if (targetm.binds_local_p (decl) |
403 | + && !TREE_ASM_WRITTEN (decl) | |
404 | + && TREE_SYMBOL_REFERENCED (id)) | |
fbb03002 PS |
405 | + { |
406 | + maybe_assemble_visibility (decl); | |
407 | + TREE_ASM_WRITTEN (decl) = 1; | |
408 | + } | |
409 | + } | |
410 | + | |
411 | + extern_symbol_head = 0; | |
412 | +} | |
413 | + | |
414 | #include "gt-varasm.h" |