Home | History | Annotate | Line # | Download | only in config
      1   1.1     skrll /* ELF object file format
      2  1.14  christos    Copyright (C) 1992-2026 Free Software Foundation, Inc.
      3   1.1     skrll 
      4   1.1     skrll    This file is part of GAS, the GNU Assembler.
      5   1.1     skrll 
      6   1.1     skrll    GAS is free software; you can redistribute it and/or modify
      7   1.1     skrll    it under the terms of the GNU General Public License as
      8   1.1     skrll    published by the Free Software Foundation; either version 3,
      9   1.1     skrll    or (at your option) any later version.
     10   1.1     skrll 
     11   1.1     skrll    GAS is distributed in the hope that it will be useful, but
     12   1.1     skrll    WITHOUT ANY WARRANTY; without even the implied warranty of
     13   1.1     skrll    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
     14   1.1     skrll    the GNU General Public License for more details.
     15   1.1     skrll 
     16   1.1     skrll    You should have received a copy of the GNU General Public License
     17   1.1     skrll    along with GAS; see the file COPYING.  If not, write to the Free
     18   1.1     skrll    Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
     19   1.1     skrll    02110-1301, USA.  */
     20   1.1     skrll 
     21   1.1     skrll #define OBJ_HEADER "obj-elf.h"
     22   1.1     skrll #include "as.h"
     23   1.1     skrll #include "safe-ctype.h"
     24   1.1     skrll #include "subsegs.h"
     25   1.1     skrll #include "obstack.h"
     26   1.1     skrll #include "dwarf2dbg.h"
     27  1.12  christos #include "ginsn.h"
     28   1.1     skrll 
     29   1.1     skrll #ifndef ECOFF_DEBUGGING
     30   1.1     skrll #define ECOFF_DEBUGGING 0
     31   1.1     skrll #else
     32   1.1     skrll #define NEED_ECOFF_DEBUG
     33   1.1     skrll #endif
     34   1.1     skrll 
     35   1.1     skrll #ifdef NEED_ECOFF_DEBUG
     36   1.1     skrll #include "ecoff.h"
     37   1.8  christos #include "bfd/ecoff-bfd.h"
     38   1.1     skrll #endif
     39   1.1     skrll 
     40   1.1     skrll #ifdef TC_ALPHA
     41   1.1     skrll #include "elf/alpha.h"
     42   1.1     skrll #endif
     43   1.1     skrll 
     44   1.1     skrll #ifdef TC_MIPS
     45   1.1     skrll #include "elf/mips.h"
     46   1.1     skrll #endif
     47   1.1     skrll 
     48   1.1     skrll #ifdef TC_PPC
     49   1.1     skrll #include "elf/ppc.h"
     50   1.1     skrll #endif
     51   1.1     skrll 
     52   1.1     skrll #ifdef TC_I386
     53   1.1     skrll #include "elf/x86-64.h"
     54   1.1     skrll #endif
     55   1.1     skrll 
     56   1.1     skrll #ifdef TC_MEP
     57   1.1     skrll #include "elf/mep.h"
     58   1.1     skrll #endif
     59   1.1     skrll 
     60   1.6  christos #ifdef TC_PRU
     61   1.6  christos #include "elf/pru.h"
     62   1.6  christos #endif
     63   1.6  christos 
     64   1.1     skrll static void obj_elf_line (int);
     65   1.1     skrll static void obj_elf_size (int);
     66   1.1     skrll static void obj_elf_type (int);
     67   1.1     skrll static void obj_elf_ident (int);
     68   1.1     skrll static void obj_elf_weak (int);
     69   1.1     skrll static void obj_elf_local (int);
     70   1.1     skrll static void obj_elf_visibility (int);
     71   1.1     skrll static void obj_elf_symver (int);
     72   1.1     skrll static void obj_elf_subsection (int);
     73   1.1     skrll static void obj_elf_popsection (int);
     74   1.1     skrll static void obj_elf_tls_common (int);
     75   1.1     skrll static void obj_elf_lcomm (int);
     76   1.1     skrll static void obj_elf_struct (int);
     77   1.9  christos static void obj_elf_attach_to_group (int);
     78   1.1     skrll 
     79   1.1     skrll static const pseudo_typeS elf_pseudo_table[] =
     80   1.1     skrll {
     81   1.9  christos   {"attach_to_group", obj_elf_attach_to_group, 0},
     82   1.1     skrll   {"comm", obj_elf_common, 0},
     83   1.1     skrll   {"common", obj_elf_common, 1},
     84   1.1     skrll   {"ident", obj_elf_ident, 0},
     85   1.1     skrll   {"lcomm", obj_elf_lcomm, 0},
     86   1.1     skrll   {"local", obj_elf_local, 0},
     87   1.1     skrll   {"previous", obj_elf_previous, 0},
     88   1.1     skrll   {"section", obj_elf_section, 0},
     89   1.1     skrll   {"section.s", obj_elf_section, 0},
     90   1.1     skrll   {"sect", obj_elf_section, 0},
     91   1.1     skrll   {"sect.s", obj_elf_section, 0},
     92   1.1     skrll   {"pushsection", obj_elf_section, 1},
     93   1.1     skrll   {"popsection", obj_elf_popsection, 0},
     94   1.1     skrll   {"size", obj_elf_size, 0},
     95   1.1     skrll   {"type", obj_elf_type, 0},
     96   1.1     skrll   {"version", obj_elf_version, 0},
     97   1.1     skrll   {"weak", obj_elf_weak, 0},
     98   1.1     skrll 
     99   1.1     skrll   /* These define symbol visibility.  */
    100   1.1     skrll   {"internal", obj_elf_visibility, STV_INTERNAL},
    101   1.1     skrll   {"hidden", obj_elf_visibility, STV_HIDDEN},
    102   1.1     skrll   {"protected", obj_elf_visibility, STV_PROTECTED},
    103   1.1     skrll 
    104   1.1     skrll   /* These are used for stabs-in-elf configurations.  */
    105   1.1     skrll   {"line", obj_elf_line, 0},
    106   1.1     skrll 
    107   1.1     skrll   /* This is a GNU extension to handle symbol versions.  */
    108   1.1     skrll   {"symver", obj_elf_symver, 0},
    109   1.1     skrll 
    110   1.1     skrll   /* A GNU extension to change subsection only.  */
    111   1.1     skrll   {"subsection", obj_elf_subsection, 0},
    112   1.1     skrll 
    113   1.1     skrll   /* These are GNU extensions to aid in garbage collecting C++ vtables.  */
    114   1.7  christos   {"vtable_inherit", obj_elf_vtable_inherit, 0},
    115   1.7  christos   {"vtable_entry", obj_elf_vtable_entry, 0},
    116   1.1     skrll 
    117   1.3  christos   /* A GNU extension for object attributes.  */
    118  1.14  christos #ifdef TC_OBJ_ATTR
    119   1.3  christos   {"gnu_attribute", obj_elf_gnu_attribute, 0},
    120  1.14  christos #if TC_OBJ_ATTR_v2
    121  1.14  christos   {"gnu_subsection", obj_elf_gnu_subsection, 0},
    122  1.14  christos #endif /* TC_OBJ_ATTR_v2 */
    123  1.14  christos #endif /* TC_OBJ_ATTR */
    124   1.3  christos 
    125   1.1     skrll   /* These are used for dwarf2.  */
    126   1.7  christos   { "file", dwarf2_directive_file, 0 },
    127   1.1     skrll   { "loc",  dwarf2_directive_loc,  0 },
    128   1.1     skrll   { "loc_mark_labels", dwarf2_directive_loc_mark_labels, 0 },
    129   1.1     skrll 
    130   1.1     skrll   /* We need to trap the section changing calls to handle .previous.  */
    131   1.1     skrll   {"data", obj_elf_data, 0},
    132   1.1     skrll   {"offset", obj_elf_struct, 0},
    133   1.1     skrll   {"struct", obj_elf_struct, 0},
    134   1.1     skrll   {"text", obj_elf_text, 0},
    135   1.9  christos   {"bss", obj_elf_bss, 0},
    136   1.1     skrll 
    137   1.1     skrll   {"tls_common", obj_elf_tls_common, 0},
    138   1.1     skrll 
    139   1.1     skrll   /* End sentinel.  */
    140   1.1     skrll   {NULL, NULL, 0},
    141   1.1     skrll };
    142   1.1     skrll 
    143   1.1     skrll static const pseudo_typeS ecoff_debug_pseudo_table[] =
    144   1.1     skrll {
    145   1.1     skrll #ifdef NEED_ECOFF_DEBUG
    146   1.1     skrll   /* COFF style debugging information for ECOFF. .ln is not used; .loc
    147   1.1     skrll      is used instead.  */
    148   1.1     skrll   { "def",	ecoff_directive_def,	0 },
    149   1.1     skrll   { "dim",	ecoff_directive_dim,	0 },
    150   1.1     skrll   { "endef",	ecoff_directive_endef,	0 },
    151   1.1     skrll   { "file",	ecoff_directive_file,	0 },
    152   1.1     skrll   { "scl",	ecoff_directive_scl,	0 },
    153   1.1     skrll   { "tag",	ecoff_directive_tag,	0 },
    154   1.1     skrll   { "val",	ecoff_directive_val,	0 },
    155   1.1     skrll 
    156   1.1     skrll   /* COFF debugging requires pseudo-ops .size and .type, but ELF
    157   1.1     skrll      already has meanings for those.  We use .esize and .etype
    158   1.1     skrll      instead.  These are only generated by gcc anyhow.  */
    159   1.1     skrll   { "esize",	ecoff_directive_size,	0 },
    160   1.1     skrll   { "etype",	ecoff_directive_type,	0 },
    161   1.1     skrll 
    162   1.1     skrll   /* ECOFF specific debugging information.  */
    163   1.6  christos   { "aent",	ecoff_directive_ent,	1 },
    164   1.1     skrll   { "begin",	ecoff_directive_begin,	0 },
    165   1.1     skrll   { "bend",	ecoff_directive_bend,	0 },
    166   1.1     skrll   { "end",	ecoff_directive_end,	0 },
    167   1.1     skrll   { "ent",	ecoff_directive_ent,	0 },
    168   1.1     skrll   { "fmask",	ecoff_directive_fmask,	0 },
    169   1.1     skrll   { "frame",	ecoff_directive_frame,	0 },
    170   1.1     skrll   { "loc",	ecoff_directive_loc,	0 },
    171   1.1     skrll   { "mask",	ecoff_directive_mask,	0 },
    172   1.1     skrll 
    173   1.1     skrll   /* Other ECOFF directives.  */
    174   1.1     skrll   { "extern",	ecoff_directive_extern,	0 },
    175   1.1     skrll 
    176   1.1     skrll   /* These are used on Irix.  I don't know how to implement them.  */
    177   1.1     skrll   { "alias",	s_ignore,		0 },
    178   1.1     skrll   { "bgnb",	s_ignore,		0 },
    179   1.1     skrll   { "endb",	s_ignore,		0 },
    180   1.1     skrll   { "lab",	s_ignore,		0 },
    181   1.1     skrll   { "noalias",	s_ignore,		0 },
    182   1.1     skrll   { "verstamp",	s_ignore,		0 },
    183   1.1     skrll   { "vreg",	s_ignore,		0 },
    184   1.1     skrll #endif
    185   1.1     skrll 
    186   1.1     skrll   {NULL, NULL, 0}			/* end sentinel */
    187   1.1     skrll };
    188   1.1     skrll 
    189   1.1     skrll #undef NO_RELOC
    190   1.1     skrll #include "aout/aout64.h"
    191   1.1     skrll 
    192   1.1     skrll asection *elf_com_section_ptr;
    193   1.1     skrll 
    194   1.1     skrll void
    195   1.1     skrll elf_pop_insert (void)
    196   1.1     skrll {
    197   1.1     skrll   pop_insert (elf_pseudo_table);
    198   1.1     skrll   if (ECOFF_DEBUGGING)
    199   1.1     skrll     pop_insert (ecoff_debug_pseudo_table);
    200   1.1     skrll }
    201   1.1     skrll 
    202   1.1     skrll void
    203   1.9  christos elf_file_symbol (const char *s)
    204   1.1     skrll {
    205   1.8  christos   asymbol *bsym;
    206   1.9  christos   symbolS *sym = symbol_new (s, absolute_section, &zero_address_frag, 0);
    207   1.9  christos   size_t name_length = strlen (s);
    208   1.8  christos 
    209   1.9  christos   if (name_length > strlen (S_GET_NAME (sym)))
    210   1.9  christos     {
    211   1.9  christos       obstack_grow (&notes, s, name_length + 1);
    212  1.13  christos       S_SET_NAME (sym, obstack_finish (&notes));
    213   1.9  christos     }
    214   1.9  christos   else
    215   1.9  christos     strcpy ((char *) S_GET_NAME (sym), s);
    216   1.1     skrll 
    217   1.9  christos   symbol_get_bfdsym (sym)->flags |= BSF_FILE;
    218   1.2     joerg 
    219   1.9  christos   if (symbol_rootP != sym
    220   1.9  christos       && ((bsym = symbol_get_bfdsym (symbol_rootP)) == NULL
    221   1.9  christos 	  || (bsym->flags & BSF_FILE) == 0))
    222   1.9  christos     {
    223   1.9  christos       symbol_remove (sym, &symbol_rootP, &symbol_lastP);
    224   1.9  christos       symbol_insert (sym, symbol_rootP, &symbol_rootP, &symbol_lastP);
    225   1.9  christos     }
    226   1.5  christos 
    227   1.1     skrll #ifdef DEBUG
    228   1.9  christos   verify_symbol_chain (symbol_rootP, symbol_lastP);
    229   1.1     skrll #endif
    230   1.1     skrll 
    231   1.1     skrll #ifdef NEED_ECOFF_DEBUG
    232   1.9  christos   ecoff_new_file (s);
    233   1.1     skrll #endif
    234   1.1     skrll }
    235   1.1     skrll 
    236   1.1     skrll /* Called from read.c:s_comm after we've parsed .comm symbol, size.
    237   1.1     skrll    Parse a possible alignment value.  */
    238   1.1     skrll 
    239   1.1     skrll symbolS *
    240   1.1     skrll elf_common_parse (int ignore ATTRIBUTE_UNUSED, symbolS *symbolP, addressT size)
    241   1.1     skrll {
    242   1.1     skrll   addressT align = 0;
    243   1.1     skrll   int is_local = symbol_get_obj (symbolP)->local;
    244   1.1     skrll 
    245   1.1     skrll   if (*input_line_pointer == ',')
    246   1.1     skrll     {
    247   1.1     skrll       char *save = input_line_pointer;
    248   1.1     skrll 
    249   1.1     skrll       input_line_pointer++;
    250   1.1     skrll       SKIP_WHITESPACE ();
    251   1.1     skrll 
    252   1.1     skrll       if (*input_line_pointer == '"')
    253   1.1     skrll 	{
    254   1.1     skrll 	  /* For sparc.  Accept .common symbol, length, "bss"  */
    255   1.1     skrll 	  input_line_pointer++;
    256   1.1     skrll 	  /* Some use the dot, some don't.  */
    257   1.1     skrll 	  if (*input_line_pointer == '.')
    258   1.1     skrll 	    input_line_pointer++;
    259   1.1     skrll 	  /* Some say data, some say bss.  */
    260   1.9  christos 	  if (startswith (input_line_pointer, "bss\""))
    261   1.1     skrll 	    input_line_pointer += 4;
    262   1.9  christos 	  else if (startswith (input_line_pointer, "data\""))
    263   1.1     skrll 	    input_line_pointer += 5;
    264   1.1     skrll 	  else
    265   1.1     skrll 	    {
    266   1.1     skrll 	      char *p = input_line_pointer;
    267   1.1     skrll 	      char c;
    268   1.1     skrll 
    269   1.1     skrll 	      while (*--p != '"')
    270   1.1     skrll 		;
    271  1.13  christos 	      while (!is_end_of_stmt (*input_line_pointer))
    272   1.1     skrll 		if (*input_line_pointer++ == '"')
    273   1.1     skrll 		  break;
    274   1.1     skrll 	      c = *input_line_pointer;
    275   1.1     skrll 	      *input_line_pointer = '\0';
    276   1.1     skrll 	      as_bad (_("bad .common segment %s"), p);
    277   1.1     skrll 	      *input_line_pointer = c;
    278   1.1     skrll 	      ignore_rest_of_line ();
    279   1.1     skrll 	      return NULL;
    280   1.1     skrll 	    }
    281   1.1     skrll 	  /* ??? Don't ask me why these are always global.  */
    282   1.1     skrll 	  is_local = 0;
    283   1.1     skrll 	}
    284   1.1     skrll       else
    285   1.1     skrll 	{
    286   1.1     skrll 	  input_line_pointer = save;
    287   1.1     skrll 	  align = parse_align (is_local);
    288   1.1     skrll 	  if (align == (addressT) -1)
    289   1.1     skrll 	    return NULL;
    290   1.1     skrll 	}
    291   1.1     skrll     }
    292   1.1     skrll 
    293   1.1     skrll   if (is_local)
    294   1.1     skrll     {
    295   1.1     skrll       bss_alloc (symbolP, size, align);
    296   1.1     skrll       S_CLEAR_EXTERNAL (symbolP);
    297   1.1     skrll     }
    298   1.1     skrll   else
    299   1.1     skrll     {
    300   1.1     skrll       S_SET_VALUE (symbolP, size);
    301   1.1     skrll       S_SET_ALIGN (symbolP, align);
    302   1.1     skrll       S_SET_EXTERNAL (symbolP);
    303   1.1     skrll       S_SET_SEGMENT (symbolP, elf_com_section_ptr);
    304   1.1     skrll     }
    305   1.1     skrll 
    306   1.1     skrll   symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT;
    307   1.1     skrll 
    308   1.1     skrll   return symbolP;
    309   1.1     skrll }
    310   1.1     skrll 
    311   1.1     skrll void
    312   1.1     skrll obj_elf_common (int is_common)
    313   1.1     skrll {
    314   1.1     skrll   if (flag_mri && is_common)
    315   1.1     skrll     s_mri_common (0);
    316   1.1     skrll   else
    317   1.1     skrll     s_comm_internal (0, elf_common_parse);
    318   1.1     skrll }
    319   1.1     skrll 
    320   1.1     skrll static void
    321   1.1     skrll obj_elf_tls_common (int ignore ATTRIBUTE_UNUSED)
    322   1.1     skrll {
    323   1.1     skrll   symbolS *symbolP = s_comm_internal (0, elf_common_parse);
    324   1.1     skrll 
    325   1.1     skrll   if (symbolP)
    326   1.1     skrll     symbol_get_bfdsym (symbolP)->flags |= BSF_THREAD_LOCAL;
    327   1.1     skrll }
    328   1.1     skrll 
    329   1.1     skrll static void
    330   1.1     skrll obj_elf_lcomm (int ignore ATTRIBUTE_UNUSED)
    331   1.1     skrll {
    332   1.1     skrll   symbolS *symbolP = s_comm_internal (0, s_lcomm_internal);
    333   1.1     skrll 
    334   1.1     skrll   if (symbolP)
    335   1.1     skrll     symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT;
    336   1.1     skrll }
    337   1.1     skrll 
    338   1.2     joerg static symbolS *
    339   1.2     joerg get_sym_from_input_line_and_check (void)
    340   1.2     joerg {
    341   1.2     joerg   char *name;
    342   1.2     joerg   char c;
    343   1.2     joerg   symbolS *sym;
    344   1.2     joerg 
    345   1.3  christos   c = get_symbol_name (& name);
    346   1.2     joerg   sym = symbol_find_or_make (name);
    347  1.13  christos   restore_line_pointer (c);
    348  1.13  christos   SKIP_WHITESPACE ();
    349   1.2     joerg 
    350   1.2     joerg   /* There is no symbol name if input_line_pointer has not moved.  */
    351   1.2     joerg   if (name == input_line_pointer)
    352   1.2     joerg     as_bad (_("Missing symbol name in directive"));
    353   1.2     joerg   return sym;
    354   1.2     joerg }
    355   1.2     joerg 
    356   1.1     skrll static void
    357   1.1     skrll obj_elf_local (int ignore ATTRIBUTE_UNUSED)
    358   1.1     skrll {
    359   1.1     skrll   int c;
    360   1.1     skrll   symbolS *symbolP;
    361   1.1     skrll 
    362   1.1     skrll   do
    363   1.1     skrll     {
    364   1.2     joerg       symbolP = get_sym_from_input_line_and_check ();
    365   1.2     joerg       c = *input_line_pointer;
    366   1.1     skrll       S_CLEAR_EXTERNAL (symbolP);
    367   1.1     skrll       symbol_get_obj (symbolP)->local = 1;
    368   1.1     skrll       if (c == ',')
    369   1.1     skrll 	{
    370   1.1     skrll 	  input_line_pointer++;
    371   1.1     skrll 	  SKIP_WHITESPACE ();
    372   1.1     skrll 	  if (*input_line_pointer == '\n')
    373   1.1     skrll 	    c = '\n';
    374   1.1     skrll 	}
    375   1.1     skrll     }
    376   1.1     skrll   while (c == ',');
    377   1.1     skrll   demand_empty_rest_of_line ();
    378   1.1     skrll }
    379   1.1     skrll 
    380   1.1     skrll static void
    381   1.1     skrll obj_elf_weak (int ignore ATTRIBUTE_UNUSED)
    382   1.1     skrll {
    383   1.1     skrll   int c;
    384   1.1     skrll   symbolS *symbolP;
    385   1.1     skrll 
    386   1.1     skrll   do
    387   1.1     skrll     {
    388   1.2     joerg       symbolP = get_sym_from_input_line_and_check ();
    389   1.2     joerg       c = *input_line_pointer;
    390   1.1     skrll       S_SET_WEAK (symbolP);
    391   1.1     skrll       if (c == ',')
    392   1.1     skrll 	{
    393   1.1     skrll 	  input_line_pointer++;
    394   1.1     skrll 	  SKIP_WHITESPACE ();
    395   1.1     skrll 	  if (*input_line_pointer == '\n')
    396   1.1     skrll 	    c = '\n';
    397   1.1     skrll 	}
    398   1.1     skrll     }
    399   1.1     skrll   while (c == ',');
    400   1.1     skrll   demand_empty_rest_of_line ();
    401   1.1     skrll }
    402   1.1     skrll 
    403   1.1     skrll static void
    404   1.1     skrll obj_elf_visibility (int visibility)
    405   1.1     skrll {
    406   1.1     skrll   int c;
    407   1.1     skrll   symbolS *symbolP;
    408   1.1     skrll   asymbol *bfdsym;
    409   1.1     skrll   elf_symbol_type *elfsym;
    410   1.1     skrll 
    411   1.1     skrll   do
    412   1.1     skrll     {
    413   1.2     joerg       symbolP = get_sym_from_input_line_and_check ();
    414   1.1     skrll 
    415   1.1     skrll       bfdsym = symbol_get_bfdsym (symbolP);
    416   1.9  christos       elfsym = elf_symbol_from (bfdsym);
    417   1.1     skrll 
    418   1.2     joerg       gas_assert (elfsym);
    419   1.1     skrll 
    420   1.1     skrll       elfsym->internal_elf_sym.st_other &= ~3;
    421   1.1     skrll       elfsym->internal_elf_sym.st_other |= visibility;
    422   1.1     skrll 
    423   1.2     joerg       c = *input_line_pointer;
    424   1.1     skrll       if (c == ',')
    425   1.1     skrll 	{
    426   1.1     skrll 	  input_line_pointer ++;
    427   1.1     skrll 
    428   1.1     skrll 	  SKIP_WHITESPACE ();
    429   1.1     skrll 
    430   1.1     skrll 	  if (*input_line_pointer == '\n')
    431   1.1     skrll 	    c = '\n';
    432   1.1     skrll 	}
    433   1.1     skrll     }
    434   1.1     skrll   while (c == ',');
    435   1.1     skrll 
    436   1.1     skrll   demand_empty_rest_of_line ();
    437   1.1     skrll }
    438   1.1     skrll 
    439   1.1     skrll static segT previous_section;
    440   1.1     skrll static int previous_subsection;
    441   1.1     skrll 
    442   1.1     skrll struct section_stack
    443   1.1     skrll {
    444   1.1     skrll   struct section_stack *next;
    445   1.1     skrll   segT seg, prev_seg;
    446   1.1     skrll   int subseg, prev_subseg;
    447   1.1     skrll };
    448   1.1     skrll 
    449   1.1     skrll static struct section_stack *section_stack;
    450   1.1     skrll 
    451   1.9  christos /* ELF section flags for unique sections.  */
    452   1.9  christos #define SEC_ASSEMBLER_SHF_MASK SHF_GNU_RETAIN
    453   1.9  christos 
    454  1.13  christos struct group_list
    455  1.13  christos {
    456  1.13  christos   asection **head;		/* Section lists.  */
    457  1.13  christos   unsigned int num_group;	/* Number of lists.  */
    458  1.13  christos   htab_t indexes; /* Maps group name to index in head array.  */
    459  1.13  christos };
    460  1.13  christos 
    461  1.13  christos static struct group_list groups;
    462   1.6  christos 
    463   1.9  christos static bool
    464  1.13  christos match_section (const asection *sec, const struct elf_section_match *match)
    465   1.1     skrll {
    466  1.13  christos   const char *linked_to_symbol_name = sec->map_head.linked_to_symbol_name;
    467   1.9  christos   unsigned int sh_info = elf_section_data (sec)->this_hdr.sh_info;
    468   1.9  christos   bfd_vma sh_flags = (elf_section_data (sec)->this_hdr.sh_flags
    469   1.9  christos 		      & SEC_ASSEMBLER_SHF_MASK);
    470   1.9  christos 
    471   1.9  christos   return (sh_info == match->sh_info
    472   1.9  christos 	  && sh_flags == match->sh_flags
    473   1.9  christos 	  && ((bfd_section_flags (sec) & SEC_ASSEMBLER_SECTION_ID)
    474   1.9  christos 	       == (match->flags & SEC_ASSEMBLER_SECTION_ID))
    475   1.9  christos 	  && sec->section_id == match->section_id
    476   1.9  christos 	  && (linked_to_symbol_name == match->linked_to_symbol_name
    477   1.9  christos 	      || (linked_to_symbol_name != NULL
    478   1.9  christos 		  && match->linked_to_symbol_name != NULL
    479   1.9  christos 		  && strcmp (linked_to_symbol_name,
    480   1.9  christos 			     match->linked_to_symbol_name) == 0)));
    481   1.1     skrll }
    482   1.1     skrll 
    483  1.13  christos /* Return TRUE iff SEC matches the section info INF.  */
    484  1.13  christos 
    485  1.13  christos static bool
    486  1.13  christos get_section_by_match (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, void *inf)
    487  1.13  christos {
    488  1.13  christos   struct elf_section_match *match = inf;
    489  1.13  christos   const char *gname = match->group_name;
    490  1.13  christos   const char *group_name = elf_group_name (sec);
    491  1.13  christos 
    492  1.13  christos   return ((group_name == gname
    493  1.13  christos 	   || (group_name != NULL
    494  1.13  christos 	       && gname != NULL
    495  1.13  christos 	       && strcmp (group_name, gname) == 0))
    496  1.13  christos 	  && match_section (sec, match));
    497  1.13  christos }
    498  1.13  christos 
    499  1.13  christos /* Go look in section lists kept per group for SEC_NAME with
    500  1.13  christos    properties given by MATCH.  If info for the group named by
    501  1.13  christos    MATCH->GROUP_NAME has been initialised, set GROUP_IDX.  */
    502  1.13  christos 
    503  1.13  christos static asection *
    504  1.13  christos group_section_find (const struct elf_section_match *match,
    505  1.13  christos 		    const char *sec_name,
    506  1.13  christos 		    unsigned int *group_idx)
    507  1.13  christos {
    508  1.13  christos   if (!groups.indexes)
    509  1.13  christos     {
    510  1.13  christos       groups.num_group = 0;
    511  1.13  christos       groups.head = NULL;
    512  1.13  christos       groups.indexes = htab_create_alloc (16, hash_string_tuple, eq_string_tuple,
    513  1.13  christos 					  NULL, notes_calloc, NULL);
    514  1.13  christos       *group_idx = ~0u;
    515  1.13  christos       return NULL;
    516  1.13  christos     }
    517  1.13  christos 
    518  1.13  christos   *group_idx = str_hash_find_int (groups.indexes, match->group_name);
    519  1.13  christos   if (*group_idx == ~0u)
    520  1.13  christos     return NULL;
    521  1.13  christos 
    522  1.13  christos   asection *s;
    523  1.13  christos   for (s = groups.head[*group_idx]; s != NULL; s = elf_next_in_group (s))
    524  1.13  christos     if ((s->name == sec_name
    525  1.13  christos 	 || strcmp (s->name, sec_name) == 0)
    526  1.13  christos 	&& match_section (s, match))
    527  1.13  christos       break;
    528  1.13  christos   return s;
    529  1.13  christos }
    530  1.13  christos 
    531  1.13  christos /* Insert SEC into section lists kept per group.  MATCH and GROUP_IDX
    532  1.13  christos    must be from a prior call to group_section_find.  */
    533  1.13  christos 
    534  1.13  christos static void
    535  1.13  christos group_section_insert (const struct elf_section_match *match,
    536  1.13  christos 		      asection *sec,
    537  1.13  christos 		      unsigned int *group_idx)
    538  1.13  christos {
    539  1.13  christos   if (*group_idx != ~0u)
    540  1.13  christos     {
    541  1.13  christos       elf_next_in_group (sec) = groups.head[*group_idx];
    542  1.13  christos       groups.head[*group_idx] = sec;
    543  1.13  christos       return;
    544  1.13  christos     }
    545  1.13  christos 
    546  1.13  christos   unsigned int i = groups.num_group;
    547  1.13  christos   if ((i & 127) == 0)
    548  1.13  christos     groups.head = XRESIZEVEC (asection *, groups.head, i + 128);
    549  1.13  christos   groups.head[i] = sec;
    550  1.13  christos   groups.num_group += 1;
    551  1.13  christos 
    552  1.13  christos   /* We keep the index into groups.head rather than the entry address
    553  1.13  christos      because groups.head may be realloc'd.  */
    554  1.13  christos   str_hash_insert_int (groups.indexes, match->group_name, i, 0);
    555  1.13  christos }
    556  1.13  christos 
    557   1.1     skrll /* Handle the .section pseudo-op.  This code supports two different
    558   1.1     skrll    syntaxes.
    559   1.1     skrll 
    560   1.1     skrll    The first is found on Solaris, and looks like
    561   1.1     skrll        .section ".sec1",#alloc,#execinstr,#write
    562   1.1     skrll    Here the names after '#' are the SHF_* flags to turn on for the
    563   1.1     skrll    section.  I'm not sure how it determines the SHT_* type (BFD
    564   1.1     skrll    doesn't really give us control over the type, anyhow).
    565   1.1     skrll 
    566   1.1     skrll    The second format is found on UnixWare, and probably most SVR4
    567   1.1     skrll    machines, and looks like
    568   1.1     skrll        .section .sec1,"a",@progbits
    569   1.1     skrll    The quoted string may contain any combination of a, w, x, and
    570   1.1     skrll    represents the SHF_* flags to turn on for the section.  The string
    571   1.1     skrll    beginning with '@' can be progbits or nobits.  There should be
    572   1.1     skrll    other possibilities, but I don't know what they are.  In any case,
    573   1.1     skrll    BFD doesn't really let us set the section type.  */
    574   1.1     skrll 
    575  1.12  christos static void
    576  1.12  christos change_section (const char *name,
    577  1.12  christos 		unsigned int type,
    578  1.12  christos 		bfd_vma attr,
    579  1.12  christos 		int entsize,
    580  1.12  christos 		struct elf_section_match *match_p,
    581  1.12  christos 		bool linkonce,
    582  1.12  christos 		bool push,
    583  1.12  christos 		subsegT new_subsection)
    584   1.1     skrll {
    585   1.1     skrll   asection *old_sec;
    586   1.1     skrll   segT sec;
    587   1.1     skrll   flagword flags;
    588   1.1     skrll   const struct bfd_elf_special_section *ssect;
    589   1.9  christos 
    590   1.9  christos   if (match_p == NULL)
    591   1.9  christos     {
    592   1.9  christos       static struct elf_section_match unused_match;
    593   1.9  christos       match_p = &unused_match;
    594   1.9  christos     }
    595   1.1     skrll 
    596   1.1     skrll #ifdef md_flush_pending_output
    597   1.1     skrll   md_flush_pending_output ();
    598   1.1     skrll #endif
    599   1.1     skrll 
    600   1.1     skrll   /* Switch to the section, creating it if necessary.  */
    601   1.1     skrll   if (push)
    602   1.1     skrll     {
    603   1.1     skrll       struct section_stack *elt;
    604   1.5  christos       elt = XNEW (struct section_stack);
    605   1.1     skrll       elt->next = section_stack;
    606   1.1     skrll       elt->seg = now_seg;
    607   1.1     skrll       elt->prev_seg = previous_section;
    608   1.1     skrll       elt->subseg = now_subseg;
    609   1.1     skrll       elt->prev_subseg = previous_subsection;
    610   1.1     skrll       section_stack = elt;
    611   1.1     skrll     }
    612   1.1     skrll 
    613   1.9  christos   obj_elf_section_change_hook ();
    614   1.9  christos 
    615  1.13  christos   unsigned int group_idx = ~0u;
    616  1.13  christos   if (match_p->group_name)
    617  1.13  christos     old_sec = group_section_find (match_p, name, &group_idx);
    618  1.13  christos   else
    619  1.13  christos     old_sec = bfd_get_section_by_name_if (stdoutput, name, get_section_by_match,
    620  1.13  christos 					  match_p);
    621   1.1     skrll   if (old_sec)
    622   1.1     skrll     {
    623   1.1     skrll       sec = old_sec;
    624  1.12  christos       subseg_set (sec, new_subsection);
    625   1.1     skrll     }
    626   1.1     skrll   else
    627  1.13  christos     {
    628  1.13  christos       sec = subseg_force_new (name, new_subsection);
    629  1.13  christos       if (match_p->group_name)
    630  1.13  christos 	group_section_insert (match_p, sec, &group_idx);
    631  1.13  christos     }
    632   1.1     skrll 
    633  1.14  christos   elf_backend_data *bed = get_elf_backend_data (stdoutput);
    634   1.1     skrll   ssect = (*bed->get_sec_type_attr) (stdoutput, sec);
    635   1.1     skrll 
    636   1.1     skrll   if (ssect != NULL)
    637   1.1     skrll     {
    638   1.9  christos       bool override = false;
    639   1.1     skrll 
    640   1.1     skrll       if (type == SHT_NULL)
    641   1.1     skrll 	type = ssect->type;
    642   1.1     skrll       else if (type != ssect->type)
    643   1.1     skrll 	{
    644   1.1     skrll 	  if (old_sec == NULL
    645   1.2     joerg 	      /* Some older versions of gcc will emit
    646   1.1     skrll 
    647   1.1     skrll 		 .section .init_array,"aw",@progbits
    648   1.1     skrll 
    649   1.1     skrll 		 for __attribute__ ((section (".init_array"))).
    650   1.1     skrll 		 "@progbits" is incorrect.  Also for x86-64 large bss
    651   1.2     joerg 		 sections, some older versions of gcc will emit
    652   1.1     skrll 
    653   1.1     skrll 		 .section .lbss,"aw",@progbits
    654   1.1     skrll 
    655   1.1     skrll 		 "@progbits" is incorrect.  */
    656   1.1     skrll #ifdef TC_I386
    657   1.1     skrll 	      && (bed->s->arch_size != 64
    658   1.1     skrll 		  || !(ssect->attr & SHF_X86_64_LARGE))
    659   1.1     skrll #endif
    660   1.1     skrll 	      && ssect->type != SHT_INIT_ARRAY
    661   1.1     skrll 	      && ssect->type != SHT_FINI_ARRAY
    662   1.1     skrll 	      && ssect->type != SHT_PREINIT_ARRAY)
    663   1.1     skrll 	    {
    664   1.1     skrll 	      /* We allow to specify any type for a .note section.  */
    665   1.5  christos 	      if (ssect->type != SHT_NOTE
    666   1.5  christos 		  /* Processor and application defined types are allowed too.  */
    667   1.5  christos 		  && type < SHT_LOPROC)
    668   1.1     skrll 		as_warn (_("setting incorrect section type for %s"),
    669   1.1     skrll 			 name);
    670   1.1     skrll 	    }
    671   1.1     skrll 	  else
    672   1.1     skrll 	    {
    673   1.1     skrll 	      as_warn (_("ignoring incorrect section type for %s"),
    674   1.1     skrll 		       name);
    675   1.1     skrll 	      type = ssect->type;
    676   1.1     skrll 	    }
    677   1.1     skrll 	}
    678   1.1     skrll 
    679   1.9  christos       if (old_sec == NULL && ((attr & ~(SHF_LINK_ORDER
    680   1.9  christos 					| SHF_MASKOS
    681   1.9  christos 					| SHF_MASKPROC))
    682   1.5  christos 			      & ~ssect->attr) != 0)
    683   1.1     skrll 	{
    684   1.9  christos 	  /* Strip SHF_GNU_RETAIN.  */
    685   1.9  christos 	  bfd_vma generic_attr = attr;
    686   1.9  christos 	  if (elf_tdata (stdoutput)->has_gnu_osabi)
    687   1.9  christos 	    generic_attr &= ~SHF_GNU_RETAIN;
    688   1.9  christos 
    689   1.1     skrll 	  /* As a GNU extension, we permit a .note section to be
    690   1.1     skrll 	     allocatable.  If the linker sees an allocatable .note
    691   1.1     skrll 	     section, it will create a PT_NOTE segment in the output
    692   1.1     skrll 	     file.  We also allow "x" for .note.GNU-stack.  */
    693   1.1     skrll 	  if (ssect->type == SHT_NOTE
    694   1.9  christos 	      && (generic_attr == SHF_ALLOC
    695   1.9  christos 		  || generic_attr == SHF_EXECINSTR))
    696   1.1     skrll 	    ;
    697   1.1     skrll 	  /* Allow different SHF_MERGE and SHF_STRINGS if we have
    698   1.1     skrll 	     something like .rodata.str.  */
    699   1.1     skrll 	  else if (ssect->suffix_length == -2
    700   1.1     skrll 		   && name[ssect->prefix_length] == '.'
    701   1.9  christos 		   && (generic_attr
    702   1.1     skrll 		       & ~ssect->attr
    703   1.1     skrll 		       & ~SHF_MERGE
    704   1.1     skrll 		       & ~SHF_STRINGS) == 0)
    705   1.1     skrll 	    ;
    706   1.1     skrll 	  /* .interp, .strtab and .symtab can have SHF_ALLOC.  */
    707   1.9  christos 	  else if (generic_attr == SHF_ALLOC
    708   1.1     skrll 		   && (strcmp (name, ".interp") == 0
    709   1.1     skrll 		       || strcmp (name, ".strtab") == 0
    710   1.1     skrll 		       || strcmp (name, ".symtab") == 0))
    711   1.9  christos 	    override = true;
    712   1.1     skrll 	  /* .note.GNU-stack can have SHF_EXECINSTR.  */
    713   1.9  christos 	  else if (generic_attr == SHF_EXECINSTR
    714   1.1     skrll 		   && strcmp (name, ".note.GNU-stack") == 0)
    715   1.9  christos 	    override = true;
    716   1.1     skrll #ifdef TC_ALPHA
    717   1.1     skrll 	  /* A section on Alpha may have SHF_ALPHA_GPREL.  */
    718   1.9  christos 	  else if ((generic_attr & ~ssect->attr) == SHF_ALPHA_GPREL)
    719   1.9  christos 	    override = true;
    720   1.1     skrll #endif
    721   1.3  christos #ifdef TC_RX
    722   1.9  christos 	  else if (generic_attr == (SHF_EXECINSTR | SHF_WRITE | SHF_ALLOC)
    723   1.3  christos 		   && (ssect->type == SHT_INIT_ARRAY
    724   1.3  christos 		       || ssect->type == SHT_FINI_ARRAY
    725   1.3  christos 		       || ssect->type == SHT_PREINIT_ARRAY))
    726   1.3  christos 	    /* RX init/fini arrays can and should have the "awx" attributes set.  */
    727   1.3  christos 	    ;
    728   1.3  christos #endif
    729   1.1     skrll 	  else
    730   1.1     skrll 	    {
    731   1.9  christos 	      if (match_p->group_name == NULL)
    732   1.1     skrll 		as_warn (_("setting incorrect section attributes for %s"),
    733   1.1     skrll 			 name);
    734   1.9  christos 	      override = true;
    735   1.1     skrll 	    }
    736   1.1     skrll 	}
    737   1.5  christos 
    738   1.1     skrll       if (!override && old_sec == NULL)
    739   1.1     skrll 	attr |= ssect->attr;
    740   1.1     skrll     }
    741   1.1     skrll 
    742   1.1     skrll   /* Convert ELF type and flags to BFD flags.  */
    743   1.1     skrll   flags = (SEC_RELOC
    744   1.1     skrll 	   | ((attr & SHF_WRITE) ? 0 : SEC_READONLY)
    745   1.1     skrll 	   | ((attr & SHF_ALLOC) ? SEC_ALLOC : 0)
    746   1.1     skrll 	   | (((attr & SHF_ALLOC) && type != SHT_NOBITS) ? SEC_LOAD : 0)
    747   1.1     skrll 	   | ((attr & SHF_EXECINSTR) ? SEC_CODE : 0)
    748   1.1     skrll 	   | ((attr & SHF_MERGE) ? SEC_MERGE : 0)
    749   1.1     skrll 	   | ((attr & SHF_STRINGS) ? SEC_STRINGS : 0)
    750   1.2     joerg 	   | ((attr & SHF_EXCLUDE) ? SEC_EXCLUDE: 0)
    751   1.1     skrll 	   | ((attr & SHF_TLS) ? SEC_THREAD_LOCAL : 0));
    752   1.1     skrll #ifdef md_elf_section_flags
    753   1.1     skrll   flags = md_elf_section_flags (flags, attr, type);
    754   1.1     skrll #endif
    755   1.1     skrll 
    756   1.1     skrll   if (linkonce)
    757   1.1     skrll     flags |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;
    758   1.1     skrll 
    759   1.9  christos   /* PR 28054: Set the SEC_ELF_OCTETS flag for debugging sections.
    760   1.9  christos      Based on the code in bfd/elf.c:_bfd_elf_make_section_from_shdr().
    761   1.9  christos 
    762   1.9  christos      FIXME: We do not set the SEC_DEBUGGING flag because that causes
    763   1.9  christos      problems for the FT32 and MSP430 targets.  Investigate and fix.  */
    764   1.9  christos   if ((flags & SEC_ALLOC) == 0 && name [0] == '.')
    765   1.9  christos     {
    766   1.9  christos       if (   startswith (name, ".debug")
    767   1.9  christos 	  || startswith (name, ".zdebug")
    768   1.9  christos 	  || startswith (name, ".gnu.debuglto_.debug_")
    769   1.9  christos 	  || startswith (name, ".gnu.linkonce.wi.")
    770   1.9  christos 	  || startswith (name, GNU_BUILD_ATTRS_SECTION_NAME)
    771   1.9  christos 	  || startswith (name, ".note.gnu"))
    772   1.9  christos 	flags |= SEC_ELF_OCTETS;
    773   1.9  christos     }
    774  1.13  christos 
    775   1.1     skrll   if (old_sec == NULL)
    776   1.1     skrll     {
    777   1.1     skrll       symbolS *secsym;
    778   1.1     skrll 
    779   1.2     joerg       if (type == SHT_NULL)
    780   1.2     joerg 	type = bfd_elf_get_default_section_type (flags);
    781   1.1     skrll       elf_section_type (sec) = type;
    782   1.1     skrll       elf_section_flags (sec) = attr;
    783   1.9  christos       elf_section_data (sec)->this_hdr.sh_info = match_p->sh_info;
    784   1.1     skrll 
    785   1.1     skrll       /* Prevent SEC_HAS_CONTENTS from being inadvertently set.  */
    786   1.1     skrll       if (type == SHT_NOBITS)
    787   1.1     skrll 	seg_info (sec)->bss = 1;
    788   1.1     skrll 
    789   1.9  christos       /* Set the section ID and flags.  */
    790   1.9  christos       sec->section_id = match_p->section_id;
    791   1.9  christos       flags |= match_p->flags;
    792   1.9  christos 
    793   1.9  christos       /* Set the linked-to symbol name.  */
    794   1.9  christos       sec->map_head.linked_to_symbol_name
    795   1.9  christos 	= match_p->linked_to_symbol_name;
    796   1.9  christos 
    797   1.8  christos       bfd_set_section_flags (sec, flags);
    798  1.14  christos       if (entsize != 0)
    799   1.1     skrll 	sec->entsize = entsize;
    800   1.9  christos       elf_group_name (sec) = match_p->group_name;
    801   1.1     skrll 
    802   1.1     skrll       /* Add a symbol for this section to the symbol table.  */
    803   1.1     skrll       secsym = symbol_find (name);
    804   1.1     skrll       if (secsym != NULL)
    805   1.9  christos 	{
    806   1.9  christos 	  /* We could be repurposing an undefined symbol here: make sure we
    807   1.9  christos 	     reset sy_value to look like other section symbols in order to avoid
    808   1.9  christos 	     trying to incorrectly resolve this section symbol later on.  */
    809   1.9  christos 	  static const expressionS exp = { .X_op = O_constant };
    810   1.9  christos 	  symbol_set_value_expression (secsym, &exp);
    811   1.9  christos 	  symbol_set_bfdsym (secsym, sec->symbol);
    812   1.9  christos 	}
    813   1.1     skrll       else
    814   1.1     skrll 	symbol_table_insert (section_symbol (sec));
    815   1.1     skrll     }
    816   1.1     skrll   else
    817   1.1     skrll     {
    818   1.1     skrll       if (type != SHT_NULL
    819   1.1     skrll 	  && (unsigned) type != elf_section_type (old_sec))
    820   1.9  christos 	{
    821   1.9  christos 	  if (ssect != NULL)
    822   1.9  christos 	    /* This is a special section with known type.  User
    823   1.9  christos 	       assembly might get the section type wrong; Even high
    824   1.9  christos 	       profile projects like glibc have done so in the past.
    825   1.9  christos 	       So don't error in this case.  */
    826   1.9  christos 	    as_warn (_("ignoring changed section type for %s"), name);
    827   1.9  christos 	  else
    828   1.9  christos 	    /* Do error when assembly isn't self-consistent.  */
    829   1.9  christos 	    as_bad (_("changed section type for %s"), name);
    830   1.9  christos 	}
    831   1.1     skrll 
    832   1.1     skrll       if (attr != 0)
    833   1.1     skrll 	{
    834   1.1     skrll 	  /* If section attributes are specified the second time we see a
    835   1.1     skrll 	     particular section, then check that they are the same as we
    836   1.1     skrll 	     saw the first time.  */
    837   1.1     skrll 	  if (((old_sec->flags ^ flags)
    838   1.1     skrll 	       & (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE
    839   1.1     skrll 		  | SEC_EXCLUDE | SEC_SORT_ENTRIES | SEC_MERGE | SEC_STRINGS
    840   1.1     skrll 		  | SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD
    841   1.1     skrll 		  | SEC_THREAD_LOCAL)))
    842   1.9  christos 	    {
    843   1.9  christos 	      if (ssect != NULL)
    844   1.9  christos 		as_warn (_("ignoring changed section attributes for %s"), name);
    845   1.9  christos 	      else
    846   1.9  christos 		as_bad (_("changed section attributes for %s"), name);
    847   1.9  christos 	    }
    848   1.5  christos 	  else
    849   1.5  christos 	    /* FIXME: Maybe we should consider removing a previously set
    850   1.9  christos 	       processor or application specific attribute as suspicious?  */
    851   1.5  christos 	    elf_section_flags (sec) = attr;
    852   1.5  christos 
    853  1.14  christos 	  if (entsize != 0
    854  1.13  christos 	      && old_sec->entsize != (unsigned) entsize)
    855   1.9  christos 	    as_bad (_("changed section entity size for %s"), name);
    856   1.1     skrll 	}
    857   1.1     skrll     }
    858   1.1     skrll 
    859   1.1     skrll #ifdef md_elf_section_change_hook
    860   1.1     skrll   md_elf_section_change_hook ();
    861   1.1     skrll #endif
    862   1.1     skrll }
    863   1.1     skrll 
    864  1.12  christos void
    865  1.12  christos obj_elf_change_section (const char *name,
    866  1.12  christos 			unsigned int type,
    867  1.12  christos 			bfd_vma attr,
    868  1.12  christos 			int entsize,
    869  1.12  christos 			struct elf_section_match *match_p,
    870  1.12  christos 			bool linkonce)
    871  1.12  christos {
    872  1.12  christos   change_section (name, type, attr, entsize, match_p, linkonce, false, 0);
    873  1.12  christos }
    874  1.12  christos 
    875   1.2     joerg static bfd_vma
    876  1.14  christos obj_elf_parse_section_letters (char *str, size_t len, bool push,
    877  1.14  christos 			       bool *is_clone, int *inherit, bfd_vma *gnu_attr,
    878  1.14  christos 			       bool *has_entsize)
    879   1.1     skrll {
    880   1.2     joerg   bfd_vma attr = 0;
    881  1.12  christos 
    882   1.9  christos   *is_clone = false;
    883  1.12  christos   *inherit = 0;
    884   1.1     skrll 
    885   1.1     skrll   while (len > 0)
    886   1.1     skrll     {
    887   1.1     skrll       switch (*str)
    888   1.1     skrll 	{
    889   1.1     skrll 	case 'a':
    890   1.1     skrll 	  attr |= SHF_ALLOC;
    891   1.9  christos 	  /* Compatibility.  */
    892   1.9  christos 	  if (len > 1 && str[1] == 'm')
    893   1.9  christos 	    {
    894   1.9  christos 	      attr |= SHF_MERGE;
    895   1.9  christos 	      str++, len--;
    896   1.9  christos 	      if (len > 1 && str[1] == 's')
    897   1.9  christos 		{
    898   1.9  christos 		  attr |= SHF_STRINGS;
    899   1.9  christos 		  str++, len--;
    900   1.9  christos 		}
    901   1.9  christos 	    }
    902   1.1     skrll 	  break;
    903  1.14  christos 	case 'd':
    904  1.14  christos 	  if (gnu_attr == NULL)
    905  1.14  christos 	    goto unrecognized;
    906  1.14  christos 	  *gnu_attr |= SHF_GNU_MBIND;
    907  1.14  christos 	  break;
    908   1.2     joerg 	case 'e':
    909   1.2     joerg 	  attr |= SHF_EXCLUDE;
    910   1.2     joerg 	  break;
    911   1.9  christos 	case 'o':
    912   1.9  christos 	  attr |= SHF_LINK_ORDER;
    913   1.9  christos 	  break;
    914   1.1     skrll 	case 'w':
    915   1.1     skrll 	  attr |= SHF_WRITE;
    916   1.1     skrll 	  break;
    917   1.1     skrll 	case 'x':
    918   1.1     skrll 	  attr |= SHF_EXECINSTR;
    919   1.1     skrll 	  break;
    920  1.14  christos 	case 'E':
    921  1.14  christos 	  *has_entsize = true;
    922  1.14  christos 	  break;
    923  1.14  christos 	case 'G':
    924  1.14  christos 	  attr |= SHF_GROUP;
    925  1.14  christos 	  break;
    926   1.1     skrll 	case 'M':
    927   1.1     skrll 	  attr |= SHF_MERGE;
    928   1.1     skrll 	  break;
    929  1.14  christos 	case 'R':
    930  1.14  christos 	  if (gnu_attr == NULL)
    931  1.14  christos 	    goto unrecognized;
    932  1.14  christos 	  *gnu_attr |= SHF_GNU_RETAIN;
    933  1.14  christos 	  break;
    934   1.1     skrll 	case 'S':
    935   1.1     skrll 	  attr |= SHF_STRINGS;
    936   1.1     skrll 	  break;
    937   1.1     skrll 	case 'T':
    938   1.1     skrll 	  attr |= SHF_TLS;
    939   1.1     skrll 	  break;
    940   1.2     joerg 	case '?':
    941   1.9  christos 	  *is_clone = true;
    942   1.2     joerg 	  break;
    943   1.1     skrll 	default:
    944  1.14  christos 	unrecognized:
    945   1.1     skrll 	  {
    946  1.14  christos 	    const char *md_extra = "";
    947  1.14  christos 
    948   1.1     skrll #ifdef md_elf_section_letter
    949  1.14  christos 	    bfd_vma md_attr = md_elf_section_letter (*str, &md_extra);
    950   1.2     joerg 	    if (md_attr != (bfd_vma) -1)
    951   1.1     skrll 	      attr |= md_attr;
    952   1.1     skrll 	    else
    953   1.1     skrll #endif
    954   1.5  christos 	      if (ISDIGIT (*str))
    955   1.5  christos 		{
    956   1.5  christos 		  char * end;
    957   1.9  christos 		  bfd_vma numeric_flags = strtoul (str, &end, 0);
    958   1.9  christos 
    959   1.9  christos 		  attr |= numeric_flags;
    960   1.9  christos 
    961  1.14  christos 		  if (gnu_attr != NULL)
    962   1.9  christos 		    {
    963   1.9  christos 		      /* Add flags in the SHF_MASKOS range to gnu_attr for
    964   1.9  christos 			 OSABIs that support those flags.
    965   1.9  christos 			 We can't just always set these bits in gnu_attr for
    966   1.9  christos 			 all OSABIs, since Binutils does not recognize all
    967   1.9  christos 			 SHF_MASKOS bits for non-GNU OSABIs.  It's therefore
    968   1.9  christos 			 possible that numeric flags are being used to set bits
    969   1.9  christos 			 in the SHF_MASKOS range for those targets, and we
    970   1.9  christos 			 don't want assembly to fail in those situations.  */
    971   1.9  christos 		      *gnu_attr |= (numeric_flags & SHF_MASKOS);
    972   1.9  christos 		    }
    973   1.5  christos 
    974   1.5  christos 		  /* Update str and len, allowing for the fact that
    975   1.5  christos 		     we will execute str++ and len-- below.  */
    976   1.5  christos 		  end --;
    977   1.5  christos 		  len -= (end - str);
    978   1.5  christos 		  str = end;
    979   1.5  christos 		}
    980  1.14  christos 	      else if (!*inherit && !attr
    981  1.14  christos 		       && (gnu_attr == NULL || !*gnu_attr)
    982  1.14  christos 		       && (*str == '+' || *str == '-'))
    983  1.12  christos 		*inherit = *str == '+' ? 1 : -1;
    984   1.5  christos 	      else
    985  1.14  christos 		{
    986  1.14  christos 		  as_bad (_("unrecognized .%ssection attribute: want %s%s%s,? or number"),
    987  1.14  christos 		    push ? "push" : "",
    988  1.14  christos 		    gnu_attr != NULL ? "a,d,e,o,w,x,E,G,M,R,S,T"
    989  1.14  christos 				     : "a,e,o,w,x,E,G,M,S,T",
    990  1.14  christos 		    md_extra != NULL ? "," : "", md_extra);
    991  1.14  christos 		  return attr;
    992  1.14  christos 		}
    993   1.1     skrll 	  }
    994   1.1     skrll 	  break;
    995   1.1     skrll 	}
    996   1.1     skrll       str++, len--;
    997   1.1     skrll     }
    998   1.1     skrll 
    999   1.1     skrll   return attr;
   1000   1.1     skrll }
   1001   1.1     skrll 
   1002   1.1     skrll static int
   1003   1.9  christos obj_elf_section_type (char *str, size_t len, bool warn)
   1004   1.1     skrll {
   1005   1.9  christos   if (len == 8 && startswith (str, "progbits"))
   1006   1.1     skrll     return SHT_PROGBITS;
   1007   1.9  christos   if (len == 6 && startswith (str, "nobits"))
   1008   1.1     skrll     return SHT_NOBITS;
   1009   1.9  christos   if (len == 4 && startswith (str, "note"))
   1010   1.1     skrll     return SHT_NOTE;
   1011   1.9  christos   if (len == 10 && startswith (str, "init_array"))
   1012   1.1     skrll     return SHT_INIT_ARRAY;
   1013   1.9  christos   if (len == 10 && startswith (str, "fini_array"))
   1014   1.1     skrll     return SHT_FINI_ARRAY;
   1015   1.9  christos   if (len == 13 && startswith (str, "preinit_array"))
   1016   1.1     skrll     return SHT_PREINIT_ARRAY;
   1017   1.1     skrll 
   1018   1.1     skrll #ifdef md_elf_section_type
   1019   1.1     skrll   {
   1020   1.1     skrll     int md_type = md_elf_section_type (str, len);
   1021   1.1     skrll     if (md_type >= 0)
   1022   1.1     skrll       return md_type;
   1023   1.1     skrll   }
   1024   1.1     skrll #endif
   1025   1.1     skrll 
   1026   1.5  christos   if (ISDIGIT (*str))
   1027   1.5  christos     {
   1028   1.5  christos       char * end;
   1029   1.5  christos       int type = strtoul (str, & end, 0);
   1030   1.5  christos 
   1031   1.5  christos       if (warn && (size_t) (end - str) != len)
   1032   1.5  christos 	as_warn (_("extraneous characters at end of numeric section type"));
   1033   1.5  christos 
   1034   1.5  christos       return type;
   1035   1.5  christos     }
   1036   1.5  christos 
   1037   1.1     skrll   if (warn)
   1038   1.1     skrll     as_warn (_("unrecognized section type"));
   1039   1.1     skrll   return 0;
   1040   1.1     skrll }
   1041   1.1     skrll 
   1042  1.12  christos #ifdef TC_SPARC
   1043   1.2     joerg static bfd_vma
   1044   1.1     skrll obj_elf_section_word (char *str, size_t len, int *type)
   1045   1.1     skrll {
   1046   1.1     skrll   int ret;
   1047   1.1     skrll 
   1048   1.9  christos   if (len == 5 && startswith (str, "write"))
   1049   1.1     skrll     return SHF_WRITE;
   1050   1.9  christos   if (len == 5 && startswith (str, "alloc"))
   1051   1.1     skrll     return SHF_ALLOC;
   1052   1.9  christos   if (len == 9 && startswith (str, "execinstr"))
   1053   1.1     skrll     return SHF_EXECINSTR;
   1054   1.9  christos   if (len == 7 && startswith (str, "exclude"))
   1055   1.2     joerg     return SHF_EXCLUDE;
   1056   1.9  christos   if (len == 3 && startswith (str, "tls"))
   1057   1.1     skrll     return SHF_TLS;
   1058   1.1     skrll 
   1059   1.9  christos   ret = obj_elf_section_type (str, len, false);
   1060   1.1     skrll   if (ret != 0)
   1061   1.1     skrll     *type = ret;
   1062   1.1     skrll   else
   1063   1.1     skrll     as_warn (_("unrecognized section attribute"));
   1064   1.1     skrll 
   1065   1.1     skrll   return 0;
   1066   1.1     skrll }
   1067  1.12  christos #endif
   1068   1.1     skrll 
   1069   1.1     skrll /* Get name of section.  */
   1070   1.5  christos const char *
   1071   1.1     skrll obj_elf_section_name (void)
   1072   1.1     skrll {
   1073   1.1     skrll   char *name;
   1074   1.1     skrll 
   1075   1.1     skrll   SKIP_WHITESPACE ();
   1076   1.1     skrll   if (*input_line_pointer == '"')
   1077   1.1     skrll     {
   1078   1.1     skrll       int dummy;
   1079   1.1     skrll 
   1080   1.1     skrll       name = demand_copy_C_string (&dummy);
   1081   1.1     skrll       if (name == NULL)
   1082   1.1     skrll 	{
   1083   1.1     skrll 	  ignore_rest_of_line ();
   1084   1.1     skrll 	  return NULL;
   1085   1.1     skrll 	}
   1086   1.1     skrll     }
   1087   1.1     skrll   else
   1088   1.1     skrll     {
   1089   1.1     skrll       char *end = input_line_pointer;
   1090   1.1     skrll 
   1091  1.13  christos       while (!is_whitespace (*end) && !is_end_of_stmt (*end) && *end != ',')
   1092   1.1     skrll 	end++;
   1093   1.1     skrll       if (end == input_line_pointer)
   1094   1.1     skrll 	{
   1095   1.1     skrll 	  as_bad (_("missing name"));
   1096   1.1     skrll 	  ignore_rest_of_line ();
   1097   1.1     skrll 	  return NULL;
   1098   1.1     skrll 	}
   1099   1.1     skrll 
   1100   1.9  christos       obstack_grow0 (&notes, input_line_pointer, end - input_line_pointer);
   1101   1.9  christos       name = obstack_base (&notes);
   1102   1.3  christos 
   1103   1.3  christos       while (flag_sectname_subst)
   1104   1.3  christos         {
   1105   1.3  christos 	  char *subst = strchr (name, '%');
   1106   1.3  christos 	  if (subst && subst[1] == 'S')
   1107   1.3  christos 	    {
   1108   1.9  christos 	      size_t head = subst - name;
   1109   1.9  christos 	      size_t tail = strlen (subst + 2) + 1;
   1110   1.9  christos 	      size_t slen = strlen (now_seg->name);
   1111   1.9  christos 
   1112   1.9  christos 	      if (slen > 2)
   1113   1.9  christos 		{
   1114   1.9  christos 		  obstack_blank (&notes, slen - 2);
   1115   1.9  christos 		  name = obstack_base (&notes);
   1116   1.9  christos 		}
   1117   1.9  christos 	      memmove (name + head + slen, name + head + 2, tail);
   1118   1.9  christos 	      memcpy (name + head, now_seg->name, slen);
   1119   1.3  christos 	    }
   1120   1.3  christos 	  else
   1121   1.3  christos 	    break;
   1122   1.3  christos 	}
   1123   1.3  christos 
   1124   1.9  christos       obstack_finish (&notes);
   1125   1.9  christos 
   1126   1.1     skrll #ifdef tc_canonicalize_section_name
   1127   1.1     skrll       name = tc_canonicalize_section_name (name);
   1128   1.1     skrll #endif
   1129   1.1     skrll       input_line_pointer = end;
   1130   1.1     skrll     }
   1131   1.1     skrll   SKIP_WHITESPACE ();
   1132   1.1     skrll   return name;
   1133   1.1     skrll }
   1134   1.1     skrll 
   1135  1.13  christos /* Arrange to put SEC, known to be in group GNAME into the per-group
   1136  1.13  christos    section lists kept by gas.  */
   1137  1.13  christos 
   1138  1.13  christos void
   1139  1.13  christos elf_set_group_name (asection *sec, const char *gname)
   1140  1.13  christos {
   1141  1.13  christos   elf_group_name (sec) = gname;
   1142  1.13  christos   elf_section_flags (sec) |= SHF_GROUP;
   1143  1.13  christos 
   1144  1.13  christos   struct elf_section_match match;
   1145  1.13  christos   match.group_name = gname;
   1146  1.13  christos   match.linked_to_symbol_name = sec->map_head.linked_to_symbol_name;
   1147  1.13  christos   match.section_id = sec->section_id;
   1148  1.13  christos   match.sh_info = elf_section_data (sec)->this_hdr.sh_info;
   1149  1.13  christos   match.sh_flags = (elf_section_data (sec)->this_hdr.sh_flags
   1150  1.13  christos 		    & SEC_ASSEMBLER_SHF_MASK);
   1151  1.13  christos   match.flags = bfd_section_flags (sec) & SEC_ASSEMBLER_SECTION_ID;
   1152  1.13  christos 
   1153  1.13  christos   unsigned int group_idx;
   1154  1.13  christos   if (!group_section_find (&match, sec->name, &group_idx))
   1155  1.13  christos     group_section_insert (&match, sec, &group_idx);
   1156  1.13  christos }
   1157  1.13  christos 
   1158   1.9  christos static void
   1159   1.9  christos obj_elf_attach_to_group (int dummy ATTRIBUTE_UNUSED)
   1160   1.9  christos {
   1161   1.9  christos   const char * gname = obj_elf_section_name ();
   1162   1.9  christos 
   1163   1.9  christos   if (gname == NULL)
   1164   1.9  christos     {
   1165   1.9  christos       as_warn (_("group name not parseable"));
   1166   1.9  christos       return;
   1167   1.9  christos     }
   1168   1.9  christos 
   1169   1.9  christos   if (elf_group_name (now_seg))
   1170   1.9  christos     {
   1171  1.12  christos       if (strcmp (elf_group_name (now_seg), gname) != 0)
   1172  1.12  christos 	as_warn (_("section %s already has a group (%s)"),
   1173  1.12  christos 		 bfd_section_name (now_seg), elf_group_name (now_seg));
   1174   1.9  christos       return;
   1175   1.9  christos     }
   1176  1.13  christos   elf_set_group_name (now_seg, gname);
   1177  1.13  christos }
   1178  1.13  christos 
   1179  1.13  christos /* Handle section related directives.
   1180   1.9  christos 
   1181  1.13  christos    Note on support for SFrame sections: These are generally expected to be
   1182  1.13  christos    generated by the assembler.  However, this function permits their direct
   1183  1.13  christos    creation by the user.  At the moment though, we go no extra mile by adding
   1184  1.13  christos    an explicit @sframe for SHT_GNU_SFRAME (using the numeric value of section
   1185  1.13  christos    type should suffice); Nor do we implement any outright refusal for
   1186  1.13  christos    non-supported targets via ELFOSABI-specific checks.  */
   1187   1.9  christos 
   1188   1.1     skrll void
   1189   1.1     skrll obj_elf_section (int push)
   1190   1.1     skrll {
   1191   1.9  christos   const char *name;
   1192   1.5  christos   char *beg;
   1193   1.2     joerg   int type, dummy;
   1194   1.2     joerg   bfd_vma attr;
   1195   1.8  christos   bfd_vma gnu_attr;
   1196   1.1     skrll   int entsize;
   1197  1.14  christos   bool linkonce, has_entsize;
   1198  1.12  christos   subsegT new_subsection = 0;
   1199   1.9  christos   struct elf_section_match match;
   1200   1.9  christos   unsigned long linked_to_section_index = -1UL;
   1201   1.1     skrll 
   1202   1.1     skrll   if (flag_mri)
   1203   1.1     skrll     {
   1204   1.1     skrll       char mri_type;
   1205   1.1     skrll 
   1206   1.1     skrll #ifdef md_flush_pending_output
   1207   1.1     skrll       md_flush_pending_output ();
   1208   1.1     skrll #endif
   1209   1.1     skrll 
   1210   1.9  christos       obj_elf_section_change_hook ();
   1211   1.1     skrll 
   1212   1.1     skrll       s_mri_sect (&mri_type);
   1213   1.1     skrll 
   1214   1.1     skrll #ifdef md_elf_section_change_hook
   1215   1.1     skrll       md_elf_section_change_hook ();
   1216   1.1     skrll #endif
   1217   1.1     skrll 
   1218   1.1     skrll       return;
   1219   1.1     skrll     }
   1220   1.1     skrll 
   1221   1.1     skrll   name = obj_elf_section_name ();
   1222   1.1     skrll   if (name == NULL)
   1223   1.1     skrll     return;
   1224   1.8  christos 
   1225   1.9  christos   memset (&match, 0, sizeof (match));
   1226   1.9  christos 
   1227   1.8  christos   symbolS * sym;
   1228   1.8  christos   if ((sym = symbol_find (name)) != NULL
   1229   1.8  christos       && ! symbol_section_p (sym)
   1230   1.8  christos       && S_IS_DEFINED (sym)
   1231   1.8  christos       && ! S_IS_VOLATILE (sym)
   1232   1.8  christos       && ! S_CAN_BE_REDEFINED (sym))
   1233   1.8  christos     {
   1234   1.8  christos       as_bad (_("section name '%s' already defined as another symbol"), name);
   1235   1.8  christos       ignore_rest_of_line ();
   1236   1.8  christos       return;
   1237   1.8  christos     }
   1238   1.1     skrll   type = SHT_NULL;
   1239   1.1     skrll   attr = 0;
   1240   1.8  christos   gnu_attr = 0;
   1241   1.1     skrll   entsize = 0;
   1242  1.14  christos   has_entsize = false;
   1243   1.1     skrll   linkonce = 0;
   1244   1.1     skrll 
   1245   1.1     skrll   if (*input_line_pointer == ',')
   1246   1.1     skrll     {
   1247   1.1     skrll       /* Skip the comma.  */
   1248   1.1     skrll       ++input_line_pointer;
   1249   1.1     skrll       SKIP_WHITESPACE ();
   1250   1.1     skrll 
   1251   1.1     skrll       if (push && ISDIGIT (*input_line_pointer))
   1252   1.1     skrll 	{
   1253   1.1     skrll 	  /* .pushsection has an optional subsection.  */
   1254  1.13  christos 	  new_subsection = get_absolute_expression ();
   1255   1.1     skrll 
   1256   1.1     skrll 	  SKIP_WHITESPACE ();
   1257   1.1     skrll 
   1258   1.1     skrll 	  /* Stop if we don't see a comma.  */
   1259   1.1     skrll 	  if (*input_line_pointer != ',')
   1260   1.1     skrll 	    goto done;
   1261   1.1     skrll 
   1262   1.1     skrll 	  /* Skip the comma.  */
   1263   1.1     skrll 	  ++input_line_pointer;
   1264   1.1     skrll 	  SKIP_WHITESPACE ();
   1265   1.1     skrll 	}
   1266   1.1     skrll 
   1267   1.1     skrll       if (*input_line_pointer == '"')
   1268   1.1     skrll 	{
   1269   1.9  christos 	  bool is_clone;
   1270  1.12  christos 	  int inherit;
   1271   1.2     joerg 
   1272   1.1     skrll 	  beg = demand_copy_C_string (&dummy);
   1273   1.1     skrll 	  if (beg == NULL)
   1274   1.1     skrll 	    {
   1275   1.1     skrll 	      ignore_rest_of_line ();
   1276   1.1     skrll 	      return;
   1277   1.1     skrll 	    }
   1278  1.14  christos 
   1279  1.14  christos 	  elf_backend_data *bed = get_elf_backend_data (stdoutput);
   1280  1.14  christos 	  bool maybe_gnu = (bed->elf_osabi == ELFOSABI_NONE
   1281  1.14  christos 			    || bed->elf_osabi == ELFOSABI_GNU
   1282  1.14  christos 			    || bed->elf_osabi == ELFOSABI_FREEBSD);
   1283  1.14  christos 	  attr = obj_elf_parse_section_letters (beg, strlen (beg), push,
   1284  1.14  christos 						&is_clone, &inherit,
   1285  1.14  christos 						maybe_gnu ? &gnu_attr : NULL,
   1286  1.14  christos 						&has_entsize);
   1287  1.12  christos 
   1288  1.12  christos 	  if (inherit > 0)
   1289  1.12  christos 	    attr |= elf_section_flags (now_seg);
   1290  1.12  christos 	  else if (inherit < 0)
   1291  1.12  christos 	    attr = elf_section_flags (now_seg) & ~attr;
   1292  1.12  christos 	  if (inherit)
   1293  1.12  christos 	    type = elf_section_type (now_seg);
   1294   1.1     skrll 
   1295  1.14  christos 	  if ((attr & (SHF_MERGE | SHF_STRINGS)) != 0)
   1296  1.14  christos 	    has_entsize = true;
   1297  1.14  christos 
   1298   1.1     skrll 	  SKIP_WHITESPACE ();
   1299   1.1     skrll 	  if (*input_line_pointer == ',')
   1300   1.1     skrll 	    {
   1301   1.1     skrll 	      char c;
   1302   1.1     skrll 	      char *save = input_line_pointer;
   1303   1.1     skrll 
   1304   1.1     skrll 	      ++input_line_pointer;
   1305   1.1     skrll 	      SKIP_WHITESPACE ();
   1306   1.1     skrll 	      c = *input_line_pointer;
   1307   1.1     skrll 	      if (c == '"')
   1308   1.1     skrll 		{
   1309   1.1     skrll 		  beg = demand_copy_C_string (&dummy);
   1310   1.1     skrll 		  if (beg == NULL)
   1311   1.1     skrll 		    {
   1312   1.1     skrll 		      ignore_rest_of_line ();
   1313   1.1     skrll 		      return;
   1314   1.1     skrll 		    }
   1315   1.9  christos 		  type = obj_elf_section_type (beg, strlen (beg), true);
   1316   1.1     skrll 		}
   1317   1.1     skrll 	      else if (c == '@' || c == '%')
   1318   1.1     skrll 		{
   1319   1.3  christos 		  ++input_line_pointer;
   1320   1.5  christos 
   1321   1.5  christos 		  if (ISDIGIT (* input_line_pointer))
   1322   1.8  christos 		    type = strtoul (input_line_pointer, &input_line_pointer, 0);
   1323   1.5  christos 		  else
   1324   1.5  christos 		    {
   1325   1.5  christos 		      c = get_symbol_name (& beg);
   1326   1.5  christos 		      (void) restore_line_pointer (c);
   1327   1.8  christos 		      type = obj_elf_section_type (beg,
   1328   1.8  christos 						   input_line_pointer - beg,
   1329   1.9  christos 						   true);
   1330   1.5  christos 		    }
   1331   1.1     skrll 		}
   1332   1.1     skrll 	      else
   1333   1.1     skrll 		input_line_pointer = save;
   1334   1.1     skrll 	    }
   1335   1.1     skrll 
   1336   1.1     skrll 	  SKIP_WHITESPACE ();
   1337  1.14  christos 	  if (has_entsize && *input_line_pointer == ',')
   1338   1.1     skrll 	    {
   1339   1.1     skrll 	      ++input_line_pointer;
   1340   1.1     skrll 	      SKIP_WHITESPACE ();
   1341  1.12  christos 	      if (inherit && *input_line_pointer == ','
   1342  1.14  christos 		  && ((bfd_section_flags (now_seg)
   1343  1.14  christos 		       & (SEC_MERGE | SEC_STRINGS)) != 0
   1344  1.14  christos 		      || now_seg->entsize))
   1345  1.14  christos 		goto fetch_entsize;
   1346  1.14  christos 	      if (is_end_of_stmt (*input_line_pointer)
   1347  1.13  christos 		  && (bfd_section_flags (now_seg)
   1348  1.13  christos 		      & (SEC_MERGE | SEC_STRINGS)) != 0)
   1349   1.1     skrll 		{
   1350  1.13  christos 		  /* ??? This is here for older versions of gcc that
   1351  1.13  christos 		     test for gas string merge support with
   1352  1.13  christos 		     '.section .rodata.str, "aMS", @progbits, 1'
   1353  1.13  christos 		     Unfortunately '@' begins a comment on arm.
   1354  1.13  christos 		     This isn't as_warn because gcc tests with
   1355  1.13  christos 		     --fatal-warnings. */
   1356  1.14  christos 		  as_tsktsk (_("missing section entity size, 1 assumed"));
   1357  1.13  christos 		  entsize = 1;
   1358  1.13  christos 		}
   1359  1.13  christos 	      else
   1360  1.13  christos 		{
   1361  1.13  christos 		  entsize = get_absolute_expression ();
   1362  1.13  christos 		  SKIP_WHITESPACE ();
   1363  1.13  christos 		  if (entsize <= 0)
   1364  1.13  christos 		    {
   1365  1.14  christos 		      as_warn (_("invalid section entity size"));
   1366  1.13  christos 		      attr &= ~(SHF_MERGE | SHF_STRINGS);
   1367  1.14  christos 		      has_entsize = false;
   1368  1.13  christos 		      entsize = 0;
   1369  1.13  christos 		    }
   1370   1.1     skrll 		}
   1371   1.1     skrll 	    }
   1372  1.14  christos 	  else if (has_entsize && inherit
   1373  1.14  christos 		    && ((bfd_section_flags (now_seg)
   1374  1.14  christos 			 & (SEC_MERGE | SEC_STRINGS)) != 0
   1375  1.14  christos 			|| now_seg->entsize))
   1376  1.12  christos 	    {
   1377  1.12  christos 	    fetch_entsize:
   1378  1.12  christos 	      entsize = now_seg->entsize;
   1379  1.12  christos 	    }
   1380   1.1     skrll 	  else if ((attr & SHF_MERGE) != 0)
   1381   1.1     skrll 	    {
   1382  1.13  christos 	      /* ??? Perhaps we should error here.  The manual says that
   1383  1.13  christos 		 entsize must be specified if SHF_MERGE is set.  */
   1384   1.1     skrll 	      as_warn (_("entity size for SHF_MERGE not specified"));
   1385  1.13  christos 	      attr &= ~(SHF_MERGE | SHF_STRINGS);
   1386  1.14  christos 	      has_entsize = false;
   1387  1.13  christos 	    }
   1388  1.13  christos 	  else if ((attr & SHF_STRINGS) != 0)
   1389  1.13  christos 	    {
   1390  1.13  christos 	      /* Ideally we would warn about this, but older versions
   1391  1.13  christos 		 of gas did not permit an entity size to be specified,
   1392  1.13  christos 		 so we have to default this silently for
   1393  1.13  christos 		 compatibility.  */
   1394  1.13  christos 	      entsize = 1;
   1395   1.1     skrll 	    }
   1396  1.14  christos 	  else if (has_entsize)
   1397  1.14  christos 	    {
   1398  1.14  christos 	      as_warn (_("entity size not specified"));
   1399  1.14  christos 	      has_entsize = false;
   1400  1.14  christos 	    }
   1401   1.1     skrll 
   1402  1.13  christos 	  if ((attr & (SHF_MERGE | SHF_STRINGS)) != 0 && type == SHT_NOBITS)
   1403  1.13  christos 	    as_warn (_("bogus SHF_MERGE / SHF_STRINGS for SHT_NOBITS section"));
   1404  1.13  christos 
   1405   1.9  christos 	  if ((attr & SHF_LINK_ORDER) != 0 && *input_line_pointer == ',')
   1406   1.9  christos 	    {
   1407   1.9  christos 	      ++input_line_pointer;
   1408   1.9  christos 	      SKIP_WHITESPACE ();
   1409   1.9  christos 	      /* Check for a numeric section index, rather than a symbol name.  */
   1410   1.9  christos 	      if (ISDIGIT (* input_line_pointer))
   1411   1.9  christos 		{
   1412   1.9  christos 		  linked_to_section_index = strtoul (input_line_pointer, & input_line_pointer, 0);
   1413   1.9  christos 		}
   1414  1.12  christos 	      else if (inherit && *input_line_pointer == ','
   1415  1.12  christos 		       && (elf_section_flags (now_seg) & SHF_LINK_ORDER) != 0)
   1416  1.12  christos 		goto fetch_linked_to;
   1417   1.9  christos 	      else
   1418   1.9  christos 		{
   1419   1.9  christos 		  char c;
   1420   1.9  christos 		  unsigned int length;
   1421   1.9  christos 
   1422   1.9  christos 		  c = get_symbol_name (& beg);
   1423   1.9  christos 		  (void) restore_line_pointer (c);
   1424   1.9  christos 		  length = input_line_pointer - beg;
   1425   1.9  christos 		  if (length)
   1426  1.13  christos 		    match.linked_to_symbol_name
   1427  1.13  christos 		      = notes_memdup (beg, length, length + 1);
   1428   1.9  christos 		}
   1429   1.9  christos 	    }
   1430  1.12  christos 	  else if ((attr & SHF_LINK_ORDER) != 0 && inherit
   1431  1.12  christos 		   && (elf_section_flags (now_seg) & SHF_LINK_ORDER) != 0)
   1432  1.12  christos 	    {
   1433  1.12  christos 	    fetch_linked_to:
   1434  1.12  christos 	      if (now_seg->map_head.linked_to_symbol_name)
   1435  1.12  christos 		match.linked_to_symbol_name =
   1436  1.12  christos 		  now_seg->map_head.linked_to_symbol_name;
   1437  1.12  christos 	      else
   1438  1.12  christos 		linked_to_section_index =
   1439  1.12  christos 		  elf_section_data (now_seg)->this_hdr.sh_link;
   1440  1.12  christos 	    }
   1441   1.9  christos 
   1442   1.2     joerg 	  if ((attr & SHF_GROUP) != 0 && is_clone)
   1443   1.2     joerg 	    {
   1444   1.2     joerg 	      as_warn (_("? section flag ignored with G present"));
   1445   1.9  christos 	      is_clone = false;
   1446   1.2     joerg 	    }
   1447   1.9  christos 
   1448   1.1     skrll 	  if ((attr & SHF_GROUP) != 0 && *input_line_pointer == ',')
   1449   1.1     skrll 	    {
   1450   1.1     skrll 	      ++input_line_pointer;
   1451  1.12  christos 	      SKIP_WHITESPACE ();
   1452  1.12  christos 	      if (inherit && *input_line_pointer == ','
   1453  1.12  christos 		  && (elf_section_flags (now_seg) & SHF_GROUP) != 0)
   1454  1.12  christos 		goto fetch_group;
   1455   1.9  christos 	      match.group_name = obj_elf_section_name ();
   1456   1.9  christos 	      if (match.group_name == NULL)
   1457   1.1     skrll 		attr &= ~SHF_GROUP;
   1458   1.2     joerg 	      else if (*input_line_pointer == ',')
   1459   1.1     skrll 		{
   1460   1.2     joerg 		  ++input_line_pointer;
   1461   1.2     joerg 		  SKIP_WHITESPACE ();
   1462   1.9  christos 		  if (startswith (input_line_pointer, "comdat"))
   1463   1.2     joerg 		    {
   1464   1.2     joerg 		      input_line_pointer += 6;
   1465   1.2     joerg 		      linkonce = 1;
   1466   1.2     joerg 		    }
   1467   1.1     skrll 		}
   1468   1.9  christos 	      else if (startswith (name, ".gnu.linkonce"))
   1469   1.1     skrll 		linkonce = 1;
   1470   1.1     skrll 	    }
   1471  1.12  christos 	  else if ((attr & SHF_GROUP) != 0 && inherit
   1472  1.12  christos 		   && (elf_section_flags (now_seg) & SHF_GROUP) != 0)
   1473  1.12  christos 	    {
   1474  1.12  christos 	    fetch_group:
   1475  1.12  christos 	      match.group_name = elf_group_name (now_seg);
   1476  1.12  christos 	      linkonce =
   1477  1.12  christos 	        (bfd_section_flags (now_seg) & SEC_LINK_ONCE) != 0;
   1478  1.12  christos 	    }
   1479   1.1     skrll 	  else if ((attr & SHF_GROUP) != 0)
   1480   1.1     skrll 	    {
   1481   1.1     skrll 	      as_warn (_("group name for SHF_GROUP not specified"));
   1482   1.1     skrll 	      attr &= ~SHF_GROUP;
   1483   1.1     skrll 	    }
   1484   1.2     joerg 
   1485   1.2     joerg 	  if (is_clone)
   1486   1.2     joerg 	    {
   1487   1.2     joerg 	      const char *now_group = elf_group_name (now_seg);
   1488   1.2     joerg 	      if (now_group != NULL)
   1489   1.2     joerg 		{
   1490   1.9  christos 		  match.group_name = now_group;
   1491   1.2     joerg 		  linkonce = (now_seg->flags & SEC_LINK_ONCE) != 0;
   1492   1.2     joerg 		}
   1493   1.2     joerg 	    }
   1494   1.6  christos 
   1495   1.8  christos 	  if ((gnu_attr & SHF_GNU_MBIND) != 0 && *input_line_pointer == ',')
   1496   1.6  christos 	    {
   1497   1.9  christos 	      char *save = input_line_pointer;
   1498   1.6  christos 	      ++input_line_pointer;
   1499   1.6  christos 	      SKIP_WHITESPACE ();
   1500   1.6  christos 	      if (ISDIGIT (* input_line_pointer))
   1501   1.6  christos 		{
   1502   1.6  christos 		  char *t = input_line_pointer;
   1503   1.9  christos 		  match.sh_info = strtoul (input_line_pointer,
   1504   1.9  christos 					&input_line_pointer, 0);
   1505  1.13  christos 		  if (match.sh_info == -1u)
   1506   1.6  christos 		    {
   1507   1.6  christos 		      as_warn (_("unsupported mbind section info: %s"), t);
   1508   1.9  christos 		      match.sh_info = 0;
   1509   1.6  christos 		    }
   1510   1.6  christos 		}
   1511   1.9  christos 	      else
   1512   1.9  christos 		input_line_pointer = save;
   1513   1.9  christos 	    }
   1514   1.9  christos 
   1515   1.9  christos 	  if ((gnu_attr & SHF_GNU_RETAIN) != 0)
   1516   1.9  christos 	    match.sh_flags |= SHF_GNU_RETAIN;
   1517   1.9  christos 
   1518   1.9  christos 	  if (*input_line_pointer == ',')
   1519   1.9  christos 	    {
   1520   1.9  christos 	      char *save = input_line_pointer;
   1521   1.9  christos 
   1522   1.9  christos 	      ++input_line_pointer;
   1523   1.9  christos 	      SKIP_WHITESPACE ();
   1524   1.9  christos 	      if (startswith (input_line_pointer, "unique"))
   1525   1.9  christos 		{
   1526   1.9  christos 		  input_line_pointer += 6;
   1527   1.9  christos 		  SKIP_WHITESPACE ();
   1528   1.9  christos 		  if (*input_line_pointer == ',')
   1529   1.9  christos 		    {
   1530   1.9  christos 		      ++input_line_pointer;
   1531   1.9  christos 		      SKIP_WHITESPACE ();
   1532   1.9  christos 		      if (ISDIGIT (* input_line_pointer))
   1533   1.9  christos 			{
   1534   1.9  christos 			  bfd_vma id;
   1535   1.9  christos 			  bool overflow;
   1536   1.9  christos 			  char *t = input_line_pointer;
   1537   1.9  christos 			  if (sizeof (bfd_vma) <= sizeof (unsigned long))
   1538   1.9  christos 			    {
   1539   1.9  christos 			      errno = 0;
   1540   1.9  christos 			      id = strtoul (input_line_pointer,
   1541   1.9  christos 					    &input_line_pointer, 0);
   1542  1.13  christos 			      overflow = id == -1ul && errno == ERANGE;
   1543   1.9  christos 			    }
   1544   1.9  christos 			  else
   1545   1.9  christos 			    {
   1546   1.9  christos 			      id = bfd_scan_vma
   1547   1.9  christos 				(input_line_pointer,
   1548   1.9  christos 				 (const char **) &input_line_pointer, 0);
   1549   1.9  christos 			      overflow = id == ~(bfd_vma) 0;
   1550   1.9  christos 			    }
   1551  1.13  christos 			  if (overflow || id > -1u)
   1552   1.9  christos 			    {
   1553   1.9  christos 			      char *linefeed, saved_char = 0;
   1554   1.9  christos 			      if ((linefeed = strchr (t, '\n')) != NULL)
   1555   1.9  christos 				{
   1556   1.9  christos 				  saved_char = *linefeed;
   1557   1.9  christos 				  *linefeed = '\0';
   1558   1.9  christos 				}
   1559   1.9  christos 			      as_bad (_("unsupported section id: %s"), t);
   1560   1.9  christos 			      if (saved_char)
   1561   1.9  christos 				*linefeed = saved_char;
   1562   1.9  christos 			    }
   1563   1.9  christos 			  else
   1564   1.9  christos 			    {
   1565   1.9  christos 			      match.section_id = id;
   1566   1.9  christos 			      match.flags |= SEC_ASSEMBLER_SECTION_ID;
   1567   1.9  christos 			    }
   1568   1.9  christos 			}
   1569   1.9  christos 		    }
   1570   1.9  christos 		}
   1571   1.9  christos 	      else
   1572   1.9  christos 		input_line_pointer = save;
   1573   1.6  christos 	    }
   1574   1.1     skrll 	}
   1575  1.12  christos #ifdef TC_SPARC
   1576   1.1     skrll       else
   1577   1.1     skrll 	{
   1578   1.1     skrll 	  do
   1579   1.1     skrll 	    {
   1580   1.1     skrll 	      char c;
   1581   1.1     skrll 
   1582   1.1     skrll 	      SKIP_WHITESPACE ();
   1583   1.1     skrll 	      if (*input_line_pointer != '#')
   1584   1.1     skrll 		{
   1585   1.1     skrll 		  as_bad (_("character following name is not '#'"));
   1586   1.1     skrll 		  ignore_rest_of_line ();
   1587   1.1     skrll 		  return;
   1588   1.1     skrll 		}
   1589   1.3  christos 	      ++input_line_pointer;
   1590   1.3  christos 	      c = get_symbol_name (& beg);
   1591   1.3  christos 	      (void) restore_line_pointer (c);
   1592   1.1     skrll 
   1593   1.8  christos 	      attr |= obj_elf_section_word (beg, input_line_pointer - beg,
   1594   1.8  christos 					    &type);
   1595   1.1     skrll 
   1596   1.1     skrll 	      SKIP_WHITESPACE ();
   1597   1.1     skrll 	    }
   1598   1.1     skrll 	  while (*input_line_pointer++ == ',');
   1599   1.1     skrll 	  --input_line_pointer;
   1600   1.1     skrll 	}
   1601  1.12  christos #endif
   1602   1.1     skrll     }
   1603   1.1     skrll 
   1604   1.9  christos  done:
   1605   1.1     skrll   demand_empty_rest_of_line ();
   1606   1.1     skrll 
   1607   1.9  christos   if ((gnu_attr & (SHF_GNU_MBIND | SHF_GNU_RETAIN)) != 0)
   1608   1.8  christos     {
   1609   1.9  christos       bool mbind_p = (gnu_attr & SHF_GNU_MBIND) != 0;
   1610   1.8  christos 
   1611   1.9  christos       if (mbind_p && (attr & SHF_ALLOC) == 0)
   1612   1.8  christos 	as_bad (_("SHF_ALLOC isn't set for GNU_MBIND section: %s"), name);
   1613   1.8  christos 
   1614  1.14  christos       if (mbind_p)
   1615  1.14  christos 	elf_tdata (stdoutput)->has_gnu_osabi |= elf_gnu_osabi_mbind;
   1616  1.14  christos       if ((gnu_attr & SHF_GNU_RETAIN) != 0)
   1617  1.14  christos 	elf_tdata (stdoutput)->has_gnu_osabi |= elf_gnu_osabi_retain;
   1618   1.9  christos 
   1619  1.14  christos       attr |= gnu_attr;
   1620   1.9  christos     }
   1621   1.9  christos 
   1622  1.12  christos   change_section (name, type, attr, entsize, &match, linkonce, push,
   1623  1.12  christos 		  new_subsection);
   1624   1.9  christos 
   1625   1.9  christos   if (linked_to_section_index != -1UL)
   1626   1.9  christos     {
   1627   1.9  christos       elf_section_flags (now_seg) |= SHF_LINK_ORDER;
   1628   1.9  christos       elf_section_data (now_seg)->this_hdr.sh_link = linked_to_section_index;
   1629   1.9  christos       /* FIXME: Should we perform some sanity checking on the section index ?  */
   1630   1.8  christos     }
   1631   1.1     skrll }
   1632   1.1     skrll 
   1633   1.9  christos /* Change to the .bss section.  */
   1634   1.9  christos 
   1635   1.9  christos void
   1636   1.9  christos obj_elf_bss (int i ATTRIBUTE_UNUSED)
   1637   1.9  christos {
   1638   1.9  christos   int temp;
   1639   1.9  christos 
   1640   1.9  christos #ifdef md_flush_pending_output
   1641   1.9  christos   md_flush_pending_output ();
   1642   1.9  christos #endif
   1643   1.9  christos 
   1644   1.9  christos   obj_elf_section_change_hook ();
   1645   1.9  christos 
   1646   1.9  christos   temp = get_absolute_expression ();
   1647  1.13  christos   subseg_set (bss_section, temp);
   1648   1.9  christos   demand_empty_rest_of_line ();
   1649   1.9  christos 
   1650   1.9  christos #ifdef md_elf_section_change_hook
   1651   1.9  christos   md_elf_section_change_hook ();
   1652   1.9  christos #endif
   1653   1.9  christos }
   1654   1.9  christos 
   1655   1.1     skrll /* Change to the .data section.  */
   1656   1.1     skrll 
   1657   1.1     skrll void
   1658   1.1     skrll obj_elf_data (int i)
   1659   1.1     skrll {
   1660   1.1     skrll #ifdef md_flush_pending_output
   1661   1.1     skrll   md_flush_pending_output ();
   1662   1.1     skrll #endif
   1663   1.1     skrll 
   1664   1.9  christos   obj_elf_section_change_hook ();
   1665   1.9  christos 
   1666   1.1     skrll   s_data (i);
   1667   1.1     skrll 
   1668   1.1     skrll #ifdef md_elf_section_change_hook
   1669   1.1     skrll   md_elf_section_change_hook ();
   1670   1.1     skrll #endif
   1671   1.1     skrll }
   1672   1.1     skrll 
   1673   1.1     skrll /* Change to the .text section.  */
   1674   1.1     skrll 
   1675   1.1     skrll void
   1676   1.1     skrll obj_elf_text (int i)
   1677   1.1     skrll {
   1678   1.1     skrll #ifdef md_flush_pending_output
   1679   1.1     skrll   md_flush_pending_output ();
   1680   1.1     skrll #endif
   1681   1.1     skrll 
   1682   1.9  christos   obj_elf_section_change_hook ();
   1683   1.9  christos 
   1684   1.1     skrll   s_text (i);
   1685   1.1     skrll 
   1686   1.1     skrll #ifdef md_elf_section_change_hook
   1687   1.1     skrll   md_elf_section_change_hook ();
   1688   1.1     skrll #endif
   1689   1.1     skrll }
   1690   1.1     skrll 
   1691   1.1     skrll /* Change to the *ABS* section.  */
   1692   1.1     skrll 
   1693   1.1     skrll void
   1694   1.1     skrll obj_elf_struct (int i)
   1695   1.1     skrll {
   1696   1.1     skrll #ifdef md_flush_pending_output
   1697   1.1     skrll   md_flush_pending_output ();
   1698   1.1     skrll #endif
   1699   1.1     skrll 
   1700   1.9  christos   obj_elf_section_change_hook ();
   1701   1.9  christos 
   1702   1.1     skrll   s_struct (i);
   1703   1.1     skrll 
   1704   1.1     skrll #ifdef md_elf_section_change_hook
   1705   1.1     skrll   md_elf_section_change_hook ();
   1706   1.1     skrll #endif
   1707   1.1     skrll }
   1708   1.1     skrll 
   1709   1.1     skrll static void
   1710   1.1     skrll obj_elf_subsection (int ignore ATTRIBUTE_UNUSED)
   1711   1.1     skrll {
   1712   1.1     skrll   int temp;
   1713   1.1     skrll 
   1714   1.1     skrll #ifdef md_flush_pending_output
   1715   1.1     skrll   md_flush_pending_output ();
   1716   1.1     skrll #endif
   1717   1.1     skrll 
   1718   1.9  christos   obj_elf_section_change_hook ();
   1719   1.1     skrll 
   1720   1.1     skrll   temp = get_absolute_expression ();
   1721  1.13  christos   subseg_set (now_seg, temp);
   1722   1.1     skrll   demand_empty_rest_of_line ();
   1723   1.1     skrll 
   1724   1.1     skrll #ifdef md_elf_section_change_hook
   1725   1.1     skrll   md_elf_section_change_hook ();
   1726   1.1     skrll #endif
   1727   1.1     skrll }
   1728   1.1     skrll 
   1729   1.1     skrll /* This can be called from the processor backends if they change
   1730   1.1     skrll    sections.  */
   1731   1.1     skrll 
   1732   1.1     skrll void
   1733   1.1     skrll obj_elf_section_change_hook (void)
   1734   1.1     skrll {
   1735   1.1     skrll   previous_section = now_seg;
   1736   1.1     skrll   previous_subsection = now_subseg;
   1737   1.1     skrll }
   1738   1.1     skrll 
   1739   1.1     skrll void
   1740   1.1     skrll obj_elf_previous (int ignore ATTRIBUTE_UNUSED)
   1741   1.1     skrll {
   1742   1.1     skrll   segT new_section;
   1743   1.1     skrll   int new_subsection;
   1744   1.1     skrll 
   1745   1.1     skrll   if (previous_section == 0)
   1746   1.1     skrll     {
   1747   1.1     skrll       as_warn (_(".previous without corresponding .section; ignored"));
   1748   1.1     skrll       return;
   1749   1.1     skrll     }
   1750   1.1     skrll 
   1751   1.1     skrll #ifdef md_flush_pending_output
   1752   1.1     skrll   md_flush_pending_output ();
   1753   1.1     skrll #endif
   1754   1.1     skrll 
   1755   1.1     skrll   new_section = previous_section;
   1756   1.1     skrll   new_subsection = previous_subsection;
   1757   1.9  christos   obj_elf_section_change_hook ();
   1758   1.9  christos 
   1759   1.1     skrll   subseg_set (new_section, new_subsection);
   1760   1.1     skrll 
   1761   1.1     skrll #ifdef md_elf_section_change_hook
   1762   1.1     skrll   md_elf_section_change_hook ();
   1763   1.1     skrll #endif
   1764   1.1     skrll }
   1765   1.1     skrll 
   1766   1.1     skrll static void
   1767   1.1     skrll obj_elf_popsection (int xxx ATTRIBUTE_UNUSED)
   1768   1.1     skrll {
   1769   1.1     skrll   struct section_stack *top = section_stack;
   1770   1.1     skrll 
   1771   1.1     skrll   if (top == NULL)
   1772   1.1     skrll     {
   1773   1.1     skrll       as_warn (_(".popsection without corresponding .pushsection; ignored"));
   1774   1.1     skrll       return;
   1775   1.1     skrll     }
   1776   1.1     skrll 
   1777   1.1     skrll #ifdef md_flush_pending_output
   1778   1.1     skrll   md_flush_pending_output ();
   1779   1.1     skrll #endif
   1780   1.1     skrll 
   1781   1.1     skrll   section_stack = top->next;
   1782   1.1     skrll   previous_section = top->prev_seg;
   1783   1.1     skrll   previous_subsection = top->prev_subseg;
   1784   1.1     skrll   subseg_set (top->seg, top->subseg);
   1785   1.1     skrll   free (top);
   1786   1.1     skrll 
   1787   1.1     skrll #ifdef md_elf_section_change_hook
   1788   1.1     skrll   md_elf_section_change_hook ();
   1789   1.1     skrll #endif
   1790   1.1     skrll }
   1791   1.1     skrll 
   1792   1.1     skrll static void
   1793   1.1     skrll obj_elf_line (int ignore ATTRIBUTE_UNUSED)
   1794   1.1     skrll {
   1795   1.1     skrll   /* Assume delimiter is part of expression.  BSD4.2 as fails with
   1796   1.1     skrll      delightful bug, so we are not being incompatible here.  */
   1797   1.1     skrll   new_logical_line (NULL, get_absolute_expression ());
   1798   1.1     skrll   demand_empty_rest_of_line ();
   1799   1.1     skrll }
   1800   1.1     skrll 
   1801   1.9  christos static struct elf_versioned_name_list *
   1802   1.9  christos obj_elf_find_and_add_versioned_name (const char *version_name,
   1803   1.9  christos 				     const char *sym_name,
   1804   1.9  christos 				     const char *ver,
   1805   1.9  christos 				     struct elf_obj_sy *sy_obj)
   1806   1.9  christos {
   1807   1.9  christos   struct elf_versioned_name_list *versioned_name;
   1808   1.9  christos   const char *p;
   1809   1.9  christos 
   1810   1.9  christos   for (p = ver + 1; *p == ELF_VER_CHR; p++)
   1811   1.9  christos     ;
   1812   1.9  christos 
   1813   1.9  christos   /* NB: Since some tests in ld/testsuite/ld-elfvers have no version
   1814   1.9  christos      names, we have to disable this.  */
   1815   1.9  christos   if (0 && *p == '\0')
   1816   1.9  christos     {
   1817   1.9  christos       as_bad (_("missing version name in `%s' for symbol `%s'"),
   1818   1.9  christos 	      version_name, sym_name);
   1819   1.9  christos       return NULL;
   1820   1.9  christos     }
   1821   1.9  christos 
   1822   1.9  christos   versioned_name = sy_obj->versioned_name;
   1823   1.9  christos 
   1824   1.9  christos   switch (p - ver)
   1825   1.9  christos     {
   1826   1.9  christos     case 1:
   1827   1.9  christos     case 2:
   1828   1.9  christos       break;
   1829   1.9  christos     case 3:
   1830   1.9  christos       if (sy_obj->rename)
   1831   1.9  christos 	{
   1832   1.9  christos 	  if (strcmp (versioned_name->name, version_name) == 0)
   1833   1.9  christos 	    return versioned_name;
   1834   1.9  christos 	  else
   1835   1.9  christos 	    {
   1836   1.9  christos 	      as_bad (_("only one version name with `@@@' is allowed "
   1837   1.9  christos 			"for symbol `%s'"), sym_name);
   1838   1.9  christos 	      return NULL;
   1839   1.9  christos 	    }
   1840   1.9  christos 	}
   1841   1.9  christos       sy_obj->rename = true;
   1842   1.9  christos       break;
   1843   1.9  christos     default:
   1844   1.9  christos       as_bad (_("invalid version name '%s' for symbol `%s'"),
   1845   1.9  christos 	      version_name, sym_name);
   1846   1.9  christos       return NULL;
   1847   1.9  christos     }
   1848   1.9  christos 
   1849   1.9  christos   for (;
   1850   1.9  christos        versioned_name != NULL;
   1851   1.9  christos        versioned_name = versioned_name->next)
   1852   1.9  christos     if (strcmp (versioned_name->name, version_name) == 0)
   1853   1.9  christos       return versioned_name;
   1854   1.9  christos 
   1855   1.9  christos   /* Add this versioned name to the head of the list,  */
   1856  1.13  christos   versioned_name = notes_alloc (sizeof (*versioned_name));
   1857  1.13  christos   versioned_name->name = notes_strdup (version_name);
   1858   1.9  christos   versioned_name->next = sy_obj->versioned_name;
   1859   1.9  christos   sy_obj->versioned_name = versioned_name;
   1860   1.9  christos 
   1861   1.9  christos   return versioned_name;
   1862   1.9  christos }
   1863   1.9  christos 
   1864   1.1     skrll /* This handles the .symver pseudo-op, which is used to specify a
   1865   1.1     skrll    symbol version.  The syntax is ``.symver NAME,SYMVERNAME''.
   1866   1.1     skrll    SYMVERNAME may contain ELF_VER_CHR ('@') characters.  This
   1867   1.1     skrll    pseudo-op causes the assembler to emit a symbol named SYMVERNAME
   1868   1.1     skrll    with the same value as the symbol NAME.  */
   1869   1.1     skrll 
   1870   1.1     skrll static void
   1871   1.1     skrll obj_elf_symver (int ignore ATTRIBUTE_UNUSED)
   1872   1.1     skrll {
   1873   1.1     skrll   char *name;
   1874   1.9  christos   const char *sym_name;
   1875   1.1     skrll   char c;
   1876   1.1     skrll   char old_lexat;
   1877   1.1     skrll   symbolS *sym;
   1878   1.9  christos   struct elf_obj_sy *sy_obj;
   1879   1.9  christos   char *p;
   1880   1.1     skrll 
   1881   1.2     joerg   sym = get_sym_from_input_line_and_check ();
   1882   1.1     skrll 
   1883   1.1     skrll   if (*input_line_pointer != ',')
   1884   1.1     skrll     {
   1885   1.1     skrll       as_bad (_("expected comma after name in .symver"));
   1886   1.1     skrll       ignore_rest_of_line ();
   1887   1.1     skrll       return;
   1888   1.1     skrll     }
   1889   1.1     skrll 
   1890   1.1     skrll   ++input_line_pointer;
   1891   1.1     skrll   SKIP_WHITESPACE ();
   1892   1.1     skrll 
   1893   1.1     skrll   /* Temporarily include '@' in symbol names.  */
   1894   1.1     skrll   old_lexat = lex_type[(unsigned char) '@'];
   1895   1.1     skrll   lex_type[(unsigned char) '@'] |= LEX_NAME;
   1896   1.3  christos   c = get_symbol_name (& name);
   1897   1.1     skrll   lex_type[(unsigned char) '@'] = old_lexat;
   1898   1.9  christos   sym_name = S_GET_NAME (sym);
   1899   1.1     skrll 
   1900   1.6  christos   if (S_IS_COMMON (sym))
   1901   1.6  christos     {
   1902   1.6  christos       as_bad (_("`%s' can't be versioned to common symbol '%s'"),
   1903   1.9  christos 	      name, sym_name);
   1904   1.6  christos       ignore_rest_of_line ();
   1905   1.6  christos       return;
   1906   1.6  christos     }
   1907   1.6  christos 
   1908   1.9  christos   p = strchr (name, ELF_VER_CHR);
   1909   1.9  christos   if (p == NULL)
   1910   1.1     skrll     {
   1911   1.9  christos       as_bad (_("missing version name in `%s' for symbol `%s'"),
   1912   1.9  christos 	      name, sym_name);
   1913   1.9  christos       ignore_rest_of_line ();
   1914   1.9  christos       return;
   1915   1.9  christos     }
   1916   1.9  christos 
   1917   1.9  christos   sy_obj = symbol_get_obj (sym);
   1918   1.9  christos   if (obj_elf_find_and_add_versioned_name (name, sym_name,
   1919   1.9  christos 					   p, sy_obj) == NULL)
   1920   1.9  christos     {
   1921   1.9  christos       sy_obj->bad_version = true;
   1922   1.9  christos       ignore_rest_of_line ();
   1923   1.9  christos       return;
   1924   1.9  christos     }
   1925   1.9  christos 
   1926   1.9  christos   (void) restore_line_pointer (c);
   1927   1.1     skrll 
   1928   1.9  christos   if (*input_line_pointer == ',')
   1929   1.9  christos     {
   1930   1.9  christos       char *save = input_line_pointer;
   1931   1.1     skrll 
   1932   1.9  christos       ++input_line_pointer;
   1933   1.9  christos       SKIP_WHITESPACE ();
   1934   1.9  christos       if (startswith (input_line_pointer, "local"))
   1935   1.1     skrll 	{
   1936   1.9  christos 	  input_line_pointer += 5;
   1937   1.9  christos 	  sy_obj->visibility = visibility_local;
   1938   1.9  christos 	}
   1939   1.9  christos       else if (startswith (input_line_pointer, "hidden"))
   1940   1.9  christos 	{
   1941   1.9  christos 	  input_line_pointer += 6;
   1942   1.9  christos 	  sy_obj->visibility = visibility_hidden;
   1943   1.1     skrll 	}
   1944   1.9  christos       else if (startswith (input_line_pointer, "remove"))
   1945   1.1     skrll 	{
   1946   1.9  christos 	  input_line_pointer += 6;
   1947   1.9  christos 	  sy_obj->visibility = visibility_remove;
   1948   1.1     skrll 	}
   1949   1.9  christos       else
   1950   1.9  christos 	input_line_pointer = save;
   1951   1.1     skrll     }
   1952   1.1     skrll 
   1953   1.1     skrll   demand_empty_rest_of_line ();
   1954   1.1     skrll }
   1955   1.1     skrll 
   1956   1.1     skrll /* This handles the .vtable_inherit pseudo-op, which is used to indicate
   1957   1.1     skrll    to the linker the hierarchy in which a particular table resides.  The
   1958   1.1     skrll    syntax is ".vtable_inherit CHILDNAME, PARENTNAME".  */
   1959   1.1     skrll 
   1960   1.1     skrll struct fix *
   1961   1.7  christos obj_elf_get_vtable_inherit (void)
   1962   1.1     skrll {
   1963   1.1     skrll   char *cname, *pname;
   1964   1.1     skrll   symbolS *csym, *psym;
   1965   1.1     skrll   char c, bad = 0;
   1966   1.1     skrll 
   1967   1.1     skrll   if (*input_line_pointer == '#')
   1968   1.1     skrll     ++input_line_pointer;
   1969   1.1     skrll 
   1970   1.3  christos   c = get_symbol_name (& cname);
   1971   1.1     skrll   csym = symbol_find (cname);
   1972   1.1     skrll 
   1973   1.1     skrll   /* GCFIXME: should check that we don't have two .vtable_inherits for
   1974   1.1     skrll      the same child symbol.  Also, we can currently only do this if the
   1975   1.1     skrll      child symbol is already exists and is placed in a fragment.  */
   1976   1.1     skrll 
   1977   1.1     skrll   if (csym == NULL || symbol_get_frag (csym) == NULL)
   1978   1.1     skrll     {
   1979   1.1     skrll       as_bad (_("expected `%s' to have already been set for .vtable_inherit"),
   1980   1.1     skrll 	      cname);
   1981   1.1     skrll       bad = 1;
   1982   1.1     skrll     }
   1983   1.1     skrll 
   1984  1.13  christos   restore_line_pointer (c);
   1985   1.1     skrll 
   1986  1.13  christos   SKIP_WHITESPACE ();
   1987   1.1     skrll   if (*input_line_pointer != ',')
   1988   1.1     skrll     {
   1989   1.1     skrll       as_bad (_("expected comma after name in .vtable_inherit"));
   1990   1.1     skrll       ignore_rest_of_line ();
   1991   1.1     skrll       return NULL;
   1992   1.1     skrll     }
   1993   1.1     skrll 
   1994   1.1     skrll   ++input_line_pointer;
   1995   1.1     skrll   SKIP_WHITESPACE ();
   1996   1.1     skrll 
   1997   1.1     skrll   if (*input_line_pointer == '#')
   1998   1.1     skrll     ++input_line_pointer;
   1999   1.1     skrll 
   2000   1.1     skrll   if (input_line_pointer[0] == '0'
   2001  1.13  christos       && (is_end_of_stmt (input_line_pointer[1])
   2002  1.13  christos 	  || is_whitespace (input_line_pointer[1])))
   2003   1.1     skrll     {
   2004   1.1     skrll       psym = section_symbol (absolute_section);
   2005   1.1     skrll       ++input_line_pointer;
   2006   1.1     skrll     }
   2007   1.1     skrll   else
   2008   1.1     skrll     {
   2009   1.3  christos       c = get_symbol_name (& pname);
   2010   1.1     skrll       psym = symbol_find_or_make (pname);
   2011   1.3  christos       restore_line_pointer (c);
   2012   1.1     skrll     }
   2013   1.1     skrll 
   2014   1.1     skrll   demand_empty_rest_of_line ();
   2015   1.1     skrll 
   2016   1.1     skrll   if (bad)
   2017   1.1     skrll     return NULL;
   2018   1.1     skrll 
   2019   1.2     joerg   gas_assert (symbol_get_value_expression (csym)->X_op == O_constant);
   2020   1.1     skrll   return fix_new (symbol_get_frag (csym),
   2021   1.1     skrll 		  symbol_get_value_expression (csym)->X_add_number,
   2022   1.1     skrll 		  0, psym, 0, 0, BFD_RELOC_VTABLE_INHERIT);
   2023   1.1     skrll }
   2024   1.1     skrll 
   2025   1.7  christos /* This is a version of obj_elf_get_vtable_inherit() that is
   2026   1.7  christos    suitable for use in struct _pseudo_type tables.  */
   2027   1.7  christos 
   2028   1.7  christos void
   2029   1.7  christos obj_elf_vtable_inherit (int ignore ATTRIBUTE_UNUSED)
   2030   1.7  christos {
   2031   1.7  christos   (void) obj_elf_get_vtable_inherit ();
   2032   1.7  christos }
   2033   1.7  christos 
   2034   1.1     skrll /* This handles the .vtable_entry pseudo-op, which is used to indicate
   2035   1.1     skrll    to the linker that a vtable slot was used.  The syntax is
   2036   1.1     skrll    ".vtable_entry tablename, offset".  */
   2037   1.1     skrll 
   2038   1.1     skrll struct fix *
   2039   1.7  christos obj_elf_get_vtable_entry (void)
   2040   1.1     skrll {
   2041   1.1     skrll   symbolS *sym;
   2042   1.1     skrll   offsetT offset;
   2043   1.1     skrll 
   2044   1.1     skrll   if (*input_line_pointer == '#')
   2045   1.1     skrll     ++input_line_pointer;
   2046   1.1     skrll 
   2047   1.2     joerg   sym = get_sym_from_input_line_and_check ();
   2048   1.1     skrll   if (*input_line_pointer != ',')
   2049   1.1     skrll     {
   2050   1.1     skrll       as_bad (_("expected comma after name in .vtable_entry"));
   2051   1.1     skrll       ignore_rest_of_line ();
   2052   1.1     skrll       return NULL;
   2053   1.1     skrll     }
   2054   1.1     skrll 
   2055   1.1     skrll   ++input_line_pointer;
   2056   1.1     skrll   if (*input_line_pointer == '#')
   2057   1.1     skrll     ++input_line_pointer;
   2058   1.1     skrll 
   2059   1.1     skrll   offset = get_absolute_expression ();
   2060   1.1     skrll 
   2061   1.1     skrll   demand_empty_rest_of_line ();
   2062   1.1     skrll 
   2063   1.1     skrll   return fix_new (frag_now, frag_now_fix (), 0, sym, offset, 0,
   2064   1.1     skrll 		  BFD_RELOC_VTABLE_ENTRY);
   2065   1.1     skrll }
   2066   1.1     skrll 
   2067   1.7  christos /* This is a version of obj_elf_get_vtable_entry() that is
   2068   1.7  christos    suitable for use in struct _pseudo_type tables.  */
   2069   1.7  christos 
   2070   1.7  christos void
   2071   1.7  christos obj_elf_vtable_entry (int ignore ATTRIBUTE_UNUSED)
   2072   1.7  christos {
   2073   1.7  christos   (void) obj_elf_get_vtable_entry ();
   2074   1.7  christos }
   2075   1.7  christos 
   2076   1.1     skrll void
   2077   1.1     skrll elf_obj_read_begin_hook (void)
   2078   1.1     skrll {
   2079   1.1     skrll #ifdef NEED_ECOFF_DEBUG
   2080   1.1     skrll   if (ECOFF_DEBUGGING)
   2081   1.1     skrll     ecoff_read_begin_hook ();
   2082   1.1     skrll #endif
   2083   1.1     skrll }
   2084   1.1     skrll 
   2085   1.1     skrll void
   2086   1.1     skrll elf_obj_symbol_new_hook (symbolS *symbolP)
   2087   1.1     skrll {
   2088   1.1     skrll   struct elf_obj_sy *sy_obj;
   2089   1.1     skrll 
   2090   1.1     skrll   sy_obj = symbol_get_obj (symbolP);
   2091   1.1     skrll   sy_obj->size = NULL;
   2092   1.1     skrll   sy_obj->versioned_name = NULL;
   2093   1.1     skrll 
   2094   1.1     skrll #ifdef NEED_ECOFF_DEBUG
   2095   1.1     skrll   if (ECOFF_DEBUGGING)
   2096   1.1     skrll     ecoff_symbol_new_hook (symbolP);
   2097   1.1     skrll #endif
   2098   1.1     skrll }
   2099   1.1     skrll 
   2100  1.13  christos /* If size is unset, copy size from src.  Because we don't track whether
   2101  1.13  christos    .size has been used, we can't differentiate .size dest, 0 from the case
   2102  1.13  christos    where dest's size is unset.  */
   2103   1.9  christos void
   2104  1.13  christos elf_copy_symbol_size (symbolS *dest, symbolS *src)
   2105   1.9  christos {
   2106  1.13  christos   struct elf_obj_sy *srcelf = symbol_get_obj (src);
   2107  1.13  christos   struct elf_obj_sy *destelf = symbol_get_obj (dest);
   2108  1.13  christos   if (!destelf->size && S_GET_SIZE (dest) == 0)
   2109   1.9  christos     {
   2110  1.13  christos       destelf->size = srcelf->size;
   2111  1.13  christos       S_SET_SIZE (dest, S_GET_SIZE (src));
   2112   1.9  christos     }
   2113   1.9  christos }
   2114   1.1     skrll 
   2115   1.1     skrll void
   2116   1.1     skrll elf_copy_symbol_attributes (symbolS *dest, symbolS *src)
   2117   1.1     skrll {
   2118  1.13  christos   elf_copy_symbol_size (dest, src);
   2119   1.1     skrll   /* Don't copy visibility.  */
   2120   1.1     skrll   S_SET_OTHER (dest, (ELF_ST_VISIBILITY (S_GET_OTHER (dest))
   2121   1.1     skrll 		      | (S_GET_OTHER (src) & ~ELF_ST_VISIBILITY (-1))));
   2122   1.1     skrll }
   2123   1.1     skrll 
   2124   1.1     skrll void
   2125   1.1     skrll obj_elf_version (int ignore ATTRIBUTE_UNUSED)
   2126   1.1     skrll {
   2127   1.1     skrll   char *name;
   2128   1.1     skrll   unsigned int c;
   2129   1.1     skrll   char *p;
   2130   1.1     skrll   asection *seg = now_seg;
   2131   1.1     skrll   subsegT subseg = now_subseg;
   2132   1.1     skrll   Elf_Internal_Note i_note;
   2133   1.1     skrll   Elf_External_Note e_note;
   2134   1.1     skrll   asection *note_secp = NULL;
   2135   1.1     skrll 
   2136   1.1     skrll   SKIP_WHITESPACE ();
   2137   1.1     skrll   if (*input_line_pointer == '\"')
   2138   1.1     skrll     {
   2139   1.1     skrll       unsigned int len;
   2140   1.1     skrll 
   2141   1.1     skrll       ++input_line_pointer;	/* -> 1st char of string.  */
   2142   1.1     skrll       name = input_line_pointer;
   2143   1.1     skrll 
   2144   1.1     skrll       while (is_a_char (c = next_char_of_string ()))
   2145   1.1     skrll 	;
   2146   1.1     skrll       c = *input_line_pointer;
   2147   1.1     skrll       *input_line_pointer = '\0';
   2148   1.1     skrll       *(input_line_pointer - 1) = '\0';
   2149   1.1     skrll       *input_line_pointer = c;
   2150   1.1     skrll 
   2151   1.1     skrll       /* Create the .note section.  */
   2152   1.1     skrll       note_secp = subseg_new (".note", 0);
   2153   1.8  christos       bfd_set_section_flags (note_secp, SEC_HAS_CONTENTS | SEC_READONLY);
   2154   1.6  christos       record_alignment (note_secp, 2);
   2155   1.1     skrll 
   2156   1.1     skrll       /* Process the version string.  */
   2157   1.1     skrll       len = strlen (name) + 1;
   2158   1.1     skrll 
   2159   1.1     skrll       /* PR 3456: Although the name field is padded out to an 4-byte
   2160   1.1     skrll 	 boundary, the namesz field should not be adjusted.  */
   2161   1.1     skrll       i_note.namesz = len;
   2162   1.1     skrll       i_note.descsz = 0;	/* No description.  */
   2163   1.1     skrll       i_note.type = NT_VERSION;
   2164   1.1     skrll       p = frag_more (sizeof (e_note.namesz));
   2165   1.1     skrll       md_number_to_chars (p, i_note.namesz, sizeof (e_note.namesz));
   2166   1.1     skrll       p = frag_more (sizeof (e_note.descsz));
   2167   1.1     skrll       md_number_to_chars (p, i_note.descsz, sizeof (e_note.descsz));
   2168   1.1     skrll       p = frag_more (sizeof (e_note.type));
   2169   1.1     skrll       md_number_to_chars (p, i_note.type, sizeof (e_note.type));
   2170   1.1     skrll       p = frag_more (len);
   2171   1.1     skrll       memcpy (p, name, len);
   2172   1.1     skrll 
   2173   1.1     skrll       frag_align (2, 0, 0);
   2174   1.1     skrll 
   2175   1.1     skrll       subseg_set (seg, subseg);
   2176   1.1     skrll     }
   2177   1.1     skrll   else
   2178   1.1     skrll     as_bad (_("expected quoted string"));
   2179   1.1     skrll 
   2180   1.1     skrll   demand_empty_rest_of_line ();
   2181   1.1     skrll }
   2182   1.1     skrll 
   2183   1.1     skrll static void
   2184   1.1     skrll obj_elf_size (int ignore ATTRIBUTE_UNUSED)
   2185   1.1     skrll {
   2186   1.3  christos   char *name;
   2187   1.3  christos   char c = get_symbol_name (&name);
   2188   1.1     skrll   char *p;
   2189   1.1     skrll   expressionS exp;
   2190   1.1     skrll   symbolS *sym;
   2191   1.1     skrll 
   2192   1.1     skrll   p = input_line_pointer;
   2193  1.13  christos   restore_line_pointer (c);
   2194  1.13  christos   SKIP_WHITESPACE ();
   2195   1.1     skrll   if (*input_line_pointer != ',')
   2196   1.1     skrll     {
   2197   1.1     skrll       *p = 0;
   2198   1.1     skrll       as_bad (_("expected comma after name `%s' in .size directive"), name);
   2199   1.1     skrll       *p = c;
   2200   1.1     skrll       ignore_rest_of_line ();
   2201   1.1     skrll       return;
   2202   1.1     skrll     }
   2203   1.1     skrll   input_line_pointer++;
   2204   1.1     skrll   expression (&exp);
   2205   1.1     skrll   if (exp.X_op == O_absent)
   2206   1.1     skrll     {
   2207   1.1     skrll       as_bad (_("missing expression in .size directive"));
   2208   1.1     skrll       exp.X_op = O_constant;
   2209   1.1     skrll       exp.X_add_number = 0;
   2210   1.1     skrll     }
   2211   1.1     skrll   *p = 0;
   2212   1.1     skrll   sym = symbol_find_or_make (name);
   2213   1.1     skrll   *p = c;
   2214   1.1     skrll   if (exp.X_op == O_constant)
   2215   1.1     skrll     {
   2216   1.1     skrll       S_SET_SIZE (sym, exp.X_add_number);
   2217   1.9  christos       symbol_get_obj (sym)->size = NULL;
   2218   1.1     skrll     }
   2219   1.1     skrll   else
   2220   1.1     skrll     {
   2221  1.13  christos       symbol_get_obj (sym)->size = notes_alloc (sizeof (exp));
   2222   1.1     skrll       *symbol_get_obj (sym)->size = exp;
   2223   1.1     skrll     }
   2224  1.12  christos 
   2225  1.12  christos   /* If the symbol in the directive matches the current function being
   2226  1.12  christos      processed, indicate end of the current stream of ginsns.  */
   2227  1.12  christos   if (flag_synth_cfi
   2228  1.12  christos       && S_IS_FUNCTION (sym) && sym == ginsn_data_func_symbol ())
   2229  1.12  christos     ginsn_data_end (symbol_temp_new_now ());
   2230  1.12  christos 
   2231   1.1     skrll   demand_empty_rest_of_line ();
   2232   1.1     skrll }
   2233   1.1     skrll 
   2234   1.1     skrll /* Handle the ELF .type pseudo-op.  This sets the type of a symbol.
   2235   1.1     skrll    There are six syntaxes:
   2236   1.1     skrll 
   2237   1.1     skrll    The first (used on Solaris) is
   2238   1.1     skrll        .type SYM,#function
   2239   1.1     skrll    The second (used on UnixWare) is
   2240   1.1     skrll        .type SYM,@function
   2241   1.1     skrll    The third (reportedly to be used on Irix 6.0) is
   2242   1.1     skrll        .type SYM STT_FUNC
   2243   1.1     skrll    The fourth (used on NetBSD/Arm and Linux/ARM) is
   2244   1.1     skrll        .type SYM,%function
   2245   1.1     skrll    The fifth (used on SVR4/860) is
   2246   1.1     skrll        .type SYM,"function"
   2247   1.1     skrll    The sixth (emitted by recent SunPRO under Solaris) is
   2248   1.1     skrll        .type SYM,[0-9]
   2249   1.1     skrll    where the integer is the STT_* value.
   2250   1.1     skrll    */
   2251   1.1     skrll 
   2252   1.1     skrll static char *
   2253   1.1     skrll obj_elf_type_name (char *cp)
   2254   1.1     skrll {
   2255   1.1     skrll   char *p;
   2256   1.1     skrll 
   2257   1.1     skrll   p = input_line_pointer;
   2258   1.1     skrll   if (*input_line_pointer >= '0'
   2259   1.1     skrll       && *input_line_pointer <= '9')
   2260   1.1     skrll     {
   2261   1.1     skrll       while (*input_line_pointer >= '0'
   2262   1.1     skrll 	     && *input_line_pointer <= '9')
   2263   1.1     skrll 	++input_line_pointer;
   2264   1.1     skrll       *cp = *input_line_pointer;
   2265   1.1     skrll       *input_line_pointer = '\0';
   2266   1.1     skrll     }
   2267   1.1     skrll   else
   2268   1.3  christos     *cp = get_symbol_name (&p);
   2269   1.1     skrll 
   2270   1.1     skrll   return p;
   2271   1.1     skrll }
   2272   1.1     skrll 
   2273   1.1     skrll static void
   2274   1.1     skrll obj_elf_type (int ignore ATTRIBUTE_UNUSED)
   2275   1.1     skrll {
   2276   1.1     skrll   char c;
   2277   1.1     skrll   int type;
   2278   1.2     joerg   const char *type_name;
   2279   1.1     skrll   symbolS *sym;
   2280   1.1     skrll   elf_symbol_type *elfsym;
   2281   1.1     skrll 
   2282   1.2     joerg   sym = get_sym_from_input_line_and_check ();
   2283   1.2     joerg   c = *input_line_pointer;
   2284   1.1     skrll   elfsym = (elf_symbol_type *) symbol_get_bfdsym (sym);
   2285   1.1     skrll 
   2286   1.1     skrll   if (*input_line_pointer == ',')
   2287   1.1     skrll     ++input_line_pointer;
   2288   1.1     skrll 
   2289   1.1     skrll   SKIP_WHITESPACE ();
   2290   1.1     skrll   if (   *input_line_pointer == '#'
   2291   1.1     skrll       || *input_line_pointer == '@'
   2292   1.1     skrll       || *input_line_pointer == '"'
   2293   1.1     skrll       || *input_line_pointer == '%')
   2294   1.1     skrll     ++input_line_pointer;
   2295   1.1     skrll 
   2296   1.2     joerg   type_name = obj_elf_type_name (& c);
   2297   1.1     skrll 
   2298   1.1     skrll   type = 0;
   2299   1.2     joerg   if (strcmp (type_name, "function") == 0
   2300   1.2     joerg       || strcmp (type_name, "2") == 0
   2301   1.2     joerg       || strcmp (type_name, "STT_FUNC") == 0)
   2302   1.1     skrll     type = BSF_FUNCTION;
   2303   1.2     joerg   else if (strcmp (type_name, "object") == 0
   2304   1.2     joerg 	   || strcmp (type_name, "1") == 0
   2305   1.2     joerg 	   || strcmp (type_name, "STT_OBJECT") == 0)
   2306   1.1     skrll     type = BSF_OBJECT;
   2307   1.2     joerg   else if (strcmp (type_name, "tls_object") == 0
   2308   1.2     joerg 	   || strcmp (type_name, "6") == 0
   2309   1.2     joerg 	   || strcmp (type_name, "STT_TLS") == 0)
   2310   1.1     skrll     type = BSF_OBJECT | BSF_THREAD_LOCAL;
   2311   1.2     joerg   else if (strcmp (type_name, "notype") == 0
   2312   1.2     joerg 	   || strcmp (type_name, "0") == 0
   2313   1.2     joerg 	   || strcmp (type_name, "STT_NOTYPE") == 0)
   2314   1.1     skrll     ;
   2315   1.2     joerg   else if (strcmp (type_name, "common") == 0
   2316   1.2     joerg 	   || strcmp (type_name, "5") == 0
   2317   1.2     joerg 	   || strcmp (type_name, "STT_COMMON") == 0)
   2318   1.1     skrll     {
   2319   1.1     skrll       type = BSF_OBJECT;
   2320   1.1     skrll 
   2321   1.1     skrll       if (! S_IS_COMMON (sym))
   2322   1.1     skrll 	{
   2323   1.1     skrll 	  if (S_IS_VOLATILE (sym))
   2324   1.1     skrll 	    {
   2325   1.1     skrll 	      sym = symbol_clone (sym, 1);
   2326   1.1     skrll 	      S_SET_SEGMENT (sym, bfd_com_section_ptr);
   2327   1.1     skrll 	      S_SET_VALUE (sym, 0);
   2328   1.1     skrll 	      S_SET_EXTERNAL (sym);
   2329   1.1     skrll 	      symbol_set_frag (sym, &zero_address_frag);
   2330   1.1     skrll 	      S_CLEAR_VOLATILE (sym);
   2331   1.1     skrll 	    }
   2332   1.1     skrll 	  else if (S_IS_DEFINED (sym) || symbol_equated_p (sym))
   2333   1.1     skrll 	    as_bad (_("symbol '%s' is already defined"), S_GET_NAME (sym));
   2334   1.1     skrll 	  else
   2335   1.1     skrll 	    {
   2336   1.1     skrll 	      /* FIXME: Is it safe to just change the section ?  */
   2337   1.1     skrll 	      S_SET_SEGMENT (sym, bfd_com_section_ptr);
   2338   1.1     skrll 	      S_SET_VALUE (sym, 0);
   2339   1.1     skrll 	      S_SET_EXTERNAL (sym);
   2340   1.1     skrll 	    }
   2341   1.1     skrll 	}
   2342   1.1     skrll     }
   2343   1.2     joerg   else if (strcmp (type_name, "gnu_indirect_function") == 0
   2344   1.2     joerg 	   || strcmp (type_name, "10") == 0
   2345   1.2     joerg 	   || strcmp (type_name, "STT_GNU_IFUNC") == 0)
   2346   1.2     joerg     {
   2347  1.14  christos       elf_backend_data *bed = get_elf_backend_data (stdoutput);
   2348   1.9  christos       if (bed->elf_osabi != ELFOSABI_NONE
   2349   1.9  christos 	  && bed->elf_osabi != ELFOSABI_GNU
   2350   1.9  christos 	  && bed->elf_osabi != ELFOSABI_FREEBSD)
   2351   1.8  christos 	as_bad (_("symbol type \"%s\" is supported only by GNU "
   2352   1.8  christos 		  "and FreeBSD targets"), type_name);
   2353  1.11  christos #if 0
   2354   1.9  christos       /* MIPS targets do not support IFUNCS.  */
   2355   1.9  christos       else if (bed->target_id == MIPS_ELF_DATA)
   2356   1.9  christos 	as_bad (_("symbol type \"%s\" is not supported by "
   2357   1.9  christos                     "MIPS targets"), type_name);
   2358  1.10  christos #endif
   2359   1.8  christos       elf_tdata (stdoutput)->has_gnu_osabi |= elf_gnu_osabi_ifunc;
   2360   1.2     joerg       type = BSF_FUNCTION | BSF_GNU_INDIRECT_FUNCTION;
   2361   1.2     joerg     }
   2362   1.2     joerg   else if (strcmp (type_name, "gnu_unique_object") == 0)
   2363   1.2     joerg     {
   2364  1.14  christos       elf_backend_data *bed = get_elf_backend_data (stdoutput);
   2365   1.9  christos       if (bed->elf_osabi != ELFOSABI_NONE
   2366   1.9  christos 	  && bed->elf_osabi != ELFOSABI_GNU)
   2367   1.2     joerg 	as_bad (_("symbol type \"%s\" is supported only by GNU targets"),
   2368   1.2     joerg 		type_name);
   2369   1.8  christos       elf_tdata (stdoutput)->has_gnu_osabi |= elf_gnu_osabi_unique;
   2370   1.2     joerg       type = BSF_OBJECT | BSF_GNU_UNIQUE;
   2371   1.2     joerg     }
   2372   1.1     skrll #ifdef md_elf_symbol_type
   2373   1.2     joerg   else if ((type = md_elf_symbol_type (type_name, sym, elfsym)) != -1)
   2374   1.1     skrll     ;
   2375   1.1     skrll #endif
   2376   1.1     skrll   else
   2377   1.2     joerg     as_bad (_("unrecognized symbol type \"%s\""), type_name);
   2378   1.1     skrll 
   2379   1.1     skrll   *input_line_pointer = c;
   2380   1.1     skrll 
   2381   1.1     skrll   if (*input_line_pointer == '"')
   2382   1.1     skrll     ++input_line_pointer;
   2383   1.1     skrll 
   2384   1.8  christos #ifdef md_elf_symbol_type_change
   2385   1.8  christos   if (!md_elf_symbol_type_change (sym, elfsym, type))
   2386   1.8  christos #endif
   2387   1.8  christos     {
   2388   1.8  christos       flagword mask = BSF_FUNCTION | BSF_OBJECT;
   2389   1.8  christos 
   2390   1.8  christos       if (type != BSF_FUNCTION)
   2391   1.8  christos 	mask |= BSF_GNU_INDIRECT_FUNCTION;
   2392   1.8  christos       if (type != BSF_OBJECT)
   2393   1.8  christos 	{
   2394   1.8  christos 	  mask |= BSF_GNU_UNIQUE | BSF_THREAD_LOCAL;
   2395   1.8  christos 
   2396   1.8  christos 	  if (S_IS_COMMON (sym))
   2397   1.8  christos 	    {
   2398   1.8  christos 	      as_bad (_("cannot change type of common symbol '%s'"),
   2399   1.8  christos 		      S_GET_NAME (sym));
   2400   1.8  christos 	      mask = type = 0;
   2401   1.8  christos 	    }
   2402   1.8  christos 	}
   2403   1.8  christos 
   2404   1.8  christos       /* Don't warn when changing to STT_NOTYPE.  */
   2405   1.8  christos       if (type)
   2406   1.8  christos 	{
   2407   1.8  christos 	  flagword new = (elfsym->symbol.flags & ~mask) | type;
   2408   1.8  christos 
   2409   1.8  christos 	  if (new != (elfsym->symbol.flags | type))
   2410   1.8  christos 	    as_warn (_("symbol '%s' already has its type set"), S_GET_NAME (sym));
   2411   1.8  christos 	  elfsym->symbol.flags = new;
   2412   1.8  christos 	}
   2413   1.8  christos       else
   2414   1.8  christos 	elfsym->symbol.flags &= ~mask;
   2415   1.8  christos     }
   2416   1.1     skrll 
   2417  1.12  christos   if (S_IS_FUNCTION (sym) && flag_synth_cfi)
   2418  1.12  christos     {
   2419  1.12  christos       /* When using SCFI, .type directive indicates start of a new FDE for SCFI
   2420  1.12  christos 	 processing.  So, we must first demarcate the previous block of ginsns,
   2421  1.12  christos 	 if any, to mark the end of a previous FDE.  */
   2422  1.12  christos       if (frchain_now->frch_ginsn_data)
   2423  1.12  christos 	ginsn_data_end (symbol_temp_new_now ());
   2424  1.12  christos       ginsn_data_begin (sym);
   2425  1.12  christos     }
   2426  1.12  christos 
   2427   1.1     skrll   demand_empty_rest_of_line ();
   2428   1.1     skrll }
   2429   1.1     skrll 
   2430  1.12  christos static segT comment_section;
   2431  1.12  christos 
   2432   1.1     skrll static void
   2433   1.1     skrll obj_elf_ident (int ignore ATTRIBUTE_UNUSED)
   2434   1.1     skrll {
   2435   1.1     skrll   segT old_section = now_seg;
   2436   1.1     skrll   int old_subsection = now_subseg;
   2437   1.1     skrll 
   2438   1.1     skrll #ifdef md_flush_pending_output
   2439   1.1     skrll   md_flush_pending_output ();
   2440   1.1     skrll #endif
   2441   1.1     skrll 
   2442   1.1     skrll   if (!comment_section)
   2443   1.1     skrll     {
   2444   1.1     skrll       char *p;
   2445   1.1     skrll       comment_section = subseg_new (".comment", 0);
   2446   1.8  christos       bfd_set_section_flags (comment_section, (SEC_READONLY | SEC_HAS_CONTENTS
   2447   1.8  christos 					       | SEC_MERGE | SEC_STRINGS));
   2448   1.2     joerg       comment_section->entsize = 1;
   2449   1.2     joerg #ifdef md_elf_section_change_hook
   2450   1.2     joerg       md_elf_section_change_hook ();
   2451   1.2     joerg #endif
   2452   1.1     skrll       p = frag_more (1);
   2453   1.1     skrll       *p = 0;
   2454   1.1     skrll     }
   2455   1.1     skrll   else
   2456  1.12  christos     {
   2457  1.12  christos       subseg_set (comment_section, 0);
   2458  1.12  christos #ifdef md_elf_section_change_hook
   2459  1.12  christos       md_elf_section_change_hook ();
   2460  1.12  christos #endif
   2461  1.12  christos     }
   2462   1.1     skrll   stringer (8 + 1);
   2463   1.1     skrll   subseg_set (old_section, old_subsection);
   2464  1.12  christos #ifdef md_elf_section_change_hook
   2465  1.12  christos   md_elf_section_change_hook ();
   2466  1.12  christos #endif
   2467   1.1     skrll }
   2468   1.1     skrll 
   2469   1.1     skrll #ifdef INIT_STAB_SECTION
   2470   1.1     skrll 
   2471   1.1     skrll /* The first entry in a .stabs section is special.  */
   2472   1.1     skrll 
   2473   1.1     skrll void
   2474  1.12  christos obj_elf_init_stab_section (segT stab, segT stabstr)
   2475   1.1     skrll {
   2476   1.9  christos   char *file;
   2477   1.1     skrll   char *p;
   2478   1.1     skrll   unsigned int stroff;
   2479   1.1     skrll 
   2480   1.1     skrll   /* Force the section to align to a longword boundary.  Without this,
   2481   1.1     skrll      UnixWare ar crashes.  */
   2482  1.12  christos   bfd_set_section_alignment (stab, 2);
   2483   1.1     skrll 
   2484   1.1     skrll   /* Make space for this first symbol.  */
   2485   1.1     skrll   p = frag_more (12);
   2486   1.1     skrll   /* Zero it out.  */
   2487   1.1     skrll   memset (p, 0, 12);
   2488   1.9  christos   file = remap_debug_filename (as_where (NULL));
   2489  1.12  christos   stroff = get_stab_string_offset (file, stabstr);
   2490   1.2     joerg   know (stroff == 1 || (stroff == 0 && file[0] == '\0'));
   2491   1.1     skrll   md_number_to_chars (p, stroff, 4);
   2492  1.12  christos   seg_info (stab)->stabu.p = p;
   2493   1.9  christos   free (file);
   2494   1.1     skrll }
   2495   1.1     skrll 
   2496   1.1     skrll #endif
   2497   1.1     skrll 
   2498  1.13  christos /* Called via bfd_map_over_sections.  If SEC's linked_to_symbol_name
   2499  1.13  christos    isn't NULL, set up its linked-to section.
   2500  1.13  christos    For .stabs section, fill in the counts in the first entry.  */
   2501   1.1     skrll 
   2502   1.1     skrll static void
   2503  1.13  christos set_additional_section_info (bfd *abfd,
   2504  1.13  christos 			     asection *sec,
   2505  1.13  christos 			     void *inf ATTRIBUTE_UNUSED)
   2506   1.1     skrll {
   2507  1.13  christos   if (sec->map_head.linked_to_symbol_name)
   2508  1.13  christos     {
   2509  1.13  christos       symbolS *linked_to_sym;
   2510  1.13  christos       linked_to_sym = symbol_find (sec->map_head.linked_to_symbol_name);
   2511  1.13  christos       if (!linked_to_sym || !S_IS_DEFINED (linked_to_sym))
   2512  1.13  christos 	as_bad (_("undefined linked-to symbol `%s' on section `%s'"),
   2513  1.13  christos 		sec->map_head.linked_to_symbol_name,
   2514  1.13  christos 		bfd_section_name (sec));
   2515  1.13  christos       else
   2516  1.13  christos 	elf_linked_to_section (sec) = S_GET_SEGMENT (linked_to_sym);
   2517  1.13  christos     }
   2518  1.13  christos 
   2519   1.1     skrll   char *name;
   2520   1.1     skrll   asection *strsec;
   2521   1.1     skrll   char *p;
   2522   1.1     skrll   int strsz, nsyms;
   2523   1.1     skrll 
   2524   1.9  christos   if (!startswith (sec->name, ".stab"))
   2525   1.1     skrll     return;
   2526   1.1     skrll   if (!strcmp ("str", sec->name + strlen (sec->name) - 3))
   2527   1.1     skrll     return;
   2528   1.1     skrll 
   2529  1.13  christos   name = concat (sec->name, "str", (const char *) NULL);
   2530   1.1     skrll   strsec = bfd_get_section_by_name (abfd, name);
   2531   1.1     skrll   if (strsec)
   2532   1.8  christos     strsz = bfd_section_size (strsec);
   2533   1.1     skrll   else
   2534   1.1     skrll     strsz = 0;
   2535   1.8  christos   nsyms = bfd_section_size (sec) / 12 - 1;
   2536   1.1     skrll 
   2537   1.1     skrll   p = seg_info (sec)->stabu.p;
   2538   1.2     joerg   gas_assert (p != 0);
   2539   1.1     skrll 
   2540   1.1     skrll   bfd_h_put_16 (abfd, nsyms, p + 6);
   2541   1.1     skrll   bfd_h_put_32 (abfd, strsz, p + 8);
   2542   1.5  christos   free (name);
   2543   1.1     skrll }
   2544   1.1     skrll 
   2545   1.1     skrll #ifdef NEED_ECOFF_DEBUG
   2546   1.1     skrll 
   2547   1.1     skrll /* This function is called by the ECOFF code.  It is supposed to
   2548   1.1     skrll    record the external symbol information so that the backend can
   2549   1.1     skrll    write it out correctly.  The ELF backend doesn't actually handle
   2550   1.1     skrll    this at the moment, so we do it ourselves.  We save the information
   2551   1.1     skrll    in the symbol.  */
   2552   1.1     skrll 
   2553   1.1     skrll #ifdef OBJ_MAYBE_ELF
   2554   1.1     skrll static
   2555   1.1     skrll #endif
   2556   1.1     skrll void
   2557   1.1     skrll elf_ecoff_set_ext (symbolS *sym, struct ecoff_extr *ext)
   2558   1.1     skrll {
   2559   1.1     skrll   symbol_get_bfdsym (sym)->udata.p = ext;
   2560   1.1     skrll }
   2561   1.1     skrll 
   2562   1.1     skrll /* This function is called by bfd_ecoff_debug_externals.  It is
   2563   1.1     skrll    supposed to *EXT to the external symbol information, and return
   2564   1.1     skrll    whether the symbol should be used at all.  */
   2565   1.1     skrll 
   2566   1.9  christos static bool
   2567   1.1     skrll elf_get_extr (asymbol *sym, EXTR *ext)
   2568   1.1     skrll {
   2569   1.1     skrll   if (sym->udata.p == NULL)
   2570   1.9  christos     return false;
   2571   1.1     skrll   *ext = *(EXTR *) sym->udata.p;
   2572   1.9  christos   return true;
   2573   1.1     skrll }
   2574   1.1     skrll 
   2575   1.1     skrll /* This function is called by bfd_ecoff_debug_externals.  It has
   2576   1.1     skrll    nothing to do for ELF.  */
   2577   1.1     skrll 
   2578   1.1     skrll static void
   2579   1.1     skrll elf_set_index (asymbol *sym ATTRIBUTE_UNUSED,
   2580   1.1     skrll 	       bfd_size_type indx ATTRIBUTE_UNUSED)
   2581   1.1     skrll {
   2582   1.1     skrll }
   2583   1.1     skrll 
   2584   1.1     skrll #endif /* NEED_ECOFF_DEBUG */
   2585   1.1     skrll 
   2586   1.1     skrll void
   2587   1.1     skrll elf_frob_symbol (symbolS *symp, int *puntp)
   2588   1.1     skrll {
   2589   1.1     skrll   struct elf_obj_sy *sy_obj;
   2590   1.2     joerg   expressionS *size;
   2591   1.9  christos   struct elf_versioned_name_list *versioned_name;
   2592   1.1     skrll 
   2593   1.1     skrll #ifdef NEED_ECOFF_DEBUG
   2594   1.1     skrll   if (ECOFF_DEBUGGING)
   2595   1.1     skrll     ecoff_frob_symbol (symp);
   2596   1.1     skrll #endif
   2597   1.1     skrll 
   2598   1.1     skrll   sy_obj = symbol_get_obj (symp);
   2599   1.1     skrll 
   2600   1.2     joerg   size = sy_obj->size;
   2601   1.2     joerg   if (size != NULL)
   2602   1.1     skrll     {
   2603   1.2     joerg       if (resolve_expression (size)
   2604   1.2     joerg 	  && size->X_op == O_constant)
   2605   1.2     joerg 	S_SET_SIZE (symp, size->X_add_number);
   2606   1.2     joerg       else
   2607   1.1     skrll 	{
   2608   1.5  christos 	  if (!flag_allow_nonconst_size)
   2609   1.2     joerg 	    as_bad (_(".size expression for %s "
   2610   1.2     joerg 		      "does not evaluate to a constant"), S_GET_NAME (symp));
   2611   1.2     joerg 	  else
   2612   1.2     joerg 	    as_warn (_(".size expression for %s "
   2613   1.2     joerg 		       "does not evaluate to a constant"), S_GET_NAME (symp));
   2614   1.1     skrll 	}
   2615   1.1     skrll       sy_obj->size = NULL;
   2616   1.1     skrll     }
   2617   1.1     skrll 
   2618   1.9  christos   versioned_name = sy_obj->versioned_name;
   2619   1.9  christos   if (versioned_name)
   2620   1.1     skrll     {
   2621   1.1     skrll       /* This symbol was given a new name with the .symver directive.
   2622   1.1     skrll 	 If this is an external reference, just rename the symbol to
   2623   1.1     skrll 	 include the version string.  This will make the relocs be
   2624   1.9  christos 	 against the correct versioned symbol.  */
   2625   1.1     skrll 
   2626   1.9  christos       /* We will have already reported an version error.  */
   2627   1.9  christos       if (sy_obj->bad_version)
   2628   1.9  christos 	*puntp = true;
   2629   1.9  christos       /* elf_frob_file_before_adjust only allows one version symbol for
   2630   1.9  christos 	 renamed symbol.  */
   2631   1.9  christos       else if (sy_obj->rename)
   2632   1.9  christos 	S_SET_NAME (symp, versioned_name->name);
   2633   1.9  christos       else if (S_IS_COMMON (symp))
   2634   1.9  christos 	{
   2635   1.9  christos 	  as_bad (_("`%s' can't be versioned to common symbol '%s'"),
   2636   1.9  christos 		  versioned_name->name, S_GET_NAME (symp));
   2637   1.9  christos 	  *puntp = true;
   2638   1.1     skrll 	}
   2639   1.1     skrll       else
   2640   1.1     skrll 	{
   2641   1.9  christos 	  asymbol *bfdsym;
   2642   1.9  christos 	  elf_symbol_type *elfsym;
   2643   1.1     skrll 
   2644   1.9  christos 	  /* This is a definition.  Add an alias for each version.
   2645   1.9  christos 	     FIXME: Using an alias will permit the debugging information
   2646   1.9  christos 	     to refer to the right symbol.  However, it's not clear
   2647   1.9  christos 	     whether it is the best approach.  */
   2648   1.9  christos 
   2649   1.9  christos 	  /* FIXME: Creating a new symbol here is risky.  We're
   2650   1.9  christos 	     in the final loop over the symbol table.  We can
   2651   1.9  christos 	     get away with it only because the symbol goes to
   2652   1.9  christos 	     the end of the list, where the loop will still see
   2653   1.9  christos 	     it.  It would probably be better to do this in
   2654   1.9  christos 	     obj_frob_file_before_adjust.  */
   2655   1.9  christos 	  for (; versioned_name != NULL;
   2656   1.9  christos 	       versioned_name = versioned_name->next)
   2657   1.1     skrll 	    {
   2658   1.9  christos 	      symbolS *symp2 = symbol_find_or_make (versioned_name->name);
   2659   1.1     skrll 
   2660   1.1     skrll 	      S_SET_SEGMENT (symp2, S_GET_SEGMENT (symp));
   2661   1.1     skrll 
   2662   1.1     skrll 	      /* Subtracting out the frag address here is a hack
   2663   1.1     skrll 		 because we are in the middle of the final loop.  */
   2664   1.1     skrll 	      S_SET_VALUE (symp2,
   2665   1.1     skrll 			   (S_GET_VALUE (symp)
   2666   1.9  christos 			    - (symbol_get_frag (symp)->fr_address
   2667   1.9  christos 			       / OCTETS_PER_BYTE)));
   2668   1.1     skrll 
   2669   1.1     skrll 	      symbol_set_frag (symp2, symbol_get_frag (symp));
   2670   1.1     skrll 
   2671   1.1     skrll 	      /* This will copy over the size information.  */
   2672   1.1     skrll 	      copy_symbol_attributes (symp2, symp);
   2673   1.1     skrll 
   2674   1.1     skrll 	      S_SET_OTHER (symp2, S_GET_OTHER (symp));
   2675   1.1     skrll 
   2676   1.1     skrll 	      if (S_IS_WEAK (symp))
   2677   1.1     skrll 		S_SET_WEAK (symp2);
   2678   1.1     skrll 
   2679   1.1     skrll 	      if (S_IS_EXTERNAL (symp))
   2680   1.1     skrll 		S_SET_EXTERNAL (symp2);
   2681   1.1     skrll 	    }
   2682   1.9  christos 
   2683   1.9  christos 	  switch (sy_obj->visibility)
   2684   1.9  christos 	    {
   2685   1.9  christos 	    case visibility_unchanged:
   2686   1.9  christos 	      break;
   2687   1.9  christos 	    case visibility_hidden:
   2688   1.9  christos 	      bfdsym = symbol_get_bfdsym (symp);
   2689   1.9  christos 	      elfsym = elf_symbol_from (bfdsym);
   2690   1.9  christos 	      elfsym->internal_elf_sym.st_other &= ~3;
   2691   1.9  christos 	      elfsym->internal_elf_sym.st_other |= STV_HIDDEN;
   2692   1.9  christos 	      break;
   2693   1.9  christos 	    case visibility_remove:
   2694   1.9  christos 	      /* Don't remove the symbol if it is used in relocation.
   2695   1.9  christos 		 Instead, mark it as to be removed and issue an error
   2696   1.9  christos 		 if the symbol has more than one versioned name.  */
   2697   1.9  christos 	      if (symbol_used_in_reloc_p (symp))
   2698   1.9  christos 		{
   2699   1.9  christos 		  if (sy_obj->versioned_name->next != NULL)
   2700   1.9  christos 		    as_bad (_("symbol '%s' with multiple versions cannot be used in relocation"),
   2701   1.9  christos 			    S_GET_NAME (symp));
   2702   1.9  christos 		  symbol_mark_removed (symp);
   2703   1.9  christos 		}
   2704   1.9  christos 	      else
   2705   1.9  christos 		symbol_remove (symp, &symbol_rootP, &symbol_lastP);
   2706   1.9  christos 	      break;
   2707   1.9  christos 	    case visibility_local:
   2708   1.9  christos 	      S_CLEAR_EXTERNAL (symp);
   2709   1.9  christos 	      break;
   2710   1.9  christos 	    }
   2711   1.1     skrll 	}
   2712   1.1     skrll     }
   2713   1.1     skrll 
   2714   1.1     skrll   /* Double check weak symbols.  */
   2715   1.1     skrll   if (S_IS_WEAK (symp))
   2716   1.1     skrll     {
   2717   1.1     skrll       if (S_IS_COMMON (symp))
   2718   1.1     skrll 	as_bad (_("symbol `%s' can not be both weak and common"),
   2719   1.1     skrll 		S_GET_NAME (symp));
   2720   1.1     skrll     }
   2721   1.1     skrll }
   2722   1.1     skrll 
   2723   1.9  christos /* Fix up SYMPP which has been marked to be removed by .symver.  */
   2724   1.9  christos 
   2725   1.9  christos void
   2726   1.9  christos elf_fixup_removed_symbol (symbolS **sympp)
   2727   1.9  christos {
   2728   1.9  christos   symbolS *symp = *sympp;
   2729   1.9  christos   struct elf_obj_sy *sy_obj = symbol_get_obj (symp);
   2730   1.9  christos 
   2731   1.9  christos   /* Replace the removed symbol with the versioned symbol.  */
   2732   1.9  christos   symp = symbol_find (sy_obj->versioned_name->name);
   2733   1.9  christos   *sympp = symp;
   2734   1.9  christos }
   2735   1.9  christos 
   2736   1.6  christos /* Create symbols for group signature.  */
   2737   1.6  christos 
   2738   1.1     skrll void
   2739   1.2     joerg elf_adjust_symtab (void)
   2740   1.1     skrll {
   2741   1.1     skrll   unsigned int i;
   2742   1.1     skrll 
   2743   1.1     skrll   /* Make the SHT_GROUP sections that describe each section group.  We
   2744   1.1     skrll      can't set up the section contents here yet, because elf section
   2745   1.1     skrll      indices have yet to be calculated.  elf.c:set_group_contents does
   2746   1.1     skrll      the rest of the work.  */
   2747   1.6  christos  for (i = 0; i < groups.num_group; i++)
   2748   1.1     skrll     {
   2749   1.6  christos       const char *group_name = elf_group_name (groups.head[i]);
   2750   1.1     skrll       const char *sec_name;
   2751   1.1     skrll       asection *s;
   2752   1.1     skrll       flagword flags;
   2753   1.1     skrll       struct symbol *sy;
   2754   1.1     skrll 
   2755   1.1     skrll       flags = SEC_READONLY | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_GROUP;
   2756   1.6  christos       for (s = groups.head[i]; s != NULL; s = elf_next_in_group (s))
   2757   1.1     skrll 	if ((s->flags ^ flags) & SEC_LINK_ONCE)
   2758   1.1     skrll 	  {
   2759   1.1     skrll 	    flags |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;
   2760   1.6  christos 	    if (s != groups.head[i])
   2761   1.1     skrll 	      {
   2762   1.1     skrll 		as_warn (_("assuming all members of group `%s' are COMDAT"),
   2763   1.1     skrll 			 group_name);
   2764   1.1     skrll 		break;
   2765   1.1     skrll 	      }
   2766   1.1     skrll 	  }
   2767   1.1     skrll 
   2768   1.2     joerg       sec_name = ".group";
   2769   1.1     skrll       s = subseg_force_new (sec_name, 0);
   2770   1.1     skrll       if (s == NULL
   2771   1.8  christos 	  || !bfd_set_section_flags (s, flags)
   2772   1.8  christos 	  || !bfd_set_section_alignment (s, 2))
   2773   1.1     skrll 	{
   2774   1.1     skrll 	  as_fatal (_("can't create group: %s"),
   2775   1.1     skrll 		    bfd_errmsg (bfd_get_error ()));
   2776   1.1     skrll 	}
   2777   1.1     skrll       elf_section_type (s) = SHT_GROUP;
   2778   1.1     skrll 
   2779   1.1     skrll       /* Pass a pointer to the first section in this group.  */
   2780   1.6  christos       elf_next_in_group (s) = groups.head[i];
   2781   1.6  christos       elf_sec_group (groups.head[i]) = s;
   2782   1.2     joerg       /* Make sure that the signature symbol for the group has the
   2783   1.2     joerg 	 name of the group.  */
   2784   1.2     joerg       sy = symbol_find_exact (group_name);
   2785   1.8  christos       if (!sy || !symbol_on_chain (sy, symbol_rootP, symbol_lastP))
   2786   1.2     joerg 	{
   2787   1.2     joerg 	  /* Create the symbol now.  */
   2788   1.9  christos 	  sy = symbol_new (group_name, now_seg, frag_now, 0);
   2789   1.2     joerg #ifdef TE_SOLARIS
   2790   1.2     joerg 	  /* Before Solaris 11 build 154, Sun ld rejects local group
   2791   1.2     joerg 	     signature symbols, so make them weak hidden instead.  */
   2792   1.2     joerg 	  symbol_get_bfdsym (sy)->flags |= BSF_WEAK;
   2793   1.2     joerg 	  S_SET_OTHER (sy, STV_HIDDEN);
   2794   1.2     joerg #else
   2795   1.2     joerg 	  symbol_get_obj (sy)->local = 1;
   2796   1.2     joerg #endif
   2797   1.2     joerg 	  symbol_table_insert (sy);
   2798   1.2     joerg 	}
   2799   1.2     joerg       elf_group_id (s) = symbol_get_bfdsym (sy);
   2800   1.9  christos       /* Mark the group signature symbol as used so that it will be
   2801   1.9  christos 	 included in the symbol table.  */
   2802   1.9  christos       symbol_mark_used_in_reloc (sy);
   2803   1.1     skrll     }
   2804   1.2     joerg }
   2805   1.2     joerg 
   2806   1.2     joerg void
   2807   1.2     joerg elf_frob_file (void)
   2808   1.2     joerg {
   2809  1.13  christos   bfd_map_over_sections (stdoutput, set_additional_section_info, NULL);
   2810   1.2     joerg 
   2811   1.1     skrll #ifdef elf_tc_final_processing
   2812   1.1     skrll   elf_tc_final_processing ();
   2813   1.1     skrll #endif
   2814   1.1     skrll }
   2815   1.1     skrll 
   2816   1.1     skrll /* It removes any unneeded versioned symbols from the symbol table.  */
   2817   1.1     skrll 
   2818   1.1     skrll void
   2819   1.1     skrll elf_frob_file_before_adjust (void)
   2820   1.1     skrll {
   2821   1.1     skrll   if (symbol_rootP)
   2822   1.1     skrll     {
   2823   1.1     skrll       symbolS *symp;
   2824   1.1     skrll 
   2825   1.1     skrll       for (symp = symbol_rootP; symp; symp = symbol_next (symp))
   2826   1.9  christos 	{
   2827   1.9  christos 	  struct elf_obj_sy *sy_obj = symbol_get_obj (symp);
   2828   1.9  christos 	  int is_defined = !!S_IS_DEFINED (symp);
   2829   1.9  christos 
   2830   1.9  christos 	  if (sy_obj->versioned_name)
   2831   1.9  christos 	    {
   2832   1.9  christos 	      char *p = strchr (sy_obj->versioned_name->name,
   2833   1.9  christos 				ELF_VER_CHR);
   2834   1.9  christos 
   2835  1.14  christos 	      /* NB: Malformed versioned symbols may not have @@@.  */
   2836  1.14  christos 	      if (sy_obj->rename
   2837  1.14  christos 		  && p[1] == ELF_VER_CHR
   2838  1.14  christos 		  && p[2] == ELF_VER_CHR)
   2839   1.9  christos 		{
   2840   1.9  christos 		  /* The @@@ syntax is a special case. If the symbol is
   2841   1.9  christos 		     not defined, 2 `@'s will be removed from the
   2842   1.9  christos 		     versioned_name. Otherwise, 1 `@' will be removed.   */
   2843   1.9  christos 		  size_t l = strlen (&p[3]) + 1;
   2844   1.9  christos 		  memmove (&p[1 + is_defined], &p[3], l);
   2845   1.9  christos 		}
   2846   1.9  christos 
   2847   1.9  christos 	      if (!is_defined)
   2848   1.9  christos 		{
   2849   1.9  christos 		  /* Verify that the name isn't using the @@ syntax--this
   2850   1.9  christos 		     is reserved for definitions of the default version
   2851   1.9  christos 		     to link against.  */
   2852   1.9  christos 		  if (!sy_obj->rename && p[1] == ELF_VER_CHR)
   2853   1.9  christos 		    {
   2854   1.9  christos 		      as_bad (_("invalid attempt to declare external "
   2855   1.9  christos 				"version name as default in symbol `%s'"),
   2856   1.9  christos 			      sy_obj->versioned_name->name);
   2857   1.9  christos 		      return;
   2858   1.9  christos 		    }
   2859   1.1     skrll 
   2860   1.9  christos 		  /* Only one version symbol is allowed for undefined
   2861   1.9  christos 		     symbol.  */
   2862   1.9  christos 		  if (sy_obj->versioned_name->next)
   2863   1.9  christos 		    {
   2864   1.9  christos 		      as_bad (_("multiple versions [`%s'|`%s'] for "
   2865   1.9  christos 				"symbol `%s'"),
   2866   1.9  christos 			      sy_obj->versioned_name->name,
   2867   1.9  christos 			      sy_obj->versioned_name->next->name,
   2868   1.9  christos 			      S_GET_NAME (symp));
   2869   1.9  christos 		      return;
   2870   1.9  christos 		    }
   2871   1.1     skrll 
   2872   1.9  christos 		  sy_obj->rename = true;
   2873   1.9  christos 		}
   2874   1.9  christos 	    }
   2875   1.1     skrll 
   2876   1.9  christos 	  /* If there was .symver or .weak, but symbol was neither
   2877   1.9  christos 	     defined nor used anywhere, remove it.  */
   2878   1.9  christos 	  if (!is_defined
   2879   1.9  christos 	      && (sy_obj->versioned_name || S_IS_WEAK (symp))
   2880   1.9  christos 	      && symbol_used_p (symp) == 0
   2881   1.9  christos 	      && symbol_used_in_reloc_p (symp) == 0)
   2882   1.9  christos 	    symbol_remove (symp, &symbol_rootP, &symbol_lastP);
   2883   1.9  christos 	}
   2884   1.1     skrll     }
   2885   1.1     skrll }
   2886   1.1     skrll 
   2887   1.1     skrll /* It is required that we let write_relocs have the opportunity to
   2888   1.1     skrll    optimize away fixups before output has begun, since it is possible
   2889   1.1     skrll    to eliminate all fixups for a section and thus we never should
   2890   1.1     skrll    have generated the relocation section.  */
   2891   1.1     skrll 
   2892   1.1     skrll void
   2893   1.1     skrll elf_frob_file_after_relocs (void)
   2894   1.1     skrll {
   2895   1.6  christos   unsigned int i;
   2896   1.6  christos 
   2897   1.6  christos   /* Set SHT_GROUP section size.  */
   2898   1.6  christos   for (i = 0; i < groups.num_group; i++)
   2899   1.6  christos     {
   2900   1.6  christos       asection *s, *head, *group;
   2901   1.6  christos       bfd_size_type size;
   2902   1.6  christos 
   2903   1.6  christos       head = groups.head[i];
   2904   1.6  christos       size = 4;
   2905   1.6  christos       for (s = head; s != NULL; s = elf_next_in_group (s))
   2906   1.6  christos 	size += (s->flags & SEC_RELOC) != 0 ? 8 : 4;
   2907   1.6  christos 
   2908   1.6  christos       group = elf_sec_group (head);
   2909   1.6  christos       subseg_set (group, 0);
   2910   1.8  christos       bfd_set_section_size (group, size);
   2911   1.6  christos       group->contents = (unsigned char *) frag_more (size);
   2912  1.13  christos       group->alloced = 1;
   2913   1.6  christos       frag_now->fr_fix = frag_now_fix_octets ();
   2914   1.6  christos       frag_wane (frag_now);
   2915   1.6  christos     }
   2916   1.6  christos 
   2917   1.1     skrll #ifdef NEED_ECOFF_DEBUG
   2918   1.1     skrll   if (ECOFF_DEBUGGING)
   2919   1.1     skrll     /* Generate the ECOFF debugging information.  */
   2920   1.1     skrll     {
   2921   1.1     skrll       const struct ecoff_debug_swap *debug_swap;
   2922   1.1     skrll       struct ecoff_debug_info debug;
   2923   1.1     skrll       char *buf;
   2924   1.1     skrll       asection *sec;
   2925   1.1     skrll 
   2926   1.1     skrll       debug_swap
   2927   1.1     skrll 	= get_elf_backend_data (stdoutput)->elf_backend_ecoff_debug_swap;
   2928   1.1     skrll       know (debug_swap != NULL);
   2929   1.1     skrll       ecoff_build_debug (&debug.symbolic_header, &buf, debug_swap);
   2930   1.1     skrll 
   2931   1.1     skrll       /* Set up the pointers in debug.  */
   2932  1.12  christos       debug.alloc_syments = true;
   2933   1.1     skrll #define SET(ptr, offset, type) \
   2934   1.1     skrll     debug.ptr = (type) (buf + debug.symbolic_header.offset)
   2935   1.1     skrll 
   2936   1.1     skrll       SET (line, cbLineOffset, unsigned char *);
   2937   1.1     skrll       SET (external_dnr, cbDnOffset, void *);
   2938   1.1     skrll       SET (external_pdr, cbPdOffset, void *);
   2939   1.1     skrll       SET (external_sym, cbSymOffset, void *);
   2940   1.1     skrll       SET (external_opt, cbOptOffset, void *);
   2941   1.1     skrll       SET (external_aux, cbAuxOffset, union aux_ext *);
   2942   1.1     skrll       SET (ss, cbSsOffset, char *);
   2943   1.1     skrll       SET (external_fdr, cbFdOffset, void *);
   2944   1.1     skrll       SET (external_rfd, cbRfdOffset, void *);
   2945   1.1     skrll       /* ssext and external_ext are set up just below.  */
   2946   1.1     skrll 
   2947   1.1     skrll #undef SET
   2948   1.1     skrll 
   2949   1.1     skrll       /* Set up the external symbols.  */
   2950   1.1     skrll       debug.ssext = debug.ssext_end = NULL;
   2951   1.1     skrll       debug.external_ext = debug.external_ext_end = NULL;
   2952   1.9  christos       if (! bfd_ecoff_debug_externals (stdoutput, &debug, debug_swap, true,
   2953   1.1     skrll 				       elf_get_extr, elf_set_index))
   2954   1.1     skrll 	as_fatal (_("failed to set up debugging information: %s"),
   2955   1.1     skrll 		  bfd_errmsg (bfd_get_error ()));
   2956   1.1     skrll 
   2957   1.1     skrll       sec = bfd_get_section_by_name (stdoutput, ".mdebug");
   2958   1.2     joerg       gas_assert (sec != NULL);
   2959   1.1     skrll 
   2960   1.1     skrll       know (!stdoutput->output_has_begun);
   2961   1.1     skrll 
   2962   1.1     skrll       /* We set the size of the section, call bfd_set_section_contents
   2963   1.1     skrll 	 to force the ELF backend to allocate a file position, and then
   2964   1.1     skrll 	 write out the data.  FIXME: Is this really the best way to do
   2965   1.1     skrll 	 this?  */
   2966   1.8  christos       bfd_set_section_size (sec, bfd_ecoff_debug_size (stdoutput, &debug,
   2967   1.8  christos 						       debug_swap));
   2968   1.1     skrll 
   2969   1.1     skrll       /* Pass BUF to bfd_set_section_contents because this will
   2970   1.1     skrll 	 eventually become a call to fwrite, and ISO C prohibits
   2971   1.1     skrll 	 passing a NULL pointer to a stdio function even if the
   2972   1.1     skrll 	 pointer will not be used.  */
   2973   1.1     skrll       if (! bfd_set_section_contents (stdoutput, sec, buf, 0, 0))
   2974   1.1     skrll 	as_fatal (_("can't start writing .mdebug section: %s"),
   2975   1.1     skrll 		  bfd_errmsg (bfd_get_error ()));
   2976   1.1     skrll 
   2977   1.1     skrll       know (stdoutput->output_has_begun);
   2978   1.1     skrll       know (sec->filepos != 0);
   2979   1.1     skrll 
   2980   1.1     skrll       if (! bfd_ecoff_write_debug (stdoutput, &debug, debug_swap,
   2981   1.1     skrll 				   sec->filepos))
   2982   1.1     skrll 	as_fatal (_("could not write .mdebug section: %s"),
   2983   1.1     skrll 		  bfd_errmsg (bfd_get_error ()));
   2984   1.1     skrll     }
   2985   1.1     skrll #endif /* NEED_ECOFF_DEBUG */
   2986   1.1     skrll }
   2987   1.1     skrll 
   2988  1.12  christos /* This is called when the assembler starts.  */
   2989  1.12  christos 
   2990  1.12  christos void
   2991  1.12  christos elf_begin (void)
   2992  1.12  christos {
   2993  1.12  christos   asection *s;
   2994  1.12  christos 
   2995  1.12  christos   /* Add symbols for the known sections to the symbol table.  */
   2996  1.12  christos   s = bfd_get_section_by_name (stdoutput, TEXT_SECTION_NAME);
   2997  1.12  christos   symbol_table_insert (section_symbol (s));
   2998  1.12  christos   s = bfd_get_section_by_name (stdoutput, DATA_SECTION_NAME);
   2999  1.12  christos   symbol_table_insert (section_symbol (s));
   3000  1.12  christos   s = bfd_get_section_by_name (stdoutput, BSS_SECTION_NAME);
   3001  1.12  christos   symbol_table_insert (section_symbol (s));
   3002  1.12  christos   elf_com_section_ptr = bfd_com_section_ptr;
   3003  1.12  christos   previous_section = NULL;
   3004  1.12  christos   previous_subsection = 0;
   3005  1.12  christos   comment_section = NULL;
   3006  1.12  christos   memset (&groups, 0, sizeof (groups));
   3007  1.14  christos 
   3008  1.14  christos #ifdef TC_OBJ_ATTR
   3009  1.14  christos   /* Set the object attribute version for the output object to the default
   3010  1.14  christos      value supported by the backend.  */
   3011  1.14  christos   elf_obj_attr_version (stdoutput)
   3012  1.14  christos     = get_elf_backend_data (stdoutput)->default_obj_attr_version;
   3013  1.14  christos 
   3014  1.14  christos #if TC_OBJ_ATTR_v1
   3015  1.14  christos   oav1_attr_info_init ();
   3016  1.14  christos #endif /* TC_OBJ_ATTR_v1 */
   3017  1.14  christos #endif /* TC_OBJ_ATTR */
   3018  1.12  christos }
   3019  1.12  christos 
   3020  1.12  christos void
   3021  1.12  christos elf_end (void)
   3022  1.12  christos {
   3023  1.12  christos   while (section_stack)
   3024  1.12  christos     {
   3025  1.12  christos       struct section_stack *top = section_stack;
   3026  1.12  christos       section_stack = top->next;
   3027  1.12  christos       free (top);
   3028  1.12  christos     }
   3029  1.12  christos   if (groups.indexes)
   3030  1.12  christos     {
   3031  1.12  christos       htab_delete (groups.indexes);
   3032  1.12  christos       free (groups.head);
   3033  1.12  christos     }
   3034  1.14  christos 
   3035  1.14  christos #if TC_OBJ_ATTR_v1
   3036  1.14  christos   oav1_attr_info_exit ();
   3037  1.14  christos #endif /* TC_OBJ_ATTR_v1 */
   3038   1.1     skrll }
   3039   1.1     skrll 
   3040  1.13  christos #ifdef USE_EMULATIONS
   3041  1.13  christos 
   3042  1.13  christos static bfd_vma
   3043  1.13  christos elf_s_get_size (symbolS *sym)
   3044  1.13  christos {
   3045  1.13  christos   return S_GET_SIZE (sym);
   3046  1.13  christos }
   3047  1.13  christos 
   3048  1.13  christos static void
   3049  1.13  christos elf_s_set_size (symbolS *sym, bfd_vma sz)
   3050  1.13  christos {
   3051  1.13  christos   S_SET_SIZE (sym, sz);
   3052  1.13  christos }
   3053  1.13  christos 
   3054  1.13  christos static bfd_vma
   3055  1.13  christos elf_s_get_align (symbolS *sym)
   3056  1.13  christos {
   3057  1.13  christos   return S_GET_ALIGN (sym);
   3058  1.13  christos }
   3059  1.13  christos 
   3060  1.13  christos static void
   3061  1.13  christos elf_s_set_align (symbolS *sym, bfd_vma align)
   3062  1.13  christos {
   3063  1.13  christos   S_SET_ALIGN (sym, align);
   3064  1.13  christos }
   3065  1.13  christos 
   3066  1.13  christos int
   3067  1.13  christos elf_s_get_other (symbolS *sym)
   3068  1.13  christos {
   3069  1.13  christos   return elf_symbol (symbol_get_bfdsym (sym))->internal_elf_sym.st_other;
   3070  1.13  christos }
   3071  1.13  christos 
   3072  1.13  christos static void
   3073  1.13  christos elf_s_set_other (symbolS *sym, int other)
   3074  1.13  christos {
   3075  1.13  christos   S_SET_OTHER (sym, other);
   3076  1.13  christos }
   3077  1.13  christos 
   3078  1.13  christos static int
   3079  1.13  christos elf_sec_sym_ok_for_reloc (asection *sec)
   3080  1.13  christos {
   3081  1.13  christos   return obj_sec_sym_ok_for_reloc (sec);
   3082  1.13  christos }
   3083  1.13  christos 
   3084  1.13  christos #ifdef NEED_ECOFF_DEBUG
   3085  1.13  christos static void
   3086  1.13  christos elf_process_stab (int what ATTRIBUTE_UNUSED,
   3087  1.13  christos 		  const char *string ATTRIBUTE_UNUSED,
   3088  1.13  christos 		  int type ATTRIBUTE_UNUSED,
   3089  1.13  christos 		  int other ATTRIBUTE_UNUSED,
   3090  1.13  christos 		  int desc ATTRIBUTE_UNUSED)
   3091  1.13  christos {
   3092  1.13  christos   if (ECOFF_DEBUGGING)
   3093  1.13  christos     ecoff_stab (what, string, type, other, desc);
   3094  1.13  christos }
   3095  1.13  christos #else
   3096  1.13  christos # define elf_process_stab NULL
   3097  1.13  christos #endif
   3098  1.13  christos 
   3099  1.13  christos static int
   3100  1.13  christos elf_separate_stab_sections (void)
   3101  1.13  christos {
   3102  1.13  christos #ifdef NEED_ECOFF_DEBUG
   3103  1.13  christos   return (!ECOFF_DEBUGGING);
   3104  1.13  christos #else
   3105  1.13  christos   return 1;
   3106  1.13  christos #endif
   3107  1.13  christos }
   3108  1.13  christos 
   3109  1.13  christos #ifdef NEED_ECOFF_DEBUG
   3110  1.13  christos static void
   3111  1.13  christos elf_init_stab_section (segT stab, segT stabstr)
   3112  1.13  christos {
   3113  1.13  christos   if (!ECOFF_DEBUGGING)
   3114  1.13  christos     obj_elf_init_stab_section (stab, stabstr);
   3115  1.13  christos }
   3116  1.13  christos #endif
   3117  1.13  christos 
   3118   1.1     skrll const struct format_ops elf_format_ops =
   3119   1.1     skrll {
   3120   1.1     skrll   bfd_target_elf_flavour,
   3121   1.1     skrll   0,	/* dfl_leading_underscore */
   3122   1.1     skrll   1,	/* emit_section_symbols */
   3123   1.1     skrll   elf_begin,
   3124  1.12  christos   elf_end,
   3125   1.1     skrll   elf_file_symbol,
   3126  1.13  christos   NULL, /* assign_symbol */
   3127   1.1     skrll   elf_frob_symbol,
   3128   1.1     skrll   elf_frob_file,
   3129   1.1     skrll   elf_frob_file_before_adjust,
   3130   1.1     skrll   0,	/* obj_frob_file_before_fix */
   3131   1.1     skrll   elf_frob_file_after_relocs,
   3132   1.1     skrll   elf_s_get_size, elf_s_set_size,
   3133   1.1     skrll   elf_s_get_align, elf_s_set_align,
   3134   1.1     skrll   elf_s_get_other,
   3135   1.1     skrll   elf_s_set_other,
   3136   1.1     skrll   0,	/* s_get_desc */
   3137   1.1     skrll   0,	/* s_set_desc */
   3138   1.1     skrll   0,	/* s_get_type */
   3139   1.1     skrll   0,	/* s_set_type */
   3140   1.1     skrll   elf_copy_symbol_attributes,
   3141   1.2     joerg   elf_process_stab,
   3142   1.1     skrll   elf_separate_stab_sections,
   3143  1.13  christos #ifdef NEED_ECOFF_DEBUG
   3144   1.1     skrll   elf_init_stab_section,
   3145  1.13  christos #else
   3146  1.13  christos   obj_elf_init_stab_section,
   3147  1.13  christos #endif
   3148   1.1     skrll   elf_sec_sym_ok_for_reloc,
   3149   1.1     skrll   elf_pop_insert,
   3150   1.1     skrll #ifdef NEED_ECOFF_DEBUG
   3151   1.1     skrll   elf_ecoff_set_ext,
   3152   1.1     skrll #else
   3153   1.1     skrll   0,	/* ecoff_set_ext */
   3154   1.1     skrll #endif
   3155   1.1     skrll   elf_obj_read_begin_hook,
   3156   1.2     joerg   elf_obj_symbol_new_hook,
   3157  1.13  christos   0,
   3158   1.2     joerg   elf_adjust_symtab
   3159   1.1     skrll };
   3160  1.13  christos 
   3161  1.13  christos #endif /* USE_EMULATIONS */
   3162