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