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