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