Home | History | Annotate | Line # | Download | only in config
obj-coff.c revision 1.6
      1  1.1  christos /* coff object file format
      2  1.6  christos    Copyright (C) 1989-2018 Free Software Foundation, Inc.
      3  1.1  christos 
      4  1.1  christos    This file is part of GAS.
      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 published by
      8  1.1  christos    the Free Software Foundation; either version 3, or (at your option)
      9  1.1  christos    any later version.
     10  1.1  christos 
     11  1.1  christos    GAS is distributed in the hope that it will be useful,
     12  1.1  christos    but WITHOUT ANY WARRANTY; without even the implied warranty of
     13  1.1  christos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14  1.1  christos    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-coff.h"
     22  1.1  christos 
     23  1.1  christos #include "as.h"
     24  1.1  christos #include "safe-ctype.h"
     25  1.1  christos #include "subsegs.h"
     26  1.3  christos #include "struc-symbol.h"
     27  1.1  christos 
     28  1.1  christos #ifdef TE_PE
     29  1.1  christos #include "coff/pe.h"
     30  1.1  christos #endif
     31  1.1  christos 
     32  1.1  christos #ifdef OBJ_XCOFF
     33  1.1  christos #include "coff/xcoff.h"
     34  1.1  christos #endif
     35  1.1  christos 
     36  1.1  christos #define streq(a,b)     (strcmp ((a), (b)) == 0)
     37  1.1  christos #define strneq(a,b,n)  (strncmp ((a), (b), (n)) == 0)
     38  1.1  christos 
     39  1.1  christos /* I think this is probably always correct.  */
     40  1.1  christos #ifndef KEEP_RELOC_INFO
     41  1.1  christos #define KEEP_RELOC_INFO
     42  1.1  christos #endif
     43  1.1  christos 
     44  1.1  christos /* obj_coff_section will use this macro to set a new section's
     45  1.1  christos    attributes when a directive has no valid flags or the "w" flag is
     46  1.1  christos    used.  This default should be appropriate for most.  */
     47  1.1  christos #ifndef TC_COFF_SECTION_DEFAULT_ATTRIBUTES
     48  1.1  christos #define TC_COFF_SECTION_DEFAULT_ATTRIBUTES (SEC_LOAD | SEC_DATA)
     49  1.1  christos #endif
     50  1.1  christos 
     51  1.1  christos /* This is used to hold the symbol built by a sequence of pseudo-ops
     52  1.1  christos    from .def and .endef.  */
     53  1.1  christos static symbolS *def_symbol_in_progress;
     54  1.1  christos #ifdef TE_PE
     55  1.1  christos /* PE weak alternate symbols begin with this string.  */
     56  1.1  christos static const char weak_altprefix[] = ".weak.";
     57  1.1  christos #endif /* TE_PE */
     58  1.1  christos 
     59  1.1  christos #include "obj-coff-seh.c"
     60  1.1  christos 
     61  1.1  christos typedef struct
     62  1.1  christos   {
     63  1.1  christos     unsigned long chunk_size;
     64  1.1  christos     unsigned long element_size;
     65  1.1  christos     unsigned long size;
     66  1.1  christos     char *data;
     67  1.1  christos     unsigned long pointer;
     68  1.1  christos   }
     69  1.1  christos stack;
     70  1.1  christos 
     71  1.1  christos 
     72  1.1  christos /* Stack stuff.  */
     74  1.1  christos 
     75  1.1  christos static stack *
     76  1.1  christos stack_init (unsigned long chunk_size,
     77  1.1  christos 	    unsigned long element_size)
     78  1.1  christos {
     79  1.1  christos   stack *st;
     80  1.5  christos 
     81  1.5  christos   st = XNEW (stack);
     82  1.1  christos   st->data = XNEWVEC (char, chunk_size);
     83  1.1  christos   if (!st->data)
     84  1.1  christos     {
     85  1.1  christos       free (st);
     86  1.1  christos       return NULL;
     87  1.1  christos     }
     88  1.1  christos   st->pointer = 0;
     89  1.1  christos   st->size = chunk_size;
     90  1.1  christos   st->chunk_size = chunk_size;
     91  1.1  christos   st->element_size = element_size;
     92  1.1  christos   return st;
     93  1.1  christos }
     94  1.1  christos 
     95  1.1  christos static char *
     96  1.1  christos stack_push (stack *st, char *element)
     97  1.1  christos {
     98  1.1  christos   if (st->pointer + st->element_size >= st->size)
     99  1.1  christos     {
    100  1.5  christos       st->size += st->chunk_size;
    101  1.1  christos       st->data = XRESIZEVEC (char, st->data, st->size);
    102  1.1  christos     }
    103  1.1  christos   memcpy (st->data + st->pointer, element, st->element_size);
    104  1.1  christos   st->pointer += st->element_size;
    105  1.1  christos   return st->data + st->pointer;
    106  1.1  christos }
    107  1.1  christos 
    108  1.1  christos static char *
    109  1.1  christos stack_pop (stack *st)
    110  1.1  christos {
    111  1.1  christos   if (st->pointer < st->element_size)
    112  1.1  christos     {
    113  1.1  christos       st->pointer = 0;
    114  1.1  christos       return NULL;
    115  1.1  christos     }
    116  1.1  christos   st->pointer -= st->element_size;
    117  1.1  christos   return st->data + st->pointer;
    118  1.1  christos }
    119  1.1  christos 
    120  1.1  christos /* Maintain a list of the tagnames of the structures.  */
    122  1.1  christos 
    123  1.1  christos static struct hash_control *tag_hash;
    124  1.1  christos 
    125  1.1  christos static void
    126  1.1  christos tag_init (void)
    127  1.1  christos {
    128  1.1  christos   tag_hash = hash_new ();
    129  1.1  christos }
    130  1.1  christos 
    131  1.1  christos static void
    132  1.1  christos tag_insert (const char *name, symbolS *symbolP)
    133  1.1  christos {
    134  1.1  christos   const char *error_string;
    135  1.1  christos 
    136  1.1  christos   if ((error_string = hash_jam (tag_hash, name, (char *) symbolP)))
    137  1.1  christos     as_fatal (_("Inserting \"%s\" into structure table failed: %s"),
    138  1.1  christos 	      name, error_string);
    139  1.1  christos }
    140  1.1  christos 
    141  1.1  christos static symbolS *
    142  1.1  christos tag_find (char *name)
    143  1.1  christos {
    144  1.1  christos   return (symbolS *) hash_find (tag_hash, name);
    145  1.1  christos }
    146  1.1  christos 
    147  1.1  christos static symbolS *
    148  1.1  christos tag_find_or_make (char *name)
    149  1.1  christos {
    150  1.1  christos   symbolS *symbolP;
    151  1.1  christos 
    152  1.1  christos   if ((symbolP = tag_find (name)) == NULL)
    153  1.1  christos     {
    154  1.1  christos       symbolP = symbol_new (name, undefined_section,
    155  1.1  christos 			    0, &zero_address_frag);
    156  1.1  christos 
    157  1.1  christos       tag_insert (S_GET_NAME (symbolP), symbolP);
    158  1.1  christos       symbol_table_insert (symbolP);
    159  1.1  christos     }
    160  1.1  christos 
    161  1.1  christos   return symbolP;
    162  1.1  christos }
    163  1.1  christos 
    164  1.1  christos /* We accept the .bss directive to set the section for backward
    165  1.1  christos    compatibility with earlier versions of gas.  */
    166  1.1  christos 
    167  1.1  christos static void
    168  1.1  christos obj_coff_bss (int ignore ATTRIBUTE_UNUSED)
    169  1.1  christos {
    170  1.1  christos   if (*input_line_pointer == '\n')
    171  1.1  christos     subseg_new (".bss", get_absolute_expression ());
    172  1.1  christos   else
    173  1.1  christos     s_lcomm (0);
    174  1.1  christos }
    175  1.1  christos 
    176  1.1  christos #ifdef TE_PE
    177  1.1  christos /* Called from read.c:s_comm after we've parsed .comm symbol, size.
    178  1.1  christos    Parse a possible alignment value.  */
    179  1.1  christos 
    180  1.1  christos static symbolS *
    181  1.1  christos obj_coff_common_parse (int ignore ATTRIBUTE_UNUSED, symbolS *symbolP, addressT size)
    182  1.1  christos {
    183  1.1  christos   addressT align = 0;
    184  1.1  christos 
    185  1.1  christos   if (*input_line_pointer == ',')
    186  1.1  christos     {
    187  1.1  christos       align = parse_align (0);
    188  1.1  christos       if (align == (addressT) -1)
    189  1.1  christos 	return NULL;
    190  1.1  christos     }
    191  1.1  christos 
    192  1.1  christos   S_SET_VALUE (symbolP, size);
    193  1.1  christos   S_SET_EXTERNAL (symbolP);
    194  1.1  christos   S_SET_SEGMENT (symbolP, bfd_com_section_ptr);
    195  1.1  christos 
    196  1.1  christos   symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT;
    197  1.1  christos 
    198  1.1  christos   /* There is no S_SET_ALIGN (symbolP, align) in COFF/PE.
    199  1.1  christos      Instead we must add a note to the .drectve section.  */
    200  1.1  christos   if (align)
    201  1.1  christos     {
    202  1.1  christos       segT current_seg = now_seg;
    203  1.1  christos       subsegT current_subseg = now_subseg;
    204  1.1  christos       flagword oldflags;
    205  1.1  christos       asection *sec;
    206  1.1  christos       size_t pfxlen, numlen;
    207  1.1  christos       char *frag;
    208  1.1  christos       char numbuff[20];
    209  1.1  christos 
    210  1.1  christos       sec = subseg_new (".drectve", 0);
    211  1.1  christos       oldflags = bfd_get_section_flags (stdoutput, sec);
    212  1.1  christos       if (oldflags == SEC_NO_FLAGS)
    213  1.1  christos 	{
    214  1.1  christos 	  if (!bfd_set_section_flags (stdoutput, sec,
    215  1.1  christos 		TC_COFF_SECTION_DEFAULT_ATTRIBUTES))
    216  1.1  christos 	    as_warn (_("error setting flags for \"%s\": %s"),
    217  1.1  christos 		bfd_section_name (stdoutput, sec),
    218  1.1  christos 		bfd_errmsg (bfd_get_error ()));
    219  1.1  christos 	}
    220  1.1  christos 
    221  1.1  christos       /* Emit a string.  Note no NUL-termination.  */
    222  1.1  christos       pfxlen = strlen (" -aligncomm:") + 2 + strlen (S_GET_NAME (symbolP)) + 1;
    223  1.1  christos       numlen = snprintf (numbuff, sizeof (numbuff), "%d", (int) align);
    224  1.1  christos       frag = frag_more (pfxlen + numlen);
    225  1.1  christos       (void) sprintf (frag, " -aligncomm:\"%s\",", S_GET_NAME (symbolP));
    226  1.1  christos       memcpy (frag + pfxlen, numbuff, numlen);
    227  1.1  christos       /* Restore original subseg. */
    228  1.1  christos       subseg_set (current_seg, current_subseg);
    229  1.1  christos     }
    230  1.1  christos 
    231  1.1  christos   return symbolP;
    232  1.1  christos }
    233  1.1  christos 
    234  1.1  christos static void
    235  1.1  christos obj_coff_comm (int ignore ATTRIBUTE_UNUSED)
    236  1.1  christos {
    237  1.1  christos   s_comm_internal (ignore, obj_coff_common_parse);
    238  1.1  christos }
    239  1.1  christos #endif /* TE_PE */
    240  1.1  christos 
    241  1.1  christos #define GET_FILENAME_STRING(X) \
    242  1.1  christos   ((char *) (&((X)->sy_symbol.ost_auxent->x_file.x_n.x_offset))[1])
    243  1.1  christos 
    244  1.1  christos /* @@ Ick.  */
    245  1.1  christos static segT
    246  1.1  christos fetch_coff_debug_section (void)
    247  1.1  christos {
    248  1.1  christos   static segT debug_section;
    249  1.1  christos 
    250  1.1  christos   if (!debug_section)
    251  1.1  christos     {
    252  1.1  christos       const asymbol *s;
    253  1.1  christos 
    254  1.1  christos       s = bfd_make_debug_symbol (stdoutput, NULL, 0);
    255  1.1  christos       gas_assert (s != 0);
    256  1.1  christos       debug_section = s->section;
    257  1.1  christos     }
    258  1.1  christos   return debug_section;
    259  1.1  christos }
    260  1.1  christos 
    261  1.1  christos void
    262  1.1  christos SA_SET_SYM_ENDNDX (symbolS *sym, symbolS *val)
    263  1.1  christos {
    264  1.1  christos   combined_entry_type *entry, *p;
    265  1.1  christos 
    266  1.1  christos   entry = &coffsymbol (symbol_get_bfdsym (sym))->native[1];
    267  1.1  christos   p = coffsymbol (symbol_get_bfdsym (val))->native;
    268  1.1  christos   entry->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.p = p;
    269  1.1  christos   entry->fix_end = 1;
    270  1.1  christos }
    271  1.1  christos 
    272  1.1  christos static void
    273  1.1  christos SA_SET_SYM_TAGNDX (symbolS *sym, symbolS *val)
    274  1.1  christos {
    275  1.1  christos   combined_entry_type *entry, *p;
    276  1.1  christos 
    277  1.1  christos   entry = &coffsymbol (symbol_get_bfdsym (sym))->native[1];
    278  1.1  christos   p = coffsymbol (symbol_get_bfdsym (val))->native;
    279  1.1  christos   entry->u.auxent.x_sym.x_tagndx.p = p;
    280  1.1  christos   entry->fix_tag = 1;
    281  1.1  christos }
    282  1.1  christos 
    283  1.1  christos static int
    284  1.1  christos S_GET_DATA_TYPE (symbolS *sym)
    285  1.1  christos {
    286  1.1  christos   return coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_type;
    287  1.1  christos }
    288  1.1  christos 
    289  1.1  christos int
    290  1.1  christos S_SET_DATA_TYPE (symbolS *sym, int val)
    291  1.1  christos {
    292  1.1  christos   coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_type = val;
    293  1.1  christos   return val;
    294  1.1  christos }
    295  1.1  christos 
    296  1.1  christos int
    297  1.1  christos S_GET_STORAGE_CLASS (symbolS *sym)
    298  1.1  christos {
    299  1.1  christos   return coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_sclass;
    300  1.1  christos }
    301  1.1  christos 
    302  1.1  christos int
    303  1.1  christos S_SET_STORAGE_CLASS (symbolS *sym, int val)
    304  1.1  christos {
    305  1.1  christos   coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_sclass = val;
    306  1.1  christos   return val;
    307  1.1  christos }
    308  1.1  christos 
    309  1.1  christos /* Merge a debug symbol containing debug information into a normal symbol.  */
    310  1.1  christos 
    311  1.1  christos static void
    312  1.1  christos c_symbol_merge (symbolS *debug, symbolS *normal)
    313  1.1  christos {
    314  1.1  christos   S_SET_DATA_TYPE (normal, S_GET_DATA_TYPE (debug));
    315  1.1  christos   S_SET_STORAGE_CLASS (normal, S_GET_STORAGE_CLASS (debug));
    316  1.1  christos 
    317  1.1  christos   if (S_GET_NUMBER_AUXILIARY (debug) > S_GET_NUMBER_AUXILIARY (normal))
    318  1.1  christos     /* Take the most we have.  */
    319  1.1  christos     S_SET_NUMBER_AUXILIARY (normal, S_GET_NUMBER_AUXILIARY (debug));
    320  1.1  christos 
    321  1.1  christos   if (S_GET_NUMBER_AUXILIARY (debug) > 0)
    322  1.1  christos     /* Move all the auxiliary information.  */
    323  1.1  christos     memcpy (SYM_AUXINFO (normal), SYM_AUXINFO (debug),
    324  1.1  christos 	    (S_GET_NUMBER_AUXILIARY (debug)
    325  1.1  christos 	     * sizeof (*SYM_AUXINFO (debug))));
    326  1.1  christos 
    327  1.1  christos   /* Move the debug flags.  */
    328  1.1  christos   SF_SET_DEBUG_FIELD (normal, SF_GET_DEBUG_FIELD (debug));
    329  1.1  christos }
    330  1.1  christos 
    331  1.1  christos void
    332  1.1  christos c_dot_file_symbol (const char *filename, int appfile ATTRIBUTE_UNUSED)
    333  1.1  christos {
    334  1.1  christos   symbolS *symbolP;
    335  1.1  christos 
    336  1.1  christos   /* BFD converts filename to a .file symbol with an aux entry.  It
    337  1.1  christos      also handles chaining.  */
    338  1.1  christos   symbolP = symbol_new (filename, bfd_abs_section_ptr, 0, &zero_address_frag);
    339  1.1  christos 
    340  1.1  christos   S_SET_STORAGE_CLASS (symbolP, C_FILE);
    341  1.1  christos   S_SET_NUMBER_AUXILIARY (symbolP, 1);
    342  1.1  christos 
    343  1.1  christos   symbol_get_bfdsym (symbolP)->flags = BSF_DEBUGGING;
    344  1.1  christos 
    345  1.1  christos #ifndef NO_LISTING
    346  1.1  christos   {
    347  1.1  christos     extern int listing;
    348  1.1  christos 
    349  1.1  christos     if (listing)
    350  1.1  christos       listing_source_file (filename);
    351  1.1  christos   }
    352  1.1  christos #endif
    353  1.1  christos 
    354  1.1  christos   /* Make sure that the symbol is first on the symbol chain.  */
    355  1.1  christos   if (symbol_rootP != symbolP)
    356  1.1  christos     {
    357  1.1  christos       symbol_remove (symbolP, &symbol_rootP, &symbol_lastP);
    358  1.1  christos       symbol_insert (symbolP, symbol_rootP, &symbol_rootP, &symbol_lastP);
    359  1.1  christos     }
    360  1.1  christos }
    361  1.1  christos 
    362  1.1  christos /* Line number handling.  */
    363  1.1  christos 
    364  1.1  christos struct line_no
    365  1.1  christos {
    366  1.1  christos   struct line_no *next;
    367  1.1  christos   fragS *frag;
    368  1.1  christos   alent l;
    369  1.1  christos };
    370  1.1  christos 
    371  1.1  christos int coff_line_base;
    372  1.1  christos 
    373  1.1  christos /* Symbol of last function, which we should hang line#s off of.  */
    374  1.1  christos static symbolS *line_fsym;
    375  1.1  christos 
    376  1.1  christos #define in_function()		(line_fsym != 0)
    377  1.1  christos #define clear_function()	(line_fsym = 0)
    378  1.1  christos #define set_function(F)		(line_fsym = (F), coff_add_linesym (F))
    379  1.1  christos 
    380  1.1  christos 
    381  1.1  christos void
    383  1.5  christos coff_obj_symbol_new_hook (symbolS *symbolP)
    384  1.1  christos {
    385  1.1  christos   long   sz = (OBJ_COFF_MAX_AUXENTRIES + 1) * sizeof (combined_entry_type);
    386  1.1  christos   char * s  = XNEWVEC (char, sz);
    387  1.3  christos 
    388  1.1  christos   memset (s, 0, sz);
    389  1.1  christos   coffsymbol (symbol_get_bfdsym (symbolP))->native = (combined_entry_type *) s;
    390  1.1  christos   coffsymbol (symbol_get_bfdsym (symbolP))->native->is_sym = TRUE;
    391  1.1  christos 
    392  1.1  christos   S_SET_DATA_TYPE (symbolP, T_NULL);
    393  1.1  christos   S_SET_STORAGE_CLASS (symbolP, 0);
    394  1.1  christos   S_SET_NUMBER_AUXILIARY (symbolP, 0);
    395  1.1  christos 
    396  1.1  christos   if (S_IS_STRING (symbolP))
    397  1.1  christos     SF_SET_STRING (symbolP);
    398  1.1  christos 
    399  1.1  christos   if (S_IS_LOCAL (symbolP))
    400  1.1  christos     SF_SET_LOCAL (symbolP);
    401  1.1  christos }
    402  1.1  christos 
    403  1.5  christos void
    404  1.5  christos coff_obj_symbol_clone_hook (symbolS *newsymP, symbolS *orgsymP)
    405  1.1  christos {
    406  1.5  christos   long elts = OBJ_COFF_MAX_AUXENTRIES + 1;
    407  1.5  christos   combined_entry_type * s = XNEWVEC (combined_entry_type, elts);
    408  1.1  christos 
    409  1.1  christos   memcpy (s, coffsymbol (symbol_get_bfdsym (orgsymP))->native,
    410  1.1  christos 	  elts * sizeof (combined_entry_type));
    411  1.1  christos   coffsymbol (symbol_get_bfdsym (newsymP))->native = s;
    412  1.1  christos 
    413  1.1  christos   SF_SET (newsymP, SF_GET (orgsymP));
    414  1.1  christos }
    415  1.1  christos 
    416  1.1  christos 
    417  1.1  christos /* Handle .ln directives.  */
    419  1.1  christos 
    420  1.1  christos static symbolS *current_lineno_sym;
    421  1.1  christos static struct line_no *line_nos;
    422  1.1  christos /* FIXME:  Blindly assume all .ln directives will be in the .text section.  */
    423  1.1  christos int coff_n_line_nos;
    424  1.5  christos 
    425  1.1  christos static void
    426  1.1  christos add_lineno (fragS * frag, addressT offset, int num)
    427  1.1  christos {
    428  1.1  christos   struct line_no * new_line = XNEW (struct line_no);
    429  1.1  christos 
    430  1.1  christos   if (!current_lineno_sym)
    431  1.1  christos     abort ();
    432  1.1  christos 
    433  1.1  christos #ifndef OBJ_XCOFF
    434  1.1  christos   /* The native aix assembler accepts negative line number.  */
    435  1.1  christos 
    436  1.1  christos   if (num <= 0)
    437  1.1  christos     {
    438  1.1  christos       /* Zero is used as an end marker in the file.  */
    439  1.1  christos       as_warn (_("Line numbers must be positive integers\n"));
    440  1.1  christos       num = 1;
    441  1.1  christos     }
    442  1.1  christos #endif /* OBJ_XCOFF */
    443  1.1  christos   new_line->next = line_nos;
    444  1.1  christos   new_line->frag = frag;
    445  1.1  christos   new_line->l.line_number = num;
    446  1.1  christos   new_line->l.u.offset = offset;
    447  1.1  christos   line_nos = new_line;
    448  1.1  christos   coff_n_line_nos++;
    449  1.1  christos }
    450  1.1  christos 
    451  1.1  christos void
    452  1.1  christos coff_add_linesym (symbolS *sym)
    453  1.1  christos {
    454  1.1  christos   if (line_nos)
    455  1.1  christos     {
    456  1.1  christos       coffsymbol (symbol_get_bfdsym (current_lineno_sym))->lineno =
    457  1.1  christos 	(alent *) line_nos;
    458  1.1  christos       coff_n_line_nos++;
    459  1.1  christos       line_nos = 0;
    460  1.1  christos     }
    461  1.1  christos   current_lineno_sym = sym;
    462  1.1  christos }
    463  1.1  christos 
    464  1.1  christos static void
    465  1.1  christos obj_coff_ln (int appline)
    466  1.1  christos {
    467  1.1  christos   int l;
    468  1.1  christos 
    469  1.1  christos   if (! appline && def_symbol_in_progress != NULL)
    470  1.1  christos     {
    471  1.1  christos       as_warn (_(".ln pseudo-op inside .def/.endef: ignored."));
    472  1.1  christos       demand_empty_rest_of_line ();
    473  1.1  christos       return;
    474  1.1  christos     }
    475  1.1  christos 
    476  1.1  christos   l = get_absolute_expression ();
    477  1.1  christos 
    478  1.1  christos   /* If there is no lineno symbol, treat a .ln
    479  1.1  christos      directive as if it were a .appline directive.  */
    480  1.1  christos   if (appline || current_lineno_sym == NULL)
    481  1.1  christos     new_logical_line ((char *) NULL, l - 1);
    482  1.1  christos   else
    483  1.1  christos     add_lineno (frag_now, frag_now_fix (), l);
    484  1.1  christos 
    485  1.1  christos #ifndef NO_LISTING
    486  1.1  christos   {
    487  1.1  christos     extern int listing;
    488  1.1  christos 
    489  1.1  christos     if (listing)
    490  1.1  christos       {
    491  1.1  christos 	if (! appline)
    492  1.1  christos 	  l += coff_line_base - 1;
    493  1.1  christos 	listing_source_line (l);
    494  1.1  christos       }
    495  1.1  christos   }
    496  1.1  christos #endif
    497  1.1  christos 
    498  1.1  christos   demand_empty_rest_of_line ();
    499  1.1  christos }
    500  1.1  christos 
    501  1.1  christos /* .loc is essentially the same as .ln; parse it for assembler
    502  1.1  christos    compatibility.  */
    503  1.1  christos 
    504  1.1  christos static void
    505  1.1  christos obj_coff_loc (int ignore ATTRIBUTE_UNUSED)
    506  1.1  christos {
    507  1.1  christos   int lineno;
    508  1.1  christos 
    509  1.1  christos   /* FIXME: Why do we need this check?  We need it for ECOFF, but why
    510  1.1  christos      do we need it for COFF?  */
    511  1.1  christos   if (now_seg != text_section)
    512  1.1  christos     {
    513  1.1  christos       as_warn (_(".loc outside of .text"));
    514  1.1  christos       demand_empty_rest_of_line ();
    515  1.1  christos       return;
    516  1.1  christos     }
    517  1.1  christos 
    518  1.1  christos   if (def_symbol_in_progress != NULL)
    519  1.1  christos     {
    520  1.1  christos       as_warn (_(".loc pseudo-op inside .def/.endef: ignored."));
    521  1.1  christos       demand_empty_rest_of_line ();
    522  1.1  christos       return;
    523  1.1  christos     }
    524  1.1  christos 
    525  1.1  christos   /* Skip the file number.  */
    526  1.1  christos   SKIP_WHITESPACE ();
    527  1.1  christos   get_absolute_expression ();
    528  1.1  christos   SKIP_WHITESPACE ();
    529  1.1  christos 
    530  1.1  christos   lineno = get_absolute_expression ();
    531  1.1  christos 
    532  1.1  christos #ifndef NO_LISTING
    533  1.1  christos   {
    534  1.1  christos     extern int listing;
    535  1.1  christos 
    536  1.1  christos     if (listing)
    537  1.1  christos       {
    538  1.1  christos 	lineno += coff_line_base - 1;
    539  1.1  christos 	listing_source_line (lineno);
    540  1.1  christos       }
    541  1.1  christos   }
    542  1.1  christos #endif
    543  1.1  christos 
    544  1.1  christos   demand_empty_rest_of_line ();
    545  1.1  christos 
    546  1.1  christos   add_lineno (frag_now, frag_now_fix (), lineno);
    547  1.1  christos }
    548  1.1  christos 
    549  1.1  christos /* Handle the .ident pseudo-op.  */
    550  1.1  christos 
    551  1.1  christos static void
    552  1.1  christos obj_coff_ident (int ignore ATTRIBUTE_UNUSED)
    553  1.1  christos {
    554  1.1  christos   segT current_seg = now_seg;
    555  1.1  christos   subsegT current_subseg = now_subseg;
    556  1.1  christos 
    557  1.1  christos #ifdef TE_PE
    558  1.1  christos   {
    559  1.1  christos     segT sec;
    560  1.1  christos 
    561  1.1  christos     /* We could put it in .comment, but that creates an extra section
    562  1.1  christos        that shouldn't be loaded into memory, which requires linker
    563  1.1  christos        changes...  For now, until proven otherwise, use .rdata.  */
    564  1.1  christos     sec = subseg_new (".rdata$zzz", 0);
    565  1.1  christos     bfd_set_section_flags (stdoutput, sec,
    566  1.1  christos 			   ((SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_DATA)
    567  1.1  christos 			    & bfd_applicable_section_flags (stdoutput)));
    568  1.1  christos   }
    569  1.1  christos #else
    570  1.1  christos   subseg_new (".comment", 0);
    571  1.1  christos #endif
    572  1.1  christos 
    573  1.1  christos   stringer (8 + 1);
    574  1.1  christos   subseg_set (current_seg, current_subseg);
    575  1.1  christos }
    576  1.1  christos 
    577  1.1  christos /* Handle .def directives.
    578  1.1  christos 
    579  1.1  christos    One might ask : why can't we symbol_new if the symbol does not
    580  1.1  christos    already exist and fill it with debug information.  Because of
    581  1.1  christos    the C_EFCN special symbol. It would clobber the value of the
    582  1.1  christos    function symbol before we have a chance to notice that it is
    583  1.1  christos    a C_EFCN. And a second reason is that the code is more clear this
    584  1.1  christos    way. (at least I think it is :-).  */
    585  1.1  christos 
    586  1.1  christos #define SKIP_SEMI_COLON()	while (*input_line_pointer++ != ';')
    587  1.1  christos #define SKIP_WHITESPACES()	while (*input_line_pointer == ' ' || \
    588  1.1  christos 				       *input_line_pointer == '\t')  \
    589  1.1  christos                                   input_line_pointer++;
    590  1.1  christos 
    591  1.1  christos static void
    592  1.1  christos obj_coff_def (int what ATTRIBUTE_UNUSED)
    593  1.1  christos {
    594  1.1  christos   char name_end;		/* Char after the end of name.  */
    595  1.1  christos   char *symbol_name;		/* Name of the debug symbol.  */
    596  1.1  christos   char *symbol_name_copy;	/* Temporary copy of the name.  */
    597  1.1  christos 
    598  1.1  christos   if (def_symbol_in_progress != NULL)
    599  1.1  christos     {
    600  1.1  christos       as_warn (_(".def pseudo-op used inside of .def/.endef: ignored."));
    601  1.1  christos       demand_empty_rest_of_line ();
    602  1.1  christos       return;
    603  1.3  christos     }
    604  1.5  christos 
    605  1.1  christos   SKIP_WHITESPACES ();
    606  1.1  christos 
    607  1.1  christos   name_end = get_symbol_name (&symbol_name);
    608  1.1  christos   symbol_name_copy = xstrdup (symbol_name);
    609  1.1  christos #ifdef tc_canonicalize_symbol_name
    610  1.1  christos   symbol_name_copy = tc_canonicalize_symbol_name (symbol_name_copy);
    611  1.1  christos #endif
    612  1.1  christos 
    613  1.1  christos   /* Initialize the new symbol.  */
    614  1.1  christos   def_symbol_in_progress = symbol_make (symbol_name_copy);
    615  1.1  christos   symbol_set_frag (def_symbol_in_progress, &zero_address_frag);
    616  1.1  christos   S_SET_VALUE (def_symbol_in_progress, 0);
    617  1.3  christos 
    618  1.1  christos   if (S_IS_STRING (def_symbol_in_progress))
    619  1.1  christos     SF_SET_STRING (def_symbol_in_progress);
    620  1.1  christos 
    621  1.1  christos   (void) restore_line_pointer (name_end);
    622  1.1  christos 
    623  1.1  christos   demand_empty_rest_of_line ();
    624  1.1  christos }
    625  1.1  christos 
    626  1.1  christos static void
    627  1.1  christos obj_coff_endef (int ignore ATTRIBUTE_UNUSED)
    628  1.1  christos {
    629  1.1  christos   symbolS *symbolP = NULL;
    630  1.1  christos 
    631  1.1  christos   if (def_symbol_in_progress == NULL)
    632  1.1  christos     {
    633  1.1  christos       as_warn (_(".endef pseudo-op used outside of .def/.endef: ignored."));
    634  1.1  christos       demand_empty_rest_of_line ();
    635  1.1  christos       return;
    636  1.1  christos     }
    637  1.1  christos 
    638  1.1  christos   /* Set the section number according to storage class.  */
    639  1.1  christos   switch (S_GET_STORAGE_CLASS (def_symbol_in_progress))
    640  1.1  christos     {
    641  1.1  christos     case C_STRTAG:
    642  1.1  christos     case C_ENTAG:
    643  1.1  christos     case C_UNTAG:
    644  1.1  christos       SF_SET_TAG (def_symbol_in_progress);
    645  1.1  christos       /* Fall through.  */
    646  1.1  christos     case C_FILE:
    647  1.1  christos     case C_TPDEF:
    648  1.1  christos       SF_SET_DEBUG (def_symbol_in_progress);
    649  1.1  christos       S_SET_SEGMENT (def_symbol_in_progress, fetch_coff_debug_section ());
    650  1.1  christos       break;
    651  1.1  christos 
    652  1.1  christos     case C_EFCN:
    653  1.1  christos       SF_SET_LOCAL (def_symbol_in_progress);	/* Do not emit this symbol.  */
    654  1.1  christos       /* Fall through.  */
    655  1.1  christos     case C_BLOCK:
    656  1.1  christos       SF_SET_PROCESS (def_symbol_in_progress);	/* Will need processing before writing.  */
    657  1.1  christos       /* Fall through.  */
    658  1.1  christos     case C_FCN:
    659  1.1  christos       {
    660  1.1  christos 	const char *name;
    661  1.1  christos 
    662  1.1  christos 	S_SET_SEGMENT (def_symbol_in_progress, text_section);
    663  1.1  christos 
    664  1.1  christos 	name = S_GET_NAME (def_symbol_in_progress);
    665  1.1  christos 	if (name[0] == '.' && name[2] == 'f' && name[3] == '\0')
    666  1.1  christos 	  {
    667  1.1  christos 	    switch (name[1])
    668  1.1  christos 	      {
    669  1.1  christos 	      case 'b':
    670  1.1  christos 		/* .bf */
    671  1.1  christos 		if (! in_function ())
    672  1.1  christos 		  as_warn (_("`%s' symbol without preceding function"), name);
    673  1.1  christos 		/* Will need relocating.  */
    674  1.1  christos 		SF_SET_PROCESS (def_symbol_in_progress);
    675  1.1  christos 		clear_function ();
    676  1.1  christos 		break;
    677  1.1  christos #ifdef TE_PE
    678  1.1  christos 	      case 'e':
    679  1.1  christos 		/* .ef */
    680  1.1  christos 		/* The MS compilers output the actual endline, not the
    681  1.1  christos 		   function-relative one... we want to match without
    682  1.1  christos 		   changing the assembler input.  */
    683  1.1  christos 		SA_SET_SYM_LNNO (def_symbol_in_progress,
    684  1.1  christos 				 (SA_GET_SYM_LNNO (def_symbol_in_progress)
    685  1.1  christos 				  + coff_line_base));
    686  1.1  christos 		break;
    687  1.1  christos #endif
    688  1.1  christos 	      }
    689  1.1  christos 	  }
    690  1.1  christos       }
    691  1.1  christos       break;
    692  1.1  christos 
    693  1.1  christos #ifdef C_AUTOARG
    694  1.1  christos     case C_AUTOARG:
    695  1.1  christos #endif /* C_AUTOARG */
    696  1.1  christos     case C_AUTO:
    697  1.1  christos     case C_REG:
    698  1.1  christos     case C_ARG:
    699  1.1  christos     case C_REGPARM:
    700  1.1  christos     case C_FIELD:
    701  1.1  christos 
    702  1.1  christos     /* According to the COFF documentation:
    703  1.1  christos 
    704  1.1  christos        http://osr5doc.sco.com:1996/topics/COFF_SectNumFld.html
    705  1.1  christos 
    706  1.1  christos        A special section number (-2) marks symbolic debugging symbols,
    707  1.1  christos        including structure/union/enumeration tag names, typedefs, and
    708  1.1  christos        the name of the file. A section number of -1 indicates that the
    709  1.1  christos        symbol has a value but is not relocatable. Examples of
    710  1.1  christos        absolute-valued symbols include automatic and register variables,
    711  1.1  christos        function arguments, and .eos symbols.
    712  1.1  christos 
    713  1.1  christos        But from Ian Lance Taylor:
    714  1.1  christos 
    715  1.1  christos        http://sources.redhat.com/ml/binutils/2000-08/msg00202.html
    716  1.1  christos 
    717  1.1  christos        the actual tools all marked them as section -1. So the GNU COFF
    718  1.1  christos        assembler follows historical COFF assemblers.
    719  1.1  christos 
    720  1.1  christos        However, it causes problems for djgpp
    721  1.1  christos 
    722  1.1  christos        http://sources.redhat.com/ml/binutils/2000-08/msg00210.html
    723  1.1  christos 
    724  1.1  christos        By defining STRICTCOFF, a COFF port can make the assembler to
    725  1.1  christos        follow the documented behavior.  */
    726  1.1  christos #ifdef STRICTCOFF
    727  1.1  christos     case C_MOS:
    728  1.1  christos     case C_MOE:
    729  1.1  christos     case C_MOU:
    730  1.1  christos     case C_EOS:
    731  1.1  christos #endif
    732  1.1  christos       SF_SET_DEBUG (def_symbol_in_progress);
    733  1.1  christos       S_SET_SEGMENT (def_symbol_in_progress, absolute_section);
    734  1.1  christos       break;
    735  1.1  christos 
    736  1.1  christos #ifndef STRICTCOFF
    737  1.1  christos     case C_MOS:
    738  1.1  christos     case C_MOE:
    739  1.1  christos     case C_MOU:
    740  1.1  christos     case C_EOS:
    741  1.1  christos       S_SET_SEGMENT (def_symbol_in_progress, absolute_section);
    742  1.1  christos       break;
    743  1.1  christos #endif
    744  1.1  christos 
    745  1.1  christos     case C_EXT:
    746  1.1  christos     case C_WEAKEXT:
    747  1.1  christos #ifdef TE_PE
    748  1.1  christos     case C_NT_WEAK:
    749  1.1  christos #endif
    750  1.1  christos     case C_STAT:
    751  1.1  christos     case C_LABEL:
    752  1.1  christos       /* Valid but set somewhere else (s_comm, s_lcomm, colon).  */
    753  1.1  christos       break;
    754  1.1  christos 
    755  1.1  christos     default:
    756  1.1  christos     case C_USTATIC:
    757  1.1  christos     case C_EXTDEF:
    758  1.1  christos     case C_ULABEL:
    759  1.1  christos       as_warn (_("unexpected storage class %d"),
    760  1.1  christos 	       S_GET_STORAGE_CLASS (def_symbol_in_progress));
    761  1.1  christos       break;
    762  1.1  christos     }
    763  1.1  christos 
    764  1.1  christos   /* Now that we have built a debug symbol, try to find if we should
    765  1.1  christos      merge with an existing symbol or not.  If a symbol is C_EFCN or
    766  1.1  christos      absolute_section or untagged SEG_DEBUG it never merges.  We also
    767  1.1  christos      don't merge labels, which are in a different namespace, nor
    768  1.1  christos      symbols which have not yet been defined since they are typically
    769  1.1  christos      unique, nor do we merge tags with non-tags.  */
    770  1.1  christos 
    771  1.1  christos   /* Two cases for functions.  Either debug followed by definition or
    772  1.1  christos      definition followed by debug.  For definition first, we will
    773  1.1  christos      merge the debug symbol into the definition.  For debug first, the
    774  1.1  christos      lineno entry MUST point to the definition function or else it
    775  1.1  christos      will point off into space when obj_crawl_symbol_chain() merges
    776  1.1  christos      the debug symbol into the real symbol.  Therefor, let's presume
    777  1.1  christos      the debug symbol is a real function reference.  */
    778  1.1  christos 
    779  1.1  christos   /* FIXME-SOON If for some reason the definition label/symbol is
    780  1.1  christos      never seen, this will probably leave an undefined symbol at link
    781  1.1  christos      time.  */
    782  1.1  christos 
    783  1.1  christos   if (S_GET_STORAGE_CLASS (def_symbol_in_progress) == C_EFCN
    784  1.1  christos       || S_GET_STORAGE_CLASS (def_symbol_in_progress) == C_LABEL
    785  1.1  christos       || (streq (bfd_get_section_name (stdoutput,
    786  1.1  christos 				       S_GET_SEGMENT (def_symbol_in_progress)),
    787  1.1  christos 		 "*DEBUG*")
    788  1.1  christos 	  && !SF_GET_TAG (def_symbol_in_progress))
    789  1.1  christos       || S_GET_SEGMENT (def_symbol_in_progress) == absolute_section
    790  1.1  christos       || ! symbol_constant_p (def_symbol_in_progress)
    791  1.1  christos       || (symbolP = symbol_find (S_GET_NAME (def_symbol_in_progress))) == NULL
    792  1.1  christos       || SF_GET_TAG (def_symbol_in_progress) != SF_GET_TAG (symbolP))
    793  1.1  christos     {
    794  1.1  christos       /* If it already is at the end of the symbol list, do nothing */
    795  1.1  christos       if (def_symbol_in_progress != symbol_lastP)
    796  1.1  christos 	{
    797  1.1  christos 	  symbol_remove (def_symbol_in_progress, &symbol_rootP, &symbol_lastP);
    798  1.1  christos 	  symbol_append (def_symbol_in_progress, symbol_lastP, &symbol_rootP,
    799  1.1  christos 			 &symbol_lastP);
    800  1.1  christos 	}
    801  1.1  christos     }
    802  1.1  christos   else
    803  1.1  christos     {
    804  1.1  christos       /* This symbol already exists, merge the newly created symbol
    805  1.1  christos 	 into the old one.  This is not mandatory. The linker can
    806  1.1  christos 	 handle duplicate symbols correctly. But I guess that it save
    807  1.1  christos 	 a *lot* of space if the assembly file defines a lot of
    808  1.1  christos 	 symbols. [loic]  */
    809  1.1  christos 
    810  1.1  christos       /* The debug entry (def_symbol_in_progress) is merged into the
    811  1.1  christos 	 previous definition.  */
    812  1.1  christos 
    813  1.1  christos       c_symbol_merge (def_symbol_in_progress, symbolP);
    814  1.1  christos       symbol_remove (def_symbol_in_progress, &symbol_rootP, &symbol_lastP);
    815  1.1  christos 
    816  1.1  christos       def_symbol_in_progress = symbolP;
    817  1.1  christos 
    818  1.1  christos       if (SF_GET_FUNCTION (def_symbol_in_progress)
    819  1.1  christos 	  || SF_GET_TAG (def_symbol_in_progress)
    820  1.1  christos 	  || S_GET_STORAGE_CLASS (def_symbol_in_progress) == C_STAT)
    821  1.1  christos 	{
    822  1.1  christos 	  /* For functions, and tags, and static symbols, the symbol
    823  1.1  christos 	     *must* be where the debug symbol appears.  Move the
    824  1.1  christos 	     existing symbol to the current place.  */
    825  1.1  christos 	  /* If it already is at the end of the symbol list, do nothing.  */
    826  1.1  christos 	  if (def_symbol_in_progress != symbol_lastP)
    827  1.1  christos 	    {
    828  1.1  christos 	      symbol_remove (def_symbol_in_progress, &symbol_rootP, &symbol_lastP);
    829  1.1  christos 	      symbol_append (def_symbol_in_progress, symbol_lastP, &symbol_rootP, &symbol_lastP);
    830  1.1  christos 	    }
    831  1.1  christos 	}
    832  1.1  christos     }
    833  1.1  christos 
    834  1.1  christos   if (SF_GET_TAG (def_symbol_in_progress))
    835  1.1  christos     {
    836  1.1  christos       symbolS *oldtag;
    837  1.1  christos 
    838  1.1  christos       oldtag = symbol_find (S_GET_NAME (def_symbol_in_progress));
    839  1.1  christos       if (oldtag == NULL || ! SF_GET_TAG (oldtag))
    840  1.1  christos 	tag_insert (S_GET_NAME (def_symbol_in_progress),
    841  1.1  christos 		    def_symbol_in_progress);
    842  1.1  christos     }
    843  1.1  christos 
    844  1.1  christos   if (SF_GET_FUNCTION (def_symbol_in_progress))
    845  1.1  christos     {
    846  1.1  christos       set_function (def_symbol_in_progress);
    847  1.1  christos       SF_SET_PROCESS (def_symbol_in_progress);
    848  1.1  christos 
    849  1.1  christos       if (symbolP == NULL)
    850  1.1  christos 	/* That is, if this is the first time we've seen the
    851  1.1  christos 	   function.  */
    852  1.1  christos 	symbol_table_insert (def_symbol_in_progress);
    853  1.1  christos 
    854  1.1  christos     }
    855  1.1  christos 
    856  1.1  christos   def_symbol_in_progress = NULL;
    857  1.1  christos   demand_empty_rest_of_line ();
    858  1.1  christos }
    859  1.1  christos 
    860  1.1  christos static void
    861  1.1  christos obj_coff_dim (int ignore ATTRIBUTE_UNUSED)
    862  1.1  christos {
    863  1.1  christos   int d_index;
    864  1.1  christos 
    865  1.1  christos   if (def_symbol_in_progress == NULL)
    866  1.1  christos     {
    867  1.1  christos       as_warn (_(".dim pseudo-op used outside of .def/.endef: ignored."));
    868  1.1  christos       demand_empty_rest_of_line ();
    869  1.1  christos       return;
    870  1.1  christos     }
    871  1.1  christos 
    872  1.1  christos   S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
    873  1.1  christos 
    874  1.1  christos   for (d_index = 0; d_index < DIMNUM; d_index++)
    875  1.1  christos     {
    876  1.1  christos       SKIP_WHITESPACES ();
    877  1.1  christos       SA_SET_SYM_DIMEN (def_symbol_in_progress, d_index,
    878  1.1  christos 			get_absolute_expression ());
    879  1.1  christos 
    880  1.1  christos       switch (*input_line_pointer)
    881  1.1  christos 	{
    882  1.1  christos 	case ',':
    883  1.1  christos 	  input_line_pointer++;
    884  1.1  christos 	  break;
    885  1.1  christos 
    886  1.1  christos 	default:
    887  1.1  christos 	  as_warn (_("badly formed .dim directive ignored"));
    888  1.1  christos 	  /* Fall through.  */
    889  1.1  christos 	case '\n':
    890  1.1  christos 	case ';':
    891  1.1  christos 	  d_index = DIMNUM;
    892  1.1  christos 	  break;
    893  1.1  christos 	}
    894  1.1  christos     }
    895  1.1  christos 
    896  1.1  christos   demand_empty_rest_of_line ();
    897  1.1  christos }
    898  1.1  christos 
    899  1.1  christos static void
    900  1.1  christos obj_coff_line (int ignore ATTRIBUTE_UNUSED)
    901  1.1  christos {
    902  1.1  christos   int this_base;
    903  1.1  christos 
    904  1.1  christos   if (def_symbol_in_progress == NULL)
    905  1.1  christos     {
    906  1.1  christos       /* Probably stabs-style line?  */
    907  1.1  christos       obj_coff_ln (0);
    908  1.1  christos       return;
    909  1.1  christos     }
    910  1.1  christos 
    911  1.1  christos   this_base = get_absolute_expression ();
    912  1.1  christos   if (streq (".bf", S_GET_NAME (def_symbol_in_progress)))
    913  1.1  christos     coff_line_base = this_base;
    914  1.1  christos 
    915  1.1  christos   S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
    916  1.1  christos   SA_SET_SYM_LNNO (def_symbol_in_progress, this_base);
    917  1.1  christos 
    918  1.1  christos   demand_empty_rest_of_line ();
    919  1.1  christos 
    920  1.1  christos #ifndef NO_LISTING
    921  1.1  christos   if (streq (".bf", S_GET_NAME (def_symbol_in_progress)))
    922  1.1  christos     {
    923  1.1  christos       extern int listing;
    924  1.1  christos 
    925  1.1  christos       if (listing)
    926  1.1  christos 	listing_source_line ((unsigned int) this_base);
    927  1.1  christos     }
    928  1.1  christos #endif
    929  1.1  christos }
    930  1.1  christos 
    931  1.1  christos static void
    932  1.6  christos obj_coff_size (int ignore ATTRIBUTE_UNUSED)
    933  1.1  christos {
    934  1.1  christos   if (def_symbol_in_progress == NULL)
    935  1.1  christos     {
    936  1.1  christos       as_warn (_(".size pseudo-op used outside of .def/.endef: ignored."));
    937  1.1  christos       demand_empty_rest_of_line ();
    938  1.1  christos       return;
    939  1.1  christos     }
    940  1.1  christos 
    941  1.1  christos   S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
    942  1.1  christos   SA_SET_SYM_SIZE (def_symbol_in_progress, get_absolute_expression ());
    943  1.1  christos   demand_empty_rest_of_line ();
    944  1.1  christos }
    945  1.1  christos 
    946  1.1  christos static void
    947  1.6  christos obj_coff_scl (int ignore ATTRIBUTE_UNUSED)
    948  1.1  christos {
    949  1.1  christos   if (def_symbol_in_progress == NULL)
    950  1.1  christos     {
    951  1.1  christos       as_warn (_(".scl pseudo-op used outside of .def/.endef: ignored."));
    952  1.1  christos       demand_empty_rest_of_line ();
    953  1.1  christos       return;
    954  1.1  christos     }
    955  1.1  christos 
    956  1.1  christos   S_SET_STORAGE_CLASS (def_symbol_in_progress, get_absolute_expression ());
    957  1.1  christos   demand_empty_rest_of_line ();
    958  1.1  christos }
    959  1.1  christos 
    960  1.1  christos static void
    961  1.1  christos obj_coff_tag (int ignore ATTRIBUTE_UNUSED)
    962  1.1  christos {
    963  1.1  christos   char *symbol_name;
    964  1.6  christos   char name_end;
    965  1.1  christos 
    966  1.1  christos   if (def_symbol_in_progress == NULL)
    967  1.1  christos     {
    968  1.1  christos       as_warn (_(".tag pseudo-op used outside of .def/.endef: ignored."));
    969  1.1  christos       demand_empty_rest_of_line ();
    970  1.3  christos       return;
    971  1.1  christos     }
    972  1.1  christos 
    973  1.1  christos   S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
    974  1.1  christos   name_end = get_symbol_name (&symbol_name);
    975  1.1  christos 
    976  1.1  christos #ifdef tc_canonicalize_symbol_name
    977  1.1  christos   symbol_name = tc_canonicalize_symbol_name (symbol_name);
    978  1.1  christos #endif
    979  1.1  christos 
    980  1.1  christos   /* Assume that the symbol referred to by .tag is always defined.
    981  1.1  christos      This was a bad assumption.  I've added find_or_make. xoxorich.  */
    982  1.1  christos   SA_SET_SYM_TAGNDX (def_symbol_in_progress,
    983  1.1  christos 		     tag_find_or_make (symbol_name));
    984  1.1  christos   if (SA_GET_SYM_TAGNDX (def_symbol_in_progress) == 0L)
    985  1.3  christos     as_warn (_("tag not found for .tag %s"), symbol_name);
    986  1.1  christos 
    987  1.1  christos   SF_SET_TAGGED (def_symbol_in_progress);
    988  1.1  christos 
    989  1.1  christos   (void) restore_line_pointer (name_end);
    990  1.1  christos   demand_empty_rest_of_line ();
    991  1.1  christos }
    992  1.1  christos 
    993  1.1  christos static void
    994  1.6  christos obj_coff_type (int ignore ATTRIBUTE_UNUSED)
    995  1.1  christos {
    996  1.1  christos   if (def_symbol_in_progress == NULL)
    997  1.1  christos     {
    998  1.1  christos       as_warn (_(".type pseudo-op used outside of .def/.endef: ignored."));
    999  1.1  christos       demand_empty_rest_of_line ();
   1000  1.1  christos       return;
   1001  1.1  christos     }
   1002  1.1  christos 
   1003  1.1  christos   S_SET_DATA_TYPE (def_symbol_in_progress, get_absolute_expression ());
   1004  1.1  christos 
   1005  1.1  christos   if (ISFCN (S_GET_DATA_TYPE (def_symbol_in_progress)) &&
   1006  1.1  christos       S_GET_STORAGE_CLASS (def_symbol_in_progress) != C_TPDEF)
   1007  1.1  christos     SF_SET_FUNCTION (def_symbol_in_progress);
   1008  1.1  christos 
   1009  1.1  christos   demand_empty_rest_of_line ();
   1010  1.1  christos }
   1011  1.1  christos 
   1012  1.1  christos static void
   1013  1.6  christos obj_coff_val (int ignore ATTRIBUTE_UNUSED)
   1014  1.1  christos {
   1015  1.1  christos   if (def_symbol_in_progress == NULL)
   1016  1.1  christos     {
   1017  1.1  christos       as_warn (_(".val pseudo-op used outside of .def/.endef: ignored."));
   1018  1.1  christos       demand_empty_rest_of_line ();
   1019  1.1  christos       return;
   1020  1.3  christos     }
   1021  1.3  christos 
   1022  1.1  christos   if (is_name_beginner (*input_line_pointer))
   1023  1.1  christos     {
   1024  1.3  christos       char *symbol_name;
   1025  1.1  christos       char name_end = get_symbol_name (&symbol_name);
   1026  1.1  christos 
   1027  1.1  christos #ifdef tc_canonicalize_symbol_name
   1028  1.1  christos       symbol_name = tc_canonicalize_symbol_name (symbol_name);
   1029  1.1  christos #endif
   1030  1.1  christos       if (streq (symbol_name, "."))
   1031  1.1  christos 	{
   1032  1.1  christos 	  /* If the .val is != from the .def (e.g. statics).  */
   1033  1.1  christos 	  symbol_set_frag (def_symbol_in_progress, frag_now);
   1034  1.1  christos 	  S_SET_VALUE (def_symbol_in_progress, (valueT) frag_now_fix ());
   1035  1.1  christos 	}
   1036  1.1  christos       else if (! streq (S_GET_NAME (def_symbol_in_progress), symbol_name))
   1037  1.1  christos 	{
   1038  1.1  christos 	  expressionS exp;
   1039  1.1  christos 
   1040  1.1  christos 	  exp.X_op = O_symbol;
   1041  1.1  christos 	  exp.X_add_symbol = symbol_find_or_make (symbol_name);
   1042  1.1  christos 	  exp.X_op_symbol = NULL;
   1043  1.1  christos 	  exp.X_add_number = 0;
   1044  1.1  christos 	  symbol_set_value_expression (def_symbol_in_progress, &exp);
   1045  1.1  christos 
   1046  1.1  christos 	  /* If the segment is undefined when the forward reference is
   1047  1.1  christos 	     resolved, then copy the segment id from the forward
   1048  1.1  christos 	     symbol.  */
   1049  1.1  christos 	  SF_SET_GET_SEGMENT (def_symbol_in_progress);
   1050  1.1  christos 
   1051  1.1  christos 	  /* FIXME: gcc can generate address expressions here in
   1052  1.1  christos 	     unusual cases (search for "obscure" in sdbout.c).  We
   1053  1.1  christos 	     just ignore the offset here, thus generating incorrect
   1054  1.1  christos 	     debugging information.  We ignore the rest of the line
   1055  1.3  christos 	     just below.  */
   1056  1.1  christos 	}
   1057  1.1  christos       /* Otherwise, it is the name of a non debug symbol and its value
   1058  1.1  christos          will be calculated later.  */
   1059  1.1  christos       (void) restore_line_pointer (name_end);
   1060  1.1  christos     }
   1061  1.1  christos   else
   1062  1.1  christos     {
   1063  1.1  christos       S_SET_VALUE (def_symbol_in_progress, get_absolute_expression ());
   1064  1.1  christos     }
   1065  1.1  christos 
   1066  1.1  christos   demand_empty_rest_of_line ();
   1067  1.1  christos }
   1068  1.1  christos 
   1069  1.1  christos #ifdef TE_PE
   1070  1.1  christos 
   1071  1.1  christos /* Return nonzero if name begins with weak alternate symbol prefix.  */
   1072  1.1  christos 
   1073  1.1  christos static int
   1074  1.1  christos weak_is_altname (const char * name)
   1075  1.1  christos {
   1076  1.1  christos   return strneq (name, weak_altprefix, sizeof (weak_altprefix) - 1);
   1077  1.1  christos }
   1078  1.1  christos 
   1079  1.1  christos /* Return the name of the alternate symbol
   1080  1.1  christos    name corresponding to a weak symbol's name.  */
   1081  1.5  christos 
   1082  1.1  christos static const char *
   1083  1.1  christos weak_name2altname (const char * name)
   1084  1.1  christos {
   1085  1.1  christos   return concat (weak_altprefix, name, (char *) NULL);
   1086  1.1  christos }
   1087  1.1  christos 
   1088  1.1  christos /* Return the name of the weak symbol corresponding to an
   1089  1.1  christos    alternate symbol.  */
   1090  1.1  christos 
   1091  1.1  christos static const char *
   1092  1.1  christos weak_altname2name (const char * name)
   1093  1.1  christos {
   1094  1.1  christos   gas_assert (weak_is_altname (name));
   1095  1.1  christos   return xstrdup (name + 6);
   1096  1.1  christos }
   1097  1.1  christos 
   1098  1.1  christos /* Make a weak symbol name unique by
   1099  1.1  christos    appending the name of an external symbol.  */
   1100  1.1  christos 
   1101  1.1  christos static const char *
   1102  1.1  christos weak_uniquify (const char * name)
   1103  1.1  christos {
   1104  1.1  christos   const char * unique = "";
   1105  1.1  christos 
   1106  1.1  christos #ifdef TE_PE
   1107  1.1  christos   if (an_external_name != NULL)
   1108  1.5  christos     unique = an_external_name;
   1109  1.1  christos #endif
   1110  1.1  christos   gas_assert (weak_is_altname (name));
   1111  1.1  christos 
   1112  1.1  christos   return concat (name, ".", unique, (char *) NULL);
   1113  1.1  christos }
   1114  1.1  christos 
   1115  1.1  christos void
   1116  1.1  christos pecoff_obj_set_weak_hook (symbolS *symbolP)
   1117  1.1  christos {
   1118  1.1  christos   symbolS *alternateP;
   1119  1.1  christos 
   1120  1.1  christos   /* See _Microsoft Portable Executable and Common Object
   1121  1.1  christos      File Format Specification_, section 5.5.3.
   1122  1.1  christos      Create a symbol representing the alternate value.
   1123  1.1  christos      coff_frob_symbol will set the value of this symbol from
   1124  1.1  christos      the value of the weak symbol itself.  */
   1125  1.1  christos   S_SET_STORAGE_CLASS (symbolP, C_NT_WEAK);
   1126  1.1  christos   S_SET_NUMBER_AUXILIARY (symbolP, 1);
   1127  1.1  christos   SA_SET_SYM_FSIZE (symbolP, IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY);
   1128  1.1  christos 
   1129  1.1  christos   alternateP = symbol_find_or_make (weak_name2altname (S_GET_NAME (symbolP)));
   1130  1.1  christos   S_SET_EXTERNAL (alternateP);
   1131  1.1  christos   S_SET_STORAGE_CLASS (alternateP, C_NT_WEAK);
   1132  1.1  christos 
   1133  1.1  christos   SA_SET_SYM_TAGNDX (symbolP, alternateP);
   1134  1.1  christos }
   1135  1.1  christos 
   1136  1.1  christos void
   1137  1.1  christos pecoff_obj_clear_weak_hook (symbolS *symbolP)
   1138  1.1  christos {
   1139  1.1  christos   symbolS *alternateP;
   1140  1.1  christos 
   1141  1.1  christos   S_SET_STORAGE_CLASS (symbolP, 0);
   1142  1.1  christos   SA_SET_SYM_FSIZE (symbolP, 0);
   1143  1.1  christos 
   1144  1.1  christos   alternateP = symbol_find (weak_name2altname (S_GET_NAME (symbolP)));
   1145  1.1  christos   S_CLEAR_EXTERNAL (alternateP);
   1146  1.1  christos }
   1147  1.1  christos 
   1148  1.1  christos #endif  /* TE_PE */
   1149  1.1  christos 
   1150  1.1  christos /* Handle .weak.  This is a GNU extension in formats other than PE. */
   1151  1.1  christos 
   1152  1.1  christos static void
   1153  1.1  christos obj_coff_weak (int ignore ATTRIBUTE_UNUSED)
   1154  1.1  christos {
   1155  1.1  christos   char *name;
   1156  1.1  christos   int c;
   1157  1.3  christos   symbolS *symbolP;
   1158  1.1  christos 
   1159  1.1  christos   do
   1160  1.1  christos     {
   1161  1.1  christos       c = get_symbol_name (&name);
   1162  1.1  christos       if (*name == 0)
   1163  1.1  christos 	{
   1164  1.1  christos 	  as_warn (_("badly formed .weak directive ignored"));
   1165  1.1  christos 	  ignore_rest_of_line ();
   1166  1.1  christos 	  return;
   1167  1.3  christos 	}
   1168  1.1  christos       c = 0;
   1169  1.1  christos       symbolP = symbol_find_or_make (name);
   1170  1.1  christos       *input_line_pointer = c;
   1171  1.1  christos       SKIP_WHITESPACE_AFTER_NAME ();
   1172  1.1  christos       S_SET_WEAK (symbolP);
   1173  1.1  christos 
   1174  1.1  christos       if (c == ',')
   1175  1.1  christos 	{
   1176  1.1  christos 	  input_line_pointer++;
   1177  1.1  christos 	  SKIP_WHITESPACE ();
   1178  1.1  christos 	  if (*input_line_pointer == '\n')
   1179  1.1  christos 	    c = '\n';
   1180  1.1  christos 	}
   1181  1.1  christos 
   1182  1.1  christos     }
   1183  1.1  christos   while (c == ',');
   1184  1.1  christos 
   1185  1.1  christos   demand_empty_rest_of_line ();
   1186  1.1  christos }
   1187  1.1  christos 
   1188  1.1  christos void
   1189  1.1  christos coff_obj_read_begin_hook (void)
   1190  1.1  christos {
   1191  1.1  christos   /* These had better be the same.  Usually 18 bytes.  */
   1192  1.1  christos   know (sizeof (SYMENT) == sizeof (AUXENT));
   1193  1.1  christos   know (SYMESZ == AUXESZ);
   1194  1.1  christos   tag_init ();
   1195  1.1  christos }
   1196  1.1  christos 
   1197  1.1  christos symbolS *coff_last_function;
   1198  1.1  christos #ifndef OBJ_XCOFF
   1199  1.1  christos static symbolS *coff_last_bf;
   1200  1.1  christos #endif
   1201  1.1  christos 
   1202  1.1  christos void
   1203  1.1  christos coff_frob_symbol (symbolS *symp, int *punt)
   1204  1.1  christos {
   1205  1.1  christos   static symbolS *last_tagP;
   1206  1.1  christos   static stack *block_stack;
   1207  1.1  christos   static symbolS *set_end;
   1208  1.1  christos   symbolS *next_set_end = NULL;
   1209  1.1  christos 
   1210  1.1  christos   if (symp == &abs_symbol)
   1211  1.1  christos     {
   1212  1.1  christos       *punt = 1;
   1213  1.1  christos       return;
   1214  1.1  christos     }
   1215  1.1  christos 
   1216  1.1  christos   if (current_lineno_sym)
   1217  1.1  christos     coff_add_linesym (NULL);
   1218  1.1  christos 
   1219  1.1  christos   if (!block_stack)
   1220  1.1  christos     block_stack = stack_init (512, sizeof (symbolS*));
   1221  1.1  christos 
   1222  1.1  christos #ifdef TE_PE
   1223  1.1  christos   if (S_GET_STORAGE_CLASS (symp) == C_NT_WEAK
   1224  1.1  christos       && ! S_IS_WEAK (symp)
   1225  1.1  christos       && weak_is_altname (S_GET_NAME (symp)))
   1226  1.1  christos     {
   1227  1.1  christos       /* This is a weak alternate symbol.  All processing of
   1228  1.1  christos 	 PECOFFweak symbols is done here, through the alternate.  */
   1229  1.1  christos       symbolS *weakp = symbol_find_noref (weak_altname2name
   1230  1.1  christos 					  (S_GET_NAME (symp)), 1);
   1231  1.1  christos 
   1232  1.1  christos       gas_assert (weakp);
   1233  1.1  christos       gas_assert (S_GET_NUMBER_AUXILIARY (weakp) == 1);
   1234  1.1  christos 
   1235  1.1  christos       if (! S_IS_WEAK (weakp))
   1236  1.1  christos 	{
   1237  1.1  christos 	  /* The symbol was turned from weak to strong.  Discard altname.  */
   1238  1.1  christos 	  *punt = 1;
   1239  1.1  christos 	  return;
   1240  1.1  christos 	}
   1241  1.1  christos       else if (symbol_equated_p (weakp))
   1242  1.1  christos 	{
   1243  1.1  christos 	  /* The weak symbol has an alternate specified; symp is unneeded.  */
   1244  1.1  christos 	  S_SET_STORAGE_CLASS (weakp, C_NT_WEAK);
   1245  1.1  christos 	  SA_SET_SYM_TAGNDX (weakp,
   1246  1.1  christos 	    symbol_get_value_expression (weakp)->X_add_symbol);
   1247  1.1  christos 
   1248  1.1  christos 	  S_CLEAR_EXTERNAL (symp);
   1249  1.1  christos 	  *punt = 1;
   1250  1.1  christos 	  return;
   1251  1.1  christos 	}
   1252  1.1  christos       else
   1253  1.1  christos 	{
   1254  1.1  christos 	  /* The weak symbol has been assigned an alternate value.
   1255  1.1  christos              Copy this value to symp, and set symp as weakp's alternate.  */
   1256  1.1  christos 	  if (S_GET_STORAGE_CLASS (weakp) != C_NT_WEAK)
   1257  1.1  christos 	    {
   1258  1.1  christos 	      S_SET_STORAGE_CLASS (symp, S_GET_STORAGE_CLASS (weakp));
   1259  1.1  christos 	      S_SET_STORAGE_CLASS (weakp, C_NT_WEAK);
   1260  1.1  christos 	    }
   1261  1.1  christos 
   1262  1.1  christos 	  if (S_IS_DEFINED (weakp))
   1263  1.1  christos 	    {
   1264  1.1  christos 	      /* This is a defined weak symbol.  Copy value information
   1265  1.1  christos 	         from the weak symbol itself to the alternate symbol.  */
   1266  1.1  christos 	      symbol_set_value_expression (symp,
   1267  1.1  christos 					   symbol_get_value_expression (weakp));
   1268  1.1  christos 	      symbol_set_frag (symp, symbol_get_frag (weakp));
   1269  1.1  christos 	      S_SET_SEGMENT (symp, S_GET_SEGMENT (weakp));
   1270  1.1  christos 	    }
   1271  1.1  christos 	  else
   1272  1.1  christos 	    {
   1273  1.1  christos 	      /* This is an undefined weak symbol.
   1274  1.1  christos 		 Define the alternate symbol to zero.  */
   1275  1.1  christos 	      S_SET_VALUE (symp, 0);
   1276  1.1  christos 	      S_SET_SEGMENT (symp, absolute_section);
   1277  1.1  christos 	    }
   1278  1.1  christos 
   1279  1.1  christos 	  S_SET_NAME (symp, weak_uniquify (S_GET_NAME (symp)));
   1280  1.1  christos 	  S_SET_STORAGE_CLASS (symp, C_EXT);
   1281  1.1  christos 
   1282  1.1  christos 	  S_SET_VALUE (weakp, 0);
   1283  1.1  christos 	  S_SET_SEGMENT (weakp, undefined_section);
   1284  1.1  christos 	}
   1285  1.1  christos     }
   1286  1.1  christos #else /* TE_PE */
   1287  1.1  christos   if (S_IS_WEAK (symp))
   1288  1.1  christos     S_SET_STORAGE_CLASS (symp, C_WEAKEXT);
   1289  1.1  christos #endif /* TE_PE */
   1290  1.1  christos 
   1291  1.1  christos   if (!S_IS_DEFINED (symp)
   1292  1.1  christos       && !S_IS_WEAK (symp)
   1293  1.1  christos       && S_GET_STORAGE_CLASS (symp) != C_STAT)
   1294  1.1  christos     S_SET_STORAGE_CLASS (symp, C_EXT);
   1295  1.1  christos 
   1296  1.1  christos   if (!SF_GET_DEBUG (symp))
   1297  1.1  christos     {
   1298  1.1  christos       symbolS * real;
   1299  1.1  christos 
   1300  1.1  christos       if (!SF_GET_LOCAL (symp)
   1301  1.1  christos 	  && !SF_GET_STATICS (symp)
   1302  1.1  christos 	  && S_GET_STORAGE_CLASS (symp) != C_LABEL
   1303  1.1  christos 	  && symbol_constant_p (symp)
   1304  1.1  christos 	  && (real = symbol_find_noref (S_GET_NAME (symp), 1))
   1305  1.1  christos 	  && S_GET_STORAGE_CLASS (real) == C_NULL
   1306  1.1  christos 	  && real != symp)
   1307  1.1  christos 	{
   1308  1.1  christos 	  c_symbol_merge (symp, real);
   1309  1.1  christos 	  *punt = 1;
   1310  1.1  christos 	  return;
   1311  1.1  christos 	}
   1312  1.1  christos 
   1313  1.1  christos       if (!S_IS_DEFINED (symp) && !SF_GET_LOCAL (symp))
   1314  1.1  christos 	{
   1315  1.1  christos 	  gas_assert (S_GET_VALUE (symp) == 0);
   1316  1.1  christos 	  if (S_IS_WEAKREFD (symp))
   1317  1.1  christos 	    *punt = 1;
   1318  1.1  christos 	  else
   1319  1.1  christos 	    S_SET_EXTERNAL (symp);
   1320  1.1  christos 	}
   1321  1.1  christos       else if (S_GET_STORAGE_CLASS (symp) == C_NULL)
   1322  1.1  christos 	{
   1323  1.1  christos 	  if (S_GET_SEGMENT (symp) == text_section
   1324  1.1  christos 	      && symp != seg_info (text_section)->sym)
   1325  1.1  christos 	    S_SET_STORAGE_CLASS (symp, C_LABEL);
   1326  1.1  christos 	  else
   1327  1.1  christos 	    S_SET_STORAGE_CLASS (symp, C_STAT);
   1328  1.1  christos 	}
   1329  1.1  christos 
   1330  1.1  christos       if (SF_GET_PROCESS (symp))
   1331  1.1  christos 	{
   1332  1.1  christos 	  if (S_GET_STORAGE_CLASS (symp) == C_BLOCK)
   1333  1.1  christos 	    {
   1334  1.1  christos 	      if (streq (S_GET_NAME (symp), ".bb"))
   1335  1.1  christos 		stack_push (block_stack, (char *) &symp);
   1336  1.1  christos 	      else
   1337  1.1  christos 		{
   1338  1.1  christos 		  symbolS *begin;
   1339  1.1  christos 
   1340  1.1  christos 		  begin = *(symbolS **) stack_pop (block_stack);
   1341  1.1  christos 		  if (begin == 0)
   1342  1.1  christos 		    as_warn (_("mismatched .eb"));
   1343  1.1  christos 		  else
   1344  1.3  christos 		    next_set_end = begin;
   1345  1.3  christos 		}
   1346  1.1  christos 	    }
   1347  1.1  christos 
   1348  1.1  christos 	  if (coff_last_function == 0 && SF_GET_FUNCTION (symp)
   1349  1.1  christos 	      && S_IS_DEFINED (symp))
   1350  1.1  christos 	    {
   1351  1.1  christos 	      union internal_auxent *auxp;
   1352  1.1  christos 
   1353  1.1  christos 	      coff_last_function = symp;
   1354  1.1  christos 	      if (S_GET_NUMBER_AUXILIARY (symp) < 1)
   1355  1.1  christos 		S_SET_NUMBER_AUXILIARY (symp, 1);
   1356  1.1  christos 	      auxp = SYM_AUXENT (symp);
   1357  1.3  christos 	      memset (auxp->x_sym.x_fcnary.x_ary.x_dimen, 0,
   1358  1.3  christos 		      sizeof (auxp->x_sym.x_fcnary.x_ary.x_dimen));
   1359  1.1  christos 	    }
   1360  1.1  christos 
   1361  1.1  christos 	  if (S_GET_STORAGE_CLASS (symp) == C_EFCN
   1362  1.1  christos 	      && S_IS_DEFINED (symp))
   1363  1.1  christos 	    {
   1364  1.1  christos 	      if (coff_last_function == 0)
   1365  1.1  christos 		as_fatal (_("C_EFCN symbol for %s out of scope"),
   1366  1.1  christos 			  S_GET_NAME (symp));
   1367  1.1  christos 	      SA_SET_SYM_FSIZE (coff_last_function,
   1368  1.1  christos 				(long) (S_GET_VALUE (symp)
   1369  1.1  christos 					- S_GET_VALUE (coff_last_function)));
   1370  1.1  christos 	      next_set_end = coff_last_function;
   1371  1.1  christos 	      coff_last_function = 0;
   1372  1.1  christos 	    }
   1373  1.1  christos 	}
   1374  1.1  christos 
   1375  1.1  christos       if (S_IS_EXTERNAL (symp))
   1376  1.1  christos 	S_SET_STORAGE_CLASS (symp, C_EXT);
   1377  1.1  christos       else if (SF_GET_LOCAL (symp))
   1378  1.1  christos 	*punt = 1;
   1379  1.1  christos 
   1380  1.1  christos       if (SF_GET_FUNCTION (symp))
   1381  1.1  christos 	symbol_get_bfdsym (symp)->flags |= BSF_FUNCTION;
   1382  1.1  christos     }
   1383  1.1  christos 
   1384  1.1  christos   /* Double check weak symbols.  */
   1385  1.1  christos   if (S_IS_WEAK (symp) && S_IS_COMMON (symp))
   1386  1.1  christos     as_bad (_("Symbol `%s' can not be both weak and common"),
   1387  1.1  christos 	    S_GET_NAME (symp));
   1388  1.1  christos 
   1389  1.1  christos   if (SF_GET_TAG (symp))
   1390  1.1  christos     last_tagP = symp;
   1391  1.1  christos   else if (S_GET_STORAGE_CLASS (symp) == C_EOS)
   1392  1.1  christos     next_set_end = last_tagP;
   1393  1.1  christos 
   1394  1.1  christos #ifdef OBJ_XCOFF
   1395  1.1  christos   /* This is pretty horrible, but we have to set *punt correctly in
   1396  1.1  christos      order to call SA_SET_SYM_ENDNDX correctly.  */
   1397  1.1  christos   if (! symbol_used_in_reloc_p (symp)
   1398  1.1  christos       && ((symbol_get_bfdsym (symp)->flags & BSF_SECTION_SYM) != 0
   1399  1.1  christos 	  || (! (S_IS_EXTERNAL (symp) || S_IS_WEAK (symp))
   1400  1.1  christos 	      && ! symbol_get_tc (symp)->output
   1401  1.1  christos 	      && S_GET_STORAGE_CLASS (symp) != C_FILE)))
   1402  1.1  christos     *punt = 1;
   1403  1.1  christos #endif
   1404  1.1  christos 
   1405  1.1  christos   if (set_end != (symbolS *) NULL
   1406  1.1  christos       && ! *punt
   1407  1.1  christos       && ((symbol_get_bfdsym (symp)->flags & BSF_NOT_AT_END) != 0
   1408  1.1  christos 	  || (S_IS_DEFINED (symp)
   1409  1.1  christos 	      && ! S_IS_COMMON (symp)
   1410  1.1  christos 	      && (! S_IS_EXTERNAL (symp) || SF_GET_FUNCTION (symp)))))
   1411  1.1  christos     {
   1412  1.1  christos       SA_SET_SYM_ENDNDX (set_end, symp);
   1413  1.1  christos       set_end = NULL;
   1414  1.1  christos     }
   1415  1.1  christos 
   1416  1.1  christos   if (next_set_end != NULL)
   1417  1.1  christos     {
   1418  1.1  christos       if (set_end != NULL)
   1419  1.1  christos 	as_warn (_("Warning: internal error: forgetting to set endndx of %s"),
   1420  1.1  christos 		 S_GET_NAME (set_end));
   1421  1.1  christos       set_end = next_set_end;
   1422  1.1  christos     }
   1423  1.1  christos 
   1424  1.1  christos #ifndef OBJ_XCOFF
   1425  1.1  christos   if (! *punt
   1426  1.1  christos       && S_GET_STORAGE_CLASS (symp) == C_FCN
   1427  1.1  christos       && streq (S_GET_NAME (symp), ".bf"))
   1428  1.1  christos     {
   1429  1.1  christos       if (coff_last_bf != NULL)
   1430  1.1  christos 	SA_SET_SYM_ENDNDX (coff_last_bf, symp);
   1431  1.1  christos       coff_last_bf = symp;
   1432  1.1  christos     }
   1433  1.1  christos #endif
   1434  1.1  christos   if (coffsymbol (symbol_get_bfdsym (symp))->lineno)
   1435  1.1  christos     {
   1436  1.1  christos       int i;
   1437  1.1  christos       struct line_no *lptr;
   1438  1.1  christos       alent *l;
   1439  1.1  christos 
   1440  1.1  christos       lptr = (struct line_no *) coffsymbol (symbol_get_bfdsym (symp))->lineno;
   1441  1.1  christos       for (i = 0; lptr; lptr = lptr->next)
   1442  1.1  christos 	i++;
   1443  1.1  christos       lptr = (struct line_no *) coffsymbol (symbol_get_bfdsym (symp))->lineno;
   1444  1.5  christos 
   1445  1.1  christos       /* We need i entries for line numbers, plus 1 for the first
   1446  1.1  christos 	 entry which BFD will override, plus 1 for the last zero
   1447  1.1  christos 	 entry (a marker for BFD).  */
   1448  1.1  christos       l = XNEWVEC (alent, (i + 2));
   1449  1.1  christos       coffsymbol (symbol_get_bfdsym (symp))->lineno = l;
   1450  1.1  christos       l[i + 1].line_number = 0;
   1451  1.1  christos       l[i + 1].u.sym = NULL;
   1452  1.1  christos       for (; i > 0; i--)
   1453  1.1  christos 	{
   1454  1.1  christos 	  if (lptr->frag)
   1455  1.1  christos 	    lptr->l.u.offset += lptr->frag->fr_address / OCTETS_PER_BYTE;
   1456  1.1  christos 	  l[i] = lptr->l;
   1457  1.1  christos 	  lptr = lptr->next;
   1458  1.1  christos 	}
   1459  1.1  christos     }
   1460  1.1  christos }
   1461  1.1  christos 
   1462  1.1  christos void
   1463  1.1  christos coff_adjust_section_syms (bfd *abfd ATTRIBUTE_UNUSED,
   1464  1.1  christos 			  asection *sec,
   1465  1.1  christos 			  void * x ATTRIBUTE_UNUSED)
   1466  1.1  christos {
   1467  1.1  christos   symbolS *secsym;
   1468  1.1  christos   segment_info_type *seginfo = seg_info (sec);
   1469  1.1  christos   int nlnno, nrelocs = 0;
   1470  1.1  christos 
   1471  1.1  christos   /* RS/6000 gas creates a .debug section manually in ppc_frob_file in
   1472  1.1  christos      tc-ppc.c.  Do not get confused by it.  */
   1473  1.1  christos   if (seginfo == NULL)
   1474  1.1  christos     return;
   1475  1.1  christos 
   1476  1.1  christos   if (streq (sec->name, ".text"))
   1477  1.1  christos     nlnno = coff_n_line_nos;
   1478  1.1  christos   else
   1479  1.1  christos     nlnno = 0;
   1480  1.1  christos   {
   1481  1.1  christos     /* @@ Hope that none of the fixups expand to more than one reloc
   1482  1.1  christos        entry...  */
   1483  1.1  christos     fixS *fixp = seginfo->fix_root;
   1484  1.1  christos     while (fixp)
   1485  1.1  christos       {
   1486  1.1  christos 	if (! fixp->fx_done)
   1487  1.1  christos 	  nrelocs++;
   1488  1.1  christos 	fixp = fixp->fx_next;
   1489  1.1  christos       }
   1490  1.1  christos   }
   1491  1.1  christos   if (bfd_get_section_size (sec) == 0
   1492  1.1  christos       && nrelocs == 0
   1493  1.1  christos       && nlnno == 0
   1494  1.1  christos       && sec != text_section
   1495  1.1  christos       && sec != data_section
   1496  1.1  christos       && sec != bss_section)
   1497  1.1  christos     return;
   1498  1.1  christos 
   1499  1.1  christos   secsym = section_symbol (sec);
   1500  1.1  christos   /* This is an estimate; we'll plug in the real value using
   1501  1.1  christos      SET_SECTION_RELOCS later */
   1502  1.1  christos   SA_SET_SCN_NRELOC (secsym, nrelocs);
   1503  1.1  christos   SA_SET_SCN_NLINNO (secsym, nlnno);
   1504  1.1  christos }
   1505  1.1  christos 
   1506  1.1  christos void
   1507  1.1  christos coff_frob_file_after_relocs (void)
   1508  1.1  christos {
   1509  1.1  christos   bfd_map_over_sections (stdoutput, coff_adjust_section_syms, NULL);
   1510  1.1  christos }
   1511  1.1  christos 
   1512  1.1  christos /* Implement the .section pseudo op:
   1513  1.1  christos   	.section name {, "flags"}
   1514  1.1  christos                   ^         ^
   1515  1.1  christos                   |         +--- optional flags: 'b' for bss
   1516  1.1  christos                   |                              'i' for info
   1517  1.1  christos                   +-- section name               'l' for lib
   1518  1.1  christos                                                  'n' for noload
   1519  1.1  christos                                                  'o' for over
   1520  1.1  christos                                                  'w' for data
   1521  1.1  christos   						 'd' (apparently m88k for data)
   1522  1.1  christos 						 'e' for exclude
   1523  1.1  christos                                                  'x' for text
   1524  1.1  christos   						 'r' for read-only data
   1525  1.1  christos   						 's' for shared data (PE)
   1526  1.1  christos 						 'y' for noread
   1527  1.1  christos 					   '0' - '9' for power-of-two alignment (GNU extension).
   1528  1.1  christos    But if the argument is not a quoted string, treat it as a
   1529  1.1  christos    subsegment number.
   1530  1.1  christos 
   1531  1.1  christos    Note the 'a' flag is silently ignored.  This allows the same
   1532  1.1  christos    .section directive to be parsed in both ELF and COFF formats.  */
   1533  1.1  christos 
   1534  1.1  christos void
   1535  1.1  christos obj_coff_section (int ignore ATTRIBUTE_UNUSED)
   1536  1.1  christos {
   1537  1.1  christos   /* Strip out the section name.  */
   1538  1.1  christos   char *section_name;
   1539  1.1  christos   char c;
   1540  1.1  christos   int alignment = -1;
   1541  1.1  christos   char *name;
   1542  1.1  christos   unsigned int exp;
   1543  1.1  christos   flagword flags, oldflags;
   1544  1.1  christos   asection *sec;
   1545  1.1  christos 
   1546  1.1  christos   if (flag_mri)
   1547  1.1  christos     {
   1548  1.1  christos       char type;
   1549  1.1  christos 
   1550  1.3  christos       s_mri_sect (&type);
   1551  1.5  christos       return;
   1552  1.1  christos     }
   1553  1.3  christos 
   1554  1.1  christos   c = get_symbol_name (&section_name);
   1555  1.1  christos   name = xmemdup0 (section_name, input_line_pointer - section_name);
   1556  1.1  christos   *input_line_pointer = c;
   1557  1.1  christos   SKIP_WHITESPACE_AFTER_NAME ();
   1558  1.1  christos 
   1559  1.1  christos   exp = 0;
   1560  1.1  christos   flags = SEC_NO_FLAGS;
   1561  1.1  christos 
   1562  1.1  christos   if (*input_line_pointer == ',')
   1563  1.1  christos     {
   1564  1.1  christos       ++input_line_pointer;
   1565  1.1  christos       SKIP_WHITESPACE ();
   1566  1.1  christos       if (*input_line_pointer != '"')
   1567  1.1  christos 	exp = get_absolute_expression ();
   1568  1.1  christos       else
   1569  1.1  christos 	{
   1570  1.1  christos 	  unsigned char attr;
   1571  1.1  christos 	  int readonly_removed = 0;
   1572  1.1  christos 	  int load_removed = 0;
   1573  1.1  christos 
   1574  1.1  christos 	  while (attr = *++input_line_pointer,
   1575  1.1  christos 		 attr != '"'
   1576  1.1  christos 		 && ! is_end_of_line[attr])
   1577  1.1  christos 	    {
   1578  1.1  christos 	      if (ISDIGIT (attr))
   1579  1.1  christos 		{
   1580  1.1  christos 		  alignment = attr - '0';
   1581  1.1  christos 		  continue;
   1582  1.1  christos 		}
   1583  1.1  christos 	      switch (attr)
   1584  1.1  christos 		{
   1585  1.1  christos 		case 'e':
   1586  1.1  christos 		  /* Exclude section from linking.  */
   1587  1.1  christos 		  flags |= SEC_EXCLUDE;
   1588  1.1  christos 		  break;
   1589  1.1  christos 
   1590  1.1  christos 		case 'b':
   1591  1.1  christos 		  /* Uninitialised data section.  */
   1592  1.1  christos 		  flags |= SEC_ALLOC;
   1593  1.1  christos 		  flags &=~ SEC_LOAD;
   1594  1.1  christos 		  break;
   1595  1.1  christos 
   1596  1.1  christos 		case 'n':
   1597  1.1  christos 		  /* Section not loaded.  */
   1598  1.1  christos 		  flags &=~ SEC_LOAD;
   1599  1.1  christos 		  flags |= SEC_NEVER_LOAD;
   1600  1.1  christos 		  load_removed = 1;
   1601  1.1  christos 		  break;
   1602  1.1  christos 
   1603  1.1  christos 		case 's':
   1604  1.1  christos 		  /* Shared section.  */
   1605  1.1  christos 		  flags |= SEC_COFF_SHARED;
   1606  1.1  christos 		  /* Fall through.  */
   1607  1.1  christos 		case 'd':
   1608  1.1  christos 		  /* Data section.  */
   1609  1.1  christos 		  flags |= SEC_DATA;
   1610  1.1  christos 		  if (! load_removed)
   1611  1.1  christos 		    flags |= SEC_LOAD;
   1612  1.1  christos 		  flags &=~ SEC_READONLY;
   1613  1.1  christos 		  break;
   1614  1.1  christos 
   1615  1.1  christos 		case 'w':
   1616  1.1  christos 		  /* Writable section.  */
   1617  1.1  christos 		  flags &=~ SEC_READONLY;
   1618  1.1  christos 		  readonly_removed = 1;
   1619  1.1  christos 		  break;
   1620  1.1  christos 
   1621  1.1  christos 		case 'a':
   1622  1.1  christos 		  /* Ignore.  Here for compatibility with ELF.  */
   1623  1.1  christos 		  break;
   1624  1.1  christos 
   1625  1.1  christos 		case 'r': /* Read-only section.  Implies a data section.  */
   1626  1.1  christos 		  readonly_removed = 0;
   1627  1.1  christos 		  /* Fall through.  */
   1628  1.1  christos 		case 'x': /* Executable section.  */
   1629  1.1  christos 		  /* If we are setting the 'x' attribute or if the 'r'
   1630  1.1  christos 		     attribute is being used to restore the readonly status
   1631  1.1  christos 		     of a code section (eg "wxr") then set the SEC_CODE flag,
   1632  1.1  christos 		     otherwise set the SEC_DATA flag.  */
   1633  1.1  christos 		  flags |= (attr == 'x' || (flags & SEC_CODE) ? SEC_CODE : SEC_DATA);
   1634  1.1  christos 		  if (! load_removed)
   1635  1.1  christos 		    flags |= SEC_LOAD;
   1636  1.1  christos 		  /* Note - the READONLY flag is set here, even for the 'x'
   1637  1.1  christos 		     attribute in order to be compatible with the MSVC
   1638  1.1  christos 		     linker.  */
   1639  1.1  christos 		  if (! readonly_removed)
   1640  1.1  christos 		    flags |= SEC_READONLY;
   1641  1.1  christos 		  break;
   1642  1.1  christos 
   1643  1.1  christos 		case 'y':
   1644  1.1  christos 		  flags |= SEC_COFF_NOREAD | SEC_READONLY;
   1645  1.1  christos 		  break;
   1646  1.1  christos 
   1647  1.1  christos 		case 'i': /* STYP_INFO */
   1648  1.1  christos 		case 'l': /* STYP_LIB */
   1649  1.1  christos 		case 'o': /* STYP_OVER */
   1650  1.1  christos 		  as_warn (_("unsupported section attribute '%c'"), attr);
   1651  1.1  christos 		  break;
   1652  1.1  christos 
   1653  1.1  christos 		default:
   1654  1.1  christos 		  as_warn (_("unknown section attribute '%c'"), attr);
   1655  1.1  christos 		  break;
   1656  1.1  christos 		}
   1657  1.1  christos 	    }
   1658  1.1  christos 	  if (attr == '"')
   1659  1.1  christos 	    ++input_line_pointer;
   1660  1.3  christos 	}
   1661  1.1  christos     }
   1662  1.1  christos 
   1663  1.1  christos   sec = subseg_new (name, (subsegT) exp);
   1664  1.1  christos 
   1665  1.1  christos   if (alignment >= 0)
   1666  1.1  christos     sec->alignment_power = alignment;
   1667  1.1  christos 
   1668  1.1  christos   oldflags = bfd_get_section_flags (stdoutput, sec);
   1669  1.1  christos   if (oldflags == SEC_NO_FLAGS)
   1670  1.1  christos     {
   1671  1.1  christos       /* Set section flags for a new section just created by subseg_new.
   1672  1.1  christos          Provide a default if no flags were parsed.  */
   1673  1.1  christos       if (flags == SEC_NO_FLAGS)
   1674  1.1  christos 	flags = TC_COFF_SECTION_DEFAULT_ATTRIBUTES;
   1675  1.1  christos 
   1676  1.1  christos #ifdef COFF_LONG_SECTION_NAMES
   1677  1.1  christos       /* Add SEC_LINK_ONCE and SEC_LINK_DUPLICATES_DISCARD to .gnu.linkonce
   1678  1.1  christos          sections so adjust_reloc_syms in write.c will correctly handle
   1679  1.1  christos          relocs which refer to non-local symbols in these sections.  */
   1680  1.1  christos       if (strneq (name, ".gnu.linkonce", sizeof (".gnu.linkonce") - 1))
   1681  1.1  christos 	flags |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;
   1682  1.1  christos #endif
   1683  1.1  christos 
   1684  1.1  christos       if (! bfd_set_section_flags (stdoutput, sec, flags))
   1685  1.1  christos 	as_warn (_("error setting flags for \"%s\": %s"),
   1686  1.1  christos 		 bfd_section_name (stdoutput, sec),
   1687  1.1  christos 		 bfd_errmsg (bfd_get_error ()));
   1688  1.1  christos     }
   1689  1.1  christos   else if (flags != SEC_NO_FLAGS)
   1690  1.1  christos     {
   1691  1.1  christos       /* This section's attributes have already been set.  Warn if the
   1692  1.1  christos          attributes don't match.  */
   1693  1.1  christos       flagword matchflags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE
   1694  1.1  christos 			     | SEC_DATA | SEC_COFF_SHARED | SEC_NEVER_LOAD
   1695  1.1  christos 			     | SEC_COFF_NOREAD);
   1696  1.1  christos       if ((flags ^ oldflags) & matchflags)
   1697  1.1  christos 	as_warn (_("Ignoring changed section attributes for %s"), name);
   1698  1.1  christos     }
   1699  1.1  christos 
   1700  1.1  christos   demand_empty_rest_of_line ();
   1701  1.1  christos }
   1702  1.1  christos 
   1703  1.1  christos void
   1704  1.1  christos coff_adjust_symtab (void)
   1705  1.1  christos {
   1706  1.1  christos   if (symbol_rootP == NULL
   1707  1.1  christos       || S_GET_STORAGE_CLASS (symbol_rootP) != C_FILE)
   1708  1.1  christos     c_dot_file_symbol ("fake", 0);
   1709  1.1  christos }
   1710  1.1  christos 
   1711  1.1  christos void
   1712  1.1  christos coff_frob_section (segT sec)
   1713  1.1  christos {
   1714  1.1  christos   segT strsec;
   1715  1.1  christos   char *p;
   1716  1.1  christos   fragS *fragp;
   1717  1.1  christos   bfd_vma n_entries;
   1718  1.1  christos 
   1719  1.1  christos   /* The COFF back end in BFD requires that all section sizes be
   1720  1.1  christos      rounded up to multiples of the corresponding section alignments,
   1721  1.1  christos      supposedly because standard COFF has no other way of encoding alignment
   1722  1.1  christos      for sections.  If your COFF flavor has a different way of encoding
   1723  1.1  christos      section alignment, then skip this step, as TICOFF does.  */
   1724  1.1  christos   bfd_vma size = bfd_get_section_size (sec);
   1725  1.1  christos #if !defined(TICOFF)
   1726  1.1  christos   bfd_vma align_power = (bfd_vma) sec->alignment_power + OCTETS_PER_BYTE_POWER;
   1727  1.1  christos   bfd_vma mask = ((bfd_vma) 1 << align_power) - 1;
   1728  1.1  christos 
   1729  1.1  christos   if (size & mask)
   1730  1.1  christos     {
   1731  1.1  christos       bfd_vma new_size;
   1732  1.1  christos       fragS *last;
   1733  1.1  christos 
   1734  1.1  christos       new_size = (size + mask) & ~mask;
   1735  1.1  christos       bfd_set_section_size (stdoutput, sec, new_size);
   1736  1.1  christos 
   1737  1.1  christos       /* If the size had to be rounded up, add some padding in
   1738  1.1  christos          the last non-empty frag.  */
   1739  1.1  christos       fragp = seg_info (sec)->frchainP->frch_root;
   1740  1.1  christos       last = seg_info (sec)->frchainP->frch_last;
   1741  1.1  christos       while (fragp->fr_next != last)
   1742  1.1  christos 	fragp = fragp->fr_next;
   1743  1.1  christos       last->fr_address = size;
   1744  1.1  christos       fragp->fr_offset += new_size - size;
   1745  1.1  christos     }
   1746  1.1  christos #endif
   1747  1.1  christos 
   1748  1.1  christos   /* If the section size is non-zero, the section symbol needs an aux
   1749  1.1  christos      entry associated with it, indicating the size.  We don't know
   1750  1.1  christos      all the values yet; coff_frob_symbol will fill them in later.  */
   1751  1.1  christos #ifndef TICOFF
   1752  1.1  christos   if (size != 0
   1753  1.1  christos       || sec == text_section
   1754  1.1  christos       || sec == data_section
   1755  1.1  christos       || sec == bss_section)
   1756  1.1  christos #endif
   1757  1.1  christos     {
   1758  1.1  christos       symbolS *secsym = section_symbol (sec);
   1759  1.1  christos       unsigned char sclass = C_STAT;
   1760  1.1  christos 
   1761  1.1  christos #ifdef OBJ_XCOFF
   1762  1.1  christos       if (bfd_get_section_flags (stdoutput, sec) & SEC_DEBUGGING)
   1763  1.1  christos         sclass = C_DWARF;
   1764  1.1  christos #endif
   1765  1.1  christos       S_SET_STORAGE_CLASS (secsym, sclass);
   1766  1.1  christos       S_SET_NUMBER_AUXILIARY (secsym, 1);
   1767  1.1  christos       SF_SET_STATICS (secsym);
   1768  1.1  christos       SA_SET_SCN_SCNLEN (secsym, size);
   1769  1.1  christos     }
   1770  1.1  christos   /* FIXME: These should be in a "stabs.h" file, or maybe as.h.  */
   1771  1.1  christos #ifndef STAB_SECTION_NAME
   1772  1.1  christos #define STAB_SECTION_NAME ".stab"
   1773  1.1  christos #endif
   1774  1.1  christos #ifndef STAB_STRING_SECTION_NAME
   1775  1.1  christos #define STAB_STRING_SECTION_NAME ".stabstr"
   1776  1.1  christos #endif
   1777  1.1  christos   if (! streq (STAB_STRING_SECTION_NAME, sec->name))
   1778  1.1  christos     return;
   1779  1.1  christos 
   1780  1.1  christos   strsec = sec;
   1781  1.1  christos   sec = subseg_get (STAB_SECTION_NAME, 0);
   1782  1.1  christos   /* size is already rounded up, since other section will be listed first */
   1783  1.1  christos   size = bfd_get_section_size (strsec);
   1784  1.1  christos 
   1785  1.1  christos   n_entries = bfd_get_section_size (sec) / 12 - 1;
   1786  1.1  christos 
   1787  1.1  christos   /* Find first non-empty frag.  It should be large enough.  */
   1788  1.1  christos   fragp = seg_info (sec)->frchainP->frch_root;
   1789  1.1  christos   while (fragp && fragp->fr_fix == 0)
   1790  1.1  christos     fragp = fragp->fr_next;
   1791  1.1  christos   gas_assert (fragp != 0 && fragp->fr_fix >= 12);
   1792  1.1  christos 
   1793  1.1  christos   /* Store the values.  */
   1794  1.1  christos   p = fragp->fr_literal;
   1795  1.1  christos   bfd_h_put_16 (stdoutput, n_entries, (bfd_byte *) p + 6);
   1796  1.1  christos   bfd_h_put_32 (stdoutput, size, (bfd_byte *) p + 8);
   1797  1.1  christos }
   1798  1.5  christos 
   1799  1.1  christos void
   1800  1.1  christos obj_coff_init_stab_section (segT seg)
   1801  1.1  christos {
   1802  1.1  christos   const char *file;
   1803  1.1  christos   char *p;
   1804  1.1  christos   char *stabstr_name;
   1805  1.1  christos   unsigned int stroff;
   1806  1.1  christos 
   1807  1.5  christos   /* Make space for this first symbol.  */
   1808  1.5  christos   p = frag_more (12);
   1809  1.1  christos   /* Zero it out.  */
   1810  1.1  christos   memset (p, 0, 12);
   1811  1.1  christos   file = as_where ((unsigned int *) NULL);
   1812  1.1  christos   stabstr_name = concat (seg->name, "str", (char *) NULL);
   1813  1.1  christos   stroff = get_stab_string_offset (file, stabstr_name);
   1814  1.1  christos   know (stroff == 1);
   1815  1.1  christos   md_number_to_chars (p, stroff, 4);
   1816  1.1  christos }
   1817  1.1  christos 
   1818  1.1  christos #ifdef DEBUG
   1819  1.1  christos const char * s_get_name (symbolS *);
   1820  1.1  christos 
   1821  1.1  christos const char *
   1822  1.1  christos s_get_name (symbolS *s)
   1823  1.1  christos {
   1824  1.1  christos   return ((s == NULL) ? "(NULL)" : S_GET_NAME (s));
   1825  1.1  christos }
   1826  1.1  christos 
   1827  1.1  christos void symbol_dump (void);
   1828  1.1  christos 
   1829  1.1  christos void
   1830  1.1  christos symbol_dump (void)
   1831  1.1  christos {
   1832  1.1  christos   symbolS *symbolP;
   1833  1.1  christos 
   1834  1.1  christos   for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
   1835  1.1  christos     printf (_("0x%lx: \"%s\" type = %ld, class = %d, segment = %d\n"),
   1836  1.1  christos 	    (unsigned long) symbolP,
   1837  1.1  christos 	    S_GET_NAME (symbolP),
   1838  1.1  christos 	    (long) S_GET_DATA_TYPE (symbolP),
   1839  1.1  christos 	    S_GET_STORAGE_CLASS (symbolP),
   1840  1.1  christos 	    (int) S_GET_SEGMENT (symbolP));
   1841  1.1  christos }
   1842  1.1  christos 
   1843  1.1  christos #endif /* DEBUG */
   1844  1.1  christos 
   1845  1.1  christos const pseudo_typeS coff_pseudo_table[] =
   1846  1.1  christos {
   1847  1.1  christos   {"ABORT", s_abort, 0},
   1848  1.1  christos   {"appline", obj_coff_ln, 1},
   1849  1.1  christos   /* We accept the .bss directive for backward compatibility with
   1850  1.1  christos      earlier versions of gas.  */
   1851  1.1  christos   {"bss", obj_coff_bss, 0},
   1852  1.1  christos #ifdef TE_PE
   1853  1.1  christos   /* PE provides an enhanced version of .comm with alignment.  */
   1854  1.1  christos   {"comm", obj_coff_comm, 0},
   1855  1.1  christos #endif /* TE_PE */
   1856  1.1  christos   {"def", obj_coff_def, 0},
   1857  1.1  christos   {"dim", obj_coff_dim, 0},
   1858  1.1  christos   {"endef", obj_coff_endef, 0},
   1859  1.1  christos   {"ident", obj_coff_ident, 0},
   1860  1.1  christos   {"line", obj_coff_line, 0},
   1861  1.1  christos   {"ln", obj_coff_ln, 0},
   1862  1.1  christos   {"scl", obj_coff_scl, 0},
   1863  1.1  christos   {"sect", obj_coff_section, 0},
   1864  1.1  christos   {"sect.s", obj_coff_section, 0},
   1865  1.1  christos   {"section", obj_coff_section, 0},
   1866  1.1  christos   {"section.s", obj_coff_section, 0},
   1867  1.1  christos   /* FIXME: We ignore the MRI short attribute.  */
   1868  1.1  christos   {"size", obj_coff_size, 0},
   1869  1.1  christos   {"tag", obj_coff_tag, 0},
   1870  1.1  christos   {"type", obj_coff_type, 0},
   1871  1.1  christos   {"val", obj_coff_val, 0},
   1872  1.1  christos   {"version", s_ignore, 0},
   1873  1.1  christos   {"loc", obj_coff_loc, 0},
   1874  1.1  christos   {"optim", s_ignore, 0},	/* For sun386i cc (?) */
   1875  1.1  christos   {"weak", obj_coff_weak, 0},
   1876  1.1  christos #if defined TC_TIC4X
   1877  1.1  christos   /* The tic4x uses sdef instead of def.  */
   1878  1.1  christos   {"sdef", obj_coff_def, 0},
   1879  1.1  christos #endif
   1880  1.1  christos #if defined(SEH_CMDS)
   1881  1.1  christos   SEH_CMDS
   1882  1.1  christos #endif
   1883  1.1  christos   {NULL, NULL, 0}
   1884  1.1  christos };
   1885  1.1  christos 
   1886  1.1  christos 
   1888  1.1  christos /* Support for a COFF emulation.  */
   1889  1.1  christos 
   1890  1.1  christos static void
   1891  1.1  christos coff_pop_insert (void)
   1892  1.1  christos {
   1893  1.1  christos   pop_insert (coff_pseudo_table);
   1894  1.1  christos }
   1895  1.1  christos 
   1896  1.1  christos static int
   1897  1.1  christos coff_separate_stab_sections (void)
   1898  1.1  christos {
   1899  1.1  christos   return 1;
   1900  1.1  christos }
   1901  1.1  christos 
   1902  1.1  christos const struct format_ops coff_format_ops =
   1903  1.1  christos {
   1904  1.1  christos   bfd_target_coff_flavour,
   1905  1.1  christos   0,	/* dfl_leading_underscore */
   1906  1.1  christos   1,	/* emit_section_symbols */
   1907  1.1  christos   0,    /* begin */
   1908  1.1  christos   c_dot_file_symbol,
   1909  1.1  christos   coff_frob_symbol,
   1910  1.1  christos   0,	/* frob_file */
   1911  1.1  christos   0,	/* frob_file_before_adjust */
   1912  1.1  christos   0,	/* frob_file_before_fix */
   1913  1.1  christos   coff_frob_file_after_relocs,
   1914  1.1  christos   0,	/* s_get_size */
   1915  1.1  christos   0,	/* s_set_size */
   1916  1.1  christos   0,	/* s_get_align */
   1917  1.1  christos   0,	/* s_set_align */
   1918  1.1  christos   0,	/* s_get_other */
   1919  1.1  christos   0,	/* s_set_other */
   1920  1.1  christos   0,	/* s_get_desc */
   1921  1.1  christos   0,	/* s_set_desc */
   1922  1.1  christos   0,	/* s_get_type */
   1923  1.1  christos   0,	/* s_set_type */
   1924  1.1  christos   0,	/* copy_symbol_attributes */
   1925  1.1  christos   0,	/* generate_asm_lineno */
   1926  1.1  christos   0,	/* process_stab */
   1927  1.1  christos   coff_separate_stab_sections,
   1928  1.1  christos   obj_coff_init_stab_section,
   1929  1.1  christos   0,	/* sec_sym_ok_for_reloc */
   1930  1.1  christos   coff_pop_insert,
   1931  1.1  christos   0,	/* ecoff_set_ext */
   1932                  coff_obj_read_begin_hook,
   1933                  coff_obj_symbol_new_hook,
   1934                  coff_obj_symbol_clone_hook,
   1935                  coff_adjust_symtab
   1936                };
   1937