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