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