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