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