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