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