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