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