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