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