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