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