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