1 From: "H dot J dot Lu" <hjl at lucon dot org>
2 Subject: RFC: PATCH: PR middle-end/20218: Can't use __attribute__ ((visibility ("hidden"))) to hide a symbol
4 This is the first attempt to to fix PR 20218. It keeps a list of
5 referenced global symbols and outputs non-default visibility at the
6 end. I only verified it on Linux/ia32, Linux/x86_64 and Linux/ia64.
9 2005-02-28 H.J. Lu <hongjiu.lu@intel.com>
12 * config/elfos.h (ASM_OUTPUT_EXTERNAL): New.
13 (TARGET_ASM_FILE_END): New.
14 * config/i386/i386-protos.h (ix86_elf_file_end): New.
15 * config/i386/i386.c (ix86_elf_file_end): New.
16 * config/i386/linux.h (TARGET_ASM_FILE_END): Defined.
17 * config/i386/linux64.h (TARGET_ASM_FILE_END): Likewise.
18 * config/ia64/hpux.h (TARGET_ASM_FILE_END): Removed.
19 * config/ia64/ia64.c (ia64_hpux_add_extern_decl): Removed.
20 (ia64_hpux_file_end): Renamed to ...
21 (ia64_file_end): This. Handle symbol with non-default
23 (TARGET_ASM_FILE_END): Defined.
24 (ia64_asm_output_external): Rewritten.
25 (extern_func_list): Removed.
26 (extern_func_head): Likewise.
27 * output.h (extern_symbol_list): New.
28 (extern_symbol_head): New.
29 (default_elf_asm_output_external): New.
30 (default_elf_asm_output_external_1): New.
31 (default_elf_asm_file_end): New.
32 (maybe_assemble_visibility): New.
33 * varasm.c (maybe_assemble_visibility): Make it extern and
35 (extern_symbol_head): New.
36 (default_elf_asm_output_external_1): New.
37 (default_elf_asm_output_external): New.
38 (default_elf_asm_file_end): New.
40 --- gcc/config/elfos.h.global 2004-10-18 09:14:38.000000000 -0700
41 +++ gcc/config/elfos.h 2005-02-28 12:23:53.013906179 -0800
42 @@ -487,3 +487,17 @@ Boston, MA 02111-1307, USA. */
43 fprintf ((FILE), "\"\n"); \
47 +/* A C statement (sans semicolon) to output to the stdio stream STREAM
48 + any text necessary for declaring the name of an external symbol
49 + named NAME whch is referenced in this compilation but not defined.
50 + It is needed to properly support non-default visibility. */
52 +#ifndef ASM_OUTPUT_EXTERNAL
53 +#define ASM_OUTPUT_EXTERNAL(FILE, DECL, NAME) \
54 + default_elf_asm_output_external (FILE, DECL, NAME)
57 +#ifndef TARGET_ASM_FILE_END
58 +#define TARGET_ASM_FILE_END default_elf_asm_file_end
60 --- gcc/config/i386/i386-protos.h.global 2005-02-01 17:41:25.000000000 -0800
61 +++ gcc/config/i386/i386-protos.h 2005-02-28 13:10:37.406053326 -0800
62 @@ -28,6 +28,7 @@ extern int ix86_frame_pointer_required (
63 extern void ix86_setup_frame_addresses (void);
65 extern void ix86_file_end (void);
66 +extern void ix86_elf_file_end (void);
67 extern HOST_WIDE_INT ix86_initial_elimination_offset (int, int);
68 extern void ix86_expand_prologue (void);
69 extern void ix86_expand_epilogue (int);
70 --- gcc/config/i386/i386.c.global 2005-02-27 22:26:51.000000000 -0800
71 +++ gcc/config/i386/i386.c 2005-02-28 13:09:58.402099944 -0800
72 @@ -3937,6 +3937,13 @@ ix86_file_end (void)
73 file_end_indicate_exec_stack ();
77 +ix86_elf_file_end (void)
80 + default_elf_asm_file_end ();
83 /* Emit code for the SET_GOT patterns. */
86 --- gcc/config/i386/linux.h.global 2004-11-28 17:04:42.000000000 -0800
87 +++ gcc/config/i386/linux.h 2005-02-28 13:12:28.068734976 -0800
88 @@ -185,3 +185,6 @@ Boston, MA 02111-1307, USA. */
90 /* This macro may be overridden in i386/k*bsd-gnu.h. */
91 #define REG_NAME(reg) reg
93 +#undef TARGET_ASM_FILE_END
94 +#define TARGET_ASM_FILE_END ix86_elf_file_end
95 --- gcc/config/i386/linux64.h.global 2004-11-28 17:04:42.000000000 -0800
96 +++ gcc/config/i386/linux64.h 2005-02-28 13:22:53.285839795 -0800
97 @@ -73,3 +73,6 @@ Boston, MA 02111-1307, USA. */
99 /* This macro may be overridden in i386/k*bsd-gnu.h. */
100 #define REG_NAME(reg) reg
102 +#undef TARGET_ASM_FILE_END
103 +#define TARGET_ASM_FILE_END ix86_elf_file_end
104 --- gcc/config/ia64/hpux.h.global 2005-02-27 22:10:57.000000000 -0800
105 +++ gcc/config/ia64/hpux.h 2005-02-28 11:28:57.000000000 -0800
106 @@ -152,10 +152,6 @@ do { \
107 definitions, so do not use them in gthr-posix.h. */
108 #define GTHREAD_USE_WEAK 0
110 -/* Put out the needed function declarations at the end. */
112 -#define TARGET_ASM_FILE_END ia64_hpux_file_end
114 #undef CTORS_SECTION_ASM_OP
115 #define CTORS_SECTION_ASM_OP "\t.section\t.init_array,\t\"aw\",\"init_array\""
117 --- gcc/config/ia64/ia64.c.global 2005-02-23 11:26:35.000000000 -0800
118 +++ gcc/config/ia64/ia64.c 2005-02-28 13:37:55.304919908 -0800
119 @@ -248,6 +248,7 @@ static void bundling (FILE *, int, rtx,
120 static void ia64_output_mi_thunk (FILE *, tree, HOST_WIDE_INT,
121 HOST_WIDE_INT, tree);
122 static void ia64_file_start (void);
123 +static void ia64_file_end (void);
125 static void ia64_select_rtx_section (enum machine_mode, rtx,
126 unsigned HOST_WIDE_INT);
127 @@ -259,10 +260,6 @@ static void ia64_rwreloc_select_rtx_sect
128 unsigned HOST_WIDE_INT)
130 static unsigned int ia64_section_type_flags (tree, const char *, int);
131 -static void ia64_hpux_add_extern_decl (tree decl)
133 -static void ia64_hpux_file_end (void)
135 static void ia64_init_libfuncs (void)
137 static void ia64_hpux_init_libfuncs (void)
138 @@ -374,6 +371,9 @@ static const struct attribute_spec ia64_
139 #undef TARGET_ASM_FILE_START
140 #define TARGET_ASM_FILE_START ia64_file_start
142 +#undef TARGET_ASM_FILE_END
143 +#define TARGET_ASM_FILE_END ia64_file_end
145 #undef TARGET_RTX_COSTS
146 #define TARGET_RTX_COSTS ia64_rtx_costs
147 #undef TARGET_ADDRESS_COST
148 @@ -4493,41 +4493,21 @@ ia64_secondary_reload_class (enum reg_cl
150 ia64_asm_output_external (FILE *file, tree decl, const char *name)
152 - int save_referenced;
154 - /* GNU as does not need anything here, but the HP linker does need
155 - something for external functions. */
158 - && (!TARGET_HPUX_LD
159 - || TREE_CODE (decl) != FUNCTION_DECL
160 - || strstr (name, "__builtin_") == name))
163 /* ??? The Intel assembler creates a reference that needs to be satisfied by
164 the linker when we do this, so we need to be careful not to do this for
165 builtin functions which have no library equivalent. Unfortunately, we
166 can't tell here whether or not a function will actually be called by
167 expand_expr, so we pull in library functions even if we may not need
169 - if (! strcmp (name, "__builtin_next_arg")
170 - || ! strcmp (name, "alloca")
171 - || ! strcmp (name, "__builtin_constant_p")
172 - || ! strcmp (name, "__builtin_args_info"))
173 + if (TREE_CODE (decl) == FUNCTION_DECL
174 + && ((TARGET_GNU_AS && strstr (name, "__builtin_") == name)
175 + || (!strcmp (name, "__builtin_next_arg")
176 + || ! strcmp (name, "alloca")
177 + || ! strcmp (name, "__builtin_constant_p")
178 + || ! strcmp (name, "__builtin_args_info"))))
181 - if (TARGET_HPUX_LD)
182 - ia64_hpux_add_extern_decl (decl);
185 - /* assemble_name will set TREE_SYMBOL_REFERENCED, so we must save and
187 - save_referenced = TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl));
188 - if (TREE_CODE (decl) == FUNCTION_DECL)
189 - ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
190 - (*targetm.asm_out.globalize_label) (file, name);
191 - TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)) = save_referenced;
193 + default_elf_asm_output_external_1 (decl);
196 /* Parse the -mfixed-range= option string. */
197 @@ -8472,36 +8452,16 @@ ia64_hpux_function_arg_padding (enum mac
198 return DEFAULT_FUNCTION_ARG_PADDING (mode, type);
201 -/* Linked list of all external functions that are to be emitted by GCC.
202 - We output the name if and only if TREE_SYMBOL_REFERENCED is set in
203 - order to avoid putting out names that are never really used. */
205 -struct extern_func_list GTY(())
207 - struct extern_func_list *next;
211 -static GTY(()) struct extern_func_list *extern_func_head;
214 -ia64_hpux_add_extern_decl (tree decl)
216 - struct extern_func_list *p = ggc_alloc (sizeof (struct extern_func_list));
219 - p->next = extern_func_head;
220 - extern_func_head = p;
223 /* Print out the list of used global functions. */
226 -ia64_hpux_file_end (void)
227 +ia64_file_end (void)
229 - struct extern_func_list *p;
230 + struct extern_symbol_list *p;
231 + int hpld = TARGET_HPUX_LD;
232 + int gas = TARGET_GNU_AS;
234 - for (p = extern_func_head; p; p = p->next)
235 + for (p = extern_symbol_head; p; p = p->next)
238 tree id = DECL_ASSEMBLER_NAME (decl);
239 @@ -8510,18 +8470,27 @@ ia64_hpux_file_end (void)
242 if (!TREE_ASM_WRITTEN (decl) && TREE_SYMBOL_REFERENCED (id))
245 + int vis = maybe_assemble_visibility (decl);
246 const char *name = XSTR (XEXP (DECL_RTL (decl), 0), 0);
248 + /* GNU as does not need anything here, but the HP linker
249 + does need something for external functions. */
251 + && TREE_CODE (decl) == FUNCTION_DECL)
253 + ASM_OUTPUT_TYPE_DIRECTIVE (asm_out_file, name,
255 + (*targetm.asm_out.globalize_label) (asm_out_file, name);
257 + else if (vis && !gas)
258 + (*targetm.asm_out.globalize_label) (asm_out_file, name);
260 TREE_ASM_WRITTEN (decl) = 1;
261 - (*targetm.asm_out.globalize_label) (asm_out_file, name);
262 - fputs (TYPE_ASM_OP, asm_out_file);
263 - assemble_name (asm_out_file, name);
264 - fprintf (asm_out_file, "," TYPE_OPERAND_FMT "\n", "function");
268 - extern_func_head = 0;
269 + extern_symbol_head = 0;
272 /* Set SImode div/mod functions, init_integral_libfuncs only initializes
273 --- gcc/output.h.global 2005-01-19 09:55:57.000000000 -0800
274 +++ gcc/output.h 2005-02-28 13:20:05.017611574 -0800
275 @@ -517,6 +517,23 @@ extern void default_file_start (void);
276 extern void file_end_indicate_exec_stack (void);
277 extern bool default_valid_pointer_mode (enum machine_mode);
279 +/* Linked list of all external symbols that are to be emitted by
282 +struct extern_symbol_list GTY(())
284 + struct extern_symbol_list *next;
288 +extern GTY(()) struct extern_symbol_list *extern_symbol_head;
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 /* dbxout helper functions */
299 --- gcc/varasm.c.global 2005-02-27 22:26:51.000000000 -0800
300 +++ gcc/varasm.c 2005-02-28 13:17:40.865263064 -0800
301 @@ -137,7 +137,6 @@ static unsigned HOST_WIDE_INT array_size
302 static unsigned min_align (unsigned, unsigned);
303 static void output_constructor (tree, unsigned HOST_WIDE_INT, unsigned int);
304 static void globalize_decl (tree);
305 -static void maybe_assemble_visibility (tree);
306 static int in_named_entry_eq (const void *, const void *);
307 static hashval_t in_named_entry_hash (const void *);
308 #ifdef BSS_SECTION_ASM_OP
309 @@ -4535,13 +4534,18 @@ default_assemble_visibility (tree decl,
311 /* A helper function to call assemble_visibility when needed for a decl. */
315 maybe_assemble_visibility (tree decl)
317 enum symbol_visibility vis = DECL_VISIBILITY (decl);
319 if (vis != VISIBILITY_DEFAULT)
320 - targetm.asm_out.visibility (decl, vis);
322 + targetm.asm_out.visibility (decl, vis);
329 /* Returns 1 if the target configuration supports defining public symbols
330 @@ -5360,4 +5364,62 @@ file_end_indicate_exec_stack (void)
331 named_section_flags (".note.GNU-stack", flags);
334 +struct extern_symbol_list *extern_symbol_head;
337 +default_elf_asm_output_external_1 (tree decl)
339 + struct extern_symbol_list *p
340 + = ggc_alloc (sizeof (struct extern_symbol_list));
343 + p->next = extern_symbol_head;
344 + extern_symbol_head = p;
347 +/* Emit text to declare externally defined symbols. It is needed to
348 + properly support non-default visibility. */
351 +default_elf_asm_output_external (FILE *file ATTRIBUTE_UNUSED,
355 + /* Ignore builtin functions. */
356 + if (TREE_CODE (decl) == FUNCTION_DECL
357 + && strstr (name, "__builtin_") == name)
360 + default_elf_asm_output_external_1 (decl);
363 +/* Print out the list of referenced global symbols with non-default
367 +default_elf_asm_file_end (void)
369 + struct extern_symbol_list *p;
371 + for (p = extern_symbol_head; p; p = p->next)
373 + tree decl = p->decl;
374 + tree id = DECL_ASSEMBLER_NAME (decl);
379 + /* We output the name if and only if TREE_SYMBOL_REFERENCED is
380 + set in order to avoid putting out names that are never really
382 + if (!TREE_ASM_WRITTEN (decl) && TREE_SYMBOL_REFERENCED (id))
384 + maybe_assemble_visibility (decl);
385 + TREE_ASM_WRITTEN (decl) = 1;
389 + extern_symbol_head = 0;
392 #include "gt-varasm.h"