]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/sol2.c
2015-06-17 Andrew MacLeod <amacleod@redhat.com>
[thirdparty/gcc.git] / gcc / config / sol2.c
CommitLineData
e02a1225 1/* General Solaris system support.
d353bf18 2 Copyright (C) 2004-2015 Free Software Foundation, Inc.
e02a1225 3 Contributed by CodeSourcery, LLC.
4
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
038d1e19 9the Free Software Foundation; either version 3, or (at your option)
e02a1225 10any later version.
11
12GCC is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
038d1e19 18along with GCC; see the file COPYING3. If not see
19<http://www.gnu.org/licenses/>. */
e02a1225 20
21#include "config.h"
22#include "system.h"
23#include "coretypes.h"
b20a8bb4 24#include "alias.h"
25#include "symtab.h"
26#include "options.h"
e02a1225 27#include "tree.h"
9ed99284 28#include "stringpool.h"
29#include "varasm.h"
dc2059b5 30#include "output.h"
e02a1225 31#include "tm.h"
d960da42 32#include "rtl.h"
b82b45b4 33#include "target.h"
e02a1225 34#include "tm_p.h"
0b205f4c 35#include "diagnostic-core.h"
e02a1225 36
37tree solaris_pending_aligns, solaris_pending_inits, solaris_pending_finis;
38
39/* Attach any pending attributes for DECL to the list in *ATTRIBUTES.
40 Pending attributes come from #pragma or _Pragma, so this code is
41 only useful in the C family front ends, but it is included in
42 all languages to avoid changing the target machine initializer
43 depending on the language. */
44
45void
46solaris_insert_attributes (tree decl, tree *attributes)
47{
48 tree *x, next;
49
50 if (solaris_pending_aligns != NULL && TREE_CODE (decl) == VAR_DECL)
51 for (x = &solaris_pending_aligns; *x; x = &TREE_CHAIN (*x))
52 {
53 tree name = TREE_PURPOSE (*x);
54 tree value = TREE_VALUE (*x);
55 if (DECL_NAME (decl) == name)
56 {
57 if (lookup_attribute ("aligned", DECL_ATTRIBUTES (decl))
58 || lookup_attribute ("aligned", *attributes))
3cf8b391 59 warning (0, "ignoring %<#pragma align%> for explicitly "
60 "aligned %q+D", decl);
e02a1225 61 else
62 *attributes = tree_cons (get_identifier ("aligned"), value,
63 *attributes);
64 next = TREE_CHAIN (*x);
65 ggc_free (*x);
66 *x = next;
67 break;
68 }
69 }
70
71 if (solaris_pending_inits != NULL && TREE_CODE (decl) == FUNCTION_DECL)
72 for (x = &solaris_pending_inits; *x; x = &TREE_CHAIN (*x))
73 {
74 tree name = TREE_PURPOSE (*x);
75 if (DECL_NAME (decl) == name)
76 {
77 *attributes = tree_cons (get_identifier ("init"), NULL,
78 *attributes);
83a23b05 79 TREE_USED (decl) = 1;
80 DECL_PRESERVE_P (decl) = 1;
e02a1225 81 next = TREE_CHAIN (*x);
82 ggc_free (*x);
83 *x = next;
84 break;
85 }
86 }
87
88 if (solaris_pending_finis != NULL && TREE_CODE (decl) == FUNCTION_DECL)
89 for (x = &solaris_pending_finis; *x; x = &TREE_CHAIN (*x))
90 {
91 tree name = TREE_PURPOSE (*x);
92 if (DECL_NAME (decl) == name)
93 {
94 *attributes = tree_cons (get_identifier ("fini"), NULL,
95 *attributes);
83a23b05 96 TREE_USED (decl) = 1;
97 DECL_PRESERVE_P (decl) = 1;
e02a1225 98 next = TREE_CHAIN (*x);
99 ggc_free (*x);
100 *x = next;
101 break;
102 }
103 }
104}
105
106/* Output initializer or finalizer entries for DECL to FILE. */
107
108void
109solaris_output_init_fini (FILE *file, tree decl)
110{
111 if (lookup_attribute ("init", DECL_ATTRIBUTES (decl)))
112 {
3468b0d6 113 fprintf (file, "\t.pushsection\t" SECTION_NAME_FORMAT "\n", ".init");
d960da42 114 ASM_OUTPUT_CALL (file, decl);
e02a1225 115 fprintf (file, "\t.popsection\n");
116 }
117
118 if (lookup_attribute ("fini", DECL_ATTRIBUTES (decl)))
119 {
3468b0d6 120 fprintf (file, "\t.pushsection\t" SECTION_NAME_FORMAT "\n", ".fini");
d960da42 121 ASM_OUTPUT_CALL (file, decl);
e02a1225 122 fprintf (file, "\t.popsection\n");
123 }
124}
125
dc2059b5 126/* Emit an assembler directive to set symbol for DECL visibility to
127 the visibility type VIS, which must not be VISIBILITY_DEFAULT. */
128
129void
4475ab54 130solaris_assemble_visibility (tree decl, int vis ATTRIBUTE_UNUSED)
dc2059b5 131{
cbbd336d 132#ifdef HAVE_GAS_HIDDEN
dc2059b5 133 /* Sun as uses .symbolic for STV_PROTECTED. STV_INTERNAL is marked as
134 `currently reserved', but the linker treats it like STV_HIDDEN. Sun
135 Studio 12.1 cc emits .hidden instead.
136
137 There are 3 Sun extensions GCC doesn't yet know about: STV_EXPORTED,
138 STV_SINGLETON, and STV_ELIMINATE.
139
140 See Linker and Libraries Guide, Ch. 2, Link-Editor, Defining
a6d6d956 141 Additional Symbols, and Ch. 7, Object-File Format, Symbol Table
142 Section. */
dc2059b5 143
144 static const char * const visibility_types[] = {
145 NULL, "symbolic", "hidden", "hidden"
146 };
147
148 const char *name, *type;
149
150 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
151 type = visibility_types[vis];
152
dc2059b5 153 fprintf (asm_out_file, "\t.%s\t", type);
154 assemble_name (asm_out_file, name);
155 fprintf (asm_out_file, "\n");
156#else
4475ab54 157 if (!DECL_ARTIFICIAL (decl))
158 warning (OPT_Wattributes, "visibility attribute not supported "
159 "in this configuration; ignored");
dc2059b5 160#endif
161}
3468b0d6 162
3468b0d6 163/* Group section information entry stored in solaris_comdat_htab. */
164
165typedef struct comdat_entry
166{
167 const char *name;
168 unsigned int flags;
169 tree decl;
170 const char *sig;
171} comdat_entry;
172
7b7a707b 173/* Helpers for maintaining solaris_comdat_htab. */
3468b0d6 174
7b7a707b 175struct comdat_entry_hasher : typed_noop_remove <comdat_entry>
176{
9969c043 177 typedef comdat_entry *value_type;
178 typedef comdat_entry *compare_type;
179 static inline hashval_t hash (const comdat_entry *);
180 static inline bool equal (const comdat_entry *, const comdat_entry *);
181 static inline void remove (comdat_entry *);
7b7a707b 182};
183
184inline hashval_t
9969c043 185comdat_entry_hasher::hash (const comdat_entry *entry)
3468b0d6 186{
3468b0d6 187 return htab_hash_string (entry->sig);
188}
189
7b7a707b 190inline bool
9969c043 191comdat_entry_hasher::equal (const comdat_entry *entry1,
192 const comdat_entry *entry2)
3468b0d6 193{
3468b0d6 194 return strcmp (entry1->sig, entry2->sig) == 0;
195}
196
7b7a707b 197/* Hash table of group signature symbols. */
198
c1f445d2 199static hash_table<comdat_entry_hasher> *solaris_comdat_htab;
7b7a707b 200
3468b0d6 201/* Output assembly to switch to COMDAT group section NAME with attributes
202 FLAGS and group signature symbol DECL, using Sun as syntax. */
203
204void
205solaris_elf_asm_comdat_section (const char *name, unsigned int flags, tree decl)
206{
207 const char *signature;
208 char *section;
209 comdat_entry entry, **slot;
210
211 if (TREE_CODE (decl) == IDENTIFIER_NODE)
212 signature = IDENTIFIER_POINTER (decl);
213 else
214 signature = IDENTIFIER_POINTER (DECL_COMDAT_GROUP (decl));
215
216 /* Sun as requires group sections to be fragmented, i.e. to have names of
217 the form <section>%<fragment>. Strictly speaking this is only
218 necessary to support cc -xF, but is enforced globally in violation of
219 the ELF gABI. We keep the section names generated by GCC (generally
220 of the form .text.<signature>) and append %<signature> to pacify as,
221 despite the redundancy. */
222 section = concat (name, "%", signature, NULL);
223
224 /* Clear SECTION_LINKONCE flag so targetm.asm_out.named_section only
225 emits this as a regular section. Emit section before .group
226 directive since Sun as treats undeclared sections as @progbits,
227 which conflicts with .bss* sections which are @nobits. */
228 targetm.asm_out.named_section (section, flags & ~SECTION_LINKONCE, decl);
229
230 /* Sun as separates declaration of a group section and of the group
231 itself, using the .group directive and the #comdat flag. */
232 fprintf (asm_out_file, "\t.group\t%s," SECTION_NAME_FORMAT ",#comdat\n",
233 signature, section);
234
235 /* Unlike GNU as, group signature symbols need to be defined explicitly
236 for Sun as. With a few exceptions, this is already the case. To
237 identify the missing ones without changing the affected frontents,
238 remember the signature symbols and emit those not marked
76005733 239 TREE_SYMBOL_REFERENCED in solaris_file_end. */
c1f445d2 240 if (!solaris_comdat_htab)
241 solaris_comdat_htab = new hash_table<comdat_entry_hasher> (37);
3468b0d6 242
243 entry.sig = signature;
c1f445d2 244 slot = solaris_comdat_htab->find_slot (&entry, INSERT);
3468b0d6 245
246 if (*slot == NULL)
247 {
248 *slot = XCNEW (comdat_entry);
249 /* Remember fragmented section name. */
250 (*slot)->name = section;
251 /* Emit as regular section, .group declaration has already been done. */
252 (*slot)->flags = flags & ~SECTION_LINKONCE;
253 (*slot)->decl = decl;
254 (*slot)->sig = signature;
255 }
256}
257
258/* Define unreferenced COMDAT group signature symbol corresponding to SLOT. */
259
7b7a707b 260int
261solaris_define_comdat_signature (comdat_entry **slot,
262 void *aux ATTRIBUTE_UNUSED)
3468b0d6 263{
7b7a707b 264 comdat_entry *entry = *slot;
3468b0d6 265 tree decl = entry->decl;
266
267 if (TREE_CODE (decl) != IDENTIFIER_NODE)
268 decl = DECL_COMDAT_GROUP (decl);
269
270 if (!TREE_SYMBOL_REFERENCED (decl))
271 {
272 /* Switch to group section, otherwise Sun as complains
273 `Group Id symbol defined outside of group'. */
274 switch_to_section (get_section (entry->name, entry->flags, entry->decl));
275
276 ASM_OUTPUT_LABEL (asm_out_file, entry->sig);
277 }
278
279 /* Continue with scan. */
280 return 1;
281}
282
283/* Emit unreferenced COMDAT group signature symbols for Sun as. */
284
285void
76005733 286solaris_file_end (void)
3468b0d6 287{
c1f445d2 288 if (!solaris_comdat_htab)
3468b0d6 289 return;
290
c1f445d2 291 solaris_comdat_htab->traverse <void *, solaris_define_comdat_signature>
292 (NULL);
3468b0d6 293}
db66903a 294
295void
296solaris_override_options (void)
297{
75d28287 298 /* Older versions of Solaris ld cannot handle CIE version 3 in .eh_frame.
299 Don't emit DWARF3/4 unless specifically selected if so. */
300 if (!HAVE_LD_EH_FRAME_CIEV3 && !global_options_set.x_dwarf_version)
db66903a 301 dwarf_version = 2;
302}