]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gas/config/obj-coff.c
octets vs bytes changes for binutils
[thirdparty/binutils-gdb.git] / gas / config / obj-coff.c
CommitLineData
252b5132 1/* coff object file format
49309057 2 Copyright (C) 1989, 90, 91, 92, 93, 94, 95, 96, 97, 98, 1999
252b5132
RH
3 Free Software Foundation, Inc.
4
5 This file is part of GAS.
6
7 GAS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 GAS is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GAS; see the file COPYING. If not, write to the Free
19 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
20 02111-1307, USA. */
21
22#define OBJ_HEADER "obj-coff.h"
23
24#include "as.h"
25#include "obstack.h"
26#include "subsegs.h"
27
28/* I think this is probably always correct. */
29#ifndef KEEP_RELOC_INFO
30#define KEEP_RELOC_INFO
31#endif
32
33static void obj_coff_bss PARAMS ((int));
34const char *s_get_name PARAMS ((symbolS * s));
0561a208
ILT
35static void obj_coff_ln PARAMS ((int));
36static void obj_coff_def PARAMS ((int));
37static void obj_coff_endef PARAMS ((int));
38static void obj_coff_dim PARAMS ((int));
39static void obj_coff_line PARAMS ((int));
40static void obj_coff_size PARAMS ((int));
41static void obj_coff_scl PARAMS ((int));
42static void obj_coff_tag PARAMS ((int));
43static void obj_coff_val PARAMS ((int));
44static void obj_coff_type PARAMS ((int));
7a6284c4 45static void obj_coff_ident PARAMS ((int));
28428223
ILT
46#ifdef BFD_ASSEMBLER
47static void obj_coff_loc PARAMS((int));
48#endif
0561a208
ILT
49
50/* This is used to hold the symbol built by a sequence of pseudo-ops
51 from .def and .endef. */
252b5132 52static symbolS *def_symbol_in_progress;
252b5132
RH
53\f
54/* stack stuff */
55typedef struct
56 {
57 unsigned long chunk_size;
58 unsigned long element_size;
59 unsigned long size;
60 char *data;
61 unsigned long pointer;
62 }
63stack;
64
65static stack *
66stack_init (chunk_size, element_size)
67 unsigned long chunk_size;
68 unsigned long element_size;
69{
70 stack *st;
71
72 st = (stack *) malloc (sizeof (stack));
73 if (!st)
74 return 0;
75 st->data = malloc (chunk_size);
76 if (!st->data)
77 {
78 free (st);
79 return 0;
80 }
81 st->pointer = 0;
82 st->size = chunk_size;
83 st->chunk_size = chunk_size;
84 st->element_size = element_size;
85 return st;
86}
87
88#if 0
89/* Not currently used. */
90static void
91stack_delete (st)
92 stack *st;
93{
94 free (st->data);
95 free (st);
96}
97#endif
98
99static char *
100stack_push (st, element)
101 stack *st;
102 char *element;
103{
104 if (st->pointer + st->element_size >= st->size)
105 {
106 st->size += st->chunk_size;
107 if ((st->data = xrealloc (st->data, st->size)) == (char *) 0)
108 return (char *) 0;
109 }
110 memcpy (st->data + st->pointer, element, st->element_size);
111 st->pointer += st->element_size;
112 return st->data + st->pointer;
113}
114
115static char *
116stack_pop (st)
117 stack *st;
118{
119 if (st->pointer < st->element_size)
120 {
121 st->pointer = 0;
122 return (char *) 0;
123 }
124 st->pointer -= st->element_size;
125 return st->data + st->pointer;
126}
127\f
128/*
129 * Maintain a list of the tagnames of the structres.
130 */
131
132static struct hash_control *tag_hash;
133
134static void
135tag_init ()
136{
137 tag_hash = hash_new ();
138}
139
140static void
141tag_insert (name, symbolP)
142 const char *name;
143 symbolS *symbolP;
144{
145 const char *error_string;
146
147 if ((error_string = hash_jam (tag_hash, name, (char *) symbolP)))
148 {
149 as_fatal (_("Inserting \"%s\" into structure table failed: %s"),
150 name, error_string);
151 }
152}
153
154static symbolS *
155tag_find (name)
156 char *name;
157{
158#ifdef STRIP_UNDERSCORE
159 if (*name == '_')
160 name++;
161#endif /* STRIP_UNDERSCORE */
162 return (symbolS *) hash_find (tag_hash, name);
163}
164
165static symbolS *
166tag_find_or_make (name)
167 char *name;
168{
169 symbolS *symbolP;
170
171 if ((symbolP = tag_find (name)) == NULL)
172 {
173 symbolP = symbol_new (name, undefined_section,
174 0, &zero_address_frag);
175
176 tag_insert (S_GET_NAME (symbolP), symbolP);
177#ifdef BFD_ASSEMBLER
178 symbol_table_insert (symbolP);
179#endif
180 } /* not found */
181
182 return symbolP;
183}
184
185/* We accept the .bss directive to set the section for backward
186 compatibility with earlier versions of gas. */
187
188static void
189obj_coff_bss (ignore)
a04b544b 190 int ignore ATTRIBUTE_UNUSED;
252b5132
RH
191{
192 if (*input_line_pointer == '\n')
193 subseg_new (".bss", get_absolute_expression ());
194 else
195 s_lcomm (0);
196}
197
198/* Handle .weak. This is a GNU extension. */
199
200static void
201obj_coff_weak (ignore)
a04b544b 202 int ignore ATTRIBUTE_UNUSED;
252b5132
RH
203{
204 char *name;
205 int c;
206 symbolS *symbolP;
207
208 do
209 {
210 name = input_line_pointer;
211 c = get_symbol_end ();
212 symbolP = symbol_find_or_make (name);
213 *input_line_pointer = c;
214 SKIP_WHITESPACE ();
215
216#ifdef BFD_ASSEMLER
217 S_SET_WEAK (symbolP);
218#endif
219
220#ifdef TE_PE
221 S_SET_STORAGE_CLASS (symbolP, C_NT_WEAK);
222#else
223 S_SET_STORAGE_CLASS (symbolP, C_WEAKEXT);
224#endif
225
226 if (c == ',')
227 {
228 input_line_pointer++;
229 SKIP_WHITESPACE ();
230 if (*input_line_pointer == '\n')
231 c = '\n';
232 }
233 }
234 while (c == ',');
235
236 demand_empty_rest_of_line ();
237}
238
239#ifdef BFD_ASSEMBLER
240
241static void SA_SET_SYM_TAGNDX PARAMS ((symbolS *, symbolS *));
242
243#define GET_FILENAME_STRING(X) \
244((char*)(&((X)->sy_symbol.ost_auxent->x_file.x_n.x_offset))[1])
245
246/* @@ Ick. */
247static segT
248fetch_coff_debug_section ()
249{
250 static segT debug_section;
251 if (!debug_section)
252 {
253 CONST asymbol *s;
254 s = bfd_make_debug_symbol (stdoutput, (char *) 0, 0);
255 assert (s != 0);
256 debug_section = s->section;
257 }
258 return debug_section;
259}
260
261void
262SA_SET_SYM_ENDNDX (sym, val)
263 symbolS *sym;
264 symbolS *val;
265{
266 combined_entry_type *entry, *p;
267
49309057
ILT
268 entry = &coffsymbol (symbol_get_bfdsym (sym))->native[1];
269 p = coffsymbol (symbol_get_bfdsym (val))->native;
252b5132
RH
270 entry->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.p = p;
271 entry->fix_end = 1;
272}
273
274static void
275SA_SET_SYM_TAGNDX (sym, val)
276 symbolS *sym;
277 symbolS *val;
278{
279 combined_entry_type *entry, *p;
280
49309057
ILT
281 entry = &coffsymbol (symbol_get_bfdsym (sym))->native[1];
282 p = coffsymbol (symbol_get_bfdsym (val))->native;
252b5132
RH
283 entry->u.auxent.x_sym.x_tagndx.p = p;
284 entry->fix_tag = 1;
285}
286
287static int
288S_GET_DATA_TYPE (sym)
289 symbolS *sym;
290{
49309057 291 return coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_type;
252b5132
RH
292}
293
294int
295S_SET_DATA_TYPE (sym, val)
296 symbolS *sym;
297 int val;
298{
49309057 299 coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_type = val;
252b5132
RH
300 return val;
301}
302
303int
304S_GET_STORAGE_CLASS (sym)
305 symbolS *sym;
306{
49309057 307 return coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_sclass;
252b5132
RH
308}
309
310int
311S_SET_STORAGE_CLASS (sym, val)
312 symbolS *sym;
313 int val;
314{
49309057 315 coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_sclass = val;
252b5132
RH
316 return val;
317}
318
319/* Merge a debug symbol containing debug information into a normal symbol. */
320
321void
322c_symbol_merge (debug, normal)
323 symbolS *debug;
324 symbolS *normal;
325{
326 S_SET_DATA_TYPE (normal, S_GET_DATA_TYPE (debug));
327 S_SET_STORAGE_CLASS (normal, S_GET_STORAGE_CLASS (debug));
328
329 if (S_GET_NUMBER_AUXILIARY (debug) > S_GET_NUMBER_AUXILIARY (normal))
330 {
331 /* take the most we have */
332 S_SET_NUMBER_AUXILIARY (normal, S_GET_NUMBER_AUXILIARY (debug));
333 }
334
335 if (S_GET_NUMBER_AUXILIARY (debug) > 0)
336 {
337 /* Move all the auxiliary information. */
338 memcpy (SYM_AUXINFO (normal), SYM_AUXINFO (debug),
339 (S_GET_NUMBER_AUXILIARY (debug)
340 * sizeof (*SYM_AUXINFO (debug))));
341 }
342
343 /* Move the debug flags. */
344 SF_SET_DEBUG_FIELD (normal, SF_GET_DEBUG_FIELD (debug));
345}
346
347void
348c_dot_file_symbol (filename)
349 char *filename;
350{
351 symbolS *symbolP;
352
0561a208
ILT
353 /* BFD converts filename to a .file symbol with an aux entry. It
354 also handles chaining. */
252b5132
RH
355 symbolP = symbol_new (filename, bfd_abs_section_ptr, 0, &zero_address_frag);
356
357 S_SET_STORAGE_CLASS (symbolP, C_FILE);
358 S_SET_NUMBER_AUXILIARY (symbolP, 1);
359
49309057 360 symbol_get_bfdsym (symbolP)->flags = BSF_DEBUGGING;
252b5132
RH
361
362#ifndef NO_LISTING
363 {
364 extern int listing;
365 if (listing)
366 {
367 listing_source_file (filename);
368 }
369 }
370#endif
371
372 /* Make sure that the symbol is first on the symbol chain */
373 if (symbol_rootP != symbolP)
374 {
375 symbol_remove (symbolP, &symbol_rootP, &symbol_lastP);
376 symbol_insert (symbolP, symbol_rootP, &symbol_rootP, &symbol_lastP);
377 } /* if not first on the list */
378}
379
380/* Line number handling */
381
382struct line_no {
383 struct line_no *next;
384 fragS *frag;
385 alent l;
386};
387
388int coff_line_base;
389
390/* Symbol of last function, which we should hang line#s off of. */
391static symbolS *line_fsym;
392
393#define in_function() (line_fsym != 0)
394#define clear_function() (line_fsym = 0)
395#define set_function(F) (line_fsym = (F), coff_add_linesym (F))
396
397\f
398void
399coff_obj_symbol_new_hook (symbolP)
400 symbolS *symbolP;
401{
402 long sz = (OBJ_COFF_MAX_AUXENTRIES + 1) * sizeof (combined_entry_type);
403 char * s = (char *) xmalloc (sz);
404
405 memset (s, 0, sz);
49309057 406 coffsymbol (symbol_get_bfdsym (symbolP))->native = (combined_entry_type *) s;
252b5132
RH
407
408 S_SET_DATA_TYPE (symbolP, T_NULL);
409 S_SET_STORAGE_CLASS (symbolP, 0);
410 S_SET_NUMBER_AUXILIARY (symbolP, 0);
411
412 if (S_IS_STRING (symbolP))
413 SF_SET_STRING (symbolP);
414
415 if (S_IS_LOCAL (symbolP))
416 SF_SET_LOCAL (symbolP);
417}
418
419\f
420/*
421 * Handle .ln directives.
422 */
423
424static symbolS *current_lineno_sym;
425static struct line_no *line_nos;
426/* @@ Blindly assume all .ln directives will be in the .text section... */
427int coff_n_line_nos;
428
429static void
430add_lineno (frag, offset, num)
431 fragS *frag;
432 int offset;
433 int num;
434{
435 struct line_no *new_line =
436 (struct line_no *) xmalloc (sizeof (struct line_no));
437 if (!current_lineno_sym)
438 {
439 abort ();
440 }
e8a3ab75
ILT
441 if (num <= 0)
442 {
443 /* Zero is used as an end marker in the file. */
444 as_bad (_("Line numbers must be positive integers\n"));
445 return;
446 }
252b5132
RH
447 new_line->next = line_nos;
448 new_line->frag = frag;
449 new_line->l.line_number = num;
450 new_line->l.u.offset = offset;
451 line_nos = new_line;
452 coff_n_line_nos++;
453}
454
455void
456coff_add_linesym (sym)
457 symbolS *sym;
458{
459 if (line_nos)
460 {
49309057
ILT
461 coffsymbol (symbol_get_bfdsym (current_lineno_sym))->lineno =
462 (alent *) line_nos;
252b5132
RH
463 coff_n_line_nos++;
464 line_nos = 0;
465 }
466 current_lineno_sym = sym;
467}
468
469static void
470obj_coff_ln (appline)
471 int appline;
472{
473 int l;
474
475 if (! appline && def_symbol_in_progress != NULL)
476 {
477 as_warn (_(".ln pseudo-op inside .def/.endef: ignored."));
478 demand_empty_rest_of_line ();
479 return;
480 }
481
482 l = get_absolute_expression ();
483 if (!appline)
484 {
485 add_lineno (frag_now, frag_now_fix (), l);
486 }
487
488 if (appline)
489 new_logical_line ((char *) NULL, l - 1);
490
491#ifndef NO_LISTING
492 {
493 extern int listing;
494
495 if (listing)
496 {
497 if (! appline)
498 l += coff_line_base - 1;
499 listing_source_line (l);
500 }
501 }
502#endif
503
504 demand_empty_rest_of_line ();
505}
506
28428223
ILT
507/* .loc is essentially the same as .ln; parse it for assembler
508 compatibility. */
509
510static void
511obj_coff_loc (ignore)
512 int ignore ATTRIBUTE_UNUSED;
513{
514 int lineno;
515
516 /* FIXME: Why do we need this check? We need it for ECOFF, but why
517 do we need it for COFF? */
518 if (now_seg != text_section)
519 {
520 as_warn (_(".loc outside of .text"));
521 demand_empty_rest_of_line ();
522 return;
523 }
524
525 if (def_symbol_in_progress != NULL)
526 {
527 as_warn (_(".loc pseudo-op inside .def/.endef: ignored."));
528 demand_empty_rest_of_line ();
529 return;
530 }
531
532 /* Skip the file number. */
533 SKIP_WHITESPACE ();
534 get_absolute_expression ();
535 SKIP_WHITESPACE ();
536
537 lineno = get_absolute_expression ();
538
539#ifndef NO_LISTING
540 {
541 extern int listing;
542
543 if (listing)
544 {
545 lineno += coff_line_base - 1;
546 listing_source_line (lineno);
547 }
548 }
549#endif
550
551 demand_empty_rest_of_line ();
552
553 add_lineno (frag_now, frag_now_fix (), lineno);
554}
555
7a6284c4
ILT
556/* Handle the .ident pseudo-op. */
557
558static void
559obj_coff_ident (ignore)
560 int ignore ATTRIBUTE_UNUSED;
561{
562 segT current_seg = now_seg;
563 subsegT current_subseg = now_subseg;
564
565#ifdef TE_PE
566 {
567 segT sec;
568
569 /* We could put it in .comment, but that creates an extra section
570 that shouldn't be loaded into memory, which requires linker
571 changes... For now, until proven otherwise, use .rdata. */
572 sec = subseg_new (".rdata$zzz", 0);
573 bfd_set_section_flags (stdoutput, sec,
574 ((SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_DATA)
575 & bfd_applicable_section_flags (stdoutput)));
576 }
577#else
578 subseg_new (".comment", 0);
579#endif
580
581 stringer (1);
582 subseg_set (current_seg, current_subseg);
583}
584
252b5132
RH
585/*
586 * def()
587 *
588 * Handle .def directives.
589 *
590 * One might ask : why can't we symbol_new if the symbol does not
591 * already exist and fill it with debug information. Because of
592 * the C_EFCN special symbol. It would clobber the value of the
593 * function symbol before we have a chance to notice that it is
594 * a C_EFCN. And a second reason is that the code is more clear this
595 * way. (at least I think it is :-).
596 *
597 */
598
599#define SKIP_SEMI_COLON() while (*input_line_pointer++ != ';')
600#define SKIP_WHITESPACES() while (*input_line_pointer == ' ' || \
601 *input_line_pointer == '\t') \
602 input_line_pointer++;
603
604static void
605obj_coff_def (what)
c4bf532f 606 int what ATTRIBUTE_UNUSED;
252b5132
RH
607{
608 char name_end; /* Char after the end of name */
609 char *symbol_name; /* Name of the debug symbol */
610 char *symbol_name_copy; /* Temporary copy of the name */
611 unsigned int symbol_name_length;
612
613 if (def_symbol_in_progress != NULL)
614 {
615 as_warn (_(".def pseudo-op used inside of .def/.endef: ignored."));
616 demand_empty_rest_of_line ();
617 return;
618 } /* if not inside .def/.endef */
619
620 SKIP_WHITESPACES ();
621
622 symbol_name = input_line_pointer;
623#ifdef STRIP_UNDERSCORE
624 if (symbol_name[0] == '_' && symbol_name[1] != 0)
625 symbol_name++;
626#endif /* STRIP_UNDERSCORE */
627
628 name_end = get_symbol_end ();
629 symbol_name_length = strlen (symbol_name);
630 symbol_name_copy = xmalloc (symbol_name_length + 1);
631 strcpy (symbol_name_copy, symbol_name);
632#ifdef tc_canonicalize_symbol_name
633 symbol_name_copy = tc_canonicalize_symbol_name (symbol_name_copy);
634#endif
635
636 /* Initialize the new symbol */
637 def_symbol_in_progress = symbol_make (symbol_name_copy);
49309057 638 symbol_set_frag (def_symbol_in_progress, &zero_address_frag);
252b5132
RH
639 S_SET_VALUE (def_symbol_in_progress, 0);
640
641 if (S_IS_STRING (def_symbol_in_progress))
642 SF_SET_STRING (def_symbol_in_progress);
643
644 *input_line_pointer = name_end;
645
646 demand_empty_rest_of_line ();
647}
648
649unsigned int dim_index;
650
651static void
652obj_coff_endef (ignore)
c4bf532f 653 int ignore ATTRIBUTE_UNUSED;
252b5132
RH
654{
655 symbolS *symbolP;
656
657 /* DIM BUG FIX sac@cygnus.com */
658 dim_index = 0;
659 if (def_symbol_in_progress == NULL)
660 {
661 as_warn (_(".endef pseudo-op used outside of .def/.endef: ignored."));
662 demand_empty_rest_of_line ();
663 return;
664 } /* if not inside .def/.endef */
665
666 /* Set the section number according to storage class. */
667 switch (S_GET_STORAGE_CLASS (def_symbol_in_progress))
668 {
669 case C_STRTAG:
670 case C_ENTAG:
671 case C_UNTAG:
672 SF_SET_TAG (def_symbol_in_progress);
673 /* intentional fallthrough */
674 case C_FILE:
675 case C_TPDEF:
676 SF_SET_DEBUG (def_symbol_in_progress);
677 S_SET_SEGMENT (def_symbol_in_progress, fetch_coff_debug_section ());
678 break;
679
680 case C_EFCN:
681 SF_SET_LOCAL (def_symbol_in_progress); /* Do not emit this symbol. */
682 /* intentional fallthrough */
683 case C_BLOCK:
684 SF_SET_PROCESS (def_symbol_in_progress); /* Will need processing before writing */
685 /* intentional fallthrough */
686 case C_FCN:
687 {
688 CONST char *name;
689 S_SET_SEGMENT (def_symbol_in_progress, text_section);
690
49309057 691 name = S_GET_NAME (def_symbol_in_progress);
23dab925
ILT
692 if (name[0] == '.' && name[2] == 'f' && name[3] == '\0')
693 {
694 switch (name[1])
695 {
696 case 'b':
697 /* .bf */
698 if (! in_function ())
699 as_warn (_("`%s' symbol without preceding function"), name);
700 /* Will need relocating. */
701 SF_SET_PROCESS (def_symbol_in_progress);
702 clear_function ();
703 break;
704#ifdef TE_PE
705 case 'e':
706 /* .ef */
707 /* The MS compilers output the actual endline, not the
708 function-relative one... we want to match without
709 changing the assembler input. */
710 SA_SET_SYM_LNNO (def_symbol_in_progress,
711 (SA_GET_SYM_LNNO (def_symbol_in_progress)
712 + coff_line_base));
713 break;
714#endif
715 }
252b5132
RH
716 }
717 }
718 break;
719
720#ifdef C_AUTOARG
721 case C_AUTOARG:
722#endif /* C_AUTOARG */
723 case C_AUTO:
724 case C_REG:
725 case C_ARG:
726 case C_REGPARM:
727 case C_FIELD:
728 SF_SET_DEBUG (def_symbol_in_progress);
729 S_SET_SEGMENT (def_symbol_in_progress, absolute_section);
730 break;
731
732 case C_MOS:
733 case C_MOE:
734 case C_MOU:
735 case C_EOS:
736 S_SET_SEGMENT (def_symbol_in_progress, absolute_section);
737 break;
738
739 case C_EXT:
740 case C_WEAKEXT:
741#ifdef TE_PE
742 case C_NT_WEAK:
743#endif
744 case C_STAT:
745 case C_LABEL:
746 /* Valid but set somewhere else (s_comm, s_lcomm, colon) */
747 break;
748
749 default:
750 case C_USTATIC:
751 case C_EXTDEF:
752 case C_ULABEL:
753 as_warn (_("unexpected storage class %d"),
754 S_GET_STORAGE_CLASS (def_symbol_in_progress));
755 break;
756 } /* switch on storage class */
757
758 /* Now that we have built a debug symbol, try to find if we should
759 merge with an existing symbol or not. If a symbol is C_EFCN or
9690c54d
ILT
760 absolute_section or untagged SEG_DEBUG it never merges. We also
761 don't merge labels, which are in a different namespace, nor
762 symbols which have not yet been defined since they are typically
763 unique, nor do we merge tags with non-tags. */
252b5132
RH
764
765 /* Two cases for functions. Either debug followed by definition or
766 definition followed by debug. For definition first, we will
767 merge the debug symbol into the definition. For debug first, the
768 lineno entry MUST point to the definition function or else it
769 will point off into space when obj_crawl_symbol_chain() merges
770 the debug symbol into the real symbol. Therefor, let's presume
771 the debug symbol is a real function reference. */
772
773 /* FIXME-SOON If for some reason the definition label/symbol is
774 never seen, this will probably leave an undefined symbol at link
775 time. */
776
777 if (S_GET_STORAGE_CLASS (def_symbol_in_progress) == C_EFCN
9690c54d 778 || S_GET_STORAGE_CLASS (def_symbol_in_progress) == C_LABEL
252b5132
RH
779 || (!strcmp (bfd_get_section_name (stdoutput,
780 S_GET_SEGMENT (def_symbol_in_progress)),
781 "*DEBUG*")
782 && !SF_GET_TAG (def_symbol_in_progress))
783 || S_GET_SEGMENT (def_symbol_in_progress) == absolute_section
9690c54d
ILT
784 || ! symbol_constant_p (def_symbol_in_progress)
785 || (symbolP = symbol_find_base (S_GET_NAME (def_symbol_in_progress),
786 DO_NOT_STRIP)) == NULL
787 || SF_GET_TAG (def_symbol_in_progress) != SF_GET_TAG (symbolP))
252b5132 788 {
9690c54d 789 /* If it already is at the end of the symbol list, do nothing */
252b5132 790 if (def_symbol_in_progress != symbol_lastP)
9690c54d
ILT
791 {
792 symbol_remove (def_symbol_in_progress, &symbol_rootP, &symbol_lastP);
793 symbol_append (def_symbol_in_progress, symbol_lastP, &symbol_rootP,
794 &symbol_lastP);
795 }
252b5132
RH
796 }
797 else
798 {
799 /* This symbol already exists, merge the newly created symbol
800 into the old one. This is not mandatory. The linker can
801 handle duplicate symbols correctly. But I guess that it save
802 a *lot* of space if the assembly file defines a lot of
803 symbols. [loic] */
804
805 /* The debug entry (def_symbol_in_progress) is merged into the
806 previous definition. */
807
808 c_symbol_merge (def_symbol_in_progress, symbolP);
809 symbol_remove (def_symbol_in_progress, &symbol_rootP, &symbol_lastP);
810
811 def_symbol_in_progress = symbolP;
812
813 if (SF_GET_FUNCTION (def_symbol_in_progress)
814 || SF_GET_TAG (def_symbol_in_progress)
815 || S_GET_STORAGE_CLASS (def_symbol_in_progress) == C_STAT)
816 {
817 /* For functions, and tags, and static symbols, the symbol
818 *must* be where the debug symbol appears. Move the
819 existing symbol to the current place. */
820 /* If it already is at the end of the symbol list, do nothing */
821 if (def_symbol_in_progress != symbol_lastP)
822 {
823 symbol_remove (def_symbol_in_progress, &symbol_rootP, &symbol_lastP);
824 symbol_append (def_symbol_in_progress, symbol_lastP, &symbol_rootP, &symbol_lastP);
825 }
826 }
827 }
828
829 if (SF_GET_TAG (def_symbol_in_progress))
830 {
831 symbolS *oldtag;
832
833 oldtag = symbol_find_base (S_GET_NAME (def_symbol_in_progress),
834 DO_NOT_STRIP);
835 if (oldtag == NULL || ! SF_GET_TAG (oldtag))
836 tag_insert (S_GET_NAME (def_symbol_in_progress),
837 def_symbol_in_progress);
838 }
839
840 if (SF_GET_FUNCTION (def_symbol_in_progress))
841 {
842 know (sizeof (def_symbol_in_progress) <= sizeof (long));
843 set_function (def_symbol_in_progress);
844 SF_SET_PROCESS (def_symbol_in_progress);
845
846 if (symbolP == NULL)
847 {
848 /* That is, if this is the first time we've seen the
849 function... */
850 symbol_table_insert (def_symbol_in_progress);
851 } /* definition follows debug */
852 } /* Create the line number entry pointing to the function being defined */
853
854 def_symbol_in_progress = NULL;
855 demand_empty_rest_of_line ();
856}
857
858static void
859obj_coff_dim (ignore)
c4bf532f 860 int ignore ATTRIBUTE_UNUSED;
252b5132
RH
861{
862 int dim_index;
863
864 if (def_symbol_in_progress == NULL)
865 {
866 as_warn (_(".dim pseudo-op used outside of .def/.endef: ignored."));
867 demand_empty_rest_of_line ();
868 return;
869 } /* if not inside .def/.endef */
870
871 S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
872
873 for (dim_index = 0; dim_index < DIMNUM; dim_index++)
874 {
875 SKIP_WHITESPACES ();
876 SA_SET_SYM_DIMEN (def_symbol_in_progress, dim_index,
877 get_absolute_expression ());
878
879 switch (*input_line_pointer)
880 {
881 case ',':
882 input_line_pointer++;
883 break;
884
885 default:
886 as_warn (_("badly formed .dim directive ignored"));
887 /* intentional fallthrough */
888 case '\n':
889 case ';':
890 dim_index = DIMNUM;
891 break;
892 }
893 }
894
895 demand_empty_rest_of_line ();
896}
897
898static void
899obj_coff_line (ignore)
c4bf532f 900 int ignore ATTRIBUTE_UNUSED;
252b5132
RH
901{
902 int this_base;
903
904 if (def_symbol_in_progress == NULL)
905 {
906 /* Probably stabs-style line? */
907 obj_coff_ln (0);
908 return;
909 }
910
911 this_base = get_absolute_expression ();
912 if (!strcmp (".bf", S_GET_NAME (def_symbol_in_progress)))
913 coff_line_base = this_base;
914
915 S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
23dab925 916 SA_SET_SYM_LNNO (def_symbol_in_progress, this_base);
252b5132
RH
917
918 demand_empty_rest_of_line ();
919
920#ifndef NO_LISTING
921 if (strcmp (".bf", S_GET_NAME (def_symbol_in_progress)) == 0)
922 {
923 extern int listing;
924
925 if (listing)
23dab925 926 listing_source_line ((unsigned int) this_base);
252b5132
RH
927 }
928#endif
929}
930
931static void
932obj_coff_size (ignore)
c4bf532f 933 int ignore ATTRIBUTE_UNUSED;
252b5132
RH
934{
935 if (def_symbol_in_progress == NULL)
936 {
937 as_warn (_(".size pseudo-op used outside of .def/.endef ignored."));
938 demand_empty_rest_of_line ();
939 return;
940 } /* if not inside .def/.endef */
941
942 S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
943 SA_SET_SYM_SIZE (def_symbol_in_progress, get_absolute_expression ());
944 demand_empty_rest_of_line ();
945}
946
947static void
948obj_coff_scl (ignore)
c4bf532f 949 int ignore ATTRIBUTE_UNUSED;
252b5132
RH
950{
951 if (def_symbol_in_progress == NULL)
952 {
953 as_warn (_(".scl pseudo-op used outside of .def/.endef ignored."));
954 demand_empty_rest_of_line ();
955 return;
956 } /* if not inside .def/.endef */
957
958 S_SET_STORAGE_CLASS (def_symbol_in_progress, get_absolute_expression ());
959 demand_empty_rest_of_line ();
960}
961
962static void
963obj_coff_tag (ignore)
c4bf532f 964 int ignore ATTRIBUTE_UNUSED;
252b5132
RH
965{
966 char *symbol_name;
967 char name_end;
968
969 if (def_symbol_in_progress == NULL)
970 {
971 as_warn (_(".tag pseudo-op used outside of .def/.endef ignored."));
972 demand_empty_rest_of_line ();
973 return;
974 }
975
976 S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
977 symbol_name = input_line_pointer;
978 name_end = get_symbol_end ();
979
980#ifdef tc_canonicalize_symbol_name
981 symbol_name = tc_canonicalize_symbol_name (symbol_name);
982#endif
983
984 /* Assume that the symbol referred to by .tag is always defined.
985 This was a bad assumption. I've added find_or_make. xoxorich. */
986 SA_SET_SYM_TAGNDX (def_symbol_in_progress,
987 tag_find_or_make (symbol_name));
988 if (SA_GET_SYM_TAGNDX (def_symbol_in_progress) == 0L)
989 {
990 as_warn (_("tag not found for .tag %s"), symbol_name);
991 } /* not defined */
992
993 SF_SET_TAGGED (def_symbol_in_progress);
994 *input_line_pointer = name_end;
995
996 demand_empty_rest_of_line ();
997}
998
999static void
1000obj_coff_type (ignore)
c4bf532f 1001 int ignore ATTRIBUTE_UNUSED;
252b5132
RH
1002{
1003 if (def_symbol_in_progress == NULL)
1004 {
1005 as_warn (_(".type pseudo-op used outside of .def/.endef ignored."));
1006 demand_empty_rest_of_line ();
1007 return;
1008 } /* if not inside .def/.endef */
1009
1010 S_SET_DATA_TYPE (def_symbol_in_progress, get_absolute_expression ());
1011
1012 if (ISFCN (S_GET_DATA_TYPE (def_symbol_in_progress)) &&
1013 S_GET_STORAGE_CLASS (def_symbol_in_progress) != C_TPDEF)
1014 {
1015 SF_SET_FUNCTION (def_symbol_in_progress);
1016 } /* is a function */
1017
1018 demand_empty_rest_of_line ();
1019}
1020
1021static void
1022obj_coff_val (ignore)
c4bf532f 1023 int ignore ATTRIBUTE_UNUSED;
252b5132
RH
1024{
1025 if (def_symbol_in_progress == NULL)
1026 {
1027 as_warn (_(".val pseudo-op used outside of .def/.endef ignored."));
1028 demand_empty_rest_of_line ();
1029 return;
1030 } /* if not inside .def/.endef */
1031
1032 if (is_name_beginner (*input_line_pointer))
1033 {
1034 char *symbol_name = input_line_pointer;
1035 char name_end = get_symbol_end ();
1036
1037#ifdef tc_canonicalize_symbol_name
1038 symbol_name = tc_canonicalize_symbol_name (symbol_name);
1039#endif
1040 if (!strcmp (symbol_name, "."))
1041 {
49309057 1042 symbol_set_frag (def_symbol_in_progress, frag_now);
252b5132
RH
1043 S_SET_VALUE (def_symbol_in_progress, (valueT) frag_now_fix ());
1044 /* If the .val is != from the .def (e.g. statics) */
1045 }
1046 else if (strcmp (S_GET_NAME (def_symbol_in_progress), symbol_name))
1047 {
49309057
ILT
1048 expressionS exp;
1049
1050 exp.X_op = O_symbol;
1051 exp.X_add_symbol = symbol_find_or_make (symbol_name);
1052 exp.X_op_symbol = NULL;
1053 exp.X_add_number = 0;
1054 symbol_set_value_expression (def_symbol_in_progress, &exp);
252b5132
RH
1055
1056 /* If the segment is undefined when the forward reference is
1057 resolved, then copy the segment id from the forward
1058 symbol. */
1059 SF_SET_GET_SEGMENT (def_symbol_in_progress);
0561a208
ILT
1060
1061 /* FIXME: gcc can generate address expressions here in
1062 unusual cases (search for "obscure" in sdbout.c). We
1063 just ignore the offset here, thus generating incorrect
1064 debugging information. We ignore the rest of the line
1065 just below. */
252b5132 1066 }
0561a208
ILT
1067 /* Otherwise, it is the name of a non debug symbol and its value
1068 will be calculated later. */
252b5132
RH
1069 *input_line_pointer = name_end;
1070 }
1071 else
1072 {
1073 S_SET_VALUE (def_symbol_in_progress, get_absolute_expression ());
1074 } /* if symbol based */
1075
1076 demand_empty_rest_of_line ();
1077}
1078
1079void
1080coff_obj_read_begin_hook ()
1081{
1082 /* These had better be the same. Usually 18 bytes. */
1083#ifndef BFD_HEADERS
1084 know (sizeof (SYMENT) == sizeof (AUXENT));
1085 know (SYMESZ == AUXESZ);
1086#endif
1087 tag_init ();
1088}
1089
1090
1091symbolS *coff_last_function;
1092static symbolS *coff_last_bf;
1093
1094void
1095coff_frob_symbol (symp, punt)
1096 symbolS *symp;
1097 int *punt;
1098{
1099 static symbolS *last_tagP;
1100 static stack *block_stack;
1101 static symbolS *set_end;
1102 symbolS *next_set_end = NULL;
1103
1104 if (symp == &abs_symbol)
1105 {
1106 *punt = 1;
1107 return;
1108 }
1109
1110 if (current_lineno_sym)
1111 coff_add_linesym ((symbolS *) 0);
1112
1113 if (!block_stack)
1114 block_stack = stack_init (512, sizeof (symbolS*));
1115
1116 if (S_IS_WEAK (symp))
1117 {
1118#ifdef TE_PE
1119 S_SET_STORAGE_CLASS (symp, C_NT_WEAK);
1120#else
1121 S_SET_STORAGE_CLASS (symp, C_WEAKEXT);
1122#endif
1123 }
1124
1125 if (!S_IS_DEFINED (symp)
1126 && !S_IS_WEAK (symp)
1127 && S_GET_STORAGE_CLASS (symp) != C_STAT)
1128 S_SET_STORAGE_CLASS (symp, C_EXT);
1129
1130 if (!SF_GET_DEBUG (symp))
1131 {
1132 symbolS *real;
1133 if (!SF_GET_LOCAL (symp)
1134 && !SF_GET_STATICS (symp)
1135 && (real = symbol_find_base (S_GET_NAME (symp), DO_NOT_STRIP))
1136 && real != symp)
1137 {
1138 c_symbol_merge (symp, real);
1139 *punt = 1;
1140 }
1141 if (!S_IS_DEFINED (symp) && !SF_GET_LOCAL (symp))
1142 {
1143 assert (S_GET_VALUE (symp) == 0);
1144 S_SET_EXTERNAL (symp);
1145 }
1146 else if (S_GET_STORAGE_CLASS (symp) == C_NULL)
1147 {
1148 if (S_GET_SEGMENT (symp) == text_section
1149 && symp != seg_info (text_section)->sym)
1150 S_SET_STORAGE_CLASS (symp, C_LABEL);
1151 else
1152 S_SET_STORAGE_CLASS (symp, C_STAT);
1153 }
1154 if (SF_GET_PROCESS (symp))
1155 {
1156 if (S_GET_STORAGE_CLASS (symp) == C_BLOCK)
1157 {
1158 if (!strcmp (S_GET_NAME (symp), ".bb"))
1159 stack_push (block_stack, (char *) &symp);
1160 else
1161 {
1162 symbolS *begin;
1163 begin = *(symbolS **) stack_pop (block_stack);
1164 if (begin == 0)
1165 as_warn (_("mismatched .eb"));
1166 else
1167 next_set_end = begin;
1168 }
1169 }
1170 if (coff_last_function == 0 && SF_GET_FUNCTION (symp))
1171 {
1172 union internal_auxent *auxp;
1173 coff_last_function = symp;
1174 if (S_GET_NUMBER_AUXILIARY (symp) < 1)
1175 S_SET_NUMBER_AUXILIARY (symp, 1);
0561a208 1176 auxp = SYM_AUXENT (symp);
252b5132
RH
1177 memset (auxp->x_sym.x_fcnary.x_ary.x_dimen, 0,
1178 sizeof (auxp->x_sym.x_fcnary.x_ary.x_dimen));
1179 }
1180 if (S_GET_STORAGE_CLASS (symp) == C_EFCN)
1181 {
1182 if (coff_last_function == 0)
1183 as_fatal (_("C_EFCN symbol out of scope"));
1184 SA_SET_SYM_FSIZE (coff_last_function,
1185 (long) (S_GET_VALUE (symp)
1186 - S_GET_VALUE (coff_last_function)));
1187 next_set_end = coff_last_function;
1188 coff_last_function = 0;
1189 }
1190 }
1191 if (S_IS_EXTERNAL (symp))
1192 S_SET_STORAGE_CLASS (symp, C_EXT);
1193 else if (SF_GET_LOCAL (symp))
1194 *punt = 1;
1195
1196 if (SF_GET_FUNCTION (symp))
49309057 1197 symbol_get_bfdsym (symp)->flags |= BSF_FUNCTION;
252b5132
RH
1198
1199 /* more ... */
1200 }
1201
8828d862
ILT
1202 /* Double check weak symbols. */
1203 if (S_IS_WEAK (symp) && S_IS_COMMON (symp))
1204 as_bad (_("Symbol `%s' can not be both weak and common"),
1205 S_GET_NAME (symp));
1206
252b5132
RH
1207 if (SF_GET_TAG (symp))
1208 last_tagP = symp;
1209 else if (S_GET_STORAGE_CLASS (symp) == C_EOS)
1210 next_set_end = last_tagP;
1211
1212#ifdef OBJ_XCOFF
1213 /* This is pretty horrible, but we have to set *punt correctly in
1214 order to call SA_SET_SYM_ENDNDX correctly. */
809ffe0d 1215 if (! symbol_used_in_reloc_p (symp)
49309057 1216 && ((symbol_get_bfdsym (symp)->flags & BSF_SECTION_SYM) != 0
252b5132 1217 || (! S_IS_EXTERNAL (symp)
809ffe0d 1218 && ! symbol_get_tc (symp)->output
252b5132
RH
1219 && S_GET_STORAGE_CLASS (symp) != C_FILE)))
1220 *punt = 1;
1221#endif
1222
1223 if (set_end != (symbolS *) NULL
1224 && ! *punt
49309057 1225 && ((symbol_get_bfdsym (symp)->flags & BSF_NOT_AT_END) != 0
252b5132
RH
1226 || (S_IS_DEFINED (symp)
1227 && ! S_IS_COMMON (symp)
1228 && (! S_IS_EXTERNAL (symp) || SF_GET_FUNCTION (symp)))))
1229 {
1230 SA_SET_SYM_ENDNDX (set_end, symp);
1231 set_end = NULL;
1232 }
1233
a04b544b
ILT
1234 if (next_set_end != NULL)
1235 {
1236 if (set_end != NULL)
1237 as_warn ("Warning: internal error: forgetting to set endndx of %s",
1238 S_GET_NAME (set_end));
1239 set_end = next_set_end;
1240 }
252b5132
RH
1241
1242 if (! *punt
1243 && S_GET_STORAGE_CLASS (symp) == C_FCN
1244 && strcmp (S_GET_NAME (symp), ".bf") == 0)
1245 {
1246 if (coff_last_bf != NULL)
1247 SA_SET_SYM_ENDNDX (coff_last_bf, symp);
1248 coff_last_bf = symp;
1249 }
1250
49309057 1251 if (coffsymbol (symbol_get_bfdsym (symp))->lineno)
252b5132
RH
1252 {
1253 int i;
1254 struct line_no *lptr;
1255 alent *l;
1256
49309057 1257 lptr = (struct line_no *) coffsymbol (symbol_get_bfdsym (symp))->lineno;
252b5132
RH
1258 for (i = 0; lptr; lptr = lptr->next)
1259 i++;
49309057 1260 lptr = (struct line_no *) coffsymbol (symbol_get_bfdsym (symp))->lineno;
252b5132
RH
1261
1262 /* We need i entries for line numbers, plus 1 for the first
1263 entry which BFD will override, plus 1 for the last zero
1264 entry (a marker for BFD). */
1265 l = (alent *) xmalloc ((i + 2) * sizeof (alent));
49309057 1266 coffsymbol (symbol_get_bfdsym (symp))->lineno = l;
252b5132
RH
1267 l[i + 1].line_number = 0;
1268 l[i + 1].u.sym = NULL;
1269 for (; i > 0; i--)
1270 {
1271 if (lptr->frag)
1272 lptr->l.u.offset += lptr->frag->fr_address;
1273 l[i] = lptr->l;
1274 lptr = lptr->next;
1275 }
1276 }
1277}
1278
1279void
1280coff_adjust_section_syms (abfd, sec, x)
c4bf532f 1281 bfd *abfd ATTRIBUTE_UNUSED;
252b5132 1282 asection *sec;
c4bf532f 1283 PTR x ATTRIBUTE_UNUSED;
252b5132
RH
1284{
1285 symbolS *secsym;
1286 segment_info_type *seginfo = seg_info (sec);
1287 int nlnno, nrelocs = 0;
1288
1289 /* RS/6000 gas creates a .debug section manually in ppc_frob_file in
1290 tc-ppc.c. Do not get confused by it. */
1291 if (seginfo == NULL)
1292 return;
1293
1294 if (!strcmp (sec->name, ".text"))
1295 nlnno = coff_n_line_nos;
1296 else
1297 nlnno = 0;
1298 {
1299 /* @@ Hope that none of the fixups expand to more than one reloc
1300 entry... */
1301 fixS *fixp = seginfo->fix_root;
1302 while (fixp)
1303 {
1304 if (! fixp->fx_done)
1305 nrelocs++;
1306 fixp = fixp->fx_next;
1307 }
1308 }
1309 if (bfd_get_section_size_before_reloc (sec) == 0
1310 && nrelocs == 0
1311 && nlnno == 0
1312 && sec != text_section
1313 && sec != data_section
1314 && sec != bss_section)
1315 return;
1316 secsym = section_symbol (sec);
945a1a6b
ILT
1317 /* This is an estimate; we'll plug in the real value using
1318 SET_SECTION_RELOCS later */
252b5132
RH
1319 SA_SET_SCN_NRELOC (secsym, nrelocs);
1320 SA_SET_SCN_NLINNO (secsym, nlnno);
1321}
1322
1323void
1324coff_frob_file_after_relocs ()
1325{
1326 bfd_map_over_sections (stdoutput, coff_adjust_section_syms, (char*) 0);
1327}
1328
1329/*
1330 * implement the .section pseudo op:
1331 * .section name {, "flags"}
1332 * ^ ^
1333 * | +--- optional flags: 'b' for bss
1334 * | 'i' for info
1335 * +-- section name 'l' for lib
1336 * 'n' for noload
1337 * 'o' for over
1338 * 'w' for data
1339 * 'd' (apparently m88k for data)
1340 * 'x' for text
1341 * 'r' for read-only data
2dcc60be 1342 * 's' for shared data (PE)
252b5132
RH
1343 * But if the argument is not a quoted string, treat it as a
1344 * subsegment number.
1345 */
1346
1347void
1348obj_coff_section (ignore)
c4bf532f 1349 int ignore ATTRIBUTE_UNUSED;
252b5132
RH
1350{
1351 /* Strip out the section name */
1352 char *section_name;
1353 char c;
1354 char *name;
1355 unsigned int exp;
1356 flagword flags;
1357 asection *sec;
1358
1359 if (flag_mri)
1360 {
1361 char type;
1362
1363 s_mri_sect (&type);
1364 return;
1365 }
1366
1367 section_name = input_line_pointer;
1368 c = get_symbol_end ();
1369
1370 name = xmalloc (input_line_pointer - section_name + 1);
1371 strcpy (name, section_name);
1372
1373 *input_line_pointer = c;
1374
1375 SKIP_WHITESPACE ();
1376
1377 exp = 0;
5881e4aa 1378 flags = SEC_LOAD;
252b5132
RH
1379
1380 if (*input_line_pointer == ',')
1381 {
1382 ++input_line_pointer;
1383 SKIP_WHITESPACE ();
1384 if (*input_line_pointer != '"')
1385 exp = get_absolute_expression ();
1386 else
1387 {
1388 ++input_line_pointer;
1389 while (*input_line_pointer != '"'
1390 && ! is_end_of_line[(unsigned char) *input_line_pointer])
1391 {
1392 switch (*input_line_pointer)
1393 {
1394 case 'b': flags |= SEC_ALLOC; flags &=~ SEC_LOAD; break;
1395 case 'n': flags &=~ SEC_LOAD; break;
5881e4aa
ILT
1396 case 'd': flags |= SEC_DATA | SEC_LOAD; /* fall through */
1397 case 'w': flags &=~ SEC_READONLY; break;
1398 case 'x': flags |= SEC_CODE | SEC_LOAD; break;
252b5132 1399 case 'r': flags |= SEC_READONLY; break;
2dcc60be 1400 case 's': flags |= SEC_SHARED; break;
252b5132
RH
1401
1402 case 'i': /* STYP_INFO */
1403 case 'l': /* STYP_LIB */
1404 case 'o': /* STYP_OVER */
1405 as_warn (_("unsupported section attribute '%c'"),
1406 *input_line_pointer);
1407 break;
1408
1409 default:
1410 as_warn(_("unknown section attribute '%c'"),
1411 *input_line_pointer);
1412 break;
1413 }
1414 ++input_line_pointer;
1415 }
1416 if (*input_line_pointer == '"')
1417 ++input_line_pointer;
1418 }
1419 }
1420
1421 sec = subseg_new (name, (subsegT) exp);
1422
1423 if (flags != SEC_NO_FLAGS)
1424 {
1425 flagword oldflags;
1426
1427 oldflags = bfd_get_section_flags (stdoutput, sec);
1428 oldflags &= SEC_LINK_ONCE | SEC_LINK_DUPLICATES;
1429 flags |= oldflags;
1430
1431 if (! bfd_set_section_flags (stdoutput, sec, flags))
1432 as_warn (_("error setting flags for \"%s\": %s"),
1433 bfd_section_name (stdoutput, sec),
1434 bfd_errmsg (bfd_get_error ()));
1435 }
1436
1437 demand_empty_rest_of_line ();
1438}
1439
1440void
1441coff_adjust_symtab ()
1442{
1443 if (symbol_rootP == NULL
1444 || S_GET_STORAGE_CLASS (symbol_rootP) != C_FILE)
1445 c_dot_file_symbol ("fake");
1446}
1447
1448void
1449coff_frob_section (sec)
1450 segT sec;
1451{
1452 segT strsec;
1453 char *p;
1454 fragS *fragp;
1455 bfd_vma size, n_entries, mask;
1456
1457 /* The COFF back end in BFD requires that all section sizes be
1458 rounded up to multiples of the corresponding section alignments.
1459 Seems kinda silly to me, but that's the way it is. */
1460 size = bfd_get_section_size_before_reloc (sec);
1461 mask = ((bfd_vma) 1 << (bfd_vma) sec->alignment_power) - 1;
1462 if (size & mask)
1463 {
1464 size = (size + mask) & ~mask;
1465 bfd_set_section_size (stdoutput, sec, size);
1466 }
1467
1468 /* If the section size is non-zero, the section symbol needs an aux
1469 entry associated with it, indicating the size. We don't know
1470 all the values yet; coff_frob_symbol will fill them in later. */
1471 if (size != 0
1472 || sec == text_section
1473 || sec == data_section
1474 || sec == bss_section)
1475 {
1476 symbolS *secsym = section_symbol (sec);
1477
1478 S_SET_STORAGE_CLASS (secsym, C_STAT);
1479 S_SET_NUMBER_AUXILIARY (secsym, 1);
1480 SF_SET_STATICS (secsym);
1481 SA_SET_SCN_SCNLEN (secsym, size);
1482 }
1483
1484 /* @@ these should be in a "stabs.h" file, or maybe as.h */
1485#ifndef STAB_SECTION_NAME
1486#define STAB_SECTION_NAME ".stab"
1487#endif
1488#ifndef STAB_STRING_SECTION_NAME
1489#define STAB_STRING_SECTION_NAME ".stabstr"
1490#endif
1491 if (strcmp (STAB_STRING_SECTION_NAME, sec->name))
1492 return;
1493
1494 strsec = sec;
1495 sec = subseg_get (STAB_SECTION_NAME, 0);
1496 /* size is already rounded up, since other section will be listed first */
1497 size = bfd_get_section_size_before_reloc (strsec);
1498
1499 n_entries = bfd_get_section_size_before_reloc (sec) / 12 - 1;
1500
1501 /* Find first non-empty frag. It should be large enough. */
1502 fragp = seg_info (sec)->frchainP->frch_root;
1503 while (fragp && fragp->fr_fix == 0)
1504 fragp = fragp->fr_next;
1505 assert (fragp != 0 && fragp->fr_fix >= 12);
1506
1507 /* Store the values. */
1508 p = fragp->fr_literal;
1509 bfd_h_put_16 (stdoutput, n_entries, (bfd_byte *) p + 6);
1510 bfd_h_put_32 (stdoutput, size, (bfd_byte *) p + 8);
1511}
1512
1513void
1514obj_coff_init_stab_section (seg)
1515 segT seg;
1516{
1517 char *file;
1518 char *p;
1519 char *stabstr_name;
1520 unsigned int stroff;
1521
1522 /* Make space for this first symbol. */
1523 p = frag_more (12);
1524 /* Zero it out. */
1525 memset (p, 0, 12);
1526 as_where (&file, (unsigned int *) NULL);
1527 stabstr_name = (char *) alloca (strlen (seg->name) + 4);
1528 strcpy (stabstr_name, seg->name);
1529 strcat (stabstr_name, "str");
1530 stroff = get_stab_string_offset (file, stabstr_name);
1531 know (stroff == 1);
1532 md_number_to_chars (p, stroff, 4);
1533}
1534
1535#ifdef DEBUG
1536/* for debugging */
1537const char *
1538s_get_name (s)
1539 symbolS *s;
1540{
1541 return ((s == NULL) ? "(NULL)" : S_GET_NAME (s));
1542}
1543
1544void
1545symbol_dump ()
1546{
1547 symbolS *symbolP;
1548
1549 for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
1550 {
1551 printf(_("0x%lx: \"%s\" type = %ld, class = %d, segment = %d\n"),
1552 (unsigned long) symbolP,
1553 S_GET_NAME(symbolP),
1554 (long) S_GET_DATA_TYPE(symbolP),
1555 S_GET_STORAGE_CLASS(symbolP),
1556 (int) S_GET_SEGMENT(symbolP));
1557 }
1558}
1559
1560#endif /* DEBUG */
1561
1562#else /* not BFD_ASSEMBLER */
1563
1564#include "frags.h"
1565/* This is needed because we include internal bfd things. */
1566#include <time.h>
1567
1568#include "libbfd.h"
1569#include "libcoff.h"
1570
1571#ifdef TE_PE
1572#include "coff/pe.h"
1573#endif
1574
1575/* The NOP_OPCODE is for the alignment fill value. Fill with nop so
1576 that we can stick sections together without causing trouble. */
1577#ifndef NOP_OPCODE
1578#define NOP_OPCODE 0x00
1579#endif
1580
1581/* The zeroes if symbol name is longer than 8 chars */
1582#define S_SET_ZEROES(s,v) ((s)->sy_symbol.ost_entry.n_zeroes = (v))
1583
1584#define MIN(a,b) ((a) < (b)? (a) : (b))
a04b544b
ILT
1585
1586/* This vector is used to turn a gas internal segment number into a
1587 section number suitable for insertion into a coff symbol table.
1588 This must correspond to seg_info_off_by_4. */
252b5132
RH
1589
1590const short seg_N_TYPE[] =
1591{ /* in: segT out: N_TYPE bits */
1592 C_ABS_SECTION,
1593 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
1594 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
1595 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
1596 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
1597 C_UNDEF_SECTION, /* SEG_UNKNOWN */
1598 C_UNDEF_SECTION, /* SEG_GOOF */
1599 C_UNDEF_SECTION, /* SEG_EXPR */
1600 C_DEBUG_SECTION, /* SEG_DEBUG */
1601 C_NTV_SECTION, /* SEG_NTV */
1602 C_PTV_SECTION, /* SEG_PTV */
1603 C_REGISTER_SECTION, /* SEG_REGISTER */
1604};
1605
1606int function_lineoff = -1; /* Offset in line#s where the last function
1607 started (the odd entry for line #0) */
1608
1609/* structure used to keep the filenames which
1610 are too long around so that we can stick them
1611 into the string table */
1612struct filename_list
1613{
1614 char *filename;
1615 struct filename_list *next;
1616};
1617
1618static struct filename_list *filename_list_head;
1619static struct filename_list *filename_list_tail;
1620
1621static symbolS *last_line_symbol;
1622
1623/* Add 4 to the real value to get the index and compensate the
1624 negatives. This vector is used by S_GET_SEGMENT to turn a coff
1625 section number into a segment number
1626*/
1627static symbolS *previous_file_symbol;
1628void c_symbol_merge ();
1629static int line_base;
1630
1631symbolS *c_section_symbol ();
1632bfd *abfd;
1633
1634static void fixup_segment PARAMS ((segment_info_type *segP,
1635 segT this_segment_type));
1636
1637
1638static void fixup_mdeps PARAMS ((fragS *,
1639 object_headers *,
1640 segT));
1641
1642
1643static void fill_section PARAMS ((bfd * abfd,
1644 object_headers *,
1645 unsigned long *));
1646
1647
1648static int c_line_new PARAMS ((symbolS * symbol, long paddr,
1649 int line_number,
1650 fragS * frag));
1651
1652
1653static void w_symbols PARAMS ((bfd * abfd, char *where,
1654 symbolS * symbol_rootP));
1655
1656static void adjust_stab_section PARAMS ((bfd *abfd, segT seg));
1657
1658static void obj_coff_lcomm PARAMS ((int));
1659static void obj_coff_text PARAMS ((int));
1660static void obj_coff_data PARAMS ((int));
252b5132
RH
1661void obj_coff_section PARAMS ((int));
1662
a04b544b 1663/* When not using BFD_ASSEMBLER, we permit up to 40 sections.
252b5132 1664
a04b544b
ILT
1665 This array maps a COFF section number into a gas section number.
1666 Because COFF uses negative section numbers, you must add 4 to the
1667 COFF section number when indexing into this array; this is done via
1668 the SEG_INFO_FROM_SECTION_NUMBER macro. This must correspond to
1669 seg_N_TYPE. */
252b5132 1670
a04b544b 1671static const segT seg_info_off_by_4[] =
252b5132 1672{
a04b544b
ILT
1673 SEG_PTV,
1674 SEG_NTV,
1675 SEG_DEBUG,
1676 SEG_ABSOLUTE,
1677 SEG_UNKNOWN,
1678 SEG_E0, SEG_E1, SEG_E2, SEG_E3, SEG_E4,
1679 SEG_E5, SEG_E6, SEG_E7, SEG_E8, SEG_E9,
1680 SEG_E10, SEG_E11, SEG_E12, SEG_E13, SEG_E14,
1681 SEG_E15, SEG_E16, SEG_E17, SEG_E18, SEG_E19,
1682 SEG_E20, SEG_E21, SEG_E22, SEG_E23, SEG_E24,
1683 SEG_E25, SEG_E26, SEG_E27, SEG_E28, SEG_E29,
1684 SEG_E30, SEG_E31, SEG_E32, SEG_E33, SEG_E34,
1685 SEG_E35, SEG_E36, SEG_E37, SEG_E38, SEG_E39,
1686 (segT) 40,
1687 (segT) 41,
1688 (segT) 42,
1689 (segT) 43,
1690 (segT) 44,
1691 (segT) 45,
1692 (segT) 0,
1693 (segT) 0,
1694 (segT) 0,
1695 SEG_REGISTER
252b5132
RH
1696};
1697
252b5132
RH
1698#define SEG_INFO_FROM_SECTION_NUMBER(x) (seg_info_off_by_4[(x)+4])
1699
1700static relax_addressT
1701relax_align (address, alignment)
1702 relax_addressT address;
1703 long alignment;
1704{
1705 relax_addressT mask;
1706 relax_addressT new_address;
1707
1708 mask = ~((~0) << alignment);
1709 new_address = (address + mask) & (~mask);
1710 return (new_address - address);
1711}
1712
1713
1714segT
1715s_get_segment (x)
1716 symbolS * x;
1717{
a04b544b 1718 return SEG_INFO_FROM_SECTION_NUMBER (x->sy_symbol.ost_entry.n_scnum);
252b5132
RH
1719}
1720
1721/* calculate the size of the frag chain and fill in the section header
1722 to contain all of it, also fill in the addr of the sections */
1723static unsigned int
1724size_section (abfd, idx)
a04b544b 1725 bfd *abfd ATTRIBUTE_UNUSED;
252b5132
RH
1726 unsigned int idx;
1727{
1728
1729 unsigned int size = 0;
1730 fragS *frag = segment_info[idx].frchainP->frch_root;
1731 while (frag)
1732 {
1733 size = frag->fr_address;
1734 if (frag->fr_address != size)
1735 {
1736 fprintf (stderr, _("Out of step\n"));
1737 size = frag->fr_address;
1738 }
1739
1740 switch (frag->fr_type)
1741 {
1742#ifdef TC_COFF_SIZEMACHDEP
1743 case rs_machine_dependent:
1744 size += TC_COFF_SIZEMACHDEP (frag);
1745 break;
1746#endif
1747 case rs_space:
1748 assert (frag->fr_symbol == 0);
1749 case rs_fill:
1750 case rs_org:
1751 size += frag->fr_fix;
1752 size += frag->fr_offset * frag->fr_var;
1753 break;
1754 case rs_align:
1755 case rs_align_code:
1756 {
1757 addressT off;
1758
1759 size += frag->fr_fix;
1760 off = relax_align (size, frag->fr_offset);
1761 if (frag->fr_subtype != 0 && off > frag->fr_subtype)
1762 off = 0;
1763 size += off;
1764 }
1765 break;
1766 default:
1767 BAD_CASE (frag->fr_type);
1768 break;
1769 }
1770 frag = frag->fr_next;
1771 }
1772 segment_info[idx].scnhdr.s_size = size;
1773 return size;
1774}
1775
1776
1777static unsigned int
1778count_entries_in_chain (idx)
1779 unsigned int idx;
1780{
1781 unsigned int nrelocs;
1782 fixS *fixup_ptr;
1783
1784 /* Count the relocations */
1785 fixup_ptr = segment_info[idx].fix_root;
1786 nrelocs = 0;
1787 while (fixup_ptr != (fixS *) NULL)
1788 {
1789 if (fixup_ptr->fx_done == 0 && TC_COUNT_RELOC (fixup_ptr))
1790 {
1791#ifdef TC_A29K
1792 if (fixup_ptr->fx_r_type == RELOC_CONSTH)
1793 nrelocs += 2;
1794 else
1795 nrelocs++;
1796#else
1797 nrelocs++;
1798#endif
1799 }
1800
1801 fixup_ptr = fixup_ptr->fx_next;
1802 }
1803 return nrelocs;
1804}
1805
1806#ifdef TE_AUX
1807
1808static int compare_external_relocs PARAMS ((const PTR, const PTR));
1809
1810/* AUX's ld expects relocations to be sorted */
1811static int
1812compare_external_relocs (x, y)
1813 const PTR x;
1814 const PTR y;
1815{
1816 struct external_reloc *a = (struct external_reloc *) x;
1817 struct external_reloc *b = (struct external_reloc *) y;
1818 bfd_vma aadr = bfd_getb32 (a->r_vaddr);
1819 bfd_vma badr = bfd_getb32 (b->r_vaddr);
1820 return (aadr < badr ? -1 : badr < aadr ? 1 : 0);
1821}
1822
1823#endif
1824
1825/* output all the relocations for a section */
1826void
1827do_relocs_for (abfd, h, file_cursor)
1828 bfd * abfd;
1829 object_headers * h;
1830 unsigned long *file_cursor;
1831{
1832 unsigned int nrelocs;
1833 unsigned int idx;
1834 unsigned long reloc_start = *file_cursor;
1835
1836 for (idx = SEG_E0; idx < SEG_LAST; idx++)
1837 {
1838 if (segment_info[idx].scnhdr.s_name[0])
1839 {
1840 struct external_reloc *ext_ptr;
1841 struct external_reloc *external_reloc_vec;
1842 unsigned int external_reloc_size;
1843 unsigned int base = segment_info[idx].scnhdr.s_paddr;
1844 fixS *fix_ptr = segment_info[idx].fix_root;
1845 nrelocs = count_entries_in_chain (idx);
1846
1847 if (nrelocs)
1848 /* Bypass this stuff if no relocs. This also incidentally
1849 avoids a SCO bug, where free(malloc(0)) tends to crash. */
1850 {
1851 external_reloc_size = nrelocs * RELSZ;
1852 external_reloc_vec =
1853 (struct external_reloc *) malloc (external_reloc_size);
1854
1855 ext_ptr = external_reloc_vec;
1856
1857 /* Fill in the internal coff style reloc struct from the
1858 internal fix list. */
1859 while (fix_ptr)
1860 {
1861 struct internal_reloc intr;
1862
1863 /* Only output some of the relocations */
1864 if (fix_ptr->fx_done == 0 && TC_COUNT_RELOC (fix_ptr))
1865 {
1866#ifdef TC_RELOC_MANGLE
1867 TC_RELOC_MANGLE (&segment_info[idx], fix_ptr, &intr,
1868 base);
1869
1870#else
1871 symbolS *dot;
1872 symbolS *symbol_ptr = fix_ptr->fx_addsy;
1873
1874 intr.r_type = TC_COFF_FIX2RTYPE (fix_ptr);
1875 intr.r_vaddr =
1876 base + fix_ptr->fx_frag->fr_address + fix_ptr->fx_where;
1877
1878#ifdef TC_KEEP_FX_OFFSET
1879 intr.r_offset = fix_ptr->fx_offset;
1880#else
1881 intr.r_offset = 0;
1882#endif
1883
1884 while (symbol_ptr->sy_value.X_op == O_symbol
1885 && (! S_IS_DEFINED (symbol_ptr)
1886 || S_IS_COMMON (symbol_ptr)))
1887 {
1888 symbolS *n;
1889
1890 /* We must avoid looping, as that can occur
1891 with a badly written program. */
1892 n = symbol_ptr->sy_value.X_add_symbol;
1893 if (n == symbol_ptr)
1894 break;
1895 symbol_ptr = n;
1896 }
1897
1898 /* Turn the segment of the symbol into an offset. */
1899 if (symbol_ptr)
1900 {
1901 resolve_symbol_value (symbol_ptr, 1);
1902 if (! symbol_ptr->sy_resolved)
1903 {
1904 char *file;
1905 unsigned int line;
1906
1907 if (expr_symbol_where (symbol_ptr, &file, &line))
1908 as_bad_where (file, line,
1909 _("unresolved relocation"));
1910 else
1911 as_bad (_("bad relocation: symbol `%s' not in symbol table"),
1912 S_GET_NAME (symbol_ptr));
1913 }
1914 dot = segment_info[S_GET_SEGMENT (symbol_ptr)].dot;
1915 if (dot)
1916 {
1917 intr.r_symndx = dot->sy_number;
1918 }
1919 else
1920 {
1921 intr.r_symndx = symbol_ptr->sy_number;
1922 }
1923
1924 }
1925 else
1926 {
1927 intr.r_symndx = -1;
1928 }
1929#endif
1930
1931 (void) bfd_coff_swap_reloc_out (abfd, &intr, ext_ptr);
1932 ext_ptr++;
1933
1934#if defined(TC_A29K)
1935
1936 /* The 29k has a special kludge for the high 16 bit
1937 reloc. Two relocations are emited, R_IHIHALF,
1938 and R_IHCONST. The second one doesn't contain a
1939 symbol, but uses the value for offset. */
1940
1941 if (intr.r_type == R_IHIHALF)
1942 {
1943 /* now emit the second bit */
1944 intr.r_type = R_IHCONST;
1945 intr.r_symndx = fix_ptr->fx_addnumber;
1946 (void) bfd_coff_swap_reloc_out (abfd, &intr, ext_ptr);
1947 ext_ptr++;
1948 }
1949#endif
1950 }
1951
1952 fix_ptr = fix_ptr->fx_next;
1953 }
1954
1955#ifdef TE_AUX
1956 /* Sort the reloc table */
1957 qsort ((PTR) external_reloc_vec, nrelocs,
1958 sizeof (struct external_reloc), compare_external_relocs);
1959#endif
1960
1961 /* Write out the reloc table */
1962 bfd_write ((PTR) external_reloc_vec, 1, external_reloc_size,
1963 abfd);
1964 free (external_reloc_vec);
1965
1966 /* Fill in section header info. */
1967 segment_info[idx].scnhdr.s_relptr = *file_cursor;
1968 *file_cursor += external_reloc_size;
1969 segment_info[idx].scnhdr.s_nreloc = nrelocs;
1970 }
1971 else
1972 {
1973 /* No relocs */
1974 segment_info[idx].scnhdr.s_relptr = 0;
1975 }
1976 }
1977 }
1978 /* Set relocation_size field in file headers */
1979 H_SET_RELOCATION_SIZE (h, *file_cursor - reloc_start, 0);
1980}
1981
1982
1983/* run through a frag chain and write out the data to go with it, fill
1984 in the scnhdrs with the info on the file postions
1985*/
1986static void
1987fill_section (abfd, h, file_cursor)
1988 bfd * abfd;
a04b544b 1989 object_headers *h ATTRIBUTE_UNUSED;
252b5132
RH
1990 unsigned long *file_cursor;
1991{
1992
1993 unsigned int i;
1994 unsigned int paddr = 0;
1995
1996 for (i = SEG_E0; i < SEG_UNKNOWN; i++)
1997 {
1998 unsigned int offset = 0;
1999 struct internal_scnhdr *s = &(segment_info[i].scnhdr);
2000
2001 PROGRESS (1);
2002
2003 if (s->s_name[0])
2004 {
2005 fragS *frag = segment_info[i].frchainP->frch_root;
2006 char *buffer;
2007
2008 if (s->s_size == 0)
2009 s->s_scnptr = 0;
2010 else
2011 {
2012 buffer = xmalloc (s->s_size);
2013 s->s_scnptr = *file_cursor;
2014 }
2015 know (s->s_paddr == paddr);
2016
2017 if (strcmp (s->s_name, ".text") == 0)
2018 s->s_flags |= STYP_TEXT;
2019 else if (strcmp (s->s_name, ".data") == 0)
2020 s->s_flags |= STYP_DATA;
2021 else if (strcmp (s->s_name, ".bss") == 0)
2022 {
2023 s->s_scnptr = 0;
2024 s->s_flags |= STYP_BSS;
2025
2026 /* @@ Should make the i386 and a29k coff targets define
2027 COFF_NOLOAD_PROBLEM, and have only one test here. */
2028#ifndef TC_I386
2029#ifndef TC_A29K
2030#ifndef COFF_NOLOAD_PROBLEM
2031 /* Apparently the SVR3 linker (and exec syscall) and UDI
2032 mondfe progrem are confused by noload sections. */
2033 s->s_flags |= STYP_NOLOAD;
2034#endif
2035#endif
2036#endif
2037 }
2038 else if (strcmp (s->s_name, ".lit") == 0)
2039 s->s_flags = STYP_LIT | STYP_TEXT;
2040 else if (strcmp (s->s_name, ".init") == 0)
2041 s->s_flags |= STYP_TEXT;
2042 else if (strcmp (s->s_name, ".fini") == 0)
2043 s->s_flags |= STYP_TEXT;
2044 else if (strncmp (s->s_name, ".comment", 8) == 0)
2045 s->s_flags |= STYP_INFO;
2046
2047 while (frag)
2048 {
2049 unsigned int fill_size;
2050 switch (frag->fr_type)
2051 {
2052 case rs_machine_dependent:
2053 if (frag->fr_fix)
2054 {
2055 memcpy (buffer + frag->fr_address,
2056 frag->fr_literal,
2057 (unsigned int) frag->fr_fix);
2058 offset += frag->fr_fix;
2059 }
2060
2061 break;
2062 case rs_space:
2063 assert (frag->fr_symbol == 0);
2064 case rs_fill:
2065 case rs_align:
2066 case rs_align_code:
2067 case rs_org:
2068 if (frag->fr_fix)
2069 {
2070 memcpy (buffer + frag->fr_address,
2071 frag->fr_literal,
2072 (unsigned int) frag->fr_fix);
2073 offset += frag->fr_fix;
2074 }
2075
2076 fill_size = frag->fr_var;
2077 if (fill_size && frag->fr_offset > 0)
2078 {
2079 unsigned int count;
2080 unsigned int off = frag->fr_fix;
2081 for (count = frag->fr_offset; count; count--)
2082 {
2083 if (fill_size + frag->fr_address + off <= s->s_size)
2084 {
2085 memcpy (buffer + frag->fr_address + off,
2086 frag->fr_literal + frag->fr_fix,
2087 fill_size);
2088 off += fill_size;
2089 offset += fill_size;
2090 }
2091 }
2092 }
2093 break;
2094 case rs_broken_word:
2095 break;
2096 default:
2097 abort ();
2098 }
2099 frag = frag->fr_next;
2100 }
2101
2102 if (s->s_size != 0)
2103 {
2104 if (s->s_scnptr != 0)
2105 {
2106 bfd_write (buffer, s->s_size, 1, abfd);
2107 *file_cursor += s->s_size;
2108 }
2109 free (buffer);
2110 }
2111 paddr += s->s_size;
2112 }
2113 }
2114}
2115
2116/* Coff file generation & utilities */
2117
2118static void
2119coff_header_append (abfd, h)
2120 bfd * abfd;
2121 object_headers * h;
2122{
2123 unsigned int i;
2124 char buffer[1000];
2125 char buffero[1000];
2126#ifdef COFF_LONG_SECTION_NAMES
2127 unsigned long string_size = 4;
2128#endif
2129
2130 bfd_seek (abfd, 0, 0);
2131
2132#ifndef OBJ_COFF_OMIT_OPTIONAL_HEADER
2133 H_SET_MAGIC_NUMBER (h, COFF_MAGIC);
2134 H_SET_VERSION_STAMP (h, 0);
2135 H_SET_ENTRY_POINT (h, 0);
2136 H_SET_TEXT_START (h, segment_info[SEG_E0].frchainP->frch_root->fr_address);
2137 H_SET_DATA_START (h, segment_info[SEG_E1].frchainP->frch_root->fr_address);
2138 H_SET_SIZEOF_OPTIONAL_HEADER (h, bfd_coff_swap_aouthdr_out(abfd, &h->aouthdr,
2139 buffero));
2140#else /* defined (OBJ_COFF_OMIT_OPTIONAL_HEADER) */
2141 H_SET_SIZEOF_OPTIONAL_HEADER (h, 0);
2142#endif /* defined (OBJ_COFF_OMIT_OPTIONAL_HEADER) */
2143
2144 i = bfd_coff_swap_filehdr_out (abfd, &h->filehdr, buffer);
2145
2146 bfd_write (buffer, i, 1, abfd);
2147 bfd_write (buffero, H_GET_SIZEOF_OPTIONAL_HEADER (h), 1, abfd);
2148
2149 for (i = SEG_E0; i < SEG_LAST; i++)
2150 {
2151 if (segment_info[i].scnhdr.s_name[0])
2152 {
2153 unsigned int size;
2154
2155#ifdef COFF_LONG_SECTION_NAMES
2156 /* Support long section names as found in PE. This code
2157 must coordinate with that in write_object_file and
2158 w_strings. */
2159 if (strlen (segment_info[i].name) > SCNNMLEN)
2160 {
2161 memset (segment_info[i].scnhdr.s_name, 0, SCNNMLEN);
2162 sprintf (segment_info[i].scnhdr.s_name, "/%lu", string_size);
2163 string_size += strlen (segment_info[i].name) + 1;
2164 }
2165#endif
2166
2167 size = bfd_coff_swap_scnhdr_out (abfd,
2168 &(segment_info[i].scnhdr),
2169 buffer);
2170 if (size == 0)
2171 as_bad (_("bfd_coff_swap_scnhdr_out failed"));
2172 bfd_write (buffer, size, 1, abfd);
2173 }
2174 }
2175}
2176
2177
2178char *
2179symbol_to_chars (abfd, where, symbolP)
2180 bfd * abfd;
2181 char *where;
2182 symbolS * symbolP;
2183{
2184 unsigned int numaux = symbolP->sy_symbol.ost_entry.n_numaux;
2185 unsigned int i;
2186 valueT val;
2187
2188 /* Turn any symbols with register attributes into abs symbols */
2189 if (S_GET_SEGMENT (symbolP) == reg_section)
2190 {
2191 S_SET_SEGMENT (symbolP, absolute_section);
2192 }
2193 /* At the same time, relocate all symbols to their output value */
2194
2195#ifndef TE_PE
2196 val = (segment_info[S_GET_SEGMENT (symbolP)].scnhdr.s_paddr
2197 + S_GET_VALUE (symbolP));
2198#else
2199 val = S_GET_VALUE (symbolP);
2200#endif
2201
2202 S_SET_VALUE (symbolP, val);
2203
2204 symbolP->sy_symbol.ost_entry.n_value = val;
2205
2206 where += bfd_coff_swap_sym_out (abfd, &symbolP->sy_symbol.ost_entry,
2207 where);
2208
2209 for (i = 0; i < numaux; i++)
2210 {
2211 where += bfd_coff_swap_aux_out (abfd,
2212 &symbolP->sy_symbol.ost_auxent[i],
2213 S_GET_DATA_TYPE (symbolP),
2214 S_GET_STORAGE_CLASS (symbolP),
2215 i, numaux, where);
2216 }
2217 return where;
2218
2219}
2220
2221void
2222coff_obj_symbol_new_hook (symbolP)
2223 symbolS *symbolP;
2224{
2225 char underscore = 0; /* Symbol has leading _ */
2226
2227 /* Effective symbol */
2228 /* Store the pointer in the offset. */
2229 S_SET_ZEROES (symbolP, 0L);
2230 S_SET_DATA_TYPE (symbolP, T_NULL);
2231 S_SET_STORAGE_CLASS (symbolP, 0);
2232 S_SET_NUMBER_AUXILIARY (symbolP, 0);
2233 /* Additional information */
2234 symbolP->sy_symbol.ost_flags = 0;
2235 /* Auxiliary entries */
2236 memset ((char *) &symbolP->sy_symbol.ost_auxent[0], 0, AUXESZ);
2237
2238 if (S_IS_STRING (symbolP))
2239 SF_SET_STRING (symbolP);
2240 if (!underscore && S_IS_LOCAL (symbolP))
2241 SF_SET_LOCAL (symbolP);
2242}
2243
2244/*
2245 * Handle .ln directives.
2246 */
2247
2248static void
2249obj_coff_ln (appline)
2250 int appline;
2251{
2252 int l;
2253
2254 if (! appline && def_symbol_in_progress != NULL)
2255 {
2256 as_warn (_(".ln pseudo-op inside .def/.endef: ignored."));
2257 demand_empty_rest_of_line ();
2258 return;
2259 } /* wrong context */
2260
2261 l = get_absolute_expression ();
2262 c_line_new (0, frag_now_fix (), l, frag_now);
2263
2264 if (appline)
2265 new_logical_line ((char *) NULL, l - 1);
2266
2267#ifndef NO_LISTING
2268 {
2269 extern int listing;
2270
2271 if (listing)
2272 {
2273 if (! appline)
2274 l += line_base - 1;
2275 listing_source_line ((unsigned int) l);
2276 }
2277
2278 }
2279#endif
2280 demand_empty_rest_of_line ();
2281}
2282
2283/*
2284 * def()
2285 *
2286 * Handle .def directives.
2287 *
2288 * One might ask : why can't we symbol_new if the symbol does not
2289 * already exist and fill it with debug information. Because of
2290 * the C_EFCN special symbol. It would clobber the value of the
2291 * function symbol before we have a chance to notice that it is
2292 * a C_EFCN. And a second reason is that the code is more clear this
2293 * way. (at least I think it is :-).
2294 *
2295 */
2296
2297#define SKIP_SEMI_COLON() while (*input_line_pointer++ != ';')
2298#define SKIP_WHITESPACES() while (*input_line_pointer == ' ' || \
2299 *input_line_pointer == '\t') \
2300 input_line_pointer++;
2301
2302static void
2303obj_coff_def (what)
a04b544b 2304 int what ATTRIBUTE_UNUSED;
252b5132
RH
2305{
2306 char name_end; /* Char after the end of name */
2307 char *symbol_name; /* Name of the debug symbol */
2308 char *symbol_name_copy; /* Temporary copy of the name */
2309 unsigned int symbol_name_length;
2310
2311 if (def_symbol_in_progress != NULL)
2312 {
2313 as_warn (_(".def pseudo-op used inside of .def/.endef: ignored."));
2314 demand_empty_rest_of_line ();
2315 return;
2316 } /* if not inside .def/.endef */
2317
2318 SKIP_WHITESPACES ();
2319
2320 def_symbol_in_progress = (symbolS *) obstack_alloc (&notes, sizeof (*def_symbol_in_progress));
2321 memset (def_symbol_in_progress, 0, sizeof (*def_symbol_in_progress));
2322
2323 symbol_name = input_line_pointer;
2324 name_end = get_symbol_end ();
2325 symbol_name_length = strlen (symbol_name);
2326 symbol_name_copy = xmalloc (symbol_name_length + 1);
2327 strcpy (symbol_name_copy, symbol_name);
2328#ifdef tc_canonicalize_symbol_name
2329 symbol_name_copy = tc_canonicalize_symbol_name (symbol_name_copy);
2330#endif
2331
2332 /* Initialize the new symbol */
2333#ifdef STRIP_UNDERSCORE
2334 S_SET_NAME (def_symbol_in_progress, (*symbol_name_copy == '_'
2335 ? symbol_name_copy + 1
2336 : symbol_name_copy));
2337#else /* STRIP_UNDERSCORE */
2338 S_SET_NAME (def_symbol_in_progress, symbol_name_copy);
2339#endif /* STRIP_UNDERSCORE */
2340 /* free(symbol_name_copy); */
2341 def_symbol_in_progress->sy_name_offset = (unsigned long) ~0;
2342 def_symbol_in_progress->sy_number = ~0;
2343 def_symbol_in_progress->sy_frag = &zero_address_frag;
2344 S_SET_VALUE (def_symbol_in_progress, 0);
2345
2346 if (S_IS_STRING (def_symbol_in_progress))
2347 SF_SET_STRING (def_symbol_in_progress);
2348
2349 *input_line_pointer = name_end;
2350
2351 demand_empty_rest_of_line ();
2352}
2353
2354unsigned int dim_index;
2355
2356
2357static void
2358obj_coff_endef (ignore)
a04b544b 2359 int ignore ATTRIBUTE_UNUSED;
252b5132
RH
2360{
2361 symbolS *symbolP = 0;
2362 /* DIM BUG FIX sac@cygnus.com */
2363 dim_index = 0;
2364 if (def_symbol_in_progress == NULL)
2365 {
2366 as_warn (_(".endef pseudo-op used outside of .def/.endef: ignored."));
2367 demand_empty_rest_of_line ();
2368 return;
2369 } /* if not inside .def/.endef */
2370
2371 /* Set the section number according to storage class. */
2372 switch (S_GET_STORAGE_CLASS (def_symbol_in_progress))
2373 {
2374 case C_STRTAG:
2375 case C_ENTAG:
2376 case C_UNTAG:
2377 SF_SET_TAG (def_symbol_in_progress);
2378 /* intentional fallthrough */
2379 case C_FILE:
2380 case C_TPDEF:
2381 SF_SET_DEBUG (def_symbol_in_progress);
2382 S_SET_SEGMENT (def_symbol_in_progress, SEG_DEBUG);
2383 break;
2384
2385 case C_EFCN:
2386 SF_SET_LOCAL (def_symbol_in_progress); /* Do not emit this symbol. */
2387 /* intentional fallthrough */
2388 case C_BLOCK:
2389 SF_SET_PROCESS (def_symbol_in_progress); /* Will need processing before writing */
2390 /* intentional fallthrough */
2391 case C_FCN:
2392 S_SET_SEGMENT (def_symbol_in_progress, SEG_E0);
2393
2394 if (strcmp (S_GET_NAME (def_symbol_in_progress), ".bf") == 0)
2395 { /* .bf */
2396 if (function_lineoff < 0)
2397 {
2398 fprintf (stderr, _("`.bf' symbol without preceding function\n"));
2399 } /* missing function symbol */
2400 SA_GET_SYM_LNNOPTR (last_line_symbol) = function_lineoff;
2401
2402 SF_SET_PROCESS (last_line_symbol);
2403 SF_SET_ADJ_LNNOPTR (last_line_symbol);
2404 SF_SET_PROCESS (def_symbol_in_progress);
2405 function_lineoff = -1;
2406 }
2407 /* Value is always set to . */
2408 def_symbol_in_progress->sy_frag = frag_now;
2409 S_SET_VALUE (def_symbol_in_progress, (valueT) frag_now_fix ());
2410 break;
2411
2412#ifdef C_AUTOARG
2413 case C_AUTOARG:
2414#endif /* C_AUTOARG */
2415 case C_AUTO:
2416 case C_REG:
2417 case C_MOS:
2418 case C_MOE:
2419 case C_MOU:
2420 case C_ARG:
2421 case C_REGPARM:
2422 case C_FIELD:
2423 case C_EOS:
2424 SF_SET_DEBUG (def_symbol_in_progress);
2425 S_SET_SEGMENT (def_symbol_in_progress, absolute_section);
2426 break;
2427
2428 case C_EXT:
2429 case C_WEAKEXT:
2430#ifdef TE_PE
2431 case C_NT_WEAK:
2432#endif
2433 case C_STAT:
2434 case C_LABEL:
2435 /* Valid but set somewhere else (s_comm, s_lcomm, colon) */
2436 break;
2437
2438 case C_USTATIC:
2439 case C_EXTDEF:
2440 case C_ULABEL:
2441 as_warn (_("unexpected storage class %d"), S_GET_STORAGE_CLASS (def_symbol_in_progress));
2442 break;
2443 } /* switch on storage class */
2444
2445 /* Now that we have built a debug symbol, try to find if we should
2446 merge with an existing symbol or not. If a symbol is C_EFCN or
2447 absolute_section or untagged SEG_DEBUG it never merges. We also
2448 don't merge labels, which are in a different namespace, nor
2449 symbols which have not yet been defined since they are typically
2450 unique, nor do we merge tags with non-tags. */
2451
2452 /* Two cases for functions. Either debug followed by definition or
2453 definition followed by debug. For definition first, we will
2454 merge the debug symbol into the definition. For debug first, the
2455 lineno entry MUST point to the definition function or else it
2456 will point off into space when crawl_symbols() merges the debug
2457 symbol into the real symbol. Therefor, let's presume the debug
2458 symbol is a real function reference. */
2459
2460 /* FIXME-SOON If for some reason the definition label/symbol is
2461 never seen, this will probably leave an undefined symbol at link
2462 time. */
2463
2464 if (S_GET_STORAGE_CLASS (def_symbol_in_progress) == C_EFCN
2465 || S_GET_STORAGE_CLASS (def_symbol_in_progress) == C_LABEL
2466 || (S_GET_SEGMENT (def_symbol_in_progress) == SEG_DEBUG
2467 && !SF_GET_TAG (def_symbol_in_progress))
2468 || S_GET_SEGMENT (def_symbol_in_progress) == absolute_section
2469 || def_symbol_in_progress->sy_value.X_op != O_constant
2470 || (symbolP = symbol_find_base (S_GET_NAME (def_symbol_in_progress), DO_NOT_STRIP)) == NULL
2471 || (SF_GET_TAG (def_symbol_in_progress) != SF_GET_TAG (symbolP)))
2472 {
2473 symbol_append (def_symbol_in_progress, symbol_lastP, &symbol_rootP,
2474 &symbol_lastP);
2475 }
2476 else
2477 {
2478 /* This symbol already exists, merge the newly created symbol
2479 into the old one. This is not mandatory. The linker can
2480 handle duplicate symbols correctly. But I guess that it save
2481 a *lot* of space if the assembly file defines a lot of
2482 symbols. [loic] */
2483
2484 /* The debug entry (def_symbol_in_progress) is merged into the
2485 previous definition. */
2486
2487 c_symbol_merge (def_symbol_in_progress, symbolP);
2488 /* FIXME-SOON Should *def_symbol_in_progress be free'd? xoxorich. */
2489 def_symbol_in_progress = symbolP;
2490
2491 if (SF_GET_FUNCTION (def_symbol_in_progress)
2492 || SF_GET_TAG (def_symbol_in_progress)
2493 || S_GET_STORAGE_CLASS (def_symbol_in_progress) == C_STAT)
2494 {
2495 /* For functions, and tags, and static symbols, the symbol
2496 *must* be where the debug symbol appears. Move the
2497 existing symbol to the current place. */
2498 /* If it already is at the end of the symbol list, do nothing */
2499 if (def_symbol_in_progress != symbol_lastP)
2500 {
2501 symbol_remove (def_symbol_in_progress, &symbol_rootP,
2502 &symbol_lastP);
2503 symbol_append (def_symbol_in_progress, symbol_lastP,
2504 &symbol_rootP, &symbol_lastP);
2505 } /* if not already in place */
2506 } /* if function */
2507 } /* normal or mergable */
2508
2509 if (SF_GET_TAG (def_symbol_in_progress))
2510 {
2511 symbolS *oldtag;
2512
2513 oldtag = symbol_find_base (S_GET_NAME (def_symbol_in_progress),
2514 DO_NOT_STRIP);
2515 if (oldtag == NULL || ! SF_GET_TAG (oldtag))
2516 tag_insert (S_GET_NAME (def_symbol_in_progress),
2517 def_symbol_in_progress);
2518 }
2519
2520 if (SF_GET_FUNCTION (def_symbol_in_progress))
2521 {
2522 know (sizeof (def_symbol_in_progress) <= sizeof (long));
2523 function_lineoff
2524 = c_line_new (def_symbol_in_progress, 0, 0, &zero_address_frag);
2525
2526 SF_SET_PROCESS (def_symbol_in_progress);
2527
2528 if (symbolP == NULL)
2529 {
2530 /* That is, if this is the first time we've seen the
2531 function... */
2532 symbol_table_insert (def_symbol_in_progress);
2533 } /* definition follows debug */
2534 } /* Create the line number entry pointing to the function being defined */
2535
2536 def_symbol_in_progress = NULL;
2537 demand_empty_rest_of_line ();
2538}
2539
2540static void
2541obj_coff_dim (ignore)
a04b544b 2542 int ignore ATTRIBUTE_UNUSED;
252b5132
RH
2543{
2544 int dim_index;
2545
2546 if (def_symbol_in_progress == NULL)
2547 {
2548 as_warn (_(".dim pseudo-op used outside of .def/.endef: ignored."));
2549 demand_empty_rest_of_line ();
2550 return;
2551 } /* if not inside .def/.endef */
2552
2553 S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
2554
2555 for (dim_index = 0; dim_index < DIMNUM; dim_index++)
2556 {
2557 SKIP_WHITESPACES ();
2558 SA_SET_SYM_DIMEN (def_symbol_in_progress, dim_index,
2559 get_absolute_expression ());
2560
2561 switch (*input_line_pointer)
2562 {
2563 case ',':
2564 input_line_pointer++;
2565 break;
2566
2567 default:
2568 as_warn (_("badly formed .dim directive ignored"));
2569 /* intentional fallthrough */
2570 case '\n':
2571 case ';':
2572 dim_index = DIMNUM;
2573 break;
2574 }
2575 }
2576
2577 demand_empty_rest_of_line ();
2578}
2579
2580static void
2581obj_coff_line (ignore)
a04b544b 2582 int ignore ATTRIBUTE_UNUSED;
252b5132
RH
2583{
2584 int this_base;
2585 const char *name;
2586
2587 if (def_symbol_in_progress == NULL)
2588 {
2589 obj_coff_ln (0);
2590 return;
2591 }
2592
2593 name = S_GET_NAME (def_symbol_in_progress);
2594 this_base = get_absolute_expression ();
2595
2596 /* Only .bf symbols indicate the use of a new base line number; the
2597 line numbers associated with .ef, .bb, .eb are relative to the
2598 start of the containing function. */
2599 if (!strcmp (".bf", name))
2600 {
2601#if 0 /* XXX Can we ever have line numbers going backwards? */
2602 if (this_base > line_base)
2603#endif
2604 {
2605 line_base = this_base;
2606 }
2607
2608#ifndef NO_LISTING
2609 {
2610 extern int listing;
2611 if (listing)
2612 {
2613 listing_source_line ((unsigned int) line_base);
2614 }
2615 }
2616#endif
2617 }
2618
2619 S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
2620 SA_SET_SYM_LNNO (def_symbol_in_progress, this_base);
2621
2622 demand_empty_rest_of_line ();
2623}
2624
2625static void
2626obj_coff_size (ignore)
a04b544b 2627 int ignore ATTRIBUTE_UNUSED;
252b5132
RH
2628{
2629 if (def_symbol_in_progress == NULL)
2630 {
2631 as_warn (_(".size pseudo-op used outside of .def/.endef ignored."));
2632 demand_empty_rest_of_line ();
2633 return;
2634 } /* if not inside .def/.endef */
2635
2636 S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
2637 SA_SET_SYM_SIZE (def_symbol_in_progress, get_absolute_expression ());
2638 demand_empty_rest_of_line ();
2639}
2640
2641static void
2642obj_coff_scl (ignore)
a04b544b 2643 int ignore ATTRIBUTE_UNUSED;
252b5132
RH
2644{
2645 if (def_symbol_in_progress == NULL)
2646 {
2647 as_warn (_(".scl pseudo-op used outside of .def/.endef ignored."));
2648 demand_empty_rest_of_line ();
2649 return;
2650 } /* if not inside .def/.endef */
2651
2652 S_SET_STORAGE_CLASS (def_symbol_in_progress, get_absolute_expression ());
2653 demand_empty_rest_of_line ();
2654}
2655
2656static void
2657obj_coff_tag (ignore)
a04b544b 2658 int ignore ATTRIBUTE_UNUSED;
252b5132
RH
2659{
2660 char *symbol_name;
2661 char name_end;
2662
2663 if (def_symbol_in_progress == NULL)
2664 {
2665 as_warn (_(".tag pseudo-op used outside of .def/.endef ignored."));
2666 demand_empty_rest_of_line ();
2667 return;
2668 }
2669
2670 S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
2671 symbol_name = input_line_pointer;
2672 name_end = get_symbol_end ();
2673#ifdef tc_canonicalize_symbol_name
2674 symbol_name = tc_canonicalize_symbol_name (symbol_name);
2675#endif
2676
2677 /* Assume that the symbol referred to by .tag is always defined.
2678 This was a bad assumption. I've added find_or_make. xoxorich. */
2679 SA_SET_SYM_TAGNDX (def_symbol_in_progress,
2680 (long) tag_find_or_make (symbol_name));
2681 if (SA_GET_SYM_TAGNDX (def_symbol_in_progress) == 0L)
2682 {
2683 as_warn (_("tag not found for .tag %s"), symbol_name);
2684 } /* not defined */
2685
2686 SF_SET_TAGGED (def_symbol_in_progress);
2687 *input_line_pointer = name_end;
2688
2689 demand_empty_rest_of_line ();
2690}
2691
2692static void
2693obj_coff_type (ignore)
a04b544b 2694 int ignore ATTRIBUTE_UNUSED;
252b5132
RH
2695{
2696 if (def_symbol_in_progress == NULL)
2697 {
2698 as_warn (_(".type pseudo-op used outside of .def/.endef ignored."));
2699 demand_empty_rest_of_line ();
2700 return;
2701 } /* if not inside .def/.endef */
2702
2703 S_SET_DATA_TYPE (def_symbol_in_progress, get_absolute_expression ());
2704
2705 if (ISFCN (S_GET_DATA_TYPE (def_symbol_in_progress)) &&
2706 S_GET_STORAGE_CLASS (def_symbol_in_progress) != C_TPDEF)
2707 {
2708 SF_SET_FUNCTION (def_symbol_in_progress);
2709 } /* is a function */
2710
2711 demand_empty_rest_of_line ();
2712}
2713
2714static void
2715obj_coff_val (ignore)
a04b544b 2716 int ignore ATTRIBUTE_UNUSED;
252b5132
RH
2717{
2718 if (def_symbol_in_progress == NULL)
2719 {
2720 as_warn (_(".val pseudo-op used outside of .def/.endef ignored."));
2721 demand_empty_rest_of_line ();
2722 return;
2723 } /* if not inside .def/.endef */
2724
2725 if (is_name_beginner (*input_line_pointer))
2726 {
2727 char *symbol_name = input_line_pointer;
2728 char name_end = get_symbol_end ();
2729
2730#ifdef tc_canonicalize_symbol_name
2731 symbol_name = tc_canonicalize_symbol_name (symbol_name);
2732#endif
2733
2734 if (!strcmp (symbol_name, "."))
2735 {
2736 def_symbol_in_progress->sy_frag = frag_now;
2737 S_SET_VALUE (def_symbol_in_progress, (valueT) frag_now_fix ());
2738 /* If the .val is != from the .def (e.g. statics) */
2739 }
2740 else if (strcmp (S_GET_NAME (def_symbol_in_progress), symbol_name))
2741 {
2742 def_symbol_in_progress->sy_value.X_op = O_symbol;
2743 def_symbol_in_progress->sy_value.X_add_symbol =
2744 symbol_find_or_make (symbol_name);
2745 def_symbol_in_progress->sy_value.X_op_symbol = NULL;
2746 def_symbol_in_progress->sy_value.X_add_number = 0;
2747
2748 /* If the segment is undefined when the forward reference is
2749 resolved, then copy the segment id from the forward
2750 symbol. */
2751 SF_SET_GET_SEGMENT (def_symbol_in_progress);
2752
0561a208
ILT
2753 /* FIXME: gcc can generate address expressions here in
2754 unusual cases (search for "obscure" in sdbout.c). We
2755 just ignore the offset here, thus generating incorrect
2756 debugging information. We ignore the rest of the line
2757 just below. */
252b5132
RH
2758 }
2759 /* Otherwise, it is the name of a non debug symbol and
2760 its value will be calculated later. */
2761 *input_line_pointer = name_end;
2762
2763 /* FIXME: this is to avoid an error message in the
2764 FIXME case mentioned just above. */
2765 while (! is_end_of_line[(unsigned char) *input_line_pointer])
2766 ++input_line_pointer;
2767 }
2768 else
2769 {
2770 S_SET_VALUE (def_symbol_in_progress,
2771 (valueT) get_absolute_expression ());
2772 } /* if symbol based */
2773
2774 demand_empty_rest_of_line ();
2775}
2776
2777#ifdef TE_PE
2778
2779/* Handle the .linkonce pseudo-op. This is parsed by s_linkonce in
2780 read.c, which then calls this object file format specific routine. */
2781
2782void
2783obj_coff_pe_handle_link_once (type)
2784 enum linkonce_type type;
2785{
2786 seg_info (now_seg)->scnhdr.s_flags |= IMAGE_SCN_LNK_COMDAT;
2787
2788 /* We store the type in the seg_info structure, and use it to set up
2789 the auxiliary entry for the section symbol in c_section_symbol. */
2790 seg_info (now_seg)->linkonce = type;
2791}
2792
2793#endif /* TE_PE */
2794
2795void
2796coff_obj_read_begin_hook ()
2797{
2798 /* These had better be the same. Usually 18 bytes. */
2799#ifndef BFD_HEADERS
2800 know (sizeof (SYMENT) == sizeof (AUXENT));
2801 know (SYMESZ == AUXESZ);
2802#endif
2803 tag_init ();
2804}
2805
2806/* This function runs through the symbol table and puts all the
2807 externals onto another chain */
2808
2809/* The chain of globals. */
2810symbolS *symbol_globalP;
2811symbolS *symbol_global_lastP;
2812
2813/* The chain of externals */
2814symbolS *symbol_externP;
2815symbolS *symbol_extern_lastP;
2816
2817stack *block_stack;
2818symbolS *last_functionP;
2819static symbolS *last_bfP;
2820symbolS *last_tagP;
2821
2822static unsigned int
2823yank_symbols ()
2824{
2825 symbolS *symbolP;
2826 unsigned int symbol_number = 0;
2827 unsigned int last_file_symno = 0;
2828
2829 struct filename_list *filename_list_scan = filename_list_head;
2830
2831 for (symbolP = symbol_rootP;
2832 symbolP;
2833 symbolP = symbolP ? symbol_next (symbolP) : symbol_rootP)
2834 {
2835 if (symbolP->sy_mri_common)
2836 {
2837 if (S_GET_STORAGE_CLASS (symbolP) == C_EXT
2838#ifdef TE_PE
2839 || S_GET_STORAGE_CLASS (symbolP) == C_NT_WEAK
2840#endif
2841 || S_GET_STORAGE_CLASS (symbolP) == C_WEAKEXT)
2842 as_bad (_("%s: global symbols not supported in common sections"),
2843 S_GET_NAME (symbolP));
2844 symbol_remove (symbolP, &symbol_rootP, &symbol_lastP);
2845 continue;
2846 }
2847
2848 if (!SF_GET_DEBUG (symbolP))
2849 {
2850 /* Debug symbols do not need all this rubbish */
2851 symbolS *real_symbolP;
2852
2853 /* L* and C_EFCN symbols never merge. */
2854 if (!SF_GET_LOCAL (symbolP)
2855 && !SF_GET_STATICS (symbolP)
2856 && S_GET_STORAGE_CLASS (symbolP) != C_LABEL
2857 && symbolP->sy_value.X_op == O_constant
2858 && (real_symbolP = symbol_find_base (S_GET_NAME (symbolP), DO_NOT_STRIP))
2859 && real_symbolP != symbolP)
2860 {
2861 /* FIXME-SOON: where do dups come from?
2862 Maybe tag references before definitions? xoxorich. */
2863 /* Move the debug data from the debug symbol to the
2864 real symbol. Do NOT do the oposite (i.e. move from
2865 real symbol to debug symbol and remove real symbol from the
2866 list.) Because some pointers refer to the real symbol
2867 whereas no pointers refer to the debug symbol. */
2868 c_symbol_merge (symbolP, real_symbolP);
2869 /* Replace the current symbol by the real one */
2870 /* The symbols will never be the last or the first
2871 because : 1st symbol is .file and 3 last symbols are
2872 .text, .data, .bss */
2873 symbol_remove (real_symbolP, &symbol_rootP, &symbol_lastP);
2874 symbol_insert (real_symbolP, symbolP, &symbol_rootP, &symbol_lastP);
2875 symbol_remove (symbolP, &symbol_rootP, &symbol_lastP);
2876 symbolP = real_symbolP;
2877 } /* if not local but dup'd */
2878
2879 if (flag_readonly_data_in_text && (S_GET_SEGMENT (symbolP) == SEG_E1))
2880 {
2881 S_SET_SEGMENT (symbolP, SEG_E0);
2882 } /* push data into text */
2883
2884 resolve_symbol_value (symbolP, 1);
2885
2886 if (S_GET_STORAGE_CLASS (symbolP) == C_NULL)
2887 {
2888 if (!S_IS_DEFINED (symbolP) && !SF_GET_LOCAL (symbolP))
2889 {
2890 S_SET_EXTERNAL (symbolP);
2891 }
2892 else if (S_GET_SEGMENT (symbolP) == SEG_E0)
2893 {
2894 S_SET_STORAGE_CLASS (symbolP, C_LABEL);
2895 }
2896 else
2897 {
2898 S_SET_STORAGE_CLASS (symbolP, C_STAT);
2899 }
2900 }
2901
2902 /* Mainly to speed up if not -g */
2903 if (SF_GET_PROCESS (symbolP))
2904 {
2905 /* Handle the nested blocks auxiliary info. */
2906 if (S_GET_STORAGE_CLASS (symbolP) == C_BLOCK)
2907 {
2908 if (!strcmp (S_GET_NAME (symbolP), ".bb"))
2909 stack_push (block_stack, (char *) &symbolP);
2910 else
2911 { /* .eb */
2912 register symbolS *begin_symbolP;
2913 begin_symbolP = *(symbolS **) stack_pop (block_stack);
2914 if (begin_symbolP == (symbolS *) 0)
2915 as_warn (_("mismatched .eb"));
2916 else
2917 SA_SET_SYM_ENDNDX (begin_symbolP, symbol_number + 2);
2918 }
2919 }
2920 /* If we are able to identify the type of a function, and we
2921 are out of a function (last_functionP == 0) then, the
2922 function symbol will be associated with an auxiliary
2923 entry. */
2924 if (last_functionP == (symbolS *) 0 &&
2925 SF_GET_FUNCTION (symbolP))
2926 {
2927 last_functionP = symbolP;
2928
2929 if (S_GET_NUMBER_AUXILIARY (symbolP) < 1)
2930 {
2931 S_SET_NUMBER_AUXILIARY (symbolP, 1);
2932 } /* make it at least 1 */
2933
2934 /* Clobber possible stale .dim information. */
2935#if 0
2936 /* Iffed out by steve - this fries the lnnoptr info too */
2937 bzero (symbolP->sy_symbol.ost_auxent[0].x_sym.x_fcnary.x_ary.x_dimen,
2938 sizeof (symbolP->sy_symbol.ost_auxent[0].x_sym.x_fcnary.x_ary.x_dimen));
2939#endif
2940 }
2941 if (S_GET_STORAGE_CLASS (symbolP) == C_FCN)
2942 {
2943 if (strcmp (S_GET_NAME (symbolP), ".bf") == 0)
2944 {
2945 if (last_bfP != NULL)
2946 SA_SET_SYM_ENDNDX (last_bfP, symbol_number);
2947 last_bfP = symbolP;
2948 }
2949 }
2950 else if (S_GET_STORAGE_CLASS (symbolP) == C_EFCN)
2951 {
2952 /* I don't even know if this is needed for sdb. But
2953 the standard assembler generates it, so... */
2954 if (last_functionP == (symbolS *) 0)
2955 as_fatal (_("C_EFCN symbol out of scope"));
2956 SA_SET_SYM_FSIZE (last_functionP,
2957 (long) (S_GET_VALUE (symbolP) -
2958 S_GET_VALUE (last_functionP)));
2959 SA_SET_SYM_ENDNDX (last_functionP, symbol_number);
2960 last_functionP = (symbolS *) 0;
2961 }
2962 }
2963 }
2964 else if (SF_GET_TAG (symbolP))
2965 {
2966 /* First descriptor of a structure must point to
2967 the first slot after the structure description. */
2968 last_tagP = symbolP;
2969
2970 }
2971 else if (S_GET_STORAGE_CLASS (symbolP) == C_EOS)
2972 {
2973 /* +2 take in account the current symbol */
2974 SA_SET_SYM_ENDNDX (last_tagP, symbol_number + 2);
2975 }
2976 else if (S_GET_STORAGE_CLASS (symbolP) == C_FILE)
2977 {
2978 /* If the filename was too long to fit in the
2979 auxent, put it in the string table */
2980 if (SA_GET_FILE_FNAME_ZEROS (symbolP) == 0
2981 && SA_GET_FILE_FNAME_OFFSET (symbolP) != 0)
2982 {
2983 SA_SET_FILE_FNAME_OFFSET (symbolP, string_byte_count);
2984 string_byte_count += strlen (filename_list_scan->filename) + 1;
2985 filename_list_scan = filename_list_scan->next;
2986 }
2987 if (S_GET_VALUE (symbolP))
2988 {
2989 S_SET_VALUE (symbolP, last_file_symno);
2990 last_file_symno = symbol_number;
2991 } /* no one points at the first .file symbol */
2992 } /* if debug or tag or eos or file */
2993
2994#ifdef tc_frob_coff_symbol
2995 tc_frob_coff_symbol (symbolP);
2996#endif
2997
2998 /* We must put the external symbols apart. The loader
2999 does not bomb if we do not. But the references in
3000 the endndx field for a .bb symbol are not corrected
3001 if an external symbol is removed between .bb and .be.
3002 I.e in the following case :
3003 [20] .bb endndx = 22
3004 [21] foo external
3005 [22] .be
3006 ld will move the symbol 21 to the end of the list but
3007 endndx will still be 22 instead of 21. */
3008
3009
3010 if (SF_GET_LOCAL (symbolP))
3011 {
3012 /* remove C_EFCN and LOCAL (L...) symbols */
3013 /* next pointer remains valid */
3014 symbol_remove (symbolP, &symbol_rootP, &symbol_lastP);
3015
3016 }
3017 else if (symbolP->sy_value.X_op == O_symbol
3018 && (! S_IS_DEFINED (symbolP) || S_IS_COMMON (symbolP)))
3019 {
3020 /* Skip symbols which were equated to undefined or common
3021 symbols. */
3022 symbol_remove (symbolP, &symbol_rootP, &symbol_lastP);
3023 }
3024 else if (!S_IS_DEFINED (symbolP)
3025 && !S_IS_DEBUG (symbolP)
3026 && !SF_GET_STATICS (symbolP)
3027 && (S_GET_STORAGE_CLASS (symbolP) == C_EXT
3028#ifdef TE_PE
3029 || S_GET_STORAGE_CLASS (symbolP) == C_NT_WEAK
3030#endif
3031 || S_GET_STORAGE_CLASS (symbolP) == C_WEAKEXT))
3032 {
3033 /* if external, Remove from the list */
3034 symbolS *hold = symbol_previous (symbolP);
3035
3036 symbol_remove (symbolP, &symbol_rootP, &symbol_lastP);
3037 symbol_clear_list_pointers (symbolP);
3038 symbol_append (symbolP, symbol_extern_lastP, &symbol_externP, &symbol_extern_lastP);
3039 symbolP = hold;
3040 }
3041 else if (! S_IS_DEBUG (symbolP)
3042 && ! SF_GET_STATICS (symbolP)
3043 && ! SF_GET_FUNCTION (symbolP)
3044 && (S_GET_STORAGE_CLASS (symbolP) == C_EXT
3045#ifdef TE_PE
3046 || S_GET_STORAGE_CLASS (symbolP) == C_NT_WEAK
3047#endif
3048 || S_GET_STORAGE_CLASS (symbolP) == C_NT_WEAK))
3049 {
3050 symbolS *hold = symbol_previous (symbolP);
3051
3052 /* The O'Reilly COFF book says that defined global symbols
3053 come at the end of the symbol table, just before
3054 undefined global symbols. */
3055
3056 symbol_remove (symbolP, &symbol_rootP, &symbol_lastP);
3057 symbol_clear_list_pointers (symbolP);
3058 symbol_append (symbolP, symbol_global_lastP, &symbol_globalP,
3059 &symbol_global_lastP);
3060 symbolP = hold;
3061 }
3062 else
3063 {
3064 if (SF_GET_STRING (symbolP))
3065 {
3066 symbolP->sy_name_offset = string_byte_count;
3067 string_byte_count += strlen (S_GET_NAME (symbolP)) + 1;
3068 }
3069 else
3070 {
3071 symbolP->sy_name_offset = 0;
3072 } /* fix "long" names */
3073
3074 symbolP->sy_number = symbol_number;
3075 symbol_number += 1 + S_GET_NUMBER_AUXILIARY (symbolP);
3076 } /* if local symbol */
3077 } /* traverse the symbol list */
3078 return symbol_number;
3079
3080}
3081
3082
3083static unsigned int
3084glue_symbols (head, tail)
3085 symbolS **head;
3086 symbolS **tail;
3087{
3088 unsigned int symbol_number = 0;
3089
3090 while (*head != NULL)
3091 {
3092 symbolS *tmp = *head;
3093
3094 /* append */
3095 symbol_remove (tmp, head, tail);
3096 symbol_append (tmp, symbol_lastP, &symbol_rootP, &symbol_lastP);
3097
3098 /* and process */
3099 if (SF_GET_STRING (tmp))
3100 {
3101 tmp->sy_name_offset = string_byte_count;
3102 string_byte_count += strlen (S_GET_NAME (tmp)) + 1;
3103 }
3104 else
3105 {
3106 tmp->sy_name_offset = 0;
3107 } /* fix "long" names */
3108
3109 tmp->sy_number = symbol_number;
3110 symbol_number += 1 + S_GET_NUMBER_AUXILIARY (tmp);
3111 } /* append the entire extern chain */
3112
3113 return symbol_number;
3114}
3115
3116static unsigned int
3117tie_tags ()
3118{
3119 unsigned int symbol_number = 0;
3120 symbolS *symbolP;
3121
3122 for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
3123 {
3124 symbolP->sy_number = symbol_number;
3125
3126 if (SF_GET_TAGGED (symbolP))
3127 {
3128 SA_SET_SYM_TAGNDX
3129 (symbolP,
3130 ((symbolS *) SA_GET_SYM_TAGNDX (symbolP))->sy_number);
3131 }
3132
3133 symbol_number += 1 + S_GET_NUMBER_AUXILIARY (symbolP);
3134 }
3135
3136 return symbol_number;
3137}
3138
3139static void
3140crawl_symbols (h, abfd)
3141 object_headers *h;
a04b544b 3142 bfd *abfd ATTRIBUTE_UNUSED;
252b5132
RH
3143{
3144 unsigned int i;
3145
3146 /* Initialize the stack used to keep track of the matching .bb .be */
3147
3148 block_stack = stack_init (512, sizeof (symbolS *));
3149
3150 /* The symbol list should be ordered according to the following sequence
3151 * order :
3152 * . .file symbol
3153 * . debug entries for functions
3154 * . fake symbols for the sections, including .text .data and .bss
3155 * . defined symbols
3156 * . undefined symbols
3157 * But this is not mandatory. The only important point is to put the
3158 * undefined symbols at the end of the list.
3159 */
3160
3161 /* Is there a .file symbol ? If not insert one at the beginning. */
3162 if (symbol_rootP == NULL
3163 || S_GET_STORAGE_CLASS (symbol_rootP) != C_FILE)
3164 {
3165 c_dot_file_symbol ("fake");
3166 }
3167
3168 /*
3169 * Build up static symbols for the sections, they are filled in later
3170 */
3171
3172
3173 for (i = SEG_E0; i < SEG_LAST; i++)
3174 if (segment_info[i].scnhdr.s_name[0])
3175 segment_info[i].dot = c_section_symbol (segment_info[i].name,
3176 i - SEG_E0 + 1);
3177
3178 /* Take all the externals out and put them into another chain */
3179 H_SET_SYMBOL_TABLE_SIZE (h, yank_symbols ());
3180 /* Take the externals and glue them onto the end.*/
3181 H_SET_SYMBOL_TABLE_SIZE (h,
3182 (H_GET_SYMBOL_COUNT (h)
3183 + glue_symbols (&symbol_globalP,
3184 &symbol_global_lastP)
3185 + glue_symbols (&symbol_externP,
3186 &symbol_extern_lastP)));
3187
3188 H_SET_SYMBOL_TABLE_SIZE (h, tie_tags ());
3189 know (symbol_globalP == NULL);
3190 know (symbol_global_lastP == NULL);
3191 know (symbol_externP == NULL);
3192 know (symbol_extern_lastP == NULL);
3193}
3194
3195/*
3196 * Find strings by crawling along symbol table chain.
3197 */
3198
3199void
3200w_strings (where)
3201 char *where;
3202{
3203 symbolS *symbolP;
3204 struct filename_list *filename_list_scan = filename_list_head;
3205
3206 /* Gotta do md_ byte-ordering stuff for string_byte_count first - KWK */
3207 md_number_to_chars (where, (valueT) string_byte_count, 4);
3208 where += 4;
3209
3210#ifdef COFF_LONG_SECTION_NAMES
3211 /* Support long section names as found in PE. This code must
3212 coordinate with that in coff_header_append and write_object_file. */
3213 {
3214 unsigned int i;
3215
3216 for (i = SEG_E0; i < SEG_LAST; i++)
3217 {
3218 if (segment_info[i].scnhdr.s_name[0]
3219 && strlen (segment_info[i].name) > SCNNMLEN)
3220 {
3221 unsigned int size;
3222
3223 size = strlen (segment_info[i].name) + 1;
3224 memcpy (where, segment_info[i].name, size);
3225 where += size;
3226 }
3227 }
3228 }
3229#endif /* COFF_LONG_SECTION_NAMES */
3230
3231 for (symbolP = symbol_rootP;
3232 symbolP;
3233 symbolP = symbol_next (symbolP))
3234 {
3235 unsigned int size;
3236
3237 if (SF_GET_STRING (symbolP))
3238 {
3239 size = strlen (S_GET_NAME (symbolP)) + 1;
3240 memcpy (where, S_GET_NAME (symbolP), size);
3241 where += size;
3242 }
3243 if (S_GET_STORAGE_CLASS (symbolP) == C_FILE
3244 && SA_GET_FILE_FNAME_ZEROS (symbolP) == 0
3245 && SA_GET_FILE_FNAME_OFFSET (symbolP) != 0)
3246 {
3247 size = strlen (filename_list_scan->filename) + 1;
3248 memcpy (where, filename_list_scan->filename, size);
3249 filename_list_scan = filename_list_scan ->next;
3250 where += size;
3251 }
3252 }
3253}
3254
3255static void
3256do_linenos_for (abfd, h, file_cursor)
3257 bfd * abfd;
3258 object_headers * h;
3259 unsigned long *file_cursor;
3260{
3261 unsigned int idx;
3262 unsigned long start = *file_cursor;
3263
3264 for (idx = SEG_E0; idx < SEG_LAST; idx++)
3265 {
3266 segment_info_type *s = segment_info + idx;
3267
3268
3269 if (s->scnhdr.s_nlnno != 0)
3270 {
3271 struct lineno_list *line_ptr;
3272
3273 struct external_lineno *buffer =
3274 (struct external_lineno *) xmalloc (s->scnhdr.s_nlnno * LINESZ);
3275
3276 struct external_lineno *dst = buffer;
3277
3278 /* Run through the table we've built and turn it into its external
3279 form, take this chance to remove duplicates */
3280
3281 for (line_ptr = s->lineno_list_head;
3282 line_ptr != (struct lineno_list *) NULL;
3283 line_ptr = line_ptr->next)
3284 {
3285
3286 if (line_ptr->line.l_lnno == 0)
3287 {
3288 /* Turn a pointer to a symbol into the symbols' index */
3289 line_ptr->line.l_addr.l_symndx =
3290 ((symbolS *) line_ptr->line.l_addr.l_symndx)->sy_number;
3291 }
3292 else
3293 {
3294 line_ptr->line.l_addr.l_paddr += ((struct frag *) (line_ptr->frag))->fr_address;
3295 }
3296
3297
3298 (void) bfd_coff_swap_lineno_out (abfd, &(line_ptr->line), dst);
3299 dst++;
3300
3301 }
3302
3303 s->scnhdr.s_lnnoptr = *file_cursor;
3304
3305 bfd_write (buffer, 1, s->scnhdr.s_nlnno * LINESZ, abfd);
3306 free (buffer);
3307
3308 *file_cursor += s->scnhdr.s_nlnno * LINESZ;
3309 }
3310 }
3311 H_SET_LINENO_SIZE (h, *file_cursor - start);
3312}
3313
3314
3315/* Now we run through the list of frag chains in a segment and
3316 make all the subsegment frags appear at the end of the
3317 list, as if the seg 0 was extra long */
3318
3319static void
3320remove_subsegs ()
3321{
3322 unsigned int i;
3323
3324 for (i = SEG_E0; i < SEG_UNKNOWN; i++)
3325 {
3326 frchainS *head = segment_info[i].frchainP;
3327 fragS dummy;
3328 fragS *prev_frag = &dummy;
3329
3330 while (head && head->frch_seg == i)
3331 {
3332 prev_frag->fr_next = head->frch_root;
3333 prev_frag = head->frch_last;
3334 head = head->frch_next;
3335 }
3336 prev_frag->fr_next = 0;
3337 }
3338}
3339
3340unsigned long machine;
3341int coff_flags;
3342extern void
3343write_object_file ()
3344{
3345 int i;
3346 const char *name;
3347 struct frchain *frchain_ptr;
3348
3349 object_headers headers;
3350 unsigned long file_cursor;
3351 bfd *abfd;
3352 unsigned int addr;
3353 abfd = bfd_openw (out_file_name, TARGET_FORMAT);
3354
3355
3356 if (abfd == 0)
3357 {
3358 as_perror (_("FATAL: Can't create %s"), out_file_name);
3359 exit (EXIT_FAILURE);
3360 }
3361 bfd_set_format (abfd, bfd_object);
3362 bfd_set_arch_mach (abfd, BFD_ARCH, machine);
3363
3364 string_byte_count = 4;
3365
3366 for (frchain_ptr = frchain_root;
3367 frchain_ptr != (struct frchain *) NULL;
3368 frchain_ptr = frchain_ptr->frch_next)
3369 {
3370 /* Run through all the sub-segments and align them up. Also
3371 close any open frags. We tack a .fill onto the end of the
3372 frag chain so that any .align's size can be worked by looking
3373 at the next frag. */
3374
3375 subseg_set (frchain_ptr->frch_seg, frchain_ptr->frch_subseg);
b9e57a38 3376
252b5132
RH
3377#ifndef SUB_SEGMENT_ALIGN
3378#define SUB_SEGMENT_ALIGN(SEG) 1
3379#endif
3380#ifdef md_do_align
3381 md_do_align (SUB_SEGMENT_ALIGN (now_seg), (char *) NULL, 0, 0,
3382 alignment_done);
3383#endif
b9e57a38
ILT
3384 frag_align (SUB_SEGMENT_ALIGN (now_seg),
3385 subseg_text_p (now_seg) ? NOP_OPCODE : 0,
3386 0);
252b5132
RH
3387#ifdef md_do_align
3388 alignment_done:
3389#endif
3390 frag_wane (frag_now);
3391 frag_now->fr_fix = 0;
3392 know (frag_now->fr_next == NULL);
3393 }
3394
3395
3396 remove_subsegs ();
3397
3398
3399 for (i = SEG_E0; i < SEG_UNKNOWN; i++)
3400 {
3401 relax_segment (segment_info[i].frchainP->frch_root, i);
3402 }
3403
3404 H_SET_NUMBER_OF_SECTIONS (&headers, 0);
3405
3406 /* Find out how big the sections are, and set the addresses. */
3407 addr = 0;
3408 for (i = SEG_E0; i < SEG_UNKNOWN; i++)
3409 {
3410 long size;
3411
3412 segment_info[i].scnhdr.s_paddr = addr;
3413 segment_info[i].scnhdr.s_vaddr = addr;
3414
3415 if (segment_info[i].scnhdr.s_name[0])
3416 {
3417 H_SET_NUMBER_OF_SECTIONS (&headers,
3418 H_GET_NUMBER_OF_SECTIONS (&headers) + 1);
3419
3420#ifdef COFF_LONG_SECTION_NAMES
3421 /* Support long section names as found in PE. This code
3422 must coordinate with that in coff_header_append and
3423 w_strings. */
3424 {
3425 unsigned int len;
3426
3427 len = strlen (segment_info[i].name);
3428 if (len > SCNNMLEN)
3429 string_byte_count += len + 1;
3430 }
3431#endif /* COFF_LONG_SECTION_NAMES */
3432 }
3433
3434 size = size_section (abfd, (unsigned int) i);
3435 addr += size;
3436
3437 /* I think the section alignment is only used on the i960; the
3438 i960 needs it, and it should do no harm on other targets. */
3439#ifdef ALIGNMENT_IN_S_FLAGS
3440 segment_info[i].scnhdr.s_flags |= (section_alignment[i] & 0xF) << 8;
3441#else
3442 segment_info[i].scnhdr.s_align = 1 << section_alignment[i];
3443#endif
3444
3445 if (i == SEG_E0)
3446 H_SET_TEXT_SIZE (&headers, size);
3447 else if (i == SEG_E1)
3448 H_SET_DATA_SIZE (&headers, size);
3449 else if (i == SEG_E2)
3450 H_SET_BSS_SIZE (&headers, size);
3451 }
3452
3453 /* Turn the gas native symbol table shape into a coff symbol table */
3454 crawl_symbols (&headers, abfd);
3455
3456 if (string_byte_count == 4)
3457 string_byte_count = 0;
3458
3459 H_SET_STRING_SIZE (&headers, string_byte_count);
3460
3461#ifdef tc_frob_file
3462 tc_frob_file ();
3463#endif
3464
3465 for (i = SEG_E0; i < SEG_UNKNOWN; i++)
3466 {
3467 fixup_mdeps (segment_info[i].frchainP->frch_root, &headers, i);
3468 fixup_segment (&segment_info[i], i);
3469 }
3470
3471 /* Look for ".stab" segments and fill in their initial symbols
3472 correctly. */
3473 for (i = SEG_E0; i < SEG_UNKNOWN; i++)
3474 {
3475 name = segment_info[i].name;
3476
3477 if (name != NULL
3478 && strncmp (".stab", name, 5) == 0
3479 && strncmp (".stabstr", name, 8) != 0)
3480 adjust_stab_section (abfd, i);
3481 }
3482
3483 file_cursor = H_GET_TEXT_FILE_OFFSET (&headers);
3484
3485 bfd_seek (abfd, (file_ptr) file_cursor, 0);
3486
3487 /* Plant the data */
3488
3489 fill_section (abfd, &headers, &file_cursor);
3490
3491 do_relocs_for (abfd, &headers, &file_cursor);
3492
3493 do_linenos_for (abfd, &headers, &file_cursor);
3494
3495 H_SET_FILE_MAGIC_NUMBER (&headers, COFF_MAGIC);
3496#ifndef OBJ_COFF_OMIT_TIMESTAMP
3497 H_SET_TIME_STAMP (&headers, (long)time((time_t *)0));
3498#else
3499 H_SET_TIME_STAMP (&headers, 0);
3500#endif
3501#ifdef TC_COFF_SET_MACHINE
3502 TC_COFF_SET_MACHINE (&headers);
3503#endif
3504
3505#ifndef COFF_FLAGS
3506#define COFF_FLAGS 0
3507#endif
3508
3509#ifdef KEEP_RELOC_INFO
3510 H_SET_FLAGS (&headers, ((H_GET_LINENO_SIZE(&headers) ? 0 : F_LNNO) |
3511 COFF_FLAGS | coff_flags));
3512#else
3513 H_SET_FLAGS (&headers, ((H_GET_LINENO_SIZE(&headers) ? 0 : F_LNNO) |
3514 (H_GET_RELOCATION_SIZE(&headers) ? 0 : F_RELFLG) |
3515 COFF_FLAGS | coff_flags));
3516#endif
3517
3518 {
3519 unsigned int symtable_size = H_GET_SYMBOL_TABLE_SIZE (&headers);
3520 char *buffer1 = xmalloc (symtable_size + string_byte_count + 1);
3521
3522 H_SET_SYMBOL_TABLE_POINTER (&headers, bfd_tell (abfd));
3523 w_symbols (abfd, buffer1, symbol_rootP);
3524 if (string_byte_count > 0)
3525 w_strings (buffer1 + symtable_size);
3526 bfd_write (buffer1, 1, symtable_size + string_byte_count, abfd);
3527 free (buffer1);
3528 }
3529
3530 coff_header_append (abfd, &headers);
3531#if 0
3532 /* Recent changes to write need this, but where it should
3533 go is up to Ken.. */
3534 if (bfd_close_all_done (abfd) == false)
3535 as_fatal (_("Can't close %s: %s"), out_file_name,
3536 bfd_errmsg (bfd_get_error ()));
3537#else
3538 {
3539 extern bfd *stdoutput;
3540 stdoutput = abfd;
3541 }
3542#endif
3543
3544}
3545
3546/* Add a new segment. This is called from subseg_new via the
3547 obj_new_segment macro. */
3548
3549segT
3550obj_coff_add_segment (name)
3551 const char *name;
3552{
3553 unsigned int i;
3554
3555#ifndef COFF_LONG_SECTION_NAMES
3556 char buf[SCNNMLEN + 1];
3557
3558 strncpy (buf, name, SCNNMLEN);
3559 buf[SCNNMLEN] = '\0';
3560 name = buf;
3561#endif
3562
3563 for (i = SEG_E0; i < SEG_LAST && segment_info[i].scnhdr.s_name[0]; i++)
3564 if (strcmp (name, segment_info[i].name) == 0)
3565 return (segT) i;
3566
3567 if (i == SEG_LAST)
3568 {
3569 as_bad (_("Too many new sections; can't add \"%s\""), name);
3570 return now_seg;
3571 }
3572
3573 /* Add a new section. */
3574 strncpy (segment_info[i].scnhdr.s_name, name,
3575 sizeof (segment_info[i].scnhdr.s_name));
3576 segment_info[i].scnhdr.s_flags = STYP_REG;
3577 segment_info[i].name = xstrdup (name);
3578
3579 return (segT) i;
3580}
3581
3582/*
3583 * implement the .section pseudo op:
3584 * .section name {, "flags"}
3585 * ^ ^
3586 * | +--- optional flags: 'b' for bss
3587 * | 'i' for info
3588 * +-- section name 'l' for lib
3589 * 'n' for noload
3590 * 'o' for over
3591 * 'w' for data
3592 * 'd' (apparently m88k for data)
3593 * 'x' for text
3594 * 'r' for read-only data
3595 * But if the argument is not a quoted string, treat it as a
3596 * subsegment number.
3597 */
3598
3599void
3600obj_coff_section (ignore)
a04b544b 3601 int ignore ATTRIBUTE_UNUSED;
252b5132
RH
3602{
3603 /* Strip out the section name */
3604 char *section_name, *name;
3605 char c;
3606 unsigned int exp;
3607 long flags;
3608
3609 if (flag_mri)
3610 {
3611 char type;
3612
3613 s_mri_sect (&type);
3614 flags = 0;
3615 if (type == 'C')
3616 flags = STYP_TEXT;
3617 else if (type == 'D')
3618 flags = STYP_DATA;
3619 segment_info[now_seg].scnhdr.s_flags |= flags;
3620
3621 return;
3622 }
3623
3624 section_name = input_line_pointer;
3625 c = get_symbol_end ();
3626
3627 name = xmalloc (input_line_pointer - section_name + 1);
3628 strcpy (name, section_name);
3629
3630 *input_line_pointer = c;
3631
3632 exp = 0;
3633 flags = 0;
3634
3635 SKIP_WHITESPACE ();
3636 if (*input_line_pointer == ',')
3637 {
3638 ++input_line_pointer;
3639 SKIP_WHITESPACE ();
3640
3641 if (*input_line_pointer != '"')
3642 exp = get_absolute_expression ();
3643 else
3644 {
3645 ++input_line_pointer;
3646 while (*input_line_pointer != '"'
3647 && ! is_end_of_line[(unsigned char) *input_line_pointer])
3648 {
3649 switch (*input_line_pointer)
3650 {
3651 case 'b': flags |= STYP_BSS; break;
3652 case 'i': flags |= STYP_INFO; break;
3653 case 'l': flags |= STYP_LIB; break;
3654 case 'n': flags |= STYP_NOLOAD; break;
3655 case 'o': flags |= STYP_OVER; break;
3656 case 'd':
3657 case 'w': flags |= STYP_DATA; break;
3658 case 'x': flags |= STYP_TEXT; break;
3659 case 'r': flags |= STYP_LIT; break;
3660 default:
3661 as_warn(_("unknown section attribute '%c'"),
3662 *input_line_pointer);
3663 break;
3664 }
3665 ++input_line_pointer;
3666 }
3667 if (*input_line_pointer == '"')
3668 ++input_line_pointer;
3669 }
3670 }
3671
3672 subseg_new (name, (subsegT) exp);
3673
3674 segment_info[now_seg].scnhdr.s_flags |= flags;
3675
3676 demand_empty_rest_of_line ();
3677}
3678
3679
3680static void
3681obj_coff_text (ignore)
a04b544b 3682 int ignore ATTRIBUTE_UNUSED;
252b5132
RH
3683{
3684 subseg_new (".text", get_absolute_expression ());
3685}
3686
3687
3688static void
3689obj_coff_data (ignore)
a04b544b 3690 int ignore ATTRIBUTE_UNUSED;
252b5132
RH
3691{
3692 if (flag_readonly_data_in_text)
3693 subseg_new (".text", get_absolute_expression () + 1000);
3694 else
3695 subseg_new (".data", get_absolute_expression ());
3696}
3697
3698static void
3699obj_coff_ident (ignore)
a04b544b 3700 int ignore ATTRIBUTE_UNUSED;
252b5132
RH
3701{
3702 segT current_seg = now_seg; /* save current seg */
3703 subsegT current_subseg = now_subseg;
3704 subseg_new (".comment", 0); /* .comment seg */
3705 stringer (1); /* read string */
3706 subseg_set (current_seg, current_subseg); /* restore current seg */
3707}
3708
3709void
3710c_symbol_merge (debug, normal)
3711 symbolS *debug;
3712 symbolS *normal;
3713{
3714 S_SET_DATA_TYPE (normal, S_GET_DATA_TYPE (debug));
3715 S_SET_STORAGE_CLASS (normal, S_GET_STORAGE_CLASS (debug));
3716
3717 if (S_GET_NUMBER_AUXILIARY (debug) > S_GET_NUMBER_AUXILIARY (normal))
3718 {
3719 S_SET_NUMBER_AUXILIARY (normal, S_GET_NUMBER_AUXILIARY (debug));
3720 } /* take the most we have */
3721
3722 if (S_GET_NUMBER_AUXILIARY (debug) > 0)
3723 {
3724 memcpy ((char *) &normal->sy_symbol.ost_auxent[0],
3725 (char *) &debug->sy_symbol.ost_auxent[0],
3726 (unsigned int) (S_GET_NUMBER_AUXILIARY (debug) * AUXESZ));
3727 } /* Move all the auxiliary information */
3728
3729 /* Move the debug flags. */
3730 SF_SET_DEBUG_FIELD (normal, SF_GET_DEBUG_FIELD (debug));
3731} /* c_symbol_merge() */
3732
3733static int
3734c_line_new (symbol, paddr, line_number, frag)
3735 symbolS * symbol;
3736 long paddr;
3737 int line_number;
3738 fragS * frag;
3739{
3740 struct lineno_list *new_line =
3741 (struct lineno_list *) xmalloc (sizeof (struct lineno_list));
3742
3743 segment_info_type *s = segment_info + now_seg;
3744 new_line->line.l_lnno = line_number;
3745
3746 if (line_number == 0)
3747 {
3748 last_line_symbol = symbol;
3749 new_line->line.l_addr.l_symndx = (long) symbol;
3750 }
3751 else
3752 {
3753 new_line->line.l_addr.l_paddr = paddr;
3754 }
3755
3756 new_line->frag = (char *) frag;
3757 new_line->next = (struct lineno_list *) NULL;
3758
3759
3760 if (s->lineno_list_head == (struct lineno_list *) NULL)
3761 {
3762 s->lineno_list_head = new_line;
3763 }
3764 else
3765 {
3766 s->lineno_list_tail->next = new_line;
3767 }
3768 s->lineno_list_tail = new_line;
3769 return LINESZ * s->scnhdr.s_nlnno++;
3770}
3771
3772void
3773c_dot_file_symbol (filename)
3774 char *filename;
3775{
3776 symbolS *symbolP;
3777
3778 symbolP = symbol_new (".file",
3779 SEG_DEBUG,
3780 0,
3781 &zero_address_frag);
3782
3783 S_SET_STORAGE_CLASS (symbolP, C_FILE);
3784 S_SET_NUMBER_AUXILIARY (symbolP, 1);
3785
3786 if (strlen (filename) > FILNMLEN)
3787 {
3788 /* Filename is too long to fit into an auxent,
3789 we stick it into the string table instead. We keep
3790 a linked list of the filenames we find so we can emit
3791 them later.*/
3792 struct filename_list *f = ((struct filename_list *)
3793 xmalloc (sizeof (struct filename_list)));
3794
3795 f->filename = filename;
3796 f->next = 0;
3797
3798 SA_SET_FILE_FNAME_ZEROS (symbolP, 0);
3799 SA_SET_FILE_FNAME_OFFSET (symbolP, 1);
3800
3801 if (filename_list_tail)
3802 filename_list_tail->next = f;
3803 else
3804 filename_list_head = f;
3805 filename_list_tail = f;
3806 }
3807 else
3808 {
3809 SA_SET_FILE_FNAME (symbolP, filename);
3810 }
3811#ifndef NO_LISTING
3812 {
3813 extern int listing;
3814 if (listing)
3815 {
3816 listing_source_file (filename);
3817 }
3818
3819 }
3820
3821#endif
3822 SF_SET_DEBUG (symbolP);
3823 S_SET_VALUE (symbolP, (valueT) previous_file_symbol);
3824
3825 previous_file_symbol = symbolP;
3826
3827 /* Make sure that the symbol is first on the symbol chain */
3828 if (symbol_rootP != symbolP)
3829 {
3830 symbol_remove (symbolP, &symbol_rootP, &symbol_lastP);
3831 symbol_insert (symbolP, symbol_rootP, &symbol_rootP, &symbol_lastP);
3832 }
3833} /* c_dot_file_symbol() */
3834
3835/*
3836 * Build a 'section static' symbol.
3837 */
3838
3839symbolS *
3840c_section_symbol (name, idx)
3841 char *name;
3842 int idx;
3843{
3844 symbolS *symbolP;
3845
3846 symbolP = symbol_find_base (name, DO_NOT_STRIP);
3847 if (symbolP == NULL)
3848 symbolP = symbol_new (name, idx, 0, &zero_address_frag);
3849 else
3850 {
3851 /* Mmmm. I just love violating interfaces. Makes me feel...dirty. */
3852 S_SET_SEGMENT (symbolP, idx);
3853 symbolP->sy_frag = &zero_address_frag;
3854 }
3855
3856 S_SET_STORAGE_CLASS (symbolP, C_STAT);
3857 S_SET_NUMBER_AUXILIARY (symbolP, 1);
3858
3859 SF_SET_STATICS (symbolP);
3860
3861#ifdef TE_DELTA
3862 /* manfred@s-direktnet.de: section symbols *must* have the LOCAL bit cleared,
3863 which is set by the new definition of LOCAL_LABEL in tc-m68k.h. */
3864 SF_CLEAR_LOCAL (symbolP);
3865#endif
3866#ifdef TE_PE
3867 /* If the .linkonce pseudo-op was used for this section, we must
3868 store the information in the auxiliary entry for the section
3869 symbol. */
3870 if (segment_info[idx].linkonce != LINKONCE_UNSET)
3871 {
3872 int type;
3873
3874 switch (segment_info[idx].linkonce)
3875 {
3876 default:
3877 abort ();
3878 case LINKONCE_DISCARD:
3879 type = IMAGE_COMDAT_SELECT_ANY;
3880 break;
3881 case LINKONCE_ONE_ONLY:
3882 type = IMAGE_COMDAT_SELECT_NODUPLICATES;
3883 break;
3884 case LINKONCE_SAME_SIZE:
3885 type = IMAGE_COMDAT_SELECT_SAME_SIZE;
3886 break;
3887 case LINKONCE_SAME_CONTENTS:
3888 type = IMAGE_COMDAT_SELECT_EXACT_MATCH;
3889 break;
3890 }
3891
3892 SYM_AUXENT (symbolP)->x_scn.x_comdat = type;
3893 }
3894#endif /* TE_PE */
3895
3896 return symbolP;
3897} /* c_section_symbol() */
3898
3899static void
3900w_symbols (abfd, where, symbol_rootP)
3901 bfd * abfd;
3902 char *where;
3903 symbolS * symbol_rootP;
3904{
3905 symbolS *symbolP;
3906 unsigned int i;
3907
3908 /* First fill in those values we have only just worked out */
3909 for (i = SEG_E0; i < SEG_LAST; i++)
3910 {
3911 symbolP = segment_info[i].dot;
3912 if (symbolP)
3913 {
3914 SA_SET_SCN_SCNLEN (symbolP, segment_info[i].scnhdr.s_size);
3915 SA_SET_SCN_NRELOC (symbolP, segment_info[i].scnhdr.s_nreloc);
3916 SA_SET_SCN_NLINNO (symbolP, segment_info[i].scnhdr.s_nlnno);
3917 }
3918 }
3919
3920 /*
3921 * Emit all symbols left in the symbol chain.
3922 */
3923 for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
3924 {
3925 /* Used to save the offset of the name. It is used to point
3926 to the string in memory but must be a file offset. */
3927 register char *temp;
3928
3929 /* We can't fix the lnnoptr field in yank_symbols with the other
3930 adjustments, because we have to wait until we know where they
3931 go in the file. */
3932 if (SF_GET_ADJ_LNNOPTR (symbolP))
3933 {
3934 SA_GET_SYM_LNNOPTR (symbolP) +=
3935 segment_info[S_GET_SEGMENT (symbolP)].scnhdr.s_lnnoptr;
3936 }
3937
3938 tc_coff_symbol_emit_hook (symbolP);
3939
3940 temp = S_GET_NAME (symbolP);
3941 if (SF_GET_STRING (symbolP))
3942 {
3943 S_SET_OFFSET (symbolP, symbolP->sy_name_offset);
3944 S_SET_ZEROES (symbolP, 0);
3945 }
3946 else
3947 {
3948 memset (symbolP->sy_symbol.ost_entry.n_name, 0, SYMNMLEN);
3949 strncpy (symbolP->sy_symbol.ost_entry.n_name, temp, SYMNMLEN);
3950 }
3951 where = symbol_to_chars (abfd, where, symbolP);
3952 S_SET_NAME (symbolP, temp);
3953 }
3954
3955} /* w_symbols() */
3956
3957static void
3958obj_coff_lcomm (ignore)
a04b544b 3959 int ignore ATTRIBUTE_UNUSED;
252b5132
RH
3960{
3961 s_lcomm(0);
3962 return;
3963#if 0
3964 char *name;
3965 char c;
3966 int temp;
3967 char *p;
3968
3969 symbolS *symbolP;
3970
3971 name = input_line_pointer;
3972
3973 c = get_symbol_end ();
3974 p = input_line_pointer;
3975 *p = c;
3976 SKIP_WHITESPACE ();
3977 if (*input_line_pointer != ',')
3978 {
3979 as_bad (_("Expected comma after name"));
3980 ignore_rest_of_line ();
3981 return;
3982 }
3983 if (*input_line_pointer == '\n')
3984 {
3985 as_bad (_("Missing size expression"));
3986 return;
3987 }
3988 input_line_pointer++;
3989 if ((temp = get_absolute_expression ()) < 0)
3990 {
3991 as_warn (_("lcomm length (%d.) <0! Ignored."), temp);
3992 ignore_rest_of_line ();
3993 return;
3994 }
3995 *p = 0;
3996
3997 symbolP = symbol_find_or_make(name);
3998
3999 if (S_GET_SEGMENT(symbolP) == SEG_UNKNOWN &&
4000 S_GET_VALUE(symbolP) == 0)
4001 {
4002 if (! need_pass_2)
4003 {
4004 char *p;
4005 segT current_seg = now_seg; /* save current seg */
4006 subsegT current_subseg = now_subseg;
4007
4008 subseg_set (SEG_E2, 1);
4009 symbolP->sy_frag = frag_now;
4010 p = frag_var(rs_org, 1, 1, (relax_substateT)0, symbolP,
4011 (offsetT) temp, (char *) 0);
4012 *p = 0;
4013 subseg_set (current_seg, current_subseg); /* restore current seg */
4014 S_SET_SEGMENT(symbolP, SEG_E2);
4015 S_SET_STORAGE_CLASS(symbolP, C_STAT);
4016 }
4017 }
4018 else
4019 as_bad(_("Symbol %s already defined"), name);
4020
4021 demand_empty_rest_of_line();
4022#endif
4023}
4024
4025static void
4026fixup_mdeps (frags, h, this_segment)
4027 fragS * frags;
4028 object_headers * h;
4029 segT this_segment;
4030{
4031 subseg_change (this_segment, 0);
4032 while (frags)
4033 {
4034 switch (frags->fr_type)
4035 {
4036 case rs_align:
4037 case rs_align_code:
4038 case rs_org:
4039#ifdef HANDLE_ALIGN
4040 HANDLE_ALIGN (frags);
4041#endif
4042 frags->fr_type = rs_fill;
4043 frags->fr_offset =
4044 ((frags->fr_next->fr_address - frags->fr_address - frags->fr_fix)
4045 / frags->fr_var);
4046 break;
4047 case rs_machine_dependent:
4048 md_convert_frag (h, this_segment, frags);
4049 frag_wane (frags);
4050 break;
4051 default:
4052 ;
4053 }
4054 frags = frags->fr_next;
4055 }
4056}
4057
4058#if 1
4059
4060#ifndef TC_FORCE_RELOCATION
4061#define TC_FORCE_RELOCATION(fix) 0
4062#endif
4063
4064static void
4065fixup_segment (segP, this_segment_type)
4066 segment_info_type * segP;
4067 segT this_segment_type;
4068{
4069 register fixS * fixP;
4070 register symbolS *add_symbolP;
4071 register symbolS *sub_symbolP;
4072 long add_number;
4073 register int size;
4074 register char *place;
4075 register long where;
4076 register char pcrel;
4077 register fragS *fragP;
4078 register segT add_symbol_segment = absolute_section;
4079
4080 for (fixP = segP->fix_root; fixP; fixP = fixP->fx_next)
4081 {
4082 fragP = fixP->fx_frag;
4083 know (fragP);
4084 where = fixP->fx_where;
4085 place = fragP->fr_literal + where;
4086 size = fixP->fx_size;
4087 add_symbolP = fixP->fx_addsy;
4088 sub_symbolP = fixP->fx_subsy;
4089 add_number = fixP->fx_offset;
4090 pcrel = fixP->fx_pcrel;
4091
4092 /* We want function-relative stabs to work on systems which
4093 may use a relaxing linker; thus we must handle the sym1-sym2
4094 fixups function-relative stabs generates.
4095
4096 Of course, if you actually enable relaxing in the linker, the
4097 line and block scoping information is going to be incorrect
4098 in some cases. The only way to really fix this is to support
4099 a reloc involving the difference of two symbols. */
4100 if (linkrelax
4101 && (!sub_symbolP || pcrel))
4102 continue;
4103
4104#ifdef TC_I960
4105 if (fixP->fx_tcbit && SF_GET_CALLNAME (add_symbolP))
4106 {
4107 /* Relocation should be done via the associated 'bal' entry
4108 point symbol. */
4109
4110 if (!SF_GET_BALNAME (tc_get_bal_of_call (add_symbolP)))
4111 {
4112 as_bad_where (fixP->fx_file, fixP->fx_line,
4113 _("No 'bal' entry point for leafproc %s"),
4114 S_GET_NAME (add_symbolP));
4115 continue;
4116 }
4117 fixP->fx_addsy = add_symbolP = tc_get_bal_of_call (add_symbolP);
4118 }
4119#endif
4120
4121 /* Make sure the symbols have been resolved; this may not have
4122 happened if these are expression symbols. */
4123 if (add_symbolP != NULL && ! add_symbolP->sy_resolved)
4124 resolve_symbol_value (add_symbolP, 1);
4125
4126 if (add_symbolP != NULL)
4127 {
4128 /* If this fixup is against a symbol which has been equated
4129 to another symbol, convert it to the other symbol. */
4130 if (add_symbolP->sy_value.X_op == O_symbol
4131 && (! S_IS_DEFINED (add_symbolP)
4132 || S_IS_COMMON (add_symbolP)))
4133 {
4134 while (add_symbolP->sy_value.X_op == O_symbol
4135 && (! S_IS_DEFINED (add_symbolP)
4136 || S_IS_COMMON (add_symbolP)))
4137 {
4138 symbolS *n;
4139
4140 /* We must avoid looping, as that can occur with a
4141 badly written program. */
4142 n = add_symbolP->sy_value.X_add_symbol;
4143 if (n == add_symbolP)
4144 break;
4145 add_number += add_symbolP->sy_value.X_add_number;
4146 add_symbolP = n;
4147 }
4148 fixP->fx_addsy = add_symbolP;
4149 fixP->fx_offset = add_number;
4150 }
4151 }
4152
4153 if (sub_symbolP != NULL && ! sub_symbolP->sy_resolved)
4154 resolve_symbol_value (sub_symbolP, 1);
4155
4156 if (add_symbolP != NULL
4157 && add_symbolP->sy_mri_common)
4158 {
4159 know (add_symbolP->sy_value.X_op == O_symbol);
4160 add_number += S_GET_VALUE (add_symbolP);
4161 fixP->fx_offset = add_number;
4162 add_symbolP = fixP->fx_addsy = add_symbolP->sy_value.X_add_symbol;
4163 }
4164
4165 if (add_symbolP)
4166 {
4167 add_symbol_segment = S_GET_SEGMENT (add_symbolP);
4168 } /* if there is an addend */
4169
4170 if (sub_symbolP)
4171 {
4172 if (add_symbolP == NULL || add_symbol_segment == absolute_section)
4173 {
4174 if (add_symbolP != NULL)
4175 {
4176 add_number += S_GET_VALUE (add_symbolP);
4177 add_symbolP = NULL;
4178 fixP->fx_addsy = NULL;
4179 }
4180
4181 /* It's just -sym. */
4182 if (S_GET_SEGMENT (sub_symbolP) == absolute_section)
4183 {
4184 add_number -= S_GET_VALUE (sub_symbolP);
4185 fixP->fx_subsy = 0;
4186 fixP->fx_done = 1;
4187 }
4188 else
4189 {
4190#ifndef TC_M68K
4191 as_bad_where (fixP->fx_file, fixP->fx_line,
4192 _("Negative of non-absolute symbol %s"),
4193 S_GET_NAME (sub_symbolP));
4194#endif
4195 add_number -= S_GET_VALUE (sub_symbolP);
4196 } /* not absolute */
4197
4198 /* if sub_symbol is in the same segment that add_symbol
4199 and add_symbol is either in DATA, TEXT, BSS or ABSOLUTE */
4200 }
4201 else if (S_GET_SEGMENT (sub_symbolP) == add_symbol_segment
4202 && SEG_NORMAL (add_symbol_segment))
4203 {
4204 /* Difference of 2 symbols from same segment. Can't
4205 make difference of 2 undefineds: 'value' means
4206 something different for N_UNDF. */
4207#ifdef TC_I960
4208 /* Makes no sense to use the difference of 2 arbitrary symbols
4209 as the target of a call instruction. */
4210 if (fixP->fx_tcbit)
4211 {
4212 as_bad_where (fixP->fx_file, fixP->fx_line,
4213 _("callj to difference of 2 symbols"));
4214 }
4215#endif /* TC_I960 */
4216 add_number += S_GET_VALUE (add_symbolP) -
4217 S_GET_VALUE (sub_symbolP);
4218 add_symbolP = NULL;
4219
4220 if (!TC_FORCE_RELOCATION (fixP))
4221 {
4222 fixP->fx_addsy = NULL;
4223 fixP->fx_subsy = NULL;
4224 fixP->fx_done = 1;
4225#ifdef TC_M68K /* is this right? */
4226 pcrel = 0;
4227 fixP->fx_pcrel = 0;
4228#endif
4229 }
4230 }
4231 else
4232 {
4233 /* Different segments in subtraction. */
4234 know (!(S_IS_EXTERNAL (sub_symbolP) && (S_GET_SEGMENT (sub_symbolP) == absolute_section)));
4235
4236 if ((S_GET_SEGMENT (sub_symbolP) == absolute_section))
4237 {
4238 add_number -= S_GET_VALUE (sub_symbolP);
4239 }
4240#ifdef DIFF_EXPR_OK
4241 else if (S_GET_SEGMENT (sub_symbolP) == this_segment_type
4242#if 0 /* Okay for 68k, at least... */
4243 && !pcrel
4244#endif
4245 )
4246 {
4247 /* Make it pc-relative. */
4248 add_number += (md_pcrel_from (fixP)
4249 - S_GET_VALUE (sub_symbolP));
4250 pcrel = 1;
4251 fixP->fx_pcrel = 1;
4252 sub_symbolP = 0;
4253 fixP->fx_subsy = 0;
4254 }
4255#endif
4256 else
4257 {
4258 as_bad_where (fixP->fx_file, fixP->fx_line,
4259 _("Can't emit reloc {- %s-seg symbol \"%s\"} @ file address %ld."),
4260 segment_name (S_GET_SEGMENT (sub_symbolP)),
4261 S_GET_NAME (sub_symbolP),
4262 (long) (fragP->fr_address + where));
4263 } /* if absolute */
4264 }
4265 } /* if sub_symbolP */
4266
4267 if (add_symbolP)
4268 {
4269 if (add_symbol_segment == this_segment_type && pcrel)
4270 {
4271 /*
4272 * This fixup was made when the symbol's segment was
4273 * SEG_UNKNOWN, but it is now in the local segment.
4274 * So we know how to do the address without relocation.
4275 */
4276#ifdef TC_I960
4277 /* reloc_callj() may replace a 'call' with a 'calls' or a 'bal',
4278 * in which cases it modifies *fixP as appropriate. In the case
4279 * of a 'calls', no further work is required, and *fixP has been
4280 * set up to make the rest of the code below a no-op.
4281 */
4282 reloc_callj (fixP);
4283#endif /* TC_I960 */
4284
4285 add_number += S_GET_VALUE (add_symbolP);
4286 add_number -= md_pcrel_from (fixP);
4287
4288 /* We used to do
4289 add_number -= segP->scnhdr.s_vaddr;
4290 if defined (TC_I386) || defined (TE_LYNX). I now
4291 think that was an error propagated from the case when
4292 we are going to emit the relocation. If we are not
4293 going to emit the relocation, then we just want to
4294 set add_number to the difference between the symbols.
4295 This is a case that would only arise when there is a
4296 PC relative reference from a section other than .text
4297 to a symbol defined in the same section, and the
4298 reference is not relaxed. Since jump instructions on
4299 the i386 are relaxed, this could only arise with a
4300 call instruction. */
4301
4302 pcrel = 0; /* Lie. Don't want further pcrel processing. */
4303 if (!TC_FORCE_RELOCATION (fixP))
4304 {
4305 fixP->fx_addsy = NULL;
4306 fixP->fx_done = 1;
4307 }
4308 }
4309 else
4310 {
4311 switch (add_symbol_segment)
4312 {
4313 case absolute_section:
4314#ifdef TC_I960
4315 reloc_callj (fixP); /* See comment about reloc_callj() above*/
4316#endif /* TC_I960 */
4317 add_number += S_GET_VALUE (add_symbolP);
4318 add_symbolP = NULL;
4319
4320 if (!TC_FORCE_RELOCATION (fixP))
4321 {
4322 fixP->fx_addsy = NULL;
4323 fixP->fx_done = 1;
4324 }
4325 break;
4326 default:
4327
4328
4329#if defined(TC_A29K) || (defined(TE_PE) && defined(TC_I386)) || defined(TC_M88K)
4330 /* This really should be handled in the linker, but
4331 backward compatibility forbids. */
4332 add_number += S_GET_VALUE (add_symbolP);
4333#else
4334 add_number += S_GET_VALUE (add_symbolP) +
4335 segment_info[S_GET_SEGMENT (add_symbolP)].scnhdr.s_paddr;
4336#endif
4337 break;
4338
4339 case SEG_UNKNOWN:
4340#ifdef TC_I960
4341 if ((int) fixP->fx_bit_fixP == 13)
4342 {
4343 /* This is a COBR instruction. They have only a
4344 * 13-bit displacement and are only to be used
4345 * for local branches: flag as error, don't generate
4346 * relocation.
4347 */
4348 as_bad_where (fixP->fx_file, fixP->fx_line,
4349 _("can't use COBR format with external label"));
4350 fixP->fx_addsy = NULL;
4351 fixP->fx_done = 1;
4352 continue;
4353 } /* COBR */
4354#endif /* TC_I960 */
4355#if ((defined (TC_I386) || defined (TE_LYNX) || defined (TE_AUX)) && !defined(TE_PE)) || defined (COFF_COMMON_ADDEND)
4356 /* 386 COFF uses a peculiar format in which the
4357 value of a common symbol is stored in the .text
4358 segment (I've checked this on SVR3.2 and SCO
4359 3.2.2) Ian Taylor <ian@cygnus.com>. */
4360 /* This is also true for 68k COFF on sysv machines
4361 (Checked on Motorola sysv68 R3V6 and R3V7.1, and also on
4362 UNIX System V/M68000, Release 1.0 from ATT/Bell Labs)
4363 Philippe De Muyter <phdm@info.ucl.ac.be>. */
4364 if (S_IS_COMMON (add_symbolP))
4365 add_number += S_GET_VALUE (add_symbolP);
4366#endif
4367 break;
4368
4369
4370 } /* switch on symbol seg */
4371 } /* if not in local seg */
4372 } /* if there was a + symbol */
4373
4374 if (pcrel)
4375 {
4376#if !defined(TC_M88K) && !(defined(TE_PE) && defined(TC_I386)) && !defined(TC_A29K)
4377 /* This adjustment is not correct on the m88k, for which the
4378 linker does all the computation. */
4379 add_number -= md_pcrel_from (fixP);
4380#endif
4381 if (add_symbolP == 0)
4382 {
4383 fixP->fx_addsy = &abs_symbol;
4384 } /* if there's an add_symbol */
4385#if defined (TC_I386) || defined (TE_LYNX) || defined (TC_I960) || defined (TC_M68K)
4386 /* On the 386 we must adjust by the segment vaddr as well.
4387 Ian Taylor.
4388
4389 I changed the i960 to work this way as well. This is
4390 compatible with the current GNU linker behaviour. I do
4391 not know what other i960 COFF assemblers do. This is not
4392 a common case: normally, only assembler code will contain
4393 a PC relative reloc, and only branches which do not
4394 originate in the .text section will have a non-zero
4395 address.
4396
4397 I changed the m68k to work this way as well. This will
4398 break existing PC relative relocs from sections which do
4399 not start at address 0, but it will make ld -r work.
4400 Ian Taylor, 4 Oct 96. */
4401
4402 add_number -= segP->scnhdr.s_vaddr;
4403#endif
4404 } /* if pcrel */
4405
ec0f0840
AM
4406#ifdef MD_APPLY_FIX3
4407 md_apply_fix3 (fixP, (valueT *) &add_number, this_segment_type);
4408#else
4409 md_apply_fix (fixP, add_number);
4410#endif
4411
252b5132
RH
4412 if (!fixP->fx_bit_fixP && ! fixP->fx_no_overflow)
4413 {
4414#ifndef TC_M88K
4415 /* The m88k uses the offset field of the reloc to get around
4416 this problem. */
4417 if ((size == 1
4418 && ((add_number & ~0xFF)
4419 || (fixP->fx_signed && (add_number & 0x80)))
4420 && ((add_number & ~0xFF) != (-1 & ~0xFF)
4421 || (add_number & 0x80) == 0))
4422 || (size == 2
4423 && ((add_number & ~0xFFFF)
4424 || (fixP->fx_signed && (add_number & 0x8000)))
4425 && ((add_number & ~0xFFFF) != (-1 & ~0xFFFF)
4426 || (add_number & 0x8000) == 0)))
4427 {
4428 as_bad_where (fixP->fx_file, fixP->fx_line,
4429 _("Value of %ld too large for field of %d bytes at 0x%lx"),
4430 (long) add_number, size,
4431 (unsigned long) (fragP->fr_address + where));
4432 }
4433#endif
4434#ifdef WARN_SIGNED_OVERFLOW_WORD
4435 /* Warn if a .word value is too large when treated as a
4436 signed number. We already know it is not too negative.
4437 This is to catch over-large switches generated by gcc on
4438 the 68k. */
4439 if (!flag_signed_overflow_ok
4440 && size == 2
4441 && add_number > 0x7fff)
4442 as_bad_where (fixP->fx_file, fixP->fx_line,
4443 _("Signed .word overflow; switch may be too large; %ld at 0x%lx"),
4444 (long) add_number,
4445 (unsigned long) (fragP->fr_address + where));
4446#endif
4447 } /* not a bit fix */
252b5132
RH
4448 } /* For each fixS in this segment. */
4449} /* fixup_segment() */
4450
4451#endif
4452
4453/* The first entry in a .stab section is special. */
4454
4455void
4456obj_coff_init_stab_section (seg)
4457 segT seg;
4458{
4459 char *file;
4460 char *p;
4461 char *stabstr_name;
4462 unsigned int stroff;
4463
4464 /* Make space for this first symbol. */
4465 p = frag_more (12);
4466 /* Zero it out. */
4467 memset (p, 0, 12);
4468 as_where (&file, (unsigned int *) NULL);
4469 stabstr_name = (char *) alloca (strlen (segment_info[seg].name) + 4);
4470 strcpy (stabstr_name, segment_info[seg].name);
4471 strcat (stabstr_name, "str");
4472 stroff = get_stab_string_offset (file, stabstr_name);
4473 know (stroff == 1);
4474 md_number_to_chars (p, stroff, 4);
4475}
4476
4477/* Fill in the counts in the first entry in a .stab section. */
4478
4479static void
4480adjust_stab_section(abfd, seg)
4481 bfd *abfd;
4482 segT seg;
4483{
4484 segT stabstrseg = SEG_UNKNOWN;
4485 const char *secname, *name2;
4486 char *name;
4487 char *p = NULL;
4488 int i, strsz = 0, nsyms;
4489 fragS *frag = segment_info[seg].frchainP->frch_root;
4490
4491 /* Look for the associated string table section. */
4492
4493 secname = segment_info[seg].name;
4494 name = (char *) alloca (strlen (secname) + 4);
4495 strcpy (name, secname);
4496 strcat (name, "str");
4497
4498 for (i = SEG_E0; i < SEG_UNKNOWN; i++)
4499 {
4500 name2 = segment_info[i].name;
4501 if (name2 != NULL && strncmp(name2, name, 8) == 0)
4502 {
4503 stabstrseg = i;
4504 break;
4505 }
4506 }
4507
4508 /* If we found the section, get its size. */
4509 if (stabstrseg != SEG_UNKNOWN)
4510 strsz = size_section (abfd, stabstrseg);
4511
4512 nsyms = size_section (abfd, seg) / 12 - 1;
4513
4514 /* Look for the first frag of sufficient size for the initial stab
4515 symbol, and collect a pointer to it. */
4516 while (frag && frag->fr_fix < 12)
4517 frag = frag->fr_next;
4518 assert (frag != 0);
4519 p = frag->fr_literal;
4520 assert (p != 0);
4521
4522 /* Write in the number of stab symbols and the size of the string
4523 table. */
4524 bfd_h_put_16 (abfd, (bfd_vma) nsyms, (bfd_byte *) p + 6);
4525 bfd_h_put_32 (abfd, (bfd_vma) strsz, (bfd_byte *) p + 8);
4526}
4527
4528#endif /* not BFD_ASSEMBLER */
4529
4c63da97 4530const pseudo_typeS coff_pseudo_table[] =
252b5132
RH
4531{
4532 {"def", obj_coff_def, 0},
4533 {"dim", obj_coff_dim, 0},
4534 {"endef", obj_coff_endef, 0},
4535 {"line", obj_coff_line, 0},
4536 {"ln", obj_coff_ln, 0},
28428223
ILT
4537#ifdef BFD_ASSEMBLER
4538 {"loc", obj_coff_loc, 0},
4539#endif
252b5132
RH
4540 {"appline", obj_coff_ln, 1},
4541 {"scl", obj_coff_scl, 0},
4542 {"size", obj_coff_size, 0},
4543 {"tag", obj_coff_tag, 0},
4544 {"type", obj_coff_type, 0},
4545 {"val", obj_coff_val, 0},
4546 {"section", obj_coff_section, 0},
4547 {"sect", obj_coff_section, 0},
4548 /* FIXME: We ignore the MRI short attribute. */
4549 {"section.s", obj_coff_section, 0},
4550 {"sect.s", obj_coff_section, 0},
4551 /* We accept the .bss directive for backward compatibility with
4552 earlier versions of gas. */
4553 {"bss", obj_coff_bss, 0},
4554 {"weak", obj_coff_weak, 0},
7a6284c4 4555 {"ident", obj_coff_ident, 0},
252b5132
RH
4556#ifndef BFD_ASSEMBLER
4557 {"use", obj_coff_section, 0},
4558 {"text", obj_coff_text, 0},
4559 {"data", obj_coff_data, 0},
4560 {"lcomm", obj_coff_lcomm, 0},
252b5132
RH
4561#else
4562 {"optim", s_ignore, 0}, /* For sun386i cc (?) */
252b5132
RH
4563#endif
4564 {"version", s_ignore, 0},
4565 {"ABORT", s_abort, 0},
4566#ifdef TC_M88K
4567 /* The m88k uses sdef instead of def. */
4568 {"sdef", obj_coff_def, 0},
4569#endif
a04b544b 4570 {NULL, NULL, 0} /* end sentinel */
4c63da97 4571}; /* coff_pseudo_table */
252b5132
RH
4572\f
4573#ifdef BFD_ASSEMBLER
4574
4575/* Support for a COFF emulation. */
4576
4c63da97
AM
4577static void coff_pop_insert PARAMS ((void));
4578
252b5132
RH
4579static void
4580coff_pop_insert ()
4581{
4c63da97 4582 pop_insert (coff_pseudo_table);
252b5132
RH
4583}
4584
252b5132
RH
4585const struct format_ops coff_format_ops =
4586{
4587 bfd_target_coff_flavour,
4c63da97
AM
4588 0, /* dfl_leading_underscore */
4589 1, /* emit_section_symbols */
252b5132 4590 coff_frob_symbol,
4c63da97 4591 0, /* frob_file */
252b5132 4592 coff_frob_file_after_relocs,
4c63da97
AM
4593 0, /* s_get_size */
4594 0, /* s_set_size */
4595 0, /* s_get_align */
4596 0, /* s_set_align */
4597 0, /* s_get_other */
4598 0, /* s_get_desc */
4599 0, /* copy_symbol_attributes */
4600 0, /* generate_asm_lineno */
4601 0, /* process_stab */
4602 0, /* sec_sym_ok_for_reloc */
252b5132 4603 coff_pop_insert,
4c63da97 4604 0, /* ecoff_set_ext */
252b5132 4605 coff_obj_read_begin_hook,
4c63da97 4606 coff_obj_symbol_new_hook
252b5132
RH
4607};
4608
4609#endif