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