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