* Preliminary support for m88k-coff.
[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
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 */
71 C_UNDEF_SECTION, /* SEG_ABSENT */
72 C_UNDEF_SECTION, /* SEG_PASS1 */
73 C_UNDEF_SECTION, /* SEG_GOOF */
74 C_UNDEF_SECTION, /* SEG_BIG */
75 C_UNDEF_SECTION, /* SEG_DIFFERENCE */
76 C_DEBUG_SECTION, /* SEG_DEBUG */
77 C_NTV_SECTION, /* SEG_NTV */
78 C_PTV_SECTION, /* SEG_PTV */
79 C_REGISTER_SECTION, /* SEG_REGISTER */
db40ba14
SC
80};
81
82
83int function_lineoff = -1; /* Offset in line#s where the last function
84 started (the odd entry for line #0) */
85
db40ba14 86
355afbcd 87static symbolS *last_line_symbol;
9a75dc1f 88
db40ba14
SC
89/* Add 4 to the real value to get the index and compensate the
90 negatives. This vector is used by S_GET_SEGMENT to turn a coff
355afbcd 91 section number into a segment number
c593cf41 92*/
db40ba14 93static symbolS *previous_file_symbol = NULL;
355afbcd 94void c_symbol_merge ();
9ce31b66 95static int line_base;
db40ba14 96
355afbcd 97symbolS *c_section_symbol ();
db40ba14 98bfd *abfd;
355afbcd
KR
99void EXFUN (bfd_as_write_hook, (struct internal_filehdr *,
100 bfd * abfd));
db40ba14 101
016e0d42 102static void EXFUN (fixup_segment, (segment_info_type *segP,
355afbcd 103 segT this_segment_type));
db40ba14 104
3ad9ec6a 105
9a75dc1f
ILT
106static void EXFUN (fixup_mdeps, (fragS *,
107 object_headers *,
108 segT));
3ad9ec6a
ILT
109
110
355afbcd 111static void EXFUN (fill_section, (bfd * abfd,
9a75dc1f
ILT
112 object_headers *,
113 unsigned long *));
db40ba14
SC
114
115
355afbcd
KR
116char *EXFUN (s_get_name, (symbolS * s));
117static symbolS *EXFUN (tag_find_or_make, (char *name));
118static symbolS *EXFUN (tag_find, (char *name));
db40ba14
SC
119
120
121static int
355afbcd
KR
122 EXFUN (c_line_new, (
123 symbolS * symbol,
124 long paddr,
125 unsigned short line_number,
126 fragS * frag));
127
128
129static void EXFUN (w_symbols,
130 (bfd * abfd,
131 char *where,
132 symbolS * symbol_rootP));
133
134
135
136static void EXFUN (obj_coff_def, (int what));
137static void EXFUN (obj_coff_lcomm, (void));
138static void EXFUN (obj_coff_dim, (void));
139static void EXFUN (obj_coff_text, (void));
140static void EXFUN (obj_coff_data, (void));
9a75dc1f
ILT
141static void EXFUN( obj_coff_bss,(void));
142static void EXFUN( obj_coff_ident,(void));
355afbcd
KR
143static void EXFUN (obj_coff_endef, (void));
144static void EXFUN (obj_coff_line, (void));
9a7d824a 145static void EXFUN (obj_coff_ln, (int));
355afbcd
KR
146static void EXFUN (obj_coff_scl, (void));
147static void EXFUN (obj_coff_size, (void));
148static void EXFUN (obj_coff_tag, (void));
149static void EXFUN (obj_coff_type, (void));
150static void EXFUN (obj_coff_val, (void));
151void EXFUN (obj_coff_section, (void));
152static void EXFUN (tag_init, (void));
153static void EXFUN (tag_insert, (char *name, symbolS * symbolP));
db40ba14
SC
154
155
156static struct hash_control *tag_hash;
157static symbolS *def_symbol_in_progress = NULL;
158
355afbcd
KR
159const pseudo_typeS obj_pseudo_table[] =
160{
161 {"def", obj_coff_def, 0},
162 {"dim", obj_coff_dim, 0},
163 {"endef", obj_coff_endef, 0},
164 {"line", obj_coff_line, 0},
165 {"ln", obj_coff_ln, 0},
9a7d824a 166 {"appline", obj_coff_ln, 1},
355afbcd
KR
167 {"scl", obj_coff_scl, 0},
168 {"size", obj_coff_size, 0},
169 {"tag", obj_coff_tag, 0},
170 {"type", obj_coff_type, 0},
171 {"val", obj_coff_val, 0},
172 {"section", obj_coff_section, 0},
173 {"use", obj_coff_section, 0},
174 {"sect", obj_coff_section, 0},
175 {"text", obj_coff_text, 0},
176 {"data", obj_coff_data, 0},
9a75dc1f
ILT
177 {"bss", obj_coff_bss, 0},
178 {"ident", obj_coff_ident, 0},
355afbcd
KR
179 {"ABORT", s_abort, 0},
180 {"lcomm", obj_coff_lcomm, 0},
c978e704
ILT
181#ifdef TC_M88K
182 /* The m88k uses sdef instead of def. */
183 {"sdef", obj_coff_def, 0},
184#endif
355afbcd
KR
185 {NULL} /* end sentinel */
186}; /* obj_pseudo_table */
187
188
189
190/* Section stuff
c593cf41 191
db40ba14
SC
192 We allow more than just the standard 3 sections, infact, we allow
193 10 sections, (though the usual three have to be there).
c593cf41 194
db40ba14 195 This structure performs the mappings for us:
c593cf41
SC
196
197*/
db40ba14 198
355afbcd 199/* OBS stuff
c593cf41
SC
200static struct internal_scnhdr bss_section_header;
201struct internal_scnhdr data_section_header;
202struct internal_scnhdr text_section_header;
203
204const segT N_TYPE_seg [32] =
205{
206
207};
208
209*/
db40ba14
SC
210
211#define N_SEG 32
355afbcd 212typedef struct
db40ba14 213{
2cb0bdc7
SC
214 segT seg_t;
215 int i;
216} seg_info_type;
355afbcd 217
2cb0bdc7 218seg_info_type seg_info_off_by_4[N_SEG] =
db40ba14 219{
2cb0bdc7
SC
220 {SEG_PTV, },
221 {SEG_NTV, },
222 {SEG_DEBUG, },
223 {SEG_ABSOLUTE, },
224 {SEG_UNKNOWN, },
225 {SEG_E0},
226 {SEG_E1},
227 {SEG_E2},
228 {SEG_E3},
229 {SEG_E4},
230 {SEG_E5},
231 {SEG_E6},
232 {SEG_E7},
233 {SEG_E8},
234 {SEG_E9},
235 {(segT)15},
236 {(segT)16},
237 {(segT)17},
238 {(segT)18},
239 {(segT)19},
240 {(segT)20},
241 {(segT)0},
242 {(segT)0},
243 {(segT)0},
244 {SEG_REGISTER}
245};
246
247
db40ba14
SC
248
249#define SEG_INFO_FROM_SECTION_NUMBER(x) (seg_info_off_by_4[(x)+4])
250#define SEG_INFO_FROM_SEG_NUMBER(x) (seg_info_off_by_4[(x)])
251
252
355afbcd
KR
253relax_addressT
254DEFUN (relax_align, (address, alignment),
255 register relax_addressT address AND
256 register long alignment)
db40ba14 257{
355afbcd
KR
258 relax_addressT mask;
259 relax_addressT new_address;
c593cf41 260
355afbcd
KR
261 mask = ~((~0) << alignment);
262 new_address = (address + mask) & (~mask);
c593cf41 263 return (new_address - address);
355afbcd 264} /* relax_align() */
db40ba14
SC
265
266
355afbcd
KR
267segT
268DEFUN (s_get_segment, (x),
269 symbolS * x)
db40ba14 270{
355afbcd 271 return SEG_INFO_FROM_SECTION_NUMBER (x->sy_symbol.ost_entry.n_scnum).seg_t;
db40ba14
SC
272}
273
274
275
276/* calculate the size of the frag chain and fill in the section header
277 to contain all of it, also fill in the addr of the sections */
355afbcd
KR
278static unsigned int
279DEFUN (size_section, (abfd, idx),
280 bfd * abfd AND
281 unsigned int idx)
db40ba14 282{
c593cf41
SC
283
284 unsigned int size = 0;
285 fragS *frag = segment_info[idx].frchainP->frch_root;
355afbcd
KR
286 while (frag)
287 {
288 size = frag->fr_address;
355afbcd
KR
289 if (frag->fr_address != size)
290 {
291 printf ("Out of step\n");
c593cf41 292 size = frag->fr_address;
db40ba14 293 }
3ad9ec6a 294
355afbcd
KR
295 switch (frag->fr_type)
296 {
3ad9ec6a 297#ifdef TC_COFF_SIZEMACHDEP
355afbcd
KR
298 case rs_machine_dependent:
299 size += TC_COFF_SIZEMACHDEP (frag);
300 break;
3ad9ec6a 301#endif
c593cf41
SC
302 case rs_fill:
303 case rs_org:
355afbcd
KR
304 size += frag->fr_fix;
305 size += frag->fr_offset * frag->fr_var;
c593cf41
SC
306 break;
307 case rs_align:
355afbcd
KR
308 size += frag->fr_fix;
309 size += relax_align (size, frag->fr_offset);
c593cf41
SC
310 }
311 frag = frag->fr_next;
312 }
313 segment_info[idx].scnhdr.s_size = size;
314 return size;
db40ba14
SC
315}
316
317
355afbcd
KR
318static unsigned int
319DEFUN (count_entries_in_chain, (idx),
320 unsigned int idx)
db40ba14 321{
355afbcd
KR
322 unsigned int nrelocs;
323 fixS *fixup_ptr;
c593cf41 324
355afbcd
KR
325 /* Count the relocations */
326 fixup_ptr = segment_info[idx].fix_root;
327 nrelocs = 0;
328 while (fixup_ptr != (fixS *) NULL)
c593cf41 329 {
355afbcd 330 if (TC_COUNT_RELOC (fixup_ptr))
c593cf41 331 {
355afbcd 332
db40ba14 333#ifdef TC_A29K
c593cf41 334
355afbcd
KR
335 if (fixup_ptr->fx_r_type == RELOC_CONSTH)
336 nrelocs += 2;
337 else
c593cf41 338 nrelocs++;
355afbcd
KR
339#else
340 nrelocs++;
db40ba14 341#endif
c593cf41 342 }
355afbcd
KR
343
344 fixup_ptr = fixup_ptr->fx_next;
c593cf41 345 }
355afbcd 346 return nrelocs;
db40ba14
SC
347}
348
349/* output all the relocations for a section */
355afbcd 350void
9a75dc1f 351DEFUN (do_relocs_for, (abfd, h, file_cursor),
355afbcd 352 bfd * abfd AND
9a75dc1f 353 object_headers * h AND
355afbcd 354 unsigned long *file_cursor)
db40ba14 355{
c593cf41
SC
356 unsigned int nrelocs;
357 unsigned int idx;
9a75dc1f
ILT
358 unsigned long reloc_start = *file_cursor;
359
355afbcd
KR
360 for (idx = SEG_E0; idx < SEG_E9; idx++)
361 {
362 if (segment_info[idx].scnhdr.s_name[0])
363 {
355afbcd
KR
364 struct external_reloc *ext_ptr;
365 struct external_reloc *external_reloc_vec;
366 unsigned int external_reloc_size;
9a75dc1f 367 unsigned int base = segment_info[idx].scnhdr.s_paddr;
355afbcd
KR
368 fixS *fix_ptr = segment_info[idx].fix_root;
369 nrelocs = count_entries_in_chain (idx);
370
155e7bc4
KR
371 if (nrelocs)
372 /* Bypass this stuff if no relocs. This also incidentally
373 avoids a SCO bug, where free(malloc(0)) tends to crash. */
355afbcd 374 {
155e7bc4
KR
375 external_reloc_size = nrelocs * RELSZ;
376 external_reloc_vec =
377 (struct external_reloc *) malloc (external_reloc_size);
c593cf41 378
155e7bc4
KR
379 ext_ptr = external_reloc_vec;
380
381 /* Fill in the internal coff style reloc struct from the
382 internal fix list. */
383 while (fix_ptr)
355afbcd 384 {
155e7bc4
KR
385 symbolS *symbol_ptr;
386 struct internal_reloc intr;
387
388 /* Only output some of the relocations */
389 if (TC_COUNT_RELOC (fix_ptr))
390 {
32e44774 391#ifdef TC_RELOC_MANGLE
155e7bc4 392 TC_RELOC_MANGLE (fix_ptr, &intr, base);
355afbcd 393
410e67eb 394#else
155e7bc4
KR
395 symbolS *dot;
396 symbol_ptr = fix_ptr->fx_addsy;
c593cf41 397
155e7bc4
KR
398 intr.r_type = TC_COFF_FIX2RTYPE (fix_ptr);
399 intr.r_vaddr =
400 base + fix_ptr->fx_frag->fr_address + fix_ptr->fx_where;
c593cf41 401
155e7bc4 402 intr.r_offset = fix_ptr->fx_offset;
c593cf41 403
155e7bc4 404 intr.r_offset = 0;
c593cf41 405
155e7bc4
KR
406 /* Turn the segment of the symbol into an offset. */
407 if (symbol_ptr)
355afbcd 408 {
155e7bc4
KR
409 dot = segment_info[S_GET_SEGMENT (symbol_ptr)].dot;
410 if (dot)
411 {
412 intr.r_symndx = dot->sy_number;
413 }
414 else
415 {
416 intr.r_symndx = symbol_ptr->sy_number;
417 }
418
355afbcd
KR
419 }
420 else
421 {
155e7bc4 422 intr.r_symndx = -1;
355afbcd 423 }
410e67eb 424#endif
c593cf41 425
155e7bc4
KR
426 (void) bfd_coff_swap_reloc_out (abfd, &intr, ext_ptr);
427 ext_ptr++;
c593cf41 428
db40ba14 429#if defined(TC_A29K)
9a75dc1f 430
155e7bc4
KR
431 /* The 29k has a special kludge for the high 16 bit
432 reloc. Two relocations are emited, R_IHIHALF,
433 and R_IHCONST. The second one doesn't contain a
434 symbol, but uses the value for offset. */
355afbcd 435
155e7bc4
KR
436 if (intr.r_type == R_IHIHALF)
437 {
438 /* now emit the second bit */
439 intr.r_type = R_IHCONST;
440 intr.r_symndx = fix_ptr->fx_addnumber;
155e7bc4
KR
441 (void) bfd_coff_swap_reloc_out (abfd, &intr, ext_ptr);
442 ext_ptr++;
443 }
db40ba14 444#endif
155e7bc4
KR
445 }
446
447 fix_ptr = fix_ptr->fx_next;
355afbcd
KR
448 }
449
155e7bc4
KR
450 /* Write out the reloc table */
451 bfd_write ((PTR) external_reloc_vec, 1, external_reloc_size,
452 abfd);
453 free (external_reloc_vec);
355afbcd 454
155e7bc4
KR
455 /* Fill in section header info. */
456 segment_info[idx].scnhdr.s_relptr = *file_cursor;
457 *file_cursor += external_reloc_size;
e02eaa59 458 segment_info[idx].scnhdr.s_nreloc = nrelocs;
155e7bc4
KR
459 }
460 else
461 {
462 /* No relocs */
463 segment_info[idx].scnhdr.s_relptr = 0;
464 }
c593cf41 465 }
355afbcd 466 }
9a75dc1f
ILT
467 /* Set relocation_size field in file headers */
468 H_SET_RELOCATION_SIZE (h, *file_cursor - reloc_start, 0);
db40ba14
SC
469}
470
471
472/* run through a frag chain and write out the data to go with it, fill
355afbcd 473 in the scnhdrs with the info on the file postions
c593cf41 474*/
355afbcd 475static void
9a75dc1f 476DEFUN (fill_section, (abfd, h, file_cursor),
355afbcd 477 bfd * abfd AND
9a75dc1f 478 object_headers *h AND
355afbcd 479 unsigned long *file_cursor)
db40ba14 480{
c593cf41 481
c58dbabf 482 unsigned int i;
016e0d42 483 unsigned int paddr = 0;
c58dbabf 484
355afbcd
KR
485 for (i = SEG_E0; i < SEG_UNKNOWN; i++)
486 {
487 unsigned int offset = 0;
488
489 struct internal_scnhdr *s = &(segment_info[i].scnhdr);
490
491 if (s->s_name[0])
492 {
493 fragS *frag = segment_info[i].frchainP->frch_root;
016e0d42
ILT
494 char *buffer;
495
9a75dc1f
ILT
496 if (s->s_size == 0)
497 s->s_scnptr = 0;
355afbcd 498 else
016e0d42 499 {
9a75dc1f
ILT
500 buffer = xmalloc (s->s_size);
501 s->s_scnptr = *file_cursor;
016e0d42 502 }
9a75dc1f 503 know (s->s_paddr == paddr);
355afbcd 504
355afbcd
KR
505 if (strcmp (s->s_name, ".text") == 0)
506 s->s_flags |= STYP_TEXT;
507 else if (strcmp (s->s_name, ".data") == 0)
508 s->s_flags |= STYP_DATA;
509 else if (strcmp (s->s_name, ".bss") == 0)
9a75dc1f
ILT
510 {
511 s->s_scnptr = 0;
512 s->s_flags |= STYP_BSS;
513#ifndef TC_I386
543d88e4 514#ifndef TC_A29K
9a75dc1f 515 /* Apparently the SVR3 linker is confused by noload
543d88e4 516 sections. So is the UDI mondfe program. */
9a75dc1f 517 s->s_flags |= STYP_NOLOAD;
543d88e4 518#endif
9a75dc1f
ILT
519#endif
520 }
355afbcd
KR
521 else if (strcmp (s->s_name, ".lit") == 0)
522 s->s_flags = STYP_LIT | STYP_TEXT;
016e0d42
ILT
523 else if (strcmp (s->s_name, ".init") == 0)
524 s->s_flags |= STYP_TEXT;
525 else if (strcmp (s->s_name, ".fini") == 0)
526 s->s_flags |= STYP_TEXT;
9a75dc1f
ILT
527 else if (strncmp (s->s_name, ".comment", 8) == 0)
528 s->s_flags |= STYP_INFO;
355afbcd
KR
529
530 while (frag)
c58dbabf 531 {
355afbcd
KR
532 unsigned int fill_size;
533 switch (frag->fr_type)
534 {
535 case rs_machine_dependent:
536 if (frag->fr_fix)
537 {
538 memcpy (buffer + frag->fr_address,
539 frag->fr_literal,
540 frag->fr_fix);
541 offset += frag->fr_fix;
542 }
543
544 break;
545 case rs_fill:
546 case rs_align:
547 case rs_org:
548 if (frag->fr_fix)
549 {
550 memcpy (buffer + frag->fr_address,
551 frag->fr_literal,
552 frag->fr_fix);
553 offset += frag->fr_fix;
554 }
555
556 fill_size = frag->fr_var;
115147fb 557 if (fill_size && frag->fr_offset > 0)
355afbcd
KR
558 {
559 unsigned int count;
560 unsigned int off = frag->fr_fix;
561 for (count = frag->fr_offset; count; count--)
562 {
9a75dc1f
ILT
563 if (fill_size < s->s_size)
564 {
565 memcpy (buffer + frag->fr_address + off,
566 frag->fr_literal + frag->fr_fix,
567 fill_size);
568 off += fill_size;
569 offset += fill_size;
570 }
2cb0bdc7 571 }
355afbcd
KR
572 }
573 break;
574 case rs_broken_word:
575 break;
576 default:
577 abort ();
578 }
579 frag = frag->fr_next;
a39116f1 580 }
c58dbabf 581
9a75dc1f 582 if (s->s_size != 0)
016e0d42 583 {
9a75dc1f
ILT
584 if (s->s_scnptr != 0)
585 {
586 bfd_write (buffer, s->s_size, 1, abfd);
587 *file_cursor += s->s_size;
588 }
016e0d42 589 free (buffer);
016e0d42 590 }
016e0d42 591 paddr += s->s_size;
355afbcd
KR
592 }
593 }
db40ba14
SC
594}
595
db40ba14
SC
596/* Coff file generation & utilities */
597
355afbcd 598static void
9a75dc1f 599DEFUN (coff_header_append, (abfd, h),
355afbcd 600 bfd * abfd AND
9a75dc1f 601 object_headers * h)
db40ba14 602{
c593cf41
SC
603 unsigned int i;
604 char buffer[1000];
605 char buffero[1000];
606
355afbcd 607 bfd_seek (abfd, 0, 0);
9a75dc1f
ILT
608
609#ifndef OBJ_COFF_OMIT_OPTIONAL_HEADER
610 H_SET_MAGIC_NUMBER (h, COFF_MAGIC);
611 H_SET_VERSION_STAMP (h, 0);
612 H_SET_ENTRY_POINT (h, 0);
613 H_SET_TEXT_START (h, segment_info[SEG_E0].frchainP->frch_root->fr_address);
614 H_SET_DATA_START (h, segment_info[SEG_E1].frchainP->frch_root->fr_address);
615 H_SET_SIZEOF_OPTIONAL_HEADER (h, bfd_coff_swap_aouthdr_out(abfd, &h->aouthdr,
616 buffero));
617#else /* defined (OBJ_COFF_OMIT_OPTIONAL_HEADER) */
618 H_SET_SIZEOF_OPTIONAL_HEADER (h, 0);
619#endif /* defined (OBJ_COFF_OMIT_OPTIONAL_HEADER) */
620
621 i = bfd_coff_swap_filehdr_out (abfd, &h->filehdr, buffer);
c593cf41 622
355afbcd 623 bfd_write (buffer, i, 1, abfd);
9a75dc1f 624 bfd_write (buffero, H_GET_SIZEOF_OPTIONAL_HEADER (h), 1, abfd);
c593cf41 625
355afbcd
KR
626 for (i = SEG_E0; i < SEG_E9; i++)
627 {
628 if (segment_info[i].scnhdr.s_name[0])
629 {
630 unsigned int size =
631 bfd_coff_swap_scnhdr_out (abfd,
632 &(segment_info[i].scnhdr),
633 buffer);
634 bfd_write (buffer, size, 1, abfd);
635 }
c593cf41 636 }
db40ba14
SC
637}
638
639
640char *
355afbcd
KR
641DEFUN (symbol_to_chars, (abfd, where, symbolP),
642 bfd * abfd AND
643 char *where AND
644 symbolS * symbolP)
db40ba14 645{
355afbcd
KR
646 unsigned int numaux = symbolP->sy_symbol.ost_entry.n_numaux;
647 unsigned int i;
85051959 648 valueT val;
c593cf41 649
355afbcd
KR
650 /* Turn any symbols with register attributes into abs symbols */
651 if (S_GET_SEGMENT (symbolP) == SEG_REGISTER)
c593cf41 652 {
355afbcd 653 S_SET_SEGMENT (symbolP, SEG_ABSOLUTE);
c593cf41 654 }
355afbcd
KR
655 /* At the same time, relocate all symbols to their output value */
656
85051959
ILT
657 val = (segment_info[S_GET_SEGMENT (symbolP)].scnhdr.s_paddr
658 + S_GET_VALUE (symbolP));
659
660 S_SET_VALUE (symbolP, val);
661
662 symbolP->sy_symbol.ost_entry.n_value = val;
355afbcd
KR
663
664 where += bfd_coff_swap_sym_out (abfd, &symbolP->sy_symbol.ost_entry,
665 where);
666
667 for (i = 0; i < numaux; i++)
668 {
669 where += bfd_coff_swap_aux_out (abfd,
670 &symbolP->sy_symbol.ost_auxent[i],
671 S_GET_DATA_TYPE (symbolP),
672 S_GET_STORAGE_CLASS (symbolP),
673 where);
c593cf41 674 }
355afbcd
KR
675 return where;
676
677}
db40ba14
SC
678
679
355afbcd
KR
680void
681obj_symbol_new_hook (symbolP)
682 symbolS *symbolP;
db40ba14 683{
355afbcd
KR
684 char underscore = 0; /* Symbol has leading _ */
685
686 /* Effective symbol */
687 /* Store the pointer in the offset. */
688 S_SET_ZEROES (symbolP, 0L);
689 S_SET_DATA_TYPE (symbolP, T_NULL);
690 S_SET_STORAGE_CLASS (symbolP, 0);
691 S_SET_NUMBER_AUXILIARY (symbolP, 0);
692 /* Additional information */
693 symbolP->sy_symbol.ost_flags = 0;
694 /* Auxiliary entries */
695 bzero ((char *) &symbolP->sy_symbol.ost_auxent[0], AUXESZ);
c593cf41 696
db40ba14 697#ifdef STRIP_UNDERSCORE
355afbcd 698 /* Remove leading underscore at the beginning of the symbol.
db40ba14
SC
699 * This is to be compatible with the standard librairies.
700 */
355afbcd
KR
701 if (*S_GET_NAME (symbolP) == '_')
702 {
703 underscore = 1;
704 S_SET_NAME (symbolP, S_GET_NAME (symbolP) + 1);
705 } /* strip underscore */
db40ba14 706#endif /* STRIP_UNDERSCORE */
c593cf41 707
355afbcd
KR
708 if (S_IS_STRING (symbolP))
709 SF_SET_STRING (symbolP);
710 if (!underscore && S_IS_LOCAL (symbolP))
711 SF_SET_LOCAL (symbolP);
c593cf41 712
355afbcd
KR
713 return;
714} /* obj_symbol_new_hook() */
db40ba14 715
355afbcd
KR
716/* stack stuff */
717stack *
718stack_init (chunk_size, element_size)
719 unsigned long chunk_size;
720 unsigned long element_size;
db40ba14 721{
355afbcd 722 stack *st;
c593cf41 723
355afbcd
KR
724 if ((st = (stack *) malloc (sizeof (stack))) == (stack *) 0)
725 return (stack *) 0;
726 if ((st->data = malloc (chunk_size)) == (char *) 0)
727 {
728 free (st);
729 return (stack *) 0;
730 }
731 st->pointer = 0;
732 st->size = chunk_size;
733 st->chunk_size = chunk_size;
734 st->element_size = element_size;
735 return st;
736} /* stack_init() */
737
738void
739stack_delete (st)
740 stack *st;
db40ba14 741{
355afbcd
KR
742 free (st->data);
743 free (st);
db40ba14
SC
744}
745
355afbcd
KR
746char *
747stack_push (st, element)
748 stack *st;
749 char *element;
db40ba14 750{
355afbcd
KR
751 if (st->pointer + st->element_size >= st->size)
752 {
753 st->size += st->chunk_size;
754 if ((st->data = xrealloc (st->data, st->size)) == (char *) 0)
755 return (char *) 0;
756 }
757 memcpy (st->data + st->pointer, element, st->element_size);
758 st->pointer += st->element_size;
759 return st->data + st->pointer;
760} /* stack_push() */
db40ba14 761
355afbcd
KR
762char *
763stack_pop (st)
764 stack *st;
db40ba14 765{
355afbcd
KR
766 if ((st->pointer -= st->element_size) < 0)
767 {
768 st->pointer = 0;
769 return (char *) 0;
c593cf41
SC
770 }
771
355afbcd 772 return st->data + st->pointer;
db40ba14
SC
773}
774
355afbcd
KR
775char *
776stack_top (st)
777 stack *st;
db40ba14 778{
355afbcd 779 return st->data + st->pointer - st->element_size;
db40ba14
SC
780}
781
782
783/*
784 * Handle .ln directives.
785 */
786
355afbcd 787static void
9a7d824a
ILT
788obj_coff_ln (appline)
789 int appline;
9ce31b66 790{
c593cf41 791 int l;
355afbcd 792
9a7d824a 793 if (! appline && def_symbol_in_progress != NULL)
355afbcd
KR
794 {
795 as_warn (".ln pseudo-op inside .def/.endef: ignored.");
796 demand_empty_rest_of_line ();
c593cf41
SC
797 return;
798 } /* wrong context */
799
355afbcd
KR
800 c_line_new (0,
801 obstack_next_free (&frags) - frag_now->fr_literal,
802 l = get_absolute_expression (),
803 frag_now);
9ce31b66 804#ifndef NO_LISTING
c593cf41 805 {
355afbcd
KR
806 extern int listing;
807
808 if (listing)
809 {
9a7d824a
ILT
810 if (! appline)
811 l += line_base - 1;
812 listing_source_line (l);
355afbcd
KR
813 }
814
c593cf41 815 }
9ce31b66 816#endif
355afbcd 817 demand_empty_rest_of_line ();
c593cf41 818 return;
9ce31b66 819} /* obj_coff_line() */
db40ba14
SC
820
821/*
822 * def()
823 *
824 * Handle .def directives.
825 *
826 * One might ask : why can't we symbol_new if the symbol does not
827 * already exist and fill it with debug information. Because of
828 * the C_EFCN special symbol. It would clobber the value of the
829 * function symbol before we have a chance to notice that it is
830 * a C_EFCN. And a second reason is that the code is more clear this
831 * way. (at least I think it is :-).
832 *
833 */
834
835#define SKIP_SEMI_COLON() while (*input_line_pointer++ != ';')
836#define SKIP_WHITESPACES() while (*input_line_pointer == ' ' || \
c593cf41
SC
837 *input_line_pointer == '\t') \
838 input_line_pointer++;
db40ba14 839
355afbcd
KR
840static void
841DEFUN (obj_coff_def, (what),
842 int what)
db40ba14 843{
355afbcd
KR
844 char name_end; /* Char after the end of name */
845 char *symbol_name; /* Name of the debug symbol */
846 char *symbol_name_copy; /* Temporary copy of the name */
847 unsigned int symbol_name_length;
848 /*$char* directiveP;$ *//* Name of the pseudo opcode */
849 /*$char directive[MAX_DIRECTIVE];$ *//* Backup of the directive */
850 /*$char end = 0;$ *//* If 1, stop parsing */
851
852 if (def_symbol_in_progress != NULL)
853 {
854 as_warn (".def pseudo-op used inside of .def/.endef: ignored.");
855 demand_empty_rest_of_line ();
856 return;
857 } /* if not inside .def/.endef */
858
859 SKIP_WHITESPACES ();
860
861 def_symbol_in_progress = (symbolS *) obstack_alloc (&notes, sizeof (*def_symbol_in_progress));
862 bzero (def_symbol_in_progress, sizeof (*def_symbol_in_progress));
863
864 symbol_name = input_line_pointer;
865 name_end = get_symbol_end ();
866 symbol_name_length = strlen (symbol_name);
867 symbol_name_copy = xmalloc (symbol_name_length + 1);
868 strcpy (symbol_name_copy, symbol_name);
869
870 /* Initialize the new symbol */
db40ba14 871#ifdef STRIP_UNDERSCORE
355afbcd
KR
872 S_SET_NAME (def_symbol_in_progress, (*symbol_name_copy == '_'
873 ? symbol_name_copy + 1
874 : symbol_name_copy));
875#else /* STRIP_UNDERSCORE */
876 S_SET_NAME (def_symbol_in_progress, symbol_name_copy);
877#endif /* STRIP_UNDERSCORE */
878 /* free(symbol_name_copy); */
879 def_symbol_in_progress->sy_name_offset = ~0;
880 def_symbol_in_progress->sy_number = ~0;
881 def_symbol_in_progress->sy_frag = &zero_address_frag;
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
5868b1fe 997 || def_symbol_in_progress->sy_value.X_seg != absolute_section
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 {
5868b1fe
ILT
1245 def_symbol_in_progress->sy_value.X_add_symbol =
1246 symbol_find_or_make (symbol_name);
1247 def_symbol_in_progress->sy_value.X_subtract_symbol = NULL;
1248 def_symbol_in_progress->sy_value.X_add_number = 0;
1249 def_symbol_in_progress->sy_value.X_seg = undefined_section;
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
5868b1fe 1380 && symbolP->sy_value.X_seg == absolute_section
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{
355afbcd 2050 change_to_section (".data", 5, get_absolute_expression ());
db40ba14
SC
2051}
2052
9a75dc1f
ILT
2053static void
2054obj_coff_bss()
2055{
2056 if (*input_line_pointer == '\n') /* .bss */
2057 change_to_section(".bss",4, get_absolute_expression());
2058 else /* .bss id,expr */
2059 obj_coff_lcomm();
2060}
2061
2062static void
2063obj_coff_ident()
2064{
2065 segT current_seg = now_seg; /* save current seg */
2066 subsegT current_subseg = now_subseg;
2067 change_to_section (".comment", 8, 0); /* .comment seg */
2068 stringer (1); /* read string */
2069 subseg_new (current_seg, current_subseg); /* restore current seg */
2070}
2071
355afbcd
KR
2072void
2073c_symbol_merge (debug, normal)
2074 symbolS *debug;
2075 symbolS *normal;
db40ba14 2076{
355afbcd
KR
2077 S_SET_DATA_TYPE (normal, S_GET_DATA_TYPE (debug));
2078 S_SET_STORAGE_CLASS (normal, S_GET_STORAGE_CLASS (debug));
c593cf41 2079
355afbcd
KR
2080 if (S_GET_NUMBER_AUXILIARY (debug) > S_GET_NUMBER_AUXILIARY (normal))
2081 {
2082 S_SET_NUMBER_AUXILIARY (normal, S_GET_NUMBER_AUXILIARY (debug));
2083 } /* take the most we have */
c593cf41 2084
355afbcd
KR
2085 if (S_GET_NUMBER_AUXILIARY (debug) > 0)
2086 {
2087 memcpy ((char *) &normal->sy_symbol.ost_auxent[0], (char *) &debug->sy_symbol.ost_auxent[0], S_GET_NUMBER_AUXILIARY (debug) * AUXESZ);
2088 } /* Move all the auxiliary information */
c593cf41 2089
355afbcd
KR
2090 /* Move the debug flags. */
2091 SF_SET_DEBUG_FIELD (normal, SF_GET_DEBUG_FIELD (debug));
2092} /* c_symbol_merge() */
db40ba14
SC
2093
2094static int
355afbcd
KR
2095DEFUN (c_line_new, (symbol, paddr, line_number, frag),
2096 symbolS * symbol AND
2097 long paddr AND
2098 unsigned short line_number AND
2099 fragS * frag)
db40ba14 2100{
355afbcd
KR
2101 struct lineno_list *new_line =
2102 (struct lineno_list *) xmalloc (sizeof (struct lineno_list));
2103
2104 segment_info_type *s = segment_info + now_seg;
c593cf41
SC
2105 new_line->line.l_lnno = line_number;
2106
355afbcd
KR
2107 if (line_number == 0)
2108 {
2109 last_line_symbol = symbol;
2110 new_line->line.l_addr.l_symndx = (long) symbol;
2111 }
2112 else
2113 {
2114 new_line->line.l_addr.l_paddr = paddr;
2115 }
c593cf41 2116
355afbcd
KR
2117 new_line->frag = (char *) frag;
2118 new_line->next = (struct lineno_list *) NULL;
2119
2120
2121 if (s->lineno_list_head == (struct lineno_list *) NULL)
2122 {
2123 s->lineno_list_head = new_line;
2124 }
2125 else
2126 {
2127 s->lineno_list_tail->next = new_line;
2128 }
c58dbabf 2129 s->lineno_list_tail = new_line;
355afbcd 2130 return LINESZ * s->scnhdr.s_nlnno++;
db40ba14
SC
2131}
2132
355afbcd
KR
2133void
2134c_dot_file_symbol (filename)
2135 char *filename;
db40ba14 2136{
355afbcd 2137 symbolS *symbolP;
c593cf41 2138
355afbcd
KR
2139 symbolP = symbol_new (".file",
2140 SEG_DEBUG,
2141 0,
2142 &zero_address_frag);
c593cf41 2143
355afbcd
KR
2144 S_SET_STORAGE_CLASS (symbolP, C_FILE);
2145 S_SET_NUMBER_AUXILIARY (symbolP, 1);
2146 SA_SET_FILE_FNAME (symbolP, filename);
9ce31b66 2147#ifndef NO_LISTING
c593cf41
SC
2148 {
2149 extern int listing;
355afbcd
KR
2150 if (listing)
2151 {
2152 listing_source_file (filename);
2153 }
2154
c593cf41 2155 }
c593cf41 2156
355afbcd
KR
2157#endif
2158 SF_SET_DEBUG (symbolP);
2159 S_SET_VALUE (symbolP, (long) previous_file_symbol);
2160
2161 previous_file_symbol = symbolP;
c593cf41 2162
355afbcd
KR
2163 /* Make sure that the symbol is first on the symbol chain */
2164 if (symbol_rootP != symbolP)
2165 {
2166 if (symbolP == symbol_lastP)
2167 {
2168 symbol_lastP = symbol_lastP->sy_previous;
2169 } /* if it was the last thing on the list */
c593cf41 2170
355afbcd
KR
2171 symbol_remove (symbolP, &symbol_rootP, &symbol_lastP);
2172 symbol_insert (symbolP, symbol_rootP, &symbol_rootP, &symbol_lastP);
2173 symbol_rootP = symbolP;
2174 } /* if not first on the list */
c593cf41 2175
355afbcd 2176} /* c_dot_file_symbol() */
db40ba14
SC
2177
2178/*
2179 * Build a 'section static' symbol.
2180 */
2181
355afbcd
KR
2182symbolS *
2183c_section_symbol (name, idx)
2184 char *name;
2185 int idx;
db40ba14 2186{
355afbcd 2187 symbolS *symbolP;
c593cf41 2188
355afbcd
KR
2189 symbolP = symbol_new (name, idx,
2190 0,
2191 &zero_address_frag);
c593cf41 2192
355afbcd
KR
2193 S_SET_STORAGE_CLASS (symbolP, C_STAT);
2194 S_SET_NUMBER_AUXILIARY (symbolP, 1);
c593cf41 2195
355afbcd 2196 SF_SET_STATICS (symbolP);
c593cf41 2197
355afbcd
KR
2198 return symbolP;
2199} /* c_section_symbol() */
db40ba14 2200
355afbcd
KR
2201static void
2202DEFUN (w_symbols, (abfd, where, symbol_rootP),
2203 bfd * abfd AND
2204 char *where AND
2205 symbolS * symbol_rootP)
db40ba14 2206{
355afbcd
KR
2207 symbolS *symbolP;
2208 unsigned int i;
2209
2210 /* First fill in those values we have only just worked out */
2211 for (i = SEG_E0; i < SEG_E9; i++)
2212 {
2213 symbolP = segment_info[i].dot;
2214 if (symbolP)
c593cf41 2215 {
355afbcd
KR
2216
2217 SA_SET_SCN_SCNLEN (symbolP, segment_info[i].scnhdr.s_size);
2218 SA_SET_SCN_NRELOC (symbolP, segment_info[i].scnhdr.s_nreloc);
2219 SA_SET_SCN_NLINNO (symbolP, segment_info[i].scnhdr.s_nlnno);
2220
c593cf41
SC
2221 }
2222 }
355afbcd
KR
2223
2224 /*
c593cf41
SC
2225 * Emit all symbols left in the symbol chain.
2226 */
355afbcd
KR
2227 for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
2228 {
2229 /* Used to save the offset of the name. It is used to point
c593cf41 2230 to the string in memory but must be a file offset. */
355afbcd 2231 register char *temp;
c593cf41 2232
355afbcd 2233 tc_coff_symbol_emit_hook (symbolP);
c593cf41 2234
355afbcd
KR
2235 temp = S_GET_NAME (symbolP);
2236 if (SF_GET_STRING (symbolP))
2237 {
2238 S_SET_OFFSET (symbolP, symbolP->sy_name_offset);
2239 S_SET_ZEROES (symbolP, 0);
db40ba14 2240 }
355afbcd
KR
2241 else
2242 {
2243 bzero (symbolP->sy_symbol.ost_entry.n_name, SYMNMLEN);
2244 strncpy (symbolP->sy_symbol.ost_entry.n_name, temp, SYMNMLEN);
2245 }
2246 where = symbol_to_chars (abfd, where, symbolP);
2247 S_SET_NAME (symbolP, temp);
2248 }
2249
db40ba14
SC
2250} /* w_symbols() */
2251
355afbcd
KR
2252static void
2253DEFUN_VOID (obj_coff_lcomm)
db40ba14 2254{
b066f445
SEF
2255 char *name;
2256 char c;
2257 int temp;
2258 char *p;
d752f749 2259
b066f445
SEF
2260 symbolS *symbolP;
2261 name = input_line_pointer;
c593cf41 2262
355afbcd 2263 c = get_symbol_end ();
b066f445
SEF
2264 p = input_line_pointer;
2265 *p = c;
355afbcd
KR
2266 SKIP_WHITESPACE ();
2267 if (*input_line_pointer != ',')
2268 {
2269 as_bad ("Expected comma after name");
2270 ignore_rest_of_line ();
2271 return;
2272 }
2273 if (*input_line_pointer == '\n')
2274 {
2275 as_bad ("Missing size expression");
2276 return;
2277 }
b066f445 2278 input_line_pointer++;
355afbcd
KR
2279 if ((temp = get_absolute_expression ()) < 0)
2280 {
2281 as_warn ("lcomm length (%d.) <0! Ignored.", temp);
2282 ignore_rest_of_line ();
2283 return;
2284 }
b066f445 2285 *p = 0;
c593cf41 2286
9a75dc1f
ILT
2287 symbolP = symbol_find_or_make(name);
2288
2289 if (S_GET_SEGMENT(symbolP) == SEG_UNKNOWN &&
2290 S_GET_VALUE(symbolP) == 0)
2291 {
2292 if (! need_pass_2)
2293 {
2294 char *p;
2295 segT current_seg = now_seg; /* save current seg */
2296 subsegT current_subseg = now_subseg;
2297
2298 subseg_new (SEG_E2, 1);
2299 symbolP->sy_frag = frag_now;
2300 p = frag_var(rs_org, 1, 1, (relax_substateT)0, symbolP,
2301 temp, (char *)0);
2302 *p = 0;
2303 subseg_new (current_seg, current_subseg); /* restore current seg */
2304 S_SET_SEGMENT(symbolP, SEG_E2);
2305 S_SET_STORAGE_CLASS(symbolP, C_STAT);
2306 }
2307 }
2308 else
2309 as_bad("Symbol %s already defined", name);
2310
2311 demand_empty_rest_of_line();
db40ba14
SC
2312}
2313
355afbcd 2314static void
9a75dc1f
ILT
2315DEFUN (fixup_mdeps, (frags, h, this_segment),
2316 fragS * frags AND
2317 object_headers * h AND
2318 segT this_segment)
3ad9ec6a 2319{
9a75dc1f 2320 subseg_change (this_segment, 0);
355afbcd 2321 while (frags)
3ad9ec6a 2322 {
355afbcd
KR
2323 switch (frags->fr_type)
2324 {
2325 case rs_align:
2326 case rs_org:
2327 frags->fr_type = rs_fill;
2328 frags->fr_offset =
2329 (frags->fr_next->fr_address - frags->fr_address - frags->fr_fix);
2330 break;
2331 case rs_machine_dependent:
9a75dc1f
ILT
2332 md_convert_frag (h, frags);
2333 frag_wane (frags);
355afbcd
KR
2334 break;
2335 default:
2336 ;
2337 }
2338 frags = frags->fr_next;
3ad9ec6a 2339 }
3ad9ec6a 2340}
355afbcd 2341
db40ba14 2342#if 1
355afbcd 2343static void
2cb0bdc7 2344DEFUN (fixup_segment, (segP, this_segment_type),
016e0d42 2345 segment_info_type * segP AND
355afbcd 2346 segT this_segment_type)
db40ba14 2347{
016e0d42 2348 register fixS * fixP;
355afbcd
KR
2349 register symbolS *add_symbolP;
2350 register symbolS *sub_symbolP;
2351 register long add_number;
2352 register int size;
2353 register char *place;
2354 register long where;
2355 register char pcrel;
2356 register fragS *fragP;
2357 register segT add_symbol_segment = SEG_ABSOLUTE;
2358
2359
016e0d42 2360 for (fixP = segP->fix_root; fixP; fixP = fixP->fx_next)
355afbcd
KR
2361 {
2362 fragP = fixP->fx_frag;
2363 know (fragP);
2364 where = fixP->fx_where;
2365 place = fragP->fr_literal + where;
2366 size = fixP->fx_size;
2367 add_symbolP = fixP->fx_addsy;
db40ba14 2368#ifdef TC_I960
355afbcd
KR
2369 if (fixP->fx_callj && TC_S_IS_CALLNAME (add_symbolP))
2370 {
2371 /* Relocation should be done via the
c593cf41
SC
2372 associated 'bal' entry point
2373 symbol. */
2374
355afbcd
KR
2375 if (!TC_S_IS_BALNAME (tc_get_bal_of_call (add_symbolP)))
2376 {
2377 as_bad ("No 'bal' entry point for leafproc %s",
2378 S_GET_NAME (add_symbolP));
2379 continue;
2380 }
2381 fixP->fx_addsy = add_symbolP = tc_get_bal_of_call (add_symbolP);
2382 } /* callj relocation */
db40ba14 2383#endif
355afbcd
KR
2384 sub_symbolP = fixP->fx_subsy;
2385 add_number = fixP->fx_offset;
2386 pcrel = fixP->fx_pcrel;
2387
2388 if (add_symbolP)
2389 {
2390 add_symbol_segment = S_GET_SEGMENT (add_symbolP);
2391 } /* if there is an addend */
2392
2393 if (sub_symbolP)
2394 {
2395 if (!add_symbolP)
2396 {
2397 /* Its just -sym */
2398 if (S_GET_SEGMENT (sub_symbolP) != SEG_ABSOLUTE)
2399 {
2400 as_bad ("Negative of non-absolute symbol %s", S_GET_NAME (sub_symbolP));
2401 } /* not absolute */
2402
2403 add_number -= S_GET_VALUE (sub_symbolP);
2404 fixP->fx_subsy = 0;
2405
2406 /* if sub_symbol is in the same segment that add_symbol
c593cf41 2407 and add_symbol is either in DATA, TEXT, BSS or ABSOLUTE */
355afbcd
KR
2408 }
2409 else if ((S_GET_SEGMENT (sub_symbolP) == add_symbol_segment)
2410 && (SEG_NORMAL (add_symbol_segment)
2411 || (add_symbol_segment == SEG_ABSOLUTE)))
2412 {
2413 /* Difference of 2 symbols from same segment. */
2414 /* Can't make difference of 2 undefineds: 'value' means */
2415 /* something different for N_UNDF. */
db40ba14 2416#ifdef TC_I960
355afbcd 2417 /* Makes no sense to use the difference of 2 arbitrary symbols
eeeaa778 2418 as the target of a call instruction. */
355afbcd
KR
2419 if (fixP->fx_callj)
2420 {
2421 as_bad ("callj to difference of 2 symbols");
2422 }
2423#endif /* TC_I960 */
2424 add_number += S_GET_VALUE (add_symbolP) -
2425 S_GET_VALUE (sub_symbolP);
2426
2427 add_symbolP = NULL;
2428 fixP->fx_addsy = NULL;
2429 }
2430 else
2431 {
2432 /* Different segments in subtraction. */
2433 know (!(S_IS_EXTERNAL (sub_symbolP) && (S_GET_SEGMENT (sub_symbolP) == SEG_ABSOLUTE)));
2434
2435 if ((S_GET_SEGMENT (sub_symbolP) == SEG_ABSOLUTE))
2436 {
2437 add_number -= S_GET_VALUE (sub_symbolP);
2438 }
2439 else
2440 {
2441 as_bad ("Can't emit reloc {- %s-seg symbol \"%s\"} @ file address %d.",
2442 segment_name (S_GET_SEGMENT (sub_symbolP)),
2443 S_GET_NAME (sub_symbolP), fragP->fr_address + where);
2444 } /* if absolute */
2445 }
2446 } /* if sub_symbolP */
2447
2448 if (add_symbolP)
2449 {
2450 if (add_symbol_segment == this_segment_type && pcrel)
2451 {
2452 /*
eeeaa778
KR
2453 * This fixup was made when the symbol's segment was
2454 * SEG_UNKNOWN, but it is now in the local segment.
2455 * So we know how to do the address without relocation.
2456 */
db40ba14 2457#ifdef TC_I960
355afbcd 2458 /* reloc_callj() may replace a 'call' with a 'calls' or a 'bal',
eeeaa778
KR
2459 * in which cases it modifies *fixP as appropriate. In the case
2460 * of a 'calls', no further work is required, and *fixP has been
2461 * set up to make the rest of the code below a no-op.
2462 */
355afbcd
KR
2463 reloc_callj (fixP);
2464#endif /* TC_I960 */
2465
2466 add_number += S_GET_VALUE (add_symbolP);
2467 add_number -= md_pcrel_from (fixP);
016e0d42
ILT
2468#ifdef TC_I386
2469 /* On the 386 we must adjust by the segment
2470 vaddr as well. Ian Taylor. */
2471 add_number -= segP->scnhdr.s_vaddr;
2472#endif
355afbcd
KR
2473 pcrel = 0; /* Lie. Don't want further pcrel processing. */
2474 fixP->fx_addsy = NULL; /* No relocations please. */
2475 }
2476 else
2477 {
2478 switch (add_symbol_segment)
2479 {
2480 case SEG_ABSOLUTE:
db40ba14 2481#ifdef TC_I960
355afbcd
KR
2482 reloc_callj (fixP); /* See comment about reloc_callj() above*/
2483#endif /* TC_I960 */
2484 add_number += S_GET_VALUE (add_symbolP);
2485 fixP->fx_addsy = NULL;
2486 add_symbolP = NULL;
2487 break;
2488 default:
2489
61001d96
ILT
2490#ifdef TC_A29K
2491 /* This really should be handled in the linker, but
2492 backward compatibility forbids. */
2493 add_number += S_GET_VALUE (add_symbolP);
2494#else
355afbcd
KR
2495 add_number += S_GET_VALUE (add_symbolP) +
2496 segment_info[S_GET_SEGMENT (add_symbolP)].scnhdr.s_paddr;
61001d96 2497#endif
355afbcd
KR
2498 break;
2499
2500 case SEG_UNKNOWN:
db40ba14 2501#ifdef TC_I960
355afbcd
KR
2502 if ((int) fixP->fx_bit_fixP == 13)
2503 {
2504 /* This is a COBR instruction. They have only a
eeeaa778
KR
2505 * 13-bit displacement and are only to be used
2506 * for local branches: flag as error, don't generate
2507 * relocation.
2508 */
355afbcd
KR
2509 as_bad ("can't use COBR format with external label");
2510 fixP->fx_addsy = NULL; /* No relocations please. */
2511 continue;
2512 } /* COBR */
2513#endif /* TC_I960 */
6142210d 2514#ifdef TC_I386
355afbcd 2515 /* 386 COFF uses a peculiar format in
016e0d42
ILT
2516 which the value of a common symbol is
2517 stored in the .text segment (I've
2518 checked this on SVR3.2 and SCO 3.2.2)
2519 Ian Taylor <ian@cygnus.com>. */
9a75dc1f
ILT
2520 if (S_IS_COMMON (add_symbolP))
2521 add_number += S_GET_VALUE (add_symbolP);
6142210d 2522#endif
355afbcd
KR
2523 break;
2524
2525
2526 } /* switch on symbol seg */
2527 } /* if not in local seg */
2528 } /* if there was a + symbol */
2529
2530 if (pcrel)
2531 {
2532 add_number -= md_pcrel_from (fixP);
2533 if (add_symbolP == 0)
2534 {
2535 fixP->fx_addsy = &abs_symbol;
2536 } /* if there's an add_symbol */
016e0d42
ILT
2537#ifdef TC_I386
2538 /* On the 386 we must adjust by the segment vaddr
2539 as well. Ian Taylor. */
2540 add_number -= segP->scnhdr.s_vaddr;
2541#endif
355afbcd
KR
2542 } /* if pcrel */
2543
2544 if (!fixP->fx_bit_fixP)
2545 {
2546 if ((size == 1 &&
2547 (add_number & ~0xFF) && ((add_number & ~0xFF) != (-1 & ~0xFF))) ||
2548 (size == 2 &&
2549 (add_number & ~0xFFFF) && ((add_number & ~0xFFFF) != (-1 & ~0xFFFF))))
2550 {
2551 as_bad ("Value of %d too large for field of %d bytes at 0x%x",
2552 add_number, size, fragP->fr_address + where);
2553 } /* generic error checking */
e41474b7 2554#ifdef WARN_SIGNED_OVERFLOW_WORD
355afbcd 2555 /* Warn if a .word value is too large when treated as
eeeaa778
KR
2556 a signed number. We already know it is not too
2557 negative. This is to catch over-large switches
2558 generated by gcc on the 68k. */
355afbcd
KR
2559 if (!flagseen['J']
2560 && size == 2
2561 && add_number > 0x7fff)
2562 as_bad ("Signed .word overflow; switch may be too large; %d at 0x%x",
2563 add_number, fragP->fr_address + where);
e41474b7 2564#endif
355afbcd
KR
2565 } /* not a bit fix */
2566 /* once this fix has been applied, we don't have to output anything
c593cf41 2567 nothing more need be done -*/
355afbcd 2568 md_apply_fix (fixP, add_number);
355afbcd 2569 } /* For each fixS in this segment. */
355afbcd 2570} /* fixup_segment() */
c593cf41 2571
355afbcd 2572#endif
This page took 0.201158 seconds and 4 git commands to generate.