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