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