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