1 Date: Wed, 4 May 2005 21:52:46 -0700
2 From: "H dot J dot Lu" <hjl at lucon dot org>
3 Subject: PATCH: PR middle-end/20218: Can't use __attribute__ ((visibility ("hidden"))) to hide a symbol
5 Here is the updated patch. It works for me on ia32, ia64 and x86_64.
7 2005-05-04 H.J. Lu <hongjiu.lu@intel.com>
10 * config/elfos.h (ASM_OUTPUT_EXTERNAL): New.
11 (TARGET_ASM_FILE_END): New.
13 * config/i386/i386-protos.h (ix86_elf_file_end): New.
15 * config/i386/i386.c (ix86_elf_file_end): New.
17 * config/i386/linux.h (TARGET_ASM_FILE_END): Defined.
18 * config/i386/linux64.h (TARGET_ASM_FILE_END): Likewise.
20 * config/ia64/hpux.h (TARGET_ASM_FILE_END): Removed.
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
26 (TARGET_ASM_FILE_END): Defined.
27 (ia64_asm_output_external): Rewritten.
28 (extern_func_list): Removed.
29 (extern_func_head): Likewise.
31 * output.h (default_elf_asm_output_external): New.
32 (default_elf_asm_output_external_1): New.
33 (default_elf_asm_file_end): New.
34 (maybe_assemble_visibility): New.
36 * tree.h (extern_symbol_list): New.
37 (extern_symbol_head): New.
39 * varasm.c (maybe_assemble_visibility): Make it extern and
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.
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
48 @@ -487,3 +487,17 @@ Boston, MA 02111-1307, USA. */
49 fprintf ((FILE), "\"\n"); \
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. */
58 +#ifndef ASM_OUTPUT_EXTERNAL
59 +#define ASM_OUTPUT_EXTERNAL(FILE, DECL, NAME) \
60 + default_elf_asm_output_external (FILE, DECL, NAME)
63 +#ifndef TARGET_ASM_FILE_END
64 +#define TARGET_ASM_FILE_END default_elf_asm_file_end
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
68 @@ -28,6 +28,7 @@ extern int ix86_frame_pointer_required (
69 extern void ix86_setup_frame_addresses (void);
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);
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)
79 file_end_indicate_exec_stack ();
83 +ix86_elf_file_end (void)
86 + default_elf_asm_file_end ();
89 /* Emit code for the SET_GOT patterns. */
92 --- gcc/config/i386/linux.h.global 2004-11-28 17:04:42.000000000 -0800
93 +++ gcc/config/i386/linux.h 2005-05-04 20:35:06.000000000 -0700
94 @@ -185,3 +185,6 @@ Boston, MA 02111-1307, USA. */
96 /* This macro may be overridden in i386/k*bsd-gnu.h. */
97 #define REG_NAME(reg) reg
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
102 +++ gcc/config/i386/linux64.h 2005-05-04 20:35:06.000000000 -0700
103 @@ -73,3 +73,6 @@ Boston, MA 02111-1307, USA. */
105 /* This macro may be overridden in i386/k*bsd-gnu.h. */
106 #define REG_NAME(reg) reg
108 +#undef TARGET_ASM_FILE_END
109 +#define TARGET_ASM_FILE_END ix86_elf_file_end
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 { \
113 definitions, so do not use them in gthr-posix.h. */
114 #define GTHREAD_USE_WEAK 0
116 -/* Put out the needed function declarations at the end. */
118 -#define TARGET_ASM_FILE_END ia64_hpux_file_end
120 #undef CTORS_SECTION_ASM_OP
121 #define CTORS_SECTION_ASM_OP "\t.section\t.init_array,\t\"aw\",\"init_array\""
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,
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);
131 static void ia64_select_rtx_section (enum machine_mode, rtx,
132 unsigned HOST_WIDE_INT);
133 @@ -245,10 +246,6 @@ static void ia64_rwreloc_select_rtx_sect
134 unsigned HOST_WIDE_INT)
136 static unsigned int ia64_section_type_flags (tree, const char *, int);
137 -static void ia64_hpux_add_extern_decl (tree decl)
139 -static void ia64_hpux_file_end (void)
141 static void ia64_init_libfuncs (void)
143 static void ia64_hpux_init_libfuncs (void)
144 @@ -360,6 +357,9 @@ static const struct attribute_spec ia64_
145 #undef TARGET_ASM_FILE_START
146 #define TARGET_ASM_FILE_START ia64_file_start
148 +#undef TARGET_ASM_FILE_END
149 +#define TARGET_ASM_FILE_END ia64_file_end
151 #undef TARGET_RTX_COSTS
152 #define TARGET_RTX_COSTS ia64_rtx_costs
153 #undef TARGET_ADDRESS_COST
154 @@ -4493,43 +4493,24 @@ ia64_secondary_reload_class (enum reg_cl
155 the Intel assembler does not support undefined externals. */
158 -ia64_asm_output_external (FILE *file, tree decl, const char *name)
159 +ia64_asm_output_external (FILE *file ATTRIBUTE_UNUSED, tree decl,
162 - int save_referenced;
164 - /* GNU as does not need anything here, but the HP linker does need
165 - something for external functions. */
168 - && (!TARGET_HPUX_LD
169 - || TREE_CODE (decl) != FUNCTION_DECL
170 - || strstr (name, "__builtin_") == name))
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
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"))))
191 - if (TARGET_HPUX_LD)
192 - ia64_hpux_add_extern_decl (decl);
195 - /* assemble_name will set TREE_SYMBOL_REFERENCED, so we must save and
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;
203 + default_elf_asm_output_external_1 (decl);
206 /* Parse the -mfixed-range= option string. */
207 @@ -7902,36 +7883,16 @@ ia64_hpux_function_arg_padding (enum mac
208 return DEFAULT_FUNCTION_ARG_PADDING (mode, type);
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. */
215 -struct extern_func_list GTY(())
217 - struct extern_func_list *next;
221 -static GTY(()) struct extern_func_list *extern_func_head;
224 -ia64_hpux_add_extern_decl (tree decl)
226 - struct extern_func_list *p = ggc_alloc (sizeof (struct extern_func_list));
229 - p->next = extern_func_head;
230 - extern_func_head = p;
233 /* Print out the list of used global functions. */
236 -ia64_hpux_file_end (void)
237 +ia64_file_end (void)
239 - struct extern_func_list *p;
240 + struct extern_symbol_list *p;
241 + int hpld = TARGET_HPUX_LD;
242 + int gas = TARGET_GNU_AS;
244 - for (p = extern_func_head; p; p = p->next)
245 + for (p = extern_symbol_head; p; p = p->next)
248 tree id = DECL_ASSEMBLER_NAME (decl);
249 @@ -7939,18 +7900,28 @@ ia64_hpux_file_end (void)
252 if (!TREE_ASM_WRITTEN (decl) && TREE_SYMBOL_REFERENCED (id))
255 + int vis = ((*targetm.binds_local_p) (decl)
256 + && maybe_assemble_visibility (decl));
257 const char *name = XSTR (XEXP (DECL_RTL (decl), 0), 0);
259 + /* GNU as does not need anything here, but the HP linker
260 + does need something for external functions. */
262 + && TREE_CODE (decl) == FUNCTION_DECL)
264 + ASM_OUTPUT_TYPE_DIRECTIVE (asm_out_file, name,
266 + (*targetm.asm_out.globalize_label) (asm_out_file, name);
268 + else if (vis && !gas)
269 + (*targetm.asm_out.globalize_label) (asm_out_file, name);
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");
279 - extern_func_head = 0;
280 + extern_symbol_head = 0;
283 /* Set SImode div/mod functions, init_integral_libfuncs only initializes
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);
287 extern void file_end_indicate_exec_stack (void);
288 extern bool default_valid_pointer_mode (enum machine_mode);
290 +extern void default_elf_asm_output_external (FILE *file, tree,
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);
296 extern int default_address_cost (rtx);
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);
305 +/* Linked list of all external symbols that are to be emitted by
308 +struct extern_symbol_list GTY(())
310 + struct extern_symbol_list *next;
314 +extern GTY(()) struct extern_symbol_list *extern_symbol_head;
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
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 *);
328 static void initialize_cold_section_name (void);
329 @@ -4664,13 +4663,18 @@ default_assemble_visibility (tree decl,
331 /* A helper function to call assemble_visibility when needed for a decl. */
335 maybe_assemble_visibility (tree decl)
337 enum symbol_visibility vis = DECL_VISIBILITY (decl);
339 if (vis != VISIBILITY_DEFAULT)
340 - targetm.asm_out.visibility (decl, vis);
342 + targetm.asm_out.visibility (decl, vis);
349 /* Returns 1 if the target configuration supports defining public symbols
350 @@ -5496,4 +5500,64 @@ file_end_indicate_exec_stack (void)
351 named_section_flags (".note.GNU-stack", flags);
354 +struct extern_symbol_list *extern_symbol_head;
357 +default_elf_asm_output_external_1 (tree decl)
359 + struct extern_symbol_list *p
360 + = ggc_alloc (sizeof (struct extern_symbol_list));
363 + p->next = extern_symbol_head;
364 + extern_symbol_head = p;
367 +/* Emit text to declare externally defined symbols. It is needed to
368 + properly support non-default visibility. */
371 +default_elf_asm_output_external (FILE *file ATTRIBUTE_UNUSED,
375 + /* Ignore builtin functions. */
376 + if (TREE_CODE (decl) == FUNCTION_DECL
377 + && strstr (name, "__builtin_") == name)
380 + default_elf_asm_output_external_1 (decl);
383 +/* Print out the list of referenced global symbols with non-default
387 +default_elf_asm_file_end (void)
389 + struct extern_symbol_list *p;
391 + for (p = extern_symbol_head; p; p = p->next)
393 + tree decl = p->decl;
394 + tree id = DECL_ASSEMBLER_NAME (decl);
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
402 + if (targetm.binds_local_p (decl)
403 + && !TREE_ASM_WRITTEN (decl)
404 + && TREE_SYMBOL_REFERENCED (id))
406 + maybe_assemble_visibility (decl);
407 + TREE_ASM_WRITTEN (decl) = 1;
411 + extern_symbol_head = 0;
414 #include "gt-varasm.h"