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