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