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