]> Git Repo - binutils.git/blob - gas/config/obj-coffbfd.c
Ran "indent", for GNU coding style; some code & comments still need fixup.
[binutils.git] / gas / config / obj-coffbfd.c
1 /* coff object file format with bfd
2    Copyright (C) 1989, 1990, 1991 Free Software Foundation, Inc.
3
4 This file is part of GAS.
5
6 GAS is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GAS is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GAS; see the file COPYING.  If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
19
20 /*
21
22  How does this releate to the rest of GAS ?
23
24  Well, all the other files in gas are more or less a black box. It
25  takes care of opening files, parsing command lines, stripping blanks
26  etc etc. This module gets a chance to register what it wants to do by
27  saying that it is interested in various pseduo ops. The other big
28  change is write_object_file. This runs through all the data
29  structures that gas builds, and outputs the file in the format of our
30  choice.
31
32  Hacked for BFDness by steve chamberlain
33
34  This object module now supports the Hitachi H8/300 and the AMD 29k
35
36  [email protected]
37 */
38
39 #include "as.h"
40 #include "obstack.h"
41 #include "subsegs.h"
42 #include "frags.h"
43 #include "../bfd/libbfd.h"
44
45
46 #define MIN(a,b) ((a) < (b)? (a) : (b))
47 /* This vector is used to turn an internal segment into a section #
48    suitable for insertion into a coff symbol table
49  */
50
51 const short seg_N_TYPE[] =
52 {                               /* in: segT   out: N_TYPE bits */
53   C_ABS_SECTION,
54   1,
55   2,
56   3,
57   4,
58   5,
59   6,
60   7,
61   8,
62   9,
63   10,
64   C_UNDEF_SECTION,              /* SEG_UNKNOWN */
65   C_UNDEF_SECTION,              /* SEG_ABSENT */
66   C_UNDEF_SECTION,              /* SEG_PASS1 */
67   C_UNDEF_SECTION,              /* SEG_GOOF */
68   C_UNDEF_SECTION,              /* SEG_BIG */
69   C_UNDEF_SECTION,              /* SEG_DIFFERENCE */
70   C_DEBUG_SECTION,              /* SEG_DEBUG */
71   C_NTV_SECTION,                /* SEG_NTV */
72   C_PTV_SECTION,                /* SEG_PTV */
73   C_REGISTER_SECTION,           /* SEG_REGISTER */
74 };
75
76
77 int function_lineoff = -1;      /* Offset in line#s where the last function
78                                    started (the odd entry for line #0) */
79
80
81 int had_lineno = 0;
82 int had_reloc = 0;
83
84 static symbolS *last_line_symbol;
85 /* Add 4 to the real value to get the index and compensate the
86    negatives. This vector is used by S_GET_SEGMENT to turn a coff
87    section number into a segment number
88 */
89 static symbolS *previous_file_symbol = NULL;
90 void c_symbol_merge ();
91 static int line_base;
92
93 symbolS *c_section_symbol ();
94 bfd *abfd;
95 void EXFUN (bfd_as_write_hook, (struct internal_filehdr *,
96                                 bfd * abfd));
97
98 static void EXFUN (fixup_segment, (fixS * fixP,
99                                    segT this_segment_type));
100
101
102 static void EXFUN (fixup_mdeps, (fragS *));
103
104
105 static void EXFUN (fill_section, (bfd * abfd,
106                                   struct internal_filehdr * f, unsigned
107                                   long *));
108
109
110 char *EXFUN (s_get_name, (symbolS * s));
111 static symbolS *EXFUN (tag_find_or_make, (char *name));
112 static symbolS *EXFUN (tag_find, (char *name));
113
114
115 static int
116   EXFUN (c_line_new, (
117                        symbolS * symbol,
118                        long paddr,
119                        unsigned short line_number,
120                        fragS * frag));
121
122
123 static void EXFUN (w_symbols,
124                      (bfd * abfd,
125                       char *where,
126                       symbolS * symbol_rootP));
127
128
129
130 static void EXFUN (obj_coff_def, (int what));
131 static void EXFUN (obj_coff_lcomm, (void));
132 static void EXFUN (obj_coff_dim, (void));
133 static void EXFUN (obj_coff_text, (void));
134 static void EXFUN (obj_coff_data, (void));
135 static void EXFUN (obj_coff_endef, (void));
136 static void EXFUN (obj_coff_line, (void));
137 static void EXFUN (obj_coff_ln, (void));
138 static void EXFUN (obj_coff_scl, (void));
139 static void EXFUN (obj_coff_size, (void));
140 static void EXFUN (obj_coff_tag, (void));
141 static void EXFUN (obj_coff_type, (void));
142 static void EXFUN (obj_coff_val, (void));
143 void EXFUN (obj_coff_section, (void));
144 static void EXFUN (tag_init, (void));
145 static void EXFUN (tag_insert, (char *name, symbolS * symbolP));
146
147
148 static struct hash_control *tag_hash;
149 static symbolS *def_symbol_in_progress = NULL;
150
151 const pseudo_typeS obj_pseudo_table[] =
152 {
153   {"def", obj_coff_def, 0},
154   {"dim", obj_coff_dim, 0},
155   {"endef", obj_coff_endef, 0},
156   {"line", obj_coff_line, 0},
157   {"ln", obj_coff_ln, 0},
158   {"scl", obj_coff_scl, 0},
159   {"size", obj_coff_size, 0},
160   {"tag", obj_coff_tag, 0},
161   {"type", obj_coff_type, 0},
162   {"val", obj_coff_val, 0},
163   {"section", obj_coff_section, 0},
164   {"use", obj_coff_section, 0},
165   {"sect", obj_coff_section, 0},
166   {"text", obj_coff_text, 0},
167   {"data", obj_coff_data, 0},
168 /* we don't yet handle this. */
169   {"ident", s_ignore, 0},
170   {"ABORT", s_abort, 0},
171   {"lcomm", obj_coff_lcomm, 0},
172   {NULL}                        /* end sentinel */
173 };                              /* obj_pseudo_table */
174
175
176
177 /* Section stuff
178
179    We allow more than just the standard 3 sections, infact, we allow
180    10 sections, (though the usual three have to be there).
181
182    This structure performs the mappings for us:
183
184 */
185
186 /* OBS stuff
187 static struct internal_scnhdr bss_section_header;
188 struct internal_scnhdr data_section_header;
189 struct internal_scnhdr text_section_header;
190
191 const segT N_TYPE_seg [32] =
192 {
193
194 };
195
196 */
197
198 #define N_SEG 32
199 typedef struct
200 {
201   segT seg_t;
202   int i;
203 }
204
205 seg_info_type;
206
207 seg_info_type seg_info_off_by_4[N_SEG] =
208 {
209   {SEG_PTV,},
210   {SEG_NTV,},
211   {SEG_DEBUG,},
212   {SEG_ABSOLUTE,},
213   {SEG_UNKNOWN,},
214   {SEG_E0},
215   {SEG_E1},
216   {SEG_E2},
217   {SEG_E3},
218   {SEG_E4},
219   {SEG_E5},
220   {SEG_E6},
221   {SEG_E7},
222   {SEG_E8},
223   {SEG_E9},
224   {15},
225   {16},
226   {17},
227   {18},
228   {19},
229   {20},
230   {0},
231   {0},
232   {0},
233   {SEG_REGISTER}, 0, 0, 0, 0};
234
235 #define SEG_INFO_FROM_SECTION_NUMBER(x) (seg_info_off_by_4[(x)+4])
236 #define SEG_INFO_FROM_SEG_NUMBER(x) (seg_info_off_by_4[(x)])
237
238
239 relax_addressT
240 DEFUN (relax_align, (address, alignment),
241        register relax_addressT address AND
242        register long alignment)
243 {
244   relax_addressT mask;
245   relax_addressT new_address;
246
247   mask = ~((~0) << alignment);
248   new_address = (address + mask) & (~mask);
249   return (new_address - address);
250 }                               /* relax_align() */
251
252
253 segT
254 DEFUN (s_get_segment, (x),
255        symbolS * x)
256 {
257   return SEG_INFO_FROM_SECTION_NUMBER (x->sy_symbol.ost_entry.n_scnum).seg_t;
258 }
259
260
261
262 /* calculate the size of the frag chain and fill in the section header
263    to contain all of it, also fill in the addr of the sections */
264 static unsigned int
265 DEFUN (size_section, (abfd, idx),
266        bfd * abfd AND
267        unsigned int idx)
268 {
269
270   unsigned int size = 0;
271   fragS *frag = segment_info[idx].frchainP->frch_root;
272   while (frag)
273     {
274       size = frag->fr_address;
275 #if 0
276       if (frag->fr_address != size)
277         {
278           printf ("Out of step\n");
279           size = frag->fr_address;
280         }
281
282       switch (frag->fr_type)
283         {
284 #ifdef TC_COFF_SIZEMACHDEP
285         case rs_machine_dependent:
286           size += TC_COFF_SIZEMACHDEP (frag);
287           break;
288 #endif
289         case rs_fill:
290         case rs_org:
291           size += frag->fr_fix;
292           size += frag->fr_offset * frag->fr_var;
293           break;
294         case rs_align:
295           size += frag->fr_fix;
296           size += relax_align (size, frag->fr_offset);
297         }
298 #endif
299       frag = frag->fr_next;
300     }
301   segment_info[idx].scnhdr.s_size = size;
302   return size;
303 }
304
305
306 static unsigned int
307 DEFUN (count_entries_in_chain, (idx),
308        unsigned int idx)
309 {
310   unsigned int nrelocs;
311   fixS *fixup_ptr;
312
313   /* Count the relocations */
314   fixup_ptr = segment_info[idx].fix_root;
315   nrelocs = 0;
316   while (fixup_ptr != (fixS *) NULL)
317     {
318       if (TC_COUNT_RELOC (fixup_ptr))
319         {
320
321 #ifdef TC_A29K
322
323           if (fixup_ptr->fx_r_type == RELOC_CONSTH)
324             nrelocs += 2;
325           else
326             nrelocs++;
327 #else
328           nrelocs++;
329 #endif
330         }
331
332       fixup_ptr = fixup_ptr->fx_next;
333     }
334   return nrelocs;
335 }
336
337 /* output all the relocations for a section */
338 void
339 DEFUN (do_relocs_for, (abfd, file_cursor),
340        bfd * abfd AND
341        unsigned long *file_cursor)
342 {
343   unsigned int nrelocs;
344   unsigned int idx;
345   unsigned int addr = 0;
346   for (idx = SEG_E0; idx < SEG_E9; idx++)
347     {
348       if (segment_info[idx].scnhdr.s_name[0])
349         {
350
351           struct external_reloc *ext_ptr;
352           struct external_reloc *external_reloc_vec;
353           unsigned int external_reloc_size;
354           unsigned int count = 0;
355           unsigned int base = addr;
356           fixS *fix_ptr = segment_info[idx].fix_root;
357           nrelocs = count_entries_in_chain (idx);
358
359           if (nrelocs)
360             had_reloc = 1;
361
362           external_reloc_size = nrelocs * RELSZ;
363           external_reloc_vec =
364             (struct external_reloc *) malloc (external_reloc_size);
365
366
367
368           ext_ptr = external_reloc_vec;
369
370           /* Fill in the internal coff style reloc struct from the
371          internal fix list */
372           while (fix_ptr)
373             {
374               symbolS *symbol_ptr;
375               struct internal_reloc intr;
376
377               /* Only output some of the relocations */
378               if (TC_COUNT_RELOC (fix_ptr))
379                 {
380 #ifdef TC_RELOC_MANGLE
381                   TC_RELOC_MANGLE (fix_ptr, &intr, base);
382
383 #else
384                   symbolS *dot;
385                   symbol_ptr = fix_ptr->fx_addsy;
386
387                   intr.r_type = TC_COFF_FIX2RTYPE (fix_ptr);
388                   intr.r_vaddr =
389                     base + fix_ptr->fx_frag->fr_address + fix_ptr->fx_where;
390
391                   intr.r_offset = fix_ptr->fx_offset;
392
393                   intr.r_offset = 0;
394
395                   /* Turn the segment of the symbol into an offset
396            */
397                   if (symbol_ptr)
398                     {
399                       dot = segment_info[S_GET_SEGMENT (symbol_ptr)].dot;
400                       if (dot)
401                         {
402                           intr.r_symndx = dot->sy_number;
403                         }
404                       else
405                         {
406                           intr.r_symndx = symbol_ptr->sy_number;
407                         }
408
409                     }
410                   else
411                     {
412                       intr.r_symndx = -1;
413
414
415                     }
416 #endif
417
418                   (void) bfd_coff_swap_reloc_out (abfd, &intr, ext_ptr);
419                   ext_ptr++;
420
421 #if defined(TC_A29K)
422                   /* The 29k has a special kludge for the high 16 bit reloc.
423              Two relocations are emmited, R_IHIHALF, and
424              R_IHCONST. The second one doesn't contain a symbol,
425              but uses the value for offset */
426
427                   if (intr.r_type == R_IHIHALF)
428                     {
429                       /* now emit the second bit */
430                       intr.r_type = R_IHCONST;
431                       intr.r_symndx = fix_ptr->fx_addnumber;
432                       (void) bfd_coff_swap_reloc_out (abfd, &intr, ext_ptr);
433                       ext_ptr++;
434                     }
435 #endif
436                 }
437
438               fix_ptr = fix_ptr->fx_next;
439             }
440
441           /* Write out the reloc table */
442           segment_info[idx].scnhdr.s_relptr = *file_cursor;
443           segment_info[idx].scnhdr.s_nreloc = nrelocs;
444           bfd_write ((PTR) external_reloc_vec, 1, external_reloc_size, abfd);
445           *file_cursor += external_reloc_size;
446           free (external_reloc_vec);
447         }
448 #ifndef ZERO_BASED_SEGMENTS
449       /* Supposedly setting segment addresses non-zero causes problems
450        for some platforms, although it shouldn't.  If you define
451        ZERO_BASED_SEGMENTS, all the segments will be based at 0.
452        Please don't make this the default, since some systems (e.g.,
453        SVR3.2) require the segments to be non-zero based.  Ian Taylor
454        <[email protected]>.  */
455       addr += segment_info[idx].scnhdr.s_size;
456 #endif
457     }
458 }
459
460
461 /* run through a frag chain and write out the data to go with it, fill
462    in the scnhdrs with the info on the file postions
463 */
464 static void
465 DEFUN (fill_section, (abfd, filehdr, file_cursor),
466        bfd * abfd AND
467        struct internal_filehdr *filehdr AND
468        unsigned long *file_cursor)
469 {
470
471   unsigned int i;
472
473   for (i = SEG_E0; i < SEG_UNKNOWN; i++)
474     {
475       unsigned int offset = 0;
476
477       struct internal_scnhdr *s = &(segment_info[i].scnhdr);
478
479       if (s->s_name[0])
480         {
481           fragS *frag = segment_info[i].frchainP->frch_root;
482           char *buffer = malloc (s->s_size);
483           if (s->s_size != 0)
484             s->s_scnptr = *file_cursor;
485           else
486             s->s_scnptr = 0;
487
488           s->s_flags = STYP_REG;
489           if (strcmp (s->s_name, ".text") == 0)
490             s->s_flags |= STYP_TEXT;
491           else if (strcmp (s->s_name, ".data") == 0)
492             s->s_flags |= STYP_DATA;
493           else if (strcmp (s->s_name, ".bss") == 0)
494             s->s_flags |= STYP_BSS | STYP_NOLOAD;
495           else if (strcmp (s->s_name, ".lit") == 0)
496             s->s_flags = STYP_LIT | STYP_TEXT;
497
498
499           while (frag)
500             {
501               unsigned int fill_size;
502               switch (frag->fr_type)
503                 {
504                 case rs_machine_dependent:
505                   if (frag->fr_fix)
506                     {
507                       memcpy (buffer + frag->fr_address,
508                               frag->fr_literal,
509                               frag->fr_fix);
510                       offset += frag->fr_fix;
511                     }
512
513                   break;
514                 case rs_fill:
515                 case rs_align:
516                 case rs_org:
517                   if (frag->fr_fix)
518                     {
519                       memcpy (buffer + frag->fr_address,
520                               frag->fr_literal,
521                               frag->fr_fix);
522                       offset += frag->fr_fix;
523                     }
524
525                   fill_size = frag->fr_var;
526                   if (fill_size)
527                     {
528                       unsigned int count;
529                       unsigned int off = frag->fr_fix;
530                       for (count = frag->fr_offset; count; count--)
531                         {
532                           memcpy (buffer + frag->fr_address + off,
533                                   frag->fr_literal + frag->fr_fix,
534                                   fill_size);
535                           off += fill_size;
536                           offset += fill_size;
537
538                         }
539
540                     }
541                   break;
542                 case rs_broken_word:
543                   break;
544                 default:
545                   abort ();
546                 }
547               frag = frag->fr_next;
548             }
549
550
551           bfd_write (buffer, s->s_size, 1, abfd);
552           free (buffer);
553
554           *file_cursor += s->s_size;
555
556         }
557     }
558
559 }
560
561
562
563 /* Coff file generation & utilities */
564
565
566 static void
567 DEFUN (coff_header_append, (abfd, filehdr, aouthdr),
568        bfd * abfd AND
569        struct internal_filehdr *filehdr AND
570        struct internal_aouthdr *aouthdr)
571 {
572   unsigned int i;
573   char buffer[1000];
574   char buffero[1000];
575
576   bfd_seek (abfd, 0, 0);
577 #if 0
578   filehdr.f_opthdr = bfd_coff_swap_aouthdr_out (abfd, aouthdr,
579                                                 buffero);
580 #else
581   filehdr->f_opthdr = 0;
582 #endif
583   i = bfd_coff_swap_filehdr_out (abfd, filehdr, buffer);
584
585   bfd_write (buffer, i, 1, abfd);
586   bfd_write (buffero, filehdr->f_opthdr, 1, abfd);
587
588   for (i = SEG_E0; i < SEG_E9; i++)
589     {
590       if (segment_info[i].scnhdr.s_name[0])
591         {
592           unsigned int size =
593           bfd_coff_swap_scnhdr_out (abfd,
594                                     &(segment_info[i].scnhdr),
595                                     buffer);
596           bfd_write (buffer, size, 1, abfd);
597         }
598     }
599 }
600
601
602 char *
603 DEFUN (symbol_to_chars, (abfd, where, symbolP),
604        bfd * abfd AND
605        char *where AND
606        symbolS * symbolP)
607 {
608   unsigned int numaux = symbolP->sy_symbol.ost_entry.n_numaux;
609   unsigned int i;
610
611   /* Turn any symbols with register attributes into abs symbols */
612   if (S_GET_SEGMENT (symbolP) == SEG_REGISTER)
613     {
614       S_SET_SEGMENT (symbolP, SEG_ABSOLUTE);
615     }
616   /* At the same time, relocate all symbols to their output value */
617
618   S_SET_VALUE (symbolP,
619                segment_info[S_GET_SEGMENT (symbolP)].scnhdr.s_paddr
620                + S_GET_VALUE (symbolP));
621
622   where += bfd_coff_swap_sym_out (abfd, &symbolP->sy_symbol.ost_entry,
623                                   where);
624
625   for (i = 0; i < numaux; i++)
626     {
627       where += bfd_coff_swap_aux_out (abfd,
628                                       &symbolP->sy_symbol.ost_auxent[i],
629                                       S_GET_DATA_TYPE (symbolP),
630                                       S_GET_STORAGE_CLASS (symbolP),
631                                       where);
632     }
633   return where;
634
635 }
636
637
638
639
640 void
641 obj_symbol_new_hook (symbolP)
642      symbolS *symbolP;
643 {
644   char underscore = 0;          /* Symbol has leading _ */
645
646   /* Effective symbol */
647   /* Store the pointer in the offset. */
648   S_SET_ZEROES (symbolP, 0L);
649   S_SET_DATA_TYPE (symbolP, T_NULL);
650   S_SET_STORAGE_CLASS (symbolP, 0);
651   S_SET_NUMBER_AUXILIARY (symbolP, 0);
652   /* Additional information */
653   symbolP->sy_symbol.ost_flags = 0;
654   /* Auxiliary entries */
655   bzero ((char *) &symbolP->sy_symbol.ost_auxent[0], AUXESZ);
656
657 #ifdef STRIP_UNDERSCORE
658   /* Remove leading underscore at the beginning of the symbol.
659          * This is to be compatible with the standard librairies.
660          */
661   if (*S_GET_NAME (symbolP) == '_')
662     {
663       underscore = 1;
664       S_SET_NAME (symbolP, S_GET_NAME (symbolP) + 1);
665     }                           /* strip underscore */
666 #endif /* STRIP_UNDERSCORE */
667
668   if (S_IS_STRING (symbolP))
669     SF_SET_STRING (symbolP);
670   if (!underscore && S_IS_LOCAL (symbolP))
671     SF_SET_LOCAL (symbolP);
672
673   return;
674 }                               /* obj_symbol_new_hook() */
675
676 /* stack stuff */
677 stack *
678 stack_init (chunk_size, element_size)
679      unsigned long chunk_size;
680      unsigned long element_size;
681 {
682   stack *st;
683
684   if ((st = (stack *) malloc (sizeof (stack))) == (stack *) 0)
685     return (stack *) 0;
686   if ((st->data = malloc (chunk_size)) == (char *) 0)
687     {
688       free (st);
689       return (stack *) 0;
690     }
691   st->pointer = 0;
692   st->size = chunk_size;
693   st->chunk_size = chunk_size;
694   st->element_size = element_size;
695   return st;
696 }                               /* stack_init() */
697
698 void
699 stack_delete (st)
700      stack *st;
701 {
702   free (st->data);
703   free (st);
704 }
705
706 char *
707 stack_push (st, element)
708      stack *st;
709      char *element;
710 {
711   if (st->pointer + st->element_size >= st->size)
712     {
713       st->size += st->chunk_size;
714       if ((st->data = xrealloc (st->data, st->size)) == (char *) 0)
715         return (char *) 0;
716     }
717   memcpy (st->data + st->pointer, element, st->element_size);
718   st->pointer += st->element_size;
719   return st->data + st->pointer;
720 }                               /* stack_push() */
721
722 char *
723 stack_pop (st)
724      stack *st;
725 {
726   if ((st->pointer -= st->element_size) < 0)
727     {
728       st->pointer = 0;
729       return (char *) 0;
730     }
731
732   return st->data + st->pointer;
733 }
734
735 char *
736 stack_top (st)
737      stack *st;
738 {
739   return st->data + st->pointer - st->element_size;
740 }
741
742
743 /*
744  * Handle .ln directives.
745  */
746
747 static void
748 obj_coff_ln ()
749 {
750   int l;
751
752   if (def_symbol_in_progress != NULL)
753     {
754       as_warn (".ln pseudo-op inside .def/.endef: ignored.");
755       demand_empty_rest_of_line ();
756       return;
757     }                           /* wrong context */
758
759   c_line_new (0,
760               obstack_next_free (&frags) - frag_now->fr_literal,
761               l = get_absolute_expression (),
762               frag_now);
763 #ifndef NO_LISTING
764   {
765     extern int listing;
766
767     if (listing)
768       {
769         listing_source_line (l + line_base - 1);
770       }
771
772   }
773 #endif
774   demand_empty_rest_of_line ();
775   return;
776 }                               /* obj_coff_line() */
777
778 /*
779  *                      def()
780  *
781  * Handle .def directives.
782  *
783  * One might ask : why can't we symbol_new if the symbol does not
784  * already exist and fill it with debug information.  Because of
785  * the C_EFCN special symbol. It would clobber the value of the
786  * function symbol before we have a chance to notice that it is
787  * a C_EFCN. And a second reason is that the code is more clear this
788  * way. (at least I think it is :-).
789  *
790  */
791
792 #define SKIP_SEMI_COLON()       while (*input_line_pointer++ != ';')
793 #define SKIP_WHITESPACES()      while (*input_line_pointer == ' ' || \
794                                       *input_line_pointer == '\t') \
795                                          input_line_pointer++;
796
797 static void
798 DEFUN (obj_coff_def, (what),
799        int what)
800 {
801   char name_end;                /* Char after the end of name */
802   char *symbol_name;            /* Name of the debug symbol */
803   char *symbol_name_copy;       /* Temporary copy of the name */
804   unsigned int symbol_name_length;
805   /*$char*      directiveP;$ *//* Name of the pseudo opcode */
806   /*$char directive[MAX_DIRECTIVE];$ *//* Backup of the directive */
807   /*$char end = 0;$ *//* If 1, stop parsing */
808
809   if (def_symbol_in_progress != NULL)
810     {
811       as_warn (".def pseudo-op used inside of .def/.endef: ignored.");
812       demand_empty_rest_of_line ();
813       return;
814     }                           /* if not inside .def/.endef */
815
816   SKIP_WHITESPACES ();
817
818   def_symbol_in_progress = (symbolS *) obstack_alloc (&notes, sizeof (*def_symbol_in_progress));
819   bzero (def_symbol_in_progress, sizeof (*def_symbol_in_progress));
820
821   symbol_name = input_line_pointer;
822   name_end = get_symbol_end ();
823   symbol_name_length = strlen (symbol_name);
824   symbol_name_copy = xmalloc (symbol_name_length + 1);
825   strcpy (symbol_name_copy, symbol_name);
826
827   /* Initialize the new symbol */
828 #ifdef STRIP_UNDERSCORE
829   S_SET_NAME (def_symbol_in_progress, (*symbol_name_copy == '_'
830                                        ? symbol_name_copy + 1
831                                        : symbol_name_copy));
832 #else /* STRIP_UNDERSCORE */
833   S_SET_NAME (def_symbol_in_progress, symbol_name_copy);
834 #endif /* STRIP_UNDERSCORE */
835   /* free(symbol_name_copy); */
836   def_symbol_in_progress->sy_name_offset = ~0;
837   def_symbol_in_progress->sy_number = ~0;
838   def_symbol_in_progress->sy_frag = &zero_address_frag;
839
840   if (S_IS_STRING (def_symbol_in_progress))
841     {
842       SF_SET_STRING (def_symbol_in_progress);
843     }                           /* "long" name */
844
845   *input_line_pointer = name_end;
846
847   demand_empty_rest_of_line ();
848   return;
849 }                               /* obj_coff_def() */
850
851 unsigned int dim_index;
852 static void
853 DEFUN_VOID (obj_coff_endef)
854 {
855   symbolS *symbolP = 0;
856   /* DIM BUG FIX [email protected] */
857   dim_index = 0;
858   if (def_symbol_in_progress == NULL)
859     {
860       as_warn (".endef pseudo-op used outside of .def/.endef: ignored.");
861       demand_empty_rest_of_line ();
862       return;
863     }                           /* if not inside .def/.endef */
864
865   /* Set the section number according to storage class. */
866   switch (S_GET_STORAGE_CLASS (def_symbol_in_progress))
867     {
868     case C_STRTAG:
869     case C_ENTAG:
870     case C_UNTAG:
871       SF_SET_TAG (def_symbol_in_progress);
872       /* intentional fallthrough */
873     case C_FILE:
874     case C_TPDEF:
875       SF_SET_DEBUG (def_symbol_in_progress);
876       S_SET_SEGMENT (def_symbol_in_progress, SEG_DEBUG);
877       break;
878
879     case C_EFCN:
880       SF_SET_LOCAL (def_symbol_in_progress);    /* Do not emit this symbol. */
881       /* intentional fallthrough */
882     case C_BLOCK:
883       SF_SET_PROCESS (def_symbol_in_progress);  /* Will need processing before writing */
884       /* intentional fallthrough */
885     case C_FCN:
886       S_SET_SEGMENT (def_symbol_in_progress, SEG_E0);
887
888       if (def_symbol_in_progress->sy_symbol.ost_entry._n._n_nptr[1][1] == 'b'
889       && def_symbol_in_progress->sy_symbol.ost_entry._n._n_nptr[1][2] == 'f')
890         {                       /* .bf */
891           if (function_lineoff < 0)
892             {
893               fprintf (stderr, "`.bf' symbol without preceding function\n");
894             }                   /* missing function symbol */
895           SA_GET_SYM_LNNOPTR (last_line_symbol) = function_lineoff;
896
897           SF_SET_PROCESS (last_line_symbol);
898           function_lineoff = -1;
899         }
900       break;
901
902 #ifdef C_AUTOARG
903     case C_AUTOARG:
904 #endif /* C_AUTOARG */
905     case C_AUTO:
906     case C_REG:
907     case C_MOS:
908     case C_MOE:
909     case C_MOU:
910     case C_ARG:
911     case C_REGPARM:
912     case C_FIELD:
913     case C_EOS:
914       SF_SET_DEBUG (def_symbol_in_progress);
915       S_SET_SEGMENT (def_symbol_in_progress, SEG_ABSOLUTE);
916       break;
917
918     case C_EXT:
919     case C_STAT:
920     case C_LABEL:
921       /* Valid but set somewhere else (s_comm, s_lcomm, colon) */
922       break;
923
924     case C_USTATIC:
925     case C_EXTDEF:
926     case C_ULABEL:
927       as_warn ("unexpected storage class %d", S_GET_STORAGE_CLASS (def_symbol_in_progress));
928       break;
929     }                           /* switch on storage class */
930
931   /* Now that we have built a debug symbol, try to
932        find if we should merge with an existing symbol
933        or not.  If a symbol is C_EFCN or SEG_ABSOLUTE or
934        untagged SEG_DEBUG it never merges. */
935
936   /* Two cases for functions.  Either debug followed
937        by definition or definition followed by debug.
938        For definition first, we will merge the debug
939        symbol into the definition.  For debug first, the
940        lineno entry MUST point to the definition
941        function or else it will point off into space
942        when crawl_symbols() merges the debug
943        symbol into the real symbol.  Therefor, let's
944        presume the debug symbol is a real function
945        reference. */
946
947   /* FIXME-SOON If for some reason the definition
948        label/symbol is never seen, this will probably
949        leave an undefined symbol at link time. */
950
951   if (S_GET_STORAGE_CLASS (def_symbol_in_progress) == C_EFCN
952       || (S_GET_SEGMENT (def_symbol_in_progress) == SEG_DEBUG
953           && !SF_GET_TAG (def_symbol_in_progress))
954       || S_GET_SEGMENT (def_symbol_in_progress) == SEG_ABSOLUTE
955       || (symbolP = symbol_find_base (S_GET_NAME (def_symbol_in_progress), DO_NOT_STRIP)) == NULL)
956     {
957
958       symbol_append (def_symbol_in_progress, symbol_lastP, &symbol_rootP, &symbol_lastP);
959
960     }
961   else
962     {
963       /* This symbol already exists, merge the
964                    newly created symbol into the old one.
965                    This is not mandatory. The linker can
966                    handle duplicate symbols correctly. But I
967                    guess that it save a *lot* of space if
968                    the assembly file defines a lot of
969                    symbols. [loic] */
970
971       /* The debug entry (def_symbol_in_progress)
972                    is merged into the previous definition. */
973
974       c_symbol_merge (def_symbol_in_progress, symbolP);
975       /* FIXME-SOON Should *def_symbol_in_progress be free'd? xoxorich. */
976       def_symbol_in_progress = symbolP;
977
978       if (SF_GET_FUNCTION (def_symbol_in_progress)
979           || SF_GET_TAG (def_symbol_in_progress))
980         {
981           /* For functions, and tags, the symbol *must* be where the debug symbol
982                            appears.  Move the existing symbol to the current place. */
983           /* If it already is at the end of the symbol list, do nothing */
984           if (def_symbol_in_progress != symbol_lastP)
985             {
986               symbol_remove (def_symbol_in_progress, &symbol_rootP, &symbol_lastP);
987               symbol_append (def_symbol_in_progress, symbol_lastP, &symbol_rootP, &symbol_lastP);
988             }                   /* if not already in place */
989         }                       /* if function */
990     }                           /* normal or mergable */
991
992   if (SF_GET_TAG (def_symbol_in_progress)
993       && symbol_find_base (S_GET_NAME (def_symbol_in_progress), DO_NOT_STRIP) == NULL)
994     {
995       tag_insert (S_GET_NAME (def_symbol_in_progress), def_symbol_in_progress);
996     }                           /* If symbol is a {structure,union} tag, associate symbol to its name. */
997
998   if (SF_GET_FUNCTION (def_symbol_in_progress))
999     {
1000       know (sizeof (def_symbol_in_progress) <= sizeof (long));
1001       function_lineoff
1002         = c_line_new (def_symbol_in_progress, 0, 0, &zero_address_frag);
1003
1004
1005
1006       SF_SET_PROCESS (def_symbol_in_progress);
1007
1008       if (symbolP == NULL)
1009         {
1010           /* That is, if this is the first
1011                        time we've seen the function... */
1012           symbol_table_insert (def_symbol_in_progress);
1013         }                       /* definition follows debug */
1014     }                           /* Create the line number entry pointing to the function being defined */
1015
1016   def_symbol_in_progress = NULL;
1017   demand_empty_rest_of_line ();
1018   return;
1019 }                               /* obj_coff_endef() */
1020
1021 static void
1022 DEFUN_VOID (obj_coff_dim)
1023 {
1024   register int dim_index;
1025
1026   if (def_symbol_in_progress == NULL)
1027     {
1028       as_warn (".dim pseudo-op used outside of .def/.endef: ignored.");
1029       demand_empty_rest_of_line ();
1030       return;
1031     }                           /* if not inside .def/.endef */
1032
1033   S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
1034
1035   for (dim_index = 0; dim_index < DIMNUM; dim_index++)
1036     {
1037       SKIP_WHITESPACES ();
1038       SA_SET_SYM_DIMEN (def_symbol_in_progress, dim_index, get_absolute_expression ());
1039
1040       switch (*input_line_pointer)
1041         {
1042
1043         case ',':
1044           input_line_pointer++;
1045           break;
1046
1047         default:
1048           as_warn ("badly formed .dim directive ignored");
1049           /* intentional fallthrough */
1050         case '\n':
1051         case ';':
1052           dim_index = DIMNUM;
1053           break;
1054         }                       /* switch on following character */
1055     }                           /* for each dimension */
1056
1057   demand_empty_rest_of_line ();
1058   return;
1059 }                               /* obj_coff_dim() */
1060
1061 static void
1062 obj_coff_line ()
1063 {
1064   int this_base;
1065
1066   if (def_symbol_in_progress == NULL)
1067     {
1068       obj_coff_ln ();
1069       return;
1070     }                           /* if it looks like a stabs style line */
1071
1072   this_base = get_absolute_expression ();
1073   if (this_base > line_base)
1074     {
1075       line_base = this_base;
1076     }
1077
1078
1079 #ifndef NO_LISTING
1080   {
1081     extern int listing;
1082     if (listing && 0)
1083       {
1084         listing_source_line (line_base);
1085       }
1086   }
1087 #endif
1088   S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
1089   SA_SET_SYM_LNNO (def_symbol_in_progress, line_base);
1090
1091   demand_empty_rest_of_line ();
1092   return;
1093 }                               /* obj_coff_line() */
1094
1095 static void
1096 obj_coff_size ()
1097 {
1098   if (def_symbol_in_progress == NULL)
1099     {
1100       as_warn (".size pseudo-op used outside of .def/.endef ignored.");
1101       demand_empty_rest_of_line ();
1102       return;
1103     }                           /* if not inside .def/.endef */
1104
1105   S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
1106   SA_SET_SYM_SIZE (def_symbol_in_progress, get_absolute_expression ());
1107   demand_empty_rest_of_line ();
1108   return;
1109 }                               /* obj_coff_size() */
1110
1111 static void
1112 obj_coff_scl ()
1113 {
1114   if (def_symbol_in_progress == NULL)
1115     {
1116       as_warn (".scl pseudo-op used outside of .def/.endef ignored.");
1117       demand_empty_rest_of_line ();
1118       return;
1119     }                           /* if not inside .def/.endef */
1120
1121   S_SET_STORAGE_CLASS (def_symbol_in_progress, get_absolute_expression ());
1122   demand_empty_rest_of_line ();
1123   return;
1124 }                               /* obj_coff_scl() */
1125
1126 static void
1127 obj_coff_tag ()
1128 {
1129   char *symbol_name;
1130   char name_end;
1131
1132   if (def_symbol_in_progress == NULL)
1133     {
1134       as_warn (".tag pseudo-op used outside of .def/.endef ignored.");
1135       demand_empty_rest_of_line ();
1136       return;
1137     }                           /* if not inside .def/.endef */
1138
1139   S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
1140   symbol_name = input_line_pointer;
1141   name_end = get_symbol_end ();
1142
1143   /* Assume that the symbol referred to by .tag is always defined. */
1144   /* This was a bad assumption.  I've added find_or_make. xoxorich. */
1145   SA_SET_SYM_TAGNDX (def_symbol_in_progress, (long) tag_find_or_make (symbol_name));
1146   if (SA_GET_SYM_TAGNDX (def_symbol_in_progress) == 0L)
1147     {
1148       as_warn ("tag not found for .tag %s", symbol_name);
1149     }                           /* not defined */
1150
1151   SF_SET_TAGGED (def_symbol_in_progress);
1152   *input_line_pointer = name_end;
1153
1154   demand_empty_rest_of_line ();
1155   return;
1156 }                               /* obj_coff_tag() */
1157
1158 static void
1159 obj_coff_type ()
1160 {
1161   if (def_symbol_in_progress == NULL)
1162     {
1163       as_warn (".type pseudo-op used outside of .def/.endef ignored.");
1164       demand_empty_rest_of_line ();
1165       return;
1166     }                           /* if not inside .def/.endef */
1167
1168   S_SET_DATA_TYPE (def_symbol_in_progress, get_absolute_expression ());
1169
1170   if (ISFCN (S_GET_DATA_TYPE (def_symbol_in_progress)) &&
1171       S_GET_STORAGE_CLASS (def_symbol_in_progress) != C_TPDEF)
1172     {
1173       SF_SET_FUNCTION (def_symbol_in_progress);
1174     }                           /* is a function */
1175
1176   demand_empty_rest_of_line ();
1177   return;
1178 }                               /* obj_coff_type() */
1179
1180 static void
1181 obj_coff_val ()
1182 {
1183   if (def_symbol_in_progress == NULL)
1184     {
1185       as_warn (".val pseudo-op used outside of .def/.endef ignored.");
1186       demand_empty_rest_of_line ();
1187       return;
1188     }                           /* if not inside .def/.endef */
1189
1190   if (is_name_beginner (*input_line_pointer))
1191     {
1192       char *symbol_name = input_line_pointer;
1193       char name_end = get_symbol_end ();
1194
1195       if (!strcmp (symbol_name, "."))
1196         {
1197           def_symbol_in_progress->sy_frag = frag_now;
1198           S_SET_VALUE (def_symbol_in_progress, obstack_next_free (&frags) - frag_now->fr_literal);
1199           /* If the .val is != from the .def (e.g. statics) */
1200         }
1201       else if (strcmp (S_GET_NAME (def_symbol_in_progress), symbol_name))
1202         {
1203           def_symbol_in_progress->sy_forward = symbol_find_or_make (symbol_name);
1204
1205           /* If the segment is undefined when the forward
1206                            reference is solved, then copy the segment id
1207                            from the forward symbol. */
1208           SF_SET_GET_SEGMENT (def_symbol_in_progress);
1209         }
1210       /* Otherwise, it is the name of a non debug symbol and its value will be calculated later. */
1211       *input_line_pointer = name_end;
1212     }
1213   else
1214     {
1215       S_SET_VALUE (def_symbol_in_progress, get_absolute_expression ());
1216     }                           /* if symbol based */
1217
1218   demand_empty_rest_of_line ();
1219   return;
1220 }                               /* obj_coff_val() */
1221
1222 /*
1223  * Maintain a list of the tagnames of the structres.
1224  */
1225
1226 static void
1227 tag_init ()
1228 {
1229   tag_hash = hash_new ();
1230   return;
1231 }                               /* tag_init() */
1232
1233 static void
1234 tag_insert (name, symbolP)
1235      char *name;
1236      symbolS *symbolP;
1237 {
1238   register char *error_string;
1239
1240   if (*(error_string = hash_jam (tag_hash, name, (char *) symbolP)))
1241     {
1242       as_fatal ("Inserting \"%s\" into structure table failed: %s",
1243                 name, error_string);
1244     }
1245   return;
1246 }                               /* tag_insert() */
1247
1248 static symbolS *
1249 tag_find_or_make (name)
1250      char *name;
1251 {
1252   symbolS *symbolP;
1253
1254   if ((symbolP = tag_find (name)) == NULL)
1255     {
1256       symbolP = symbol_new (name,
1257                             SEG_UNKNOWN,
1258                             0,
1259                             &zero_address_frag);
1260
1261       tag_insert (S_GET_NAME (symbolP), symbolP);
1262       symbol_table_insert (symbolP);
1263     }                           /* not found */
1264
1265   return (symbolP);
1266 }                               /* tag_find_or_make() */
1267
1268 static symbolS *
1269 tag_find (name)
1270      char *name;
1271 {
1272 #ifdef STRIP_UNDERSCORE
1273   if (*name == '_')
1274     name++;
1275 #endif /* STRIP_UNDERSCORE */
1276   return ((symbolS *) hash_find (tag_hash, name));
1277 }                               /* tag_find() */
1278
1279 void
1280 obj_read_begin_hook ()
1281 {
1282   /* These had better be the same.  Usually 18 bytes. */
1283 #ifndef BFD_HEADERS
1284   know (sizeof (SYMENT) == sizeof (AUXENT));
1285   know (SYMESZ == AUXESZ);
1286 #endif
1287   tag_init ();
1288
1289   return;
1290 }                               /* obj_read_begin_hook() */
1291
1292 /* This function runs through the symbol table and puts all the
1293    externals onto another chain */
1294
1295 /* The chain of externals */
1296 symbolS *symbol_externP = NULL;
1297 symbolS *symbol_extern_lastP = NULL;
1298
1299 stack *block_stack;
1300 symbolS *last_functionP = NULL;
1301 symbolS *last_tagP;
1302
1303
1304 static unsigned int
1305 DEFUN_VOID (yank_symbols)
1306 {
1307   symbolS *symbolP;
1308   unsigned int symbol_number = 0;
1309
1310   for (symbolP = symbol_rootP;
1311        symbolP;
1312        symbolP = symbolP ? symbol_next (symbolP) : symbol_rootP)
1313     {
1314       if (!SF_GET_DEBUG (symbolP))
1315         {
1316           /* Debug symbols do not need all this rubbish */
1317           symbolS *real_symbolP;
1318
1319           /* L* and C_EFCN symbols never merge. */
1320           if (!SF_GET_LOCAL (symbolP)
1321               && (real_symbolP = symbol_find_base (S_GET_NAME (symbolP), DO_NOT_STRIP))
1322               && real_symbolP != symbolP)
1323             {
1324               /* FIXME-SOON: where do dups come from?
1325                  Maybe tag references before definitions? xoxorich. */
1326               /* Move the debug data from the debug symbol to the
1327                  real symbol. Do NOT do the oposite (i.e. move from
1328                  real symbol to debug symbol and remove real symbol from the
1329                  list.) Because some pointers refer to the real symbol
1330                  whereas no pointers refer to the debug symbol. */
1331               c_symbol_merge (symbolP, real_symbolP);
1332               /* Replace the current symbol by the real one */
1333               /* The symbols will never be the last or the first
1334                  because : 1st symbol is .file and 3 last symbols are
1335                  .text, .data, .bss */
1336               symbol_remove (real_symbolP, &symbol_rootP, &symbol_lastP);
1337               symbol_insert (real_symbolP, symbolP, &symbol_rootP, &symbol_lastP);
1338               symbol_remove (symbolP, &symbol_rootP, &symbol_lastP);
1339               symbolP = real_symbolP;
1340             }                   /* if not local but dup'd */
1341
1342           if (flagseen['R'] && (S_GET_SEGMENT (symbolP) == SEG_E1))
1343             {
1344               S_SET_SEGMENT (symbolP, SEG_E0);
1345             }                   /* push data into text */
1346
1347           S_SET_VALUE (symbolP,
1348                        S_GET_VALUE (symbolP) + symbolP->sy_frag->fr_address);
1349
1350           if (!S_IS_DEFINED (symbolP) && !SF_GET_LOCAL (symbolP))
1351             {
1352               S_SET_EXTERNAL (symbolP);
1353             }
1354           else if (S_GET_STORAGE_CLASS (symbolP) == C_NULL)
1355             {
1356               if (S_GET_SEGMENT (symbolP) == SEG_E0)
1357                 {
1358                   S_SET_STORAGE_CLASS (symbolP, C_LABEL);
1359                 }
1360               else
1361                 {
1362                   S_SET_STORAGE_CLASS (symbolP, C_STAT);
1363                 }
1364             }
1365
1366           /* Mainly to speed up if not -g */
1367           if (SF_GET_PROCESS (symbolP))
1368             {
1369               /* Handle the nested blocks auxiliary info. */
1370               if (S_GET_STORAGE_CLASS (symbolP) == C_BLOCK)
1371                 {
1372                   if (!strcmp (S_GET_NAME (symbolP), ".bb"))
1373                     stack_push (block_stack, (char *) &symbolP);
1374                   else
1375                     {           /* .eb */
1376                       register symbolS *begin_symbolP;
1377                       begin_symbolP = *(symbolS **) stack_pop (block_stack);
1378                       if (begin_symbolP == (symbolS *) 0)
1379                         as_warn ("mismatched .eb");
1380                       else
1381                         SA_SET_SYM_ENDNDX (begin_symbolP, symbol_number + 2);
1382                     }
1383                 }
1384               /* If we are able to identify the type of a function, and we
1385                are out of a function (last_functionP == 0) then, the
1386                function symbol will be associated with an auxiliary
1387                entry. */
1388               if (last_functionP == (symbolS *) 0 &&
1389                   SF_GET_FUNCTION (symbolP))
1390                 {
1391                   last_functionP = symbolP;
1392
1393                   if (S_GET_NUMBER_AUXILIARY (symbolP) < 1)
1394                     {
1395                       S_SET_NUMBER_AUXILIARY (symbolP, 1);
1396                     }           /* make it at least 1 */
1397
1398                   /* Clobber possible stale .dim information. */
1399 #if 0
1400                   /* Iffed out by steve - this fries the lnnoptr info too */
1401                   bzero (symbolP->sy_symbol.ost_auxent[0].x_sym.x_fcnary.x_ary.x_dimen,
1402                          sizeof (symbolP->sy_symbol.ost_auxent[0].x_sym.x_fcnary.x_ary.x_dimen));
1403 #endif
1404                 }
1405               /* The C_FCN doesn't need any additional information.
1406                I don't even know if this is needed for sdb. But the
1407                standard assembler generates it, so...
1408                */
1409               if (S_GET_STORAGE_CLASS (symbolP) == C_EFCN)
1410                 {
1411                   if (last_functionP == (symbolS *) 0)
1412                     as_fatal ("C_EFCN symbol out of scope");
1413                   SA_SET_SYM_FSIZE (last_functionP,
1414                                     (long) (S_GET_VALUE (symbolP) -
1415                                             S_GET_VALUE (last_functionP)));
1416                   SA_SET_SYM_ENDNDX (last_functionP, symbol_number);
1417                   last_functionP = (symbolS *) 0;
1418                 }
1419             }
1420         }
1421       else if (SF_GET_TAG (symbolP))
1422         {
1423           /* First descriptor of a structure must point to
1424                the first slot after the structure description. */
1425           last_tagP = symbolP;
1426
1427         }
1428       else if (S_GET_STORAGE_CLASS (symbolP) == C_EOS)
1429         {
1430           /* +2 take in account the current symbol */
1431           SA_SET_SYM_ENDNDX (last_tagP, symbol_number + 2);
1432         }
1433       else if (S_GET_STORAGE_CLASS (symbolP) == C_FILE)
1434         {
1435           if (S_GET_VALUE (symbolP))
1436             {
1437               S_SET_VALUE ((symbolS *) S_GET_VALUE (symbolP), symbol_number);
1438               S_SET_VALUE (symbolP, 0);
1439             }                   /* no one points at the first .file symbol */
1440         }                       /* if debug or tag or eos or file */
1441
1442       /* We must put the external symbols apart. The loader
1443          does not bomb if we do not. But the references in
1444          the endndx field for a .bb symbol are not corrected
1445          if an external symbol is removed between .bb and .be.
1446          I.e in the following case :
1447          [20] .bb endndx = 22
1448          [21] foo external
1449          [22] .be
1450          ld will move the symbol 21 to the end of the list but
1451          endndx will still be 22 instead of 21. */
1452
1453
1454       if (SF_GET_LOCAL (symbolP))
1455         {
1456           /* remove C_EFCN and LOCAL (L...) symbols */
1457           /* next pointer remains valid */
1458           symbol_remove (symbolP, &symbol_rootP, &symbol_lastP);
1459
1460         }
1461       else if (!S_IS_DEFINED (symbolP)
1462                && !S_IS_DEBUG (symbolP)
1463                && !SF_GET_STATICS (symbolP) &&
1464                S_GET_STORAGE_CLASS (symbolP) == C_EXT)
1465         {                       /* C_EXT && !SF_GET_FUNCTION(symbolP))  */
1466           /* if external, Remove from the list */
1467           symbolS *hold = symbol_previous (symbolP);
1468
1469           symbol_remove (symbolP, &symbol_rootP, &symbol_lastP);
1470           symbol_clear_list_pointers (symbolP);
1471           symbol_append (symbolP, symbol_extern_lastP, &symbol_externP, &symbol_extern_lastP);
1472           symbolP = hold;
1473         }
1474       else
1475         {
1476           if (SF_GET_STRING (symbolP))
1477             {
1478               symbolP->sy_name_offset = string_byte_count;
1479               string_byte_count += strlen (S_GET_NAME (symbolP)) + 1;
1480             }
1481           else
1482             {
1483               symbolP->sy_name_offset = 0;
1484             }                   /* fix "long" names */
1485
1486           symbolP->sy_number = symbol_number;
1487           symbol_number += 1 + S_GET_NUMBER_AUXILIARY (symbolP);
1488         }                       /* if local symbol */
1489     }                           /* traverse the symbol list */
1490   return symbol_number;
1491
1492 }
1493
1494
1495 static unsigned int
1496 DEFUN_VOID (glue_symbols)
1497 {
1498   unsigned int symbol_number = 0;
1499   symbolS *symbolP;
1500   for (symbolP = symbol_externP; symbol_externP;)
1501     {
1502       symbolS *tmp = symbol_externP;
1503
1504       /* append */
1505       symbol_remove (tmp, &symbol_externP, &symbol_extern_lastP);
1506       symbol_append (tmp, symbol_lastP, &symbol_rootP, &symbol_lastP);
1507
1508       /* and process */
1509       if (SF_GET_STRING (tmp))
1510         {
1511           tmp->sy_name_offset = string_byte_count;
1512           string_byte_count += strlen (S_GET_NAME (tmp)) + 1;
1513         }
1514       else
1515         {
1516           tmp->sy_name_offset = 0;
1517         }                       /* fix "long" names */
1518
1519       tmp->sy_number = symbol_number;
1520       symbol_number += 1 + S_GET_NUMBER_AUXILIARY (tmp);
1521     }                           /* append the entire extern chain */
1522   return symbol_number;
1523
1524 }
1525
1526 static unsigned int
1527 DEFUN_VOID (tie_tags)
1528 {
1529   unsigned int symbol_number = 0;
1530
1531   symbolS *symbolP;
1532   for (symbolP = symbol_rootP; symbolP; symbolP =
1533        symbol_next (symbolP))
1534     {
1535       symbolP->sy_number = symbol_number;
1536
1537
1538
1539       if (SF_GET_TAGGED (symbolP))
1540         {
1541           SA_SET_SYM_TAGNDX
1542             (symbolP,
1543              ((symbolS *) SA_GET_SYM_TAGNDX (symbolP))->sy_number);
1544         }
1545
1546       symbol_number += 1 + S_GET_NUMBER_AUXILIARY (symbolP);
1547     }
1548   return symbol_number;
1549
1550 }
1551
1552 static void
1553 DEFUN (crawl_symbols, (headers, abfd),
1554        struct internal_filehdr *headers AND
1555        bfd * abfd)
1556 {
1557
1558   unsigned int i;
1559   unsigned int ptr = 0;
1560
1561
1562   symbolS *symbolP;
1563
1564   /* Initialize the stack used to keep track of the matching .bb .be */
1565
1566   block_stack = stack_init (512, sizeof (symbolS *));
1567   /* JF deal with forward references first... */
1568   for (symbolP = symbol_rootP;
1569        symbolP;
1570        symbolP = symbol_next (symbolP))
1571     {
1572
1573       if (symbolP->sy_forward)
1574         {
1575           S_SET_VALUE (symbolP, (S_GET_VALUE (symbolP)
1576                                  + S_GET_VALUE (symbolP->sy_forward)
1577                                + symbolP->sy_forward->sy_frag->fr_address));
1578
1579           if (SF_GET_GET_SEGMENT (symbolP))
1580             {
1581               S_SET_SEGMENT (symbolP, S_GET_SEGMENT (symbolP->sy_forward));
1582             }                   /* forward segment also */
1583
1584           symbolP->sy_forward = 0;
1585         }                       /* if it has a forward reference */
1586     }                           /* walk the symbol chain */
1587
1588
1589   /* The symbol list should be ordered according to the following sequence
1590    * order :
1591    * . .file symbol
1592    * . debug entries for functions
1593    * . fake symbols for the sections, including.text .data and .bss
1594    * . defined symbols
1595    * . undefined symbols
1596    * But this is not mandatory. The only important point is to put the
1597    * undefined symbols at the end of the list.
1598    */
1599
1600   if (symbol_rootP == NULL
1601       || S_GET_STORAGE_CLASS (symbol_rootP) != C_FILE)
1602     {
1603       c_dot_file_symbol ("fake");
1604     }
1605   /* Is there a .file symbol ? If not insert one at the beginning. */
1606
1607   /*
1608    * Build up static symbols for the sections, they are filled in later
1609    */
1610
1611
1612   for (i = SEG_E0; i < SEG_E9; i++)
1613     {
1614       if (segment_info[i].scnhdr.s_name[0])
1615         {
1616           segment_info[i].dot =
1617             c_section_symbol (segment_info[i].scnhdr.s_name,
1618                               i - SEG_E0 + 1);
1619
1620         }
1621     }
1622
1623
1624   /* Take all the externals out and put them into another chain */
1625   headers->f_nsyms = yank_symbols ();
1626   /* Take the externals and glue them onto the end.*/
1627   headers->f_nsyms += glue_symbols ();
1628
1629   headers->f_nsyms = tie_tags ();
1630   know (symbol_externP == NULL);
1631   know (symbol_extern_lastP == NULL);
1632
1633   return;
1634 }
1635
1636 /*
1637  * Find strings by crawling along symbol table chain.
1638  */
1639
1640 void
1641 DEFUN (w_strings, (where),
1642        char *where)
1643 {
1644   symbolS *symbolP;
1645
1646   /* Gotta do md_ byte-ordering stuff for string_byte_count first - KWK */
1647   md_number_to_chars (where, string_byte_count, sizeof (string_byte_count));
1648   where += sizeof (string_byte_count);
1649   for (symbolP = symbol_rootP;
1650        symbolP;
1651        symbolP = symbol_next (symbolP))
1652     {
1653       unsigned int size;
1654
1655       if (SF_GET_STRING (symbolP))
1656         {
1657           size = strlen (S_GET_NAME (symbolP)) + 1;
1658
1659           memcpy (where, S_GET_NAME (symbolP), size);
1660           where += size;
1661
1662         }
1663     }
1664
1665 }
1666
1667
1668
1669
1670
1671 static void
1672 DEFUN (do_linenos_for, (abfd, file_cursor),
1673        bfd * abfd AND
1674        unsigned long *file_cursor)
1675 {
1676   unsigned int idx;
1677
1678   for (idx = SEG_E0; idx < SEG_E9; idx++)
1679     {
1680       segment_info_type *s = segment_info + idx;
1681
1682
1683       if (s->scnhdr.s_nlnno != 0)
1684         {
1685           struct lineno_list *line_ptr;
1686
1687           struct external_lineno *buffer =
1688           (struct external_lineno *) xmalloc (s->scnhdr.s_nlnno * LINESZ);
1689
1690           struct external_lineno *dst = buffer;
1691
1692           /* Run through the table we've built and turn it into its external
1693          form, take this chance to remove duplicates */
1694
1695           for (line_ptr = s->lineno_list_head;
1696                line_ptr != (struct lineno_list *) NULL;
1697                line_ptr = line_ptr->next)
1698             {
1699
1700               if (line_ptr->line.l_lnno == 0)
1701                 {
1702                   /* Turn a pointer to a symbol into the symbols' index */
1703                   line_ptr->line.l_addr.l_symndx =
1704                     ((symbolS *) line_ptr->line.l_addr.l_symndx)->sy_number;
1705                 }
1706               else
1707                 {
1708                   line_ptr->line.l_addr.l_paddr += ((struct frag *) (line_ptr->frag))->fr_address;
1709                 }
1710
1711
1712               (void) bfd_coff_swap_lineno_out (abfd, &(line_ptr->line), dst);
1713               dst++;
1714
1715             }
1716
1717           s->scnhdr.s_lnnoptr = *file_cursor;
1718
1719           bfd_write (buffer, 1, s->scnhdr.s_nlnno * LINESZ, abfd);
1720           free (buffer);
1721
1722           *file_cursor += s->scnhdr.s_nlnno * LINESZ;
1723         }
1724     }
1725 }
1726
1727
1728 /* Now we run through the list of frag chains in a segment and
1729    make all the subsegment frags appear at the end of the
1730    list, as if the seg 0 was extra long */
1731
1732 static void
1733 DEFUN_VOID (remove_subsegs)
1734 {
1735   unsigned int i;
1736
1737   for (i = SEG_E0; i < SEG_UNKNOWN; i++)
1738     {
1739       frchainS *head = segment_info[i].frchainP;
1740       fragS dummy;
1741       fragS *prev_frag = &dummy;
1742
1743       while (head && head->frch_seg == i)
1744         {
1745           prev_frag->fr_next = head->frch_root;
1746           prev_frag = head->frch_last;
1747           head = head->frch_next;
1748         }
1749       prev_frag->fr_next = 0;
1750     }
1751 }
1752
1753 int machine;
1754 int coff_flags;
1755 extern void
1756 DEFUN_VOID (write_object_file)
1757 {
1758   int i;
1759   struct frchain *frchain_ptr;
1760
1761   struct internal_filehdr filehdr;
1762   struct internal_aouthdr aouthdr;
1763   unsigned long file_cursor;
1764   bfd *abfd;
1765   unsigned int addr;
1766   abfd = bfd_openw (out_file_name, TARGET_FORMAT);
1767
1768
1769   if (abfd == 0)
1770     {
1771       as_perror ("FATAL: Can't create %s", out_file_name);
1772       exit (42);
1773     }
1774   bfd_set_format (abfd, bfd_object);
1775   bfd_set_arch_mach (abfd, BFD_ARCH, machine);
1776
1777
1778
1779   string_byte_count = 4;
1780
1781   for (frchain_ptr = frchain_root;
1782        frchain_ptr != (struct frchain *) NULL;
1783        frchain_ptr = frchain_ptr->frch_next)
1784     {
1785       /* Run through all the sub-segments and align them up. Also close any
1786                open frags. We tack a .fill onto the end of the frag chain so
1787                that any .align's size can be worked by looking at the next
1788                frag */
1789
1790       subseg_new (frchain_ptr->frch_seg, frchain_ptr->frch_subseg);
1791 #define SUB_SEGMENT_ALIGN 1
1792       frag_align (SUB_SEGMENT_ALIGN, 0);
1793       frag_wane (frag_now);
1794       frag_now->fr_fix = 0;
1795       know (frag_now->fr_next == NULL);
1796     }
1797
1798
1799   remove_subsegs ();
1800
1801
1802   for (i = SEG_E0; i < SEG_UNKNOWN; i++)
1803     {
1804       relax_segment (segment_info[i].frchainP->frch_root, i);
1805     }
1806
1807   filehdr.f_nscns = 0;
1808
1809   /* Find out how big the sections are, and set the addresses.  */
1810   addr = 0;
1811   for (i = SEG_E0; i < SEG_UNKNOWN; i++)
1812     {
1813       segment_info[i].scnhdr.s_paddr = addr;
1814       segment_info[i].scnhdr.s_vaddr = addr;
1815
1816       if (segment_info[i].scnhdr.s_name[0])
1817         {
1818           filehdr.f_nscns++;
1819         }
1820
1821 #ifndef ZERO_BASED_SEGMENTS
1822       /* See the comment at the previous ZERO_BASED_SEGMENTS check.  */
1823       if (i == SEG_E2)
1824         {
1825           /* This is a special case, we leave the size alone, which
1826              will have been made up from all and any lcomms seen.  */
1827           addr += segment_info[i].scnhdr.s_size;
1828         }
1829       else
1830         {
1831           addr += size_section (abfd, i);
1832         }
1833 #endif
1834     }
1835
1836
1837
1838   /* Turn the gas native symbol table shape into a coff symbol table */
1839   crawl_symbols (&filehdr, abfd);
1840 #if !defined(TC_H8300) && !defined(TC_Z8K)
1841   for (i = SEG_E0; i < SEG_UNKNOWN; i++)
1842     {
1843       fixup_mdeps (segment_info[i].frchainP->frch_root);
1844       fixup_segment (segment_info[i].fix_root, i);
1845     }
1846 #endif
1847
1848   file_cursor = FILHSZ + SCNHSZ * filehdr.f_nscns;
1849
1850   bfd_seek (abfd, file_cursor, 0);
1851
1852
1853   do_relocs_for (abfd, &file_cursor);
1854
1855   do_linenos_for (abfd, &file_cursor);
1856
1857
1858   /* Plant the data */
1859
1860   fill_section (abfd, &filehdr, &file_cursor);
1861
1862
1863
1864   filehdr.f_magic = COFF_MAGIC;
1865   filehdr.f_timdat = time (0);
1866   filehdr.f_flags = COFF_FLAGS | coff_flags;
1867
1868   if (!had_lineno)
1869     {
1870       filehdr.f_flags |= F_LNNO;
1871     }
1872   if (!had_reloc)
1873     {
1874       filehdr.f_flags |= F_RELFLG;
1875     }
1876
1877
1878
1879
1880
1881
1882
1883   {
1884
1885     unsigned int symtable_size = filehdr.f_nsyms * SYMESZ;
1886     char *buffer1 = malloc (symtable_size + string_byte_count + 4);
1887     char *ptr = buffer1;
1888     filehdr.f_symptr = bfd_tell (abfd);
1889     w_symbols (abfd, buffer1, symbol_rootP);
1890     w_strings (buffer1 + symtable_size);
1891     bfd_write (buffer1, 1, symtable_size + string_byte_count + 4, abfd);
1892     free (buffer1);
1893
1894   }
1895   coff_header_append (abfd, &filehdr, &aouthdr);
1896
1897   if (bfd_close_all_done (abfd) == false)
1898     as_fatal ("Can't close %s: %s", out_file_name,
1899               bfd_errmsg (bfd_error));
1900 }
1901
1902
1903 static void
1904 DEFUN (change_to_section, (name, len, exp),
1905        char *name AND
1906        unsigned int len AND
1907        unsigned int exp)
1908 {
1909   unsigned int i;
1910   /* Find out if we've already got a section of this name etc */
1911   for (i = SEG_E0; i < SEG_E9 && segment_info[i].scnhdr.s_name[0]; i++)
1912     {
1913       if (strncmp (segment_info[i].scnhdr.s_name, name, len) == 0)
1914         {
1915           subseg_new (i, exp);
1916           return;
1917
1918         }
1919     }
1920   /* No section, add one */
1921   strncpy (segment_info[i].scnhdr.s_name, name, 8);
1922   subseg_new (i, exp);
1923 }
1924
1925 void
1926 DEFUN_VOID (obj_coff_section)
1927 {
1928   /* Strip out the section name */
1929   char *section_name;
1930   char *section_name_end;
1931   char c;
1932
1933   unsigned int len;
1934   unsigned int exp;
1935
1936   section_name = input_line_pointer;
1937   c = get_symbol_end ();
1938   section_name_end = input_line_pointer;
1939
1940   len = section_name_end - section_name;
1941   input_line_pointer++;
1942   SKIP_WHITESPACE ();
1943   if (c == ',')
1944     {
1945       exp = get_absolute_expression ();
1946     }
1947   else if (*input_line_pointer == ',')
1948     {
1949
1950       input_line_pointer++;
1951       exp = get_absolute_expression ();
1952     }
1953   else
1954     {
1955       exp = 0;
1956     }
1957
1958   change_to_section (section_name, len, exp);
1959   *section_name_end = c;
1960
1961 }
1962
1963
1964 static void
1965 obj_coff_text ()
1966 {
1967   change_to_section (".text", 5, get_absolute_expression ());
1968 }
1969
1970
1971 static void
1972 obj_coff_data ()
1973 {
1974   change_to_section (".data", 5, get_absolute_expression ());
1975 }
1976
1977 void
1978 c_symbol_merge (debug, normal)
1979      symbolS *debug;
1980      symbolS *normal;
1981 {
1982   S_SET_DATA_TYPE (normal, S_GET_DATA_TYPE (debug));
1983   S_SET_STORAGE_CLASS (normal, S_GET_STORAGE_CLASS (debug));
1984
1985   if (S_GET_NUMBER_AUXILIARY (debug) > S_GET_NUMBER_AUXILIARY (normal))
1986     {
1987       S_SET_NUMBER_AUXILIARY (normal, S_GET_NUMBER_AUXILIARY (debug));
1988     }                           /* take the most we have */
1989
1990   if (S_GET_NUMBER_AUXILIARY (debug) > 0)
1991     {
1992       memcpy ((char *) &normal->sy_symbol.ost_auxent[0], (char *) &debug->sy_symbol.ost_auxent[0], S_GET_NUMBER_AUXILIARY (debug) * AUXESZ);
1993     }                           /* Move all the auxiliary information */
1994
1995   /* Move the debug flags. */
1996   SF_SET_DEBUG_FIELD (normal, SF_GET_DEBUG_FIELD (debug));
1997 }                               /* c_symbol_merge() */
1998
1999 static int
2000 DEFUN (c_line_new, (symbol, paddr, line_number, frag),
2001        symbolS * symbol AND
2002        long paddr AND
2003        unsigned short line_number AND
2004        fragS * frag)
2005 {
2006   struct lineno_list *new_line =
2007   (struct lineno_list *) xmalloc (sizeof (struct lineno_list));
2008
2009   segment_info_type *s = segment_info + now_seg;
2010   new_line->line.l_lnno = line_number;
2011
2012   had_lineno = 1;
2013
2014   if (line_number == 0)
2015     {
2016       last_line_symbol = symbol;
2017       new_line->line.l_addr.l_symndx = (long) symbol;
2018     }
2019   else
2020     {
2021       new_line->line.l_addr.l_paddr = paddr;
2022     }
2023
2024   new_line->frag = (char *) frag;
2025   new_line->next = (struct lineno_list *) NULL;
2026
2027
2028   if (s->lineno_list_head == (struct lineno_list *) NULL)
2029     {
2030       s->lineno_list_head = new_line;
2031     }
2032   else
2033     {
2034       s->lineno_list_tail->next = new_line;
2035     }
2036   s->lineno_list_tail = new_line;
2037   return LINESZ * s->scnhdr.s_nlnno++;
2038 }
2039
2040 void
2041 c_dot_file_symbol (filename)
2042      char *filename;
2043 {
2044   symbolS *symbolP;
2045
2046   symbolP = symbol_new (".file",
2047                         SEG_DEBUG,
2048                         0,
2049                         &zero_address_frag);
2050
2051   S_SET_STORAGE_CLASS (symbolP, C_FILE);
2052   S_SET_NUMBER_AUXILIARY (symbolP, 1);
2053   SA_SET_FILE_FNAME (symbolP, filename);
2054 #ifndef NO_LISTING
2055   {
2056     extern int listing;
2057     if (listing)
2058       {
2059         listing_source_file (filename);
2060       }
2061
2062   }
2063
2064 #endif
2065   SF_SET_DEBUG (symbolP);
2066   S_SET_VALUE (symbolP, (long) previous_file_symbol);
2067
2068   previous_file_symbol = symbolP;
2069
2070   /* Make sure that the symbol is first on the symbol chain */
2071   if (symbol_rootP != symbolP)
2072     {
2073       if (symbolP == symbol_lastP)
2074         {
2075           symbol_lastP = symbol_lastP->sy_previous;
2076         }                       /* if it was the last thing on the list */
2077
2078       symbol_remove (symbolP, &symbol_rootP, &symbol_lastP);
2079       symbol_insert (symbolP, symbol_rootP, &symbol_rootP, &symbol_lastP);
2080       symbol_rootP = symbolP;
2081     }                           /* if not first on the list */
2082
2083 }                               /* c_dot_file_symbol() */
2084
2085 /*
2086  * Build a 'section static' symbol.
2087  */
2088
2089 symbolS *
2090 c_section_symbol (name, idx)
2091      char *name;
2092      int idx;
2093 {
2094   symbolS *symbolP;
2095
2096   symbolP = symbol_new (name, idx,
2097                         0,
2098                         &zero_address_frag);
2099
2100   S_SET_STORAGE_CLASS (symbolP, C_STAT);
2101   S_SET_NUMBER_AUXILIARY (symbolP, 1);
2102
2103   SF_SET_STATICS (symbolP);
2104
2105   return symbolP;
2106 }                               /* c_section_symbol() */
2107
2108 static void
2109 DEFUN (w_symbols, (abfd, where, symbol_rootP),
2110        bfd * abfd AND
2111        char *where AND
2112        symbolS * symbol_rootP)
2113 {
2114   symbolS *symbolP;
2115   unsigned int i;
2116
2117   /* First fill in those values we have only just worked out */
2118   for (i = SEG_E0; i < SEG_E9; i++)
2119     {
2120       symbolP = segment_info[i].dot;
2121       if (symbolP)
2122         {
2123
2124           SA_SET_SCN_SCNLEN (symbolP, segment_info[i].scnhdr.s_size);
2125           SA_SET_SCN_NRELOC (symbolP, segment_info[i].scnhdr.s_nreloc);
2126           SA_SET_SCN_NLINNO (symbolP, segment_info[i].scnhdr.s_nlnno);
2127
2128         }
2129     }
2130
2131   /*
2132      * Emit all symbols left in the symbol chain.
2133      */
2134   for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
2135     {
2136       /* Used to save the offset of the name. It is used to point
2137                to the string in memory but must be a file offset. */
2138       register char *temp;
2139
2140       tc_coff_symbol_emit_hook (symbolP);
2141
2142       temp = S_GET_NAME (symbolP);
2143       if (SF_GET_STRING (symbolP))
2144         {
2145           S_SET_OFFSET (symbolP, symbolP->sy_name_offset);
2146           S_SET_ZEROES (symbolP, 0);
2147         }
2148       else
2149         {
2150           bzero (symbolP->sy_symbol.ost_entry.n_name, SYMNMLEN);
2151           strncpy (symbolP->sy_symbol.ost_entry.n_name, temp, SYMNMLEN);
2152         }
2153       where = symbol_to_chars (abfd, where, symbolP);
2154       S_SET_NAME (symbolP, temp);
2155     }
2156
2157 }                               /* w_symbols() */
2158
2159 static void
2160 DEFUN_VOID (obj_coff_lcomm)
2161 {
2162   char *name;
2163   char c;
2164   int temp;
2165   char *p;
2166   unsigned long vma;
2167
2168   symbolS *symbolP;
2169   name = input_line_pointer;
2170
2171
2172   c = get_symbol_end ();
2173   p = input_line_pointer;
2174   *p = c;
2175   SKIP_WHITESPACE ();
2176   if (*input_line_pointer != ',')
2177     {
2178       as_bad ("Expected comma after name");
2179       ignore_rest_of_line ();
2180       return;
2181     }
2182   if (*input_line_pointer == '\n')
2183     {
2184       as_bad ("Missing size expression");
2185       return;
2186     }
2187   input_line_pointer++;
2188   if ((temp = get_absolute_expression ()) < 0)
2189     {
2190       as_warn ("lcomm length (%d.) <0! Ignored.", temp);
2191       ignore_rest_of_line ();
2192       return;
2193     }
2194   *p = 0;
2195
2196   {
2197     /* Allocate zero static local data in the .data section now
2198        instead of the bss section as a symbol with a value */
2199     char *x;
2200     segT oldseg = now_seg;
2201     int oldsubseg = now_subseg;
2202
2203     subseg_new (SEG_DATA, 10);
2204     colon (name);
2205     frag_align (2, 0);
2206     record_alignment (SEG_DATA, 4);
2207     x = frag_var (rs_fill, 1, 1, (relax_substateT) 0, (symbolS *) 0,
2208                   temp, (char *) 0);
2209     *x = 0;
2210
2211     subseg_new (oldseg, oldsubseg);
2212   }
2213   demand_empty_rest_of_line ();
2214 }
2215
2216 static void
2217 DEFUN (fixup_mdeps, (frags),
2218        fragS * frags)
2219 {
2220   while (frags)
2221     {
2222       switch (frags->fr_type)
2223         {
2224         case rs_align:
2225         case rs_org:
2226           frags->fr_type = rs_fill;
2227           frags->fr_offset =
2228             (frags->fr_next->fr_address - frags->fr_address - frags->fr_fix);
2229           break;
2230         case rs_machine_dependent:
2231           md_convert_frag (0, frags);
2232           break;
2233         default:
2234           ;
2235         }
2236       frags = frags->fr_next;
2237     }
2238
2239 }
2240
2241 #if 1
2242 static void
2243 DEFUN (fixup_segment, (fixP, this_segment_type),
2244        register fixS * fixP AND
2245        segT this_segment_type)
2246 {
2247   register symbolS *add_symbolP;
2248   register symbolS *sub_symbolP;
2249   register long add_number;
2250   register int size;
2251   register char *place;
2252   register long where;
2253   register char pcrel;
2254   register fragS *fragP;
2255   register segT add_symbol_segment = SEG_ABSOLUTE;
2256
2257
2258   for (; fixP; fixP = fixP->fx_next)
2259     {
2260       fragP = fixP->fx_frag;
2261       know (fragP);
2262       where = fixP->fx_where;
2263       place = fragP->fr_literal + where;
2264       size = fixP->fx_size;
2265       add_symbolP = fixP->fx_addsy;
2266 #ifdef TC_I960
2267       if (fixP->fx_callj && TC_S_IS_CALLNAME (add_symbolP))
2268         {
2269           /* Relocation should be done via the
2270                    associated 'bal' entry point
2271                    symbol. */
2272
2273           if (!TC_S_IS_BALNAME (tc_get_bal_of_call (add_symbolP)))
2274             {
2275               as_bad ("No 'bal' entry point for leafproc %s",
2276                       S_GET_NAME (add_symbolP));
2277               continue;
2278             }
2279           fixP->fx_addsy = add_symbolP = tc_get_bal_of_call (add_symbolP);
2280         }                       /* callj relocation */
2281 #endif
2282       sub_symbolP = fixP->fx_subsy;
2283       add_number = fixP->fx_offset;
2284       pcrel = fixP->fx_pcrel;
2285
2286       if (add_symbolP)
2287         {
2288           add_symbol_segment = S_GET_SEGMENT (add_symbolP);
2289         }                       /* if there is an addend */
2290
2291       if (sub_symbolP)
2292         {
2293           if (!add_symbolP)
2294             {
2295               /* Its just -sym */
2296               if (S_GET_SEGMENT (sub_symbolP) != SEG_ABSOLUTE)
2297                 {
2298                   as_bad ("Negative of non-absolute symbol %s", S_GET_NAME (sub_symbolP));
2299                 }               /* not absolute */
2300
2301               add_number -= S_GET_VALUE (sub_symbolP);
2302               fixP->fx_subsy = 0;
2303
2304               /* if sub_symbol is in the same segment that add_symbol
2305                            and add_symbol is either in DATA, TEXT, BSS or ABSOLUTE */
2306             }
2307           else if ((S_GET_SEGMENT (sub_symbolP) == add_symbol_segment)
2308                    && (SEG_NORMAL (add_symbol_segment)
2309                        || (add_symbol_segment == SEG_ABSOLUTE)))
2310             {
2311               /* Difference of 2 symbols from same segment. */
2312               /* Can't make difference of 2 undefineds: 'value' means */
2313               /* something different for N_UNDF. */
2314 #ifdef TC_I960
2315               /* Makes no sense to use the difference of 2 arbitrary symbols
2316                              * as the target of a call instruction.
2317                              */
2318               if (fixP->fx_callj)
2319                 {
2320                   as_bad ("callj to difference of 2 symbols");
2321                 }
2322 #endif /* TC_I960 */
2323               add_number += S_GET_VALUE (add_symbolP) -
2324                 S_GET_VALUE (sub_symbolP);
2325
2326               add_symbolP = NULL;
2327               fixP->fx_addsy = NULL;
2328             }
2329           else
2330             {
2331               /* Different segments in subtraction. */
2332               know (!(S_IS_EXTERNAL (sub_symbolP) && (S_GET_SEGMENT (sub_symbolP) == SEG_ABSOLUTE)));
2333
2334               if ((S_GET_SEGMENT (sub_symbolP) == SEG_ABSOLUTE))
2335                 {
2336                   add_number -= S_GET_VALUE (sub_symbolP);
2337                 }
2338               else
2339                 {
2340                   as_bad ("Can't emit reloc {- %s-seg symbol \"%s\"} @ file address %d.",
2341                           segment_name (S_GET_SEGMENT (sub_symbolP)),
2342                        S_GET_NAME (sub_symbolP), fragP->fr_address + where);
2343                 }               /* if absolute */
2344             }
2345         }                       /* if sub_symbolP */
2346
2347       if (add_symbolP)
2348         {
2349           if (add_symbol_segment == this_segment_type && pcrel)
2350             {
2351               /*
2352                          * This fixup was made when the symbol's segment was
2353                          * SEG_UNKNOWN, but it is now in the local segment.
2354                          * So we know how to do the address without relocation.
2355                          */
2356 #ifdef TC_I960
2357               /* reloc_callj() may replace a 'call' with a 'calls' or a 'bal',
2358                          * in which cases it modifies *fixP as appropriate.  In the case
2359                          * of a 'calls', no further work is required, and *fixP has been
2360                          * set up to make the rest of the code below a no-op.
2361                          */
2362               reloc_callj (fixP);
2363 #endif /* TC_I960 */
2364
2365               add_number += S_GET_VALUE (add_symbolP);
2366               add_number -= md_pcrel_from (fixP);
2367               pcrel = 0;        /* Lie. Don't want further pcrel processing. */
2368               fixP->fx_addsy = NULL;    /* No relocations please. */
2369             }
2370           else
2371             {
2372               switch (add_symbol_segment)
2373                 {
2374                 case SEG_ABSOLUTE:
2375 #ifdef TC_I960
2376                   reloc_callj (fixP);   /* See comment about reloc_callj() above*/
2377 #endif /* TC_I960 */
2378                   add_number += S_GET_VALUE (add_symbolP);
2379                   fixP->fx_addsy = NULL;
2380                   add_symbolP = NULL;
2381                   break;
2382                 default:
2383
2384                   add_number += S_GET_VALUE (add_symbolP) +
2385                     segment_info[S_GET_SEGMENT (add_symbolP)].scnhdr.s_paddr;
2386                   break;
2387
2388                 case SEG_UNKNOWN:
2389 #ifdef TC_I960
2390                   if ((int) fixP->fx_bit_fixP == 13)
2391                     {
2392                       /* This is a COBR instruction.  They have only a
2393                                      * 13-bit displacement and are only to be used
2394                                      * for local branches: flag as error, don't generate
2395                                      * relocation.
2396                                      */
2397                       as_bad ("can't use COBR format with external label");
2398                       fixP->fx_addsy = NULL;    /* No relocations please. */
2399                       continue;
2400                     }           /* COBR */
2401 #endif /* TC_I960 */
2402 #ifdef TC_I386
2403                   /* 386 COFF uses a peculiar format in
2404                                which the value of a common symbol is
2405                                stored in the .text segment (I've
2406                                checked this on SVR3.2 and SCO 3.2.2)
2407                                Ian Taylor <[email protected]>.  */
2408                   add_number += S_GET_VALUE (add_symbolP);
2409 #endif
2410                   break;
2411
2412
2413                 }               /* switch on symbol seg */
2414             }                   /* if not in local seg */
2415         }                       /* if there was a + symbol */
2416
2417       if (pcrel)
2418         {
2419           add_number -= md_pcrel_from (fixP);
2420           if (add_symbolP == 0)
2421             {
2422               fixP->fx_addsy = &abs_symbol;
2423             }                   /* if there's an add_symbol */
2424         }                       /* if pcrel */
2425
2426       if (!fixP->fx_bit_fixP)
2427         {
2428           if ((size == 1 &&
2429           (add_number & ~0xFF) && ((add_number & ~0xFF) != (-1 & ~0xFF))) ||
2430               (size == 2 &&
2431                (add_number & ~0xFFFF) && ((add_number & ~0xFFFF) != (-1 & ~0xFFFF))))
2432             {
2433               as_bad ("Value of %d too large for field of %d bytes at 0x%x",
2434                       add_number, size, fragP->fr_address + where);
2435             }                   /* generic error checking */
2436 #ifdef WARN_SIGNED_OVERFLOW_WORD
2437           /* Warn if a .word value is too large when treated as
2438                    a signed number.  We already know it is not too
2439                    negative.  This is to catch over-large switches
2440                    generated by gcc on the 68k.  */
2441           if (!flagseen['J']
2442               && size == 2
2443               && add_number > 0x7fff)
2444             as_bad ("Signed .word overflow; switch may be too large; %d at 0x%x",
2445                     add_number, fragP->fr_address + where);
2446 #endif
2447         }                       /* not a bit fix */
2448       /* once this fix has been applied, we don't have to output anything
2449            nothing more need be done -*/
2450       md_apply_fix (fixP, add_number);
2451
2452     }                           /* For each fixS in this segment. */
2453
2454
2455 }                               /* fixup_segment() */
2456
2457 #endif
This page took 0.171693 seconds and 4 git commands to generate.