Home | History | Annotate | Line # | Download | only in config
      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