Flag error if absolute constant is too large for an immediate field.
[deliverable/binutils-gdb.git] / gas / config / obj-coff.c
CommitLineData
fecd2382 1/* coff object file format
a87b3269 2 Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc.
a39116f1
RP
3
4 This file is part of GAS.
5
6 GAS is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GAS is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GAS; see the file COPYING. If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
fecd2382 19
fecd2382
RP
20#include "as.h"
21
22#include "obstack.h"
23
24lineno* lineno_rootP;
25
26const short seg_N_TYPE[] = { /* in: segT out: N_TYPE bits */
27 C_ABS_SECTION,
28 C_TEXT_SECTION,
29 C_DATA_SECTION,
30 C_BSS_SECTION,
31 C_UNDEF_SECTION, /* SEG_UNKNOWN */
32 C_UNDEF_SECTION, /* SEG_ABSENT */
33 C_UNDEF_SECTION, /* SEG_PASS1 */
34 C_UNDEF_SECTION, /* SEG_GOOF */
35 C_UNDEF_SECTION, /* SEG_BIG */
36 C_UNDEF_SECTION, /* SEG_DIFFERENCE */
37 C_DEBUG_SECTION, /* SEG_DEBUG */
38 C_NTV_SECTION, /* SEG_NTV */
39 C_PTV_SECTION, /* SEG_PTV */
57574979 40 C_REGISTER_SECTION, /* SEG_REGISTER */
fecd2382
RP
41};
42
43
44/* Add 4 to the real value to get the index and compensate the negatives */
45
46const segT N_TYPE_seg [32] =
47{
a39116f1
RP
48 SEG_PTV, /* C_PTV_SECTION == -4 */
49 SEG_NTV, /* C_NTV_SECTION == -3 */
50 SEG_DEBUG, /* C_DEBUG_SECTION == -2 */
51 SEG_ABSOLUTE, /* C_ABS_SECTION == -1 */
52 SEG_UNKNOWN, /* C_UNDEF_SECTION == 0 */
53 SEG_TEXT, /* C_TEXT_SECTION == 1 */
54 SEG_DATA, /* C_DATA_SECTION == 2 */
55 SEG_BSS, /* C_BSS_SECTION == 3 */
56 SEG_REGISTER, /* C_REGISTER_SECTION == 4 */
57 SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,
58 SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,
59 SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF
60 };
fecd2382 61
a87b3269 62#if __STDC__ == 1
fecd2382
RP
63
64char *s_get_name(symbolS *s);
65static symbolS *tag_find_or_make(char *name);
66static symbolS* tag_find(char *name);
57574979
SC
67#ifdef BFD_HEADERS
68static void obj_coff_section_header_append(char **where, struct internal_scnhdr *header);
69#else
70static void obj_coff_section_header_append(char **where, SCNHDR *header);
71#endif
fecd2382
RP
72static void obj_coff_def(int what);
73static void obj_coff_dim(void);
74static void obj_coff_endef(void);
75static void obj_coff_line(void);
76static void obj_coff_ln(void);
77static void obj_coff_scl(void);
78static void obj_coff_size(void);
79static void obj_coff_stab(int what);
80static void obj_coff_tag(void);
81static void obj_coff_type(void);
82static void obj_coff_val(void);
83static void tag_init(void);
84static void tag_insert(char *name, symbolS *symbolP);
85
a87b3269 86#else /* not __STDC__ */
fecd2382
RP
87
88char *s_get_name();
89static symbolS *tag_find();
90static symbolS *tag_find_or_make();
57574979 91static void obj_coff_section_header_append();
fecd2382
RP
92static void obj_coff_def();
93static void obj_coff_dim();
94static void obj_coff_endef();
95static void obj_coff_line();
96static void obj_coff_ln();
97static void obj_coff_scl();
98static void obj_coff_size();
99static void obj_coff_stab();
100static void obj_coff_tag();
101static void obj_coff_type();
102static void obj_coff_val();
103static void tag_init();
104static void tag_insert();
105
a87b3269 106#endif /* not __STDC__ */
fecd2382
RP
107
108static struct hash_control *tag_hash;
109static symbolS *def_symbol_in_progress = NULL;
110
111const pseudo_typeS obj_pseudo_table[] = {
112#ifndef IGNORE_DEBUG
113 { "def", obj_coff_def, 0 },
114 { "dim", obj_coff_dim, 0 },
115 { "endef", obj_coff_endef, 0 },
116 { "line", obj_coff_line, 0 },
117 { "ln", obj_coff_ln, 0 },
118 { "scl", obj_coff_scl, 0 },
119 { "size", obj_coff_size, 0 },
120 { "tag", obj_coff_tag, 0 },
121 { "type", obj_coff_type, 0 },
122 { "val", obj_coff_val, 0 },
123#else
124 { "def", s_ignore, 0 },
125 { "dim", s_ignore, 0 },
126 { "endef", s_ignore, 0 },
127 { "line", s_ignore, 0 },
128 { "ln", s_ignore, 0 },
129 { "scl", s_ignore, 0 },
130 { "size", s_ignore, 0 },
131 { "tag", s_ignore, 0 },
132 { "type", s_ignore, 0 },
133 { "val", s_ignore, 0 },
134#endif /* ignore debug */
a39116f1 135
d1a9e594 136 { "ident", s_ignore, 0 }, /* we don't yet handle this. */
a39116f1
RP
137
138
139 /* stabs aka a.out aka b.out directives for debug symbols.
140 Currently ignored silently. Except for .line at which
141 we guess from context. */
fecd2382 142 { "desc", s_ignore, 0 }, /* def */
a39116f1 143 /* { "line", s_ignore, 0 }, */ /* source code line number */
fecd2382
RP
144 { "stabd", obj_coff_stab, 'd' }, /* stabs */
145 { "stabn", obj_coff_stab, 'n' }, /* stabs */
146 { "stabs", obj_coff_stab, 's' }, /* stabs */
a39116f1
RP
147
148 /* stabs-in-coff (?) debug pseudos (ignored) */
d1a9e594 149 { "optim", s_ignore, 0 }, /* For sun386i cc (?) */
a39116f1 150 /* other stuff */
fecd2382 151 { "ABORT", s_abort, 0 },
a39116f1 152
fecd2382
RP
153 { NULL} /* end sentinel */
154}; /* obj_pseudo_table */
155
156
a39116f1 157/* obj dependant output values */
57574979
SC
158#ifdef BFD_HEADERS
159static struct internal_scnhdr bss_section_header;
160struct internal_scnhdr data_section_header;
161struct internal_scnhdr text_section_header;
162#else
fecd2382 163static SCNHDR bss_section_header;
57574979
SC
164SCNHDR data_section_header;
165SCNHDR text_section_header;
166#endif
fecd2382
RP
167/* Relocation. */
168
6d5460ab
RP
169static int reloc_compare(p1, p2)
170#ifdef BFD_HEADERS
171struct internal_reloc *p1, *p2;
172#else
173RELOC *p1, *p2;
174#endif
175{
176 return (int)(p1->r_vaddr - p2->r_vaddr);
177}
178
fecd2382
RP
179/*
180 * emit_relocations()
181 *
182 * Crawl along a fixS chain. Emit the segment's relocations.
183 */
184
185void obj_emit_relocations(where, fixP, segment_address_in_file)
186char **where;
187fixS *fixP; /* Fixup chain for this segment. */
188relax_addressT segment_address_in_file;
189{
57574979 190#ifdef BFD_HEADERS
6d5460ab 191 struct internal_reloc *ri_table;
57574979 192#else
6d5460ab 193 RELOC *ri_table;
57574979 194#endif
fecd2382 195 symbolS *symbolP;
6d5460ab
RP
196 int i, count;
197 fixS *p;
198
199 for (count = 0, p = fixP; p ; p = p->fx_next)
200 if (p->fx_addsy) count++;
201 if (!count)
202 return;
203
204#ifdef BFD_HEADERS
205 ri_table = (struct internal_reloc *) calloc(sizeof(*ri_table),count);
206#else
207 ri_table = (RELOC *) calloc(sizeof(*ri_table),count);
208#endif
209 if (!ri_table)
210 as_fatal ("obj_emit_relocations: Could not malloc relocation table");
211
212#ifdef TC_I960
213 callj_table = (char *)malloc (sizeof(char)*count);
214 if (!callj_table)
215 as_fatal ("obj_emit_relocations: Could not malloc callj table");
216#endif
a39116f1 217
6d5460ab 218 for (i = 0; fixP; fixP = fixP->fx_next) {
fecd2382
RP
219 if (symbolP = fixP->fx_addsy) {
220#if defined(TC_M68K)
6d5460ab
RP
221 ri_table[i].r_type = (fixP->fx_pcrel ?
222 (fixP->fx_size == 1 ? R_PCRBYTE :
223 fixP->fx_size == 2 ? R_PCRWORD :
224 R_PCRLONG):
225 (fixP->fx_size == 1 ? R_RELBYTE :
226 fixP->fx_size == 2 ? R_RELWORD :
227 R_RELLONG));
fecd2382 228#elif defined(TC_I386)
6d5460ab
RP
229 /* FIXME-SOON R_OFF8 & R_DIR16 are a vague guess, completly
230 untested. */
231 ri_table[i].r_type = (fixP->fx_pcrel ?
232 (fixP->fx_size == 1 ? R_PCRBYTE :
233 fixP->fx_size == 2 ? R_PCRWORD :
234 R_PCRLONG):
235 (fixP->fx_size == 1 ? R_OFF8 :
236 fixP->fx_size == 2 ? R_DIR16 :
237 R_DIR32));
fecd2382 238#elif defined(TC_I960)
6d5460ab
RP
239 ri_table[i].r_type = (fixP->fx_pcrel
240 ? R_IPRMED
241 : R_RELLONG);
242 callj_table[i] = fixP->fx_callj ? 1 : 0;
fecd2382 243#elif defined(TC_A29K)
6d5460ab 244 ri_table[i].r_type = tc_coff_fix2rtype(fixP);
a39116f1 245
fecd2382 246#else
6d5460ab 247#error you lose
fecd2382 248#endif /* TC_M68K || TC_I386 */
6d5460ab
RP
249 ri_table[i].r_vaddr = (fixP->fx_frag->fr_address
250 + fixP->fx_where);
fecd2382
RP
251 /* If symbol associated to relocation entry is a bss symbol
252 or undefined symbol just remember the index of the symbol.
253 Otherwise store the index of the symbol describing the
254 section the symbol belong to. This heuristic speeds up ld.
255 */
256 /* Local symbols can generate relocation information. In case
257 of structure return for instance. But they have no symbol
258 number because they won't be emitted in the final object.
259 In the case where they are in the BSS section, this leads
260 to an incorrect r_symndx.
6d5460ab
RP
261 Under bsd the loader do not care if the symbol reference
262 is incorrect. But the SYS V ld complains about this. To
263 avoid this we associate the symbol to the associated
264 section, *even* if it is the BSS section. */
fecd2382
RP
265 /* If someone can tell me why the other symbols of the bss
266 section are not associated with the .bss section entry,
267 I'd be gratefull. I guess that it has to do with the special
268 nature of the .bss section. Or maybe this is because the
269 bss symbols are declared in the common section and can
270 be resized later. Can it break code some where ? */
6d5460ab
RP
271 ri_table[i].r_symndx = (S_GET_SEGMENT(symbolP) == SEG_TEXT
272 ? dot_text_symbol->sy_number
273 : (S_GET_SEGMENT(symbolP) == SEG_DATA
274 ? dot_data_symbol->sy_number
275 : ((SF_GET_LOCAL(symbolP)
276 ? dot_bss_symbol->sy_number
277 : symbolP->sy_number)))); /* bss or undefined */
a39116f1 278
fecd2382 279 /* md_ri_to_chars((char *) &ri, ri); */ /* Last step : write md f */
57574979 280
6d5460ab
RP
281 i++;
282 } /* if there's a symbol */
283 } /* for each fixP */
284
285 /*
286 * AIX ld prefer to have the reloc table with r_vaddr sorted.
287 * But sorting it should not hurt any other ld.
288 */
289 qsort (ri_table, count, sizeof(*ri_table), reloc_compare);
290
291 for (i = 0; i < count; i++)
292 {
57574979 293#ifdef BFD_HEADERS
6d5460ab
RP
294 *where += bfd_coff_swap_reloc_out(stdoutput, &ri_table[i], *where);
295# ifdef TC_A29K
296 /* The 29k has a special kludge for the high 16 bit reloc.
297 Two relocations are emmited, R_IHIHALF, and R_IHCONST.
298 The second one doesn't contain a symbol, but uses the
299 value for offset */
300 if (ri_table[i].r_type == R_IHIHALF)
301 {
a39116f1 302 /* now emit the second bit */
6d5460ab
RP
303 ri_table[i].r_type = R_IHCONST;
304 ri_table[i].r_symndx = fixP->fx_addnumber;
305 *where += bfd_coff_swap_reloc_out(stdoutput, &ri_table[i],
306 *where);
57574979 307 }
6d5460ab
RP
308# endif /* TC_A29K */
309
310#else /* not BFD_HEADERS */
311 append(where, (char *) &ri_table[i], RELSZ);
312#endif /* not BFD_HEADERS */
313
fecd2382 314#ifdef TC_I960
6d5460ab
RP
315 if (callj_table[i])
316 {
317 ri_table[i].r_type = R_OPTCALL;
318# ifdef BFD_HEADERS
319 *where += bfd_coff_swap_reloc_out(stdoutput, &ri_table[i],
320 *where);
321# else
322 append(where, (char *) &ri_table[i], (unsigned long)RELSZ);
323# endif /* BFD_HEADERS */
fecd2382
RP
324 } /* if it's a callj, do it again for the opcode */
325#endif /* TC_I960 */
6d5460ab
RP
326 }
327
328 free (ri_table);
329#ifdef TC_I960
330 free (callj_table);
331#endif
a39116f1 332
fecd2382
RP
333 return;
334} /* obj_emit_relocations() */
335
336/* Coff file generation & utilities */
337
57574979
SC
338#ifdef BFD_HEADERS
339void obj_header_append(where, headers)
340char **where;
341object_headers *headers;
342{
a39116f1
RP
343 tc_headers_hook(headers);
344 *where += bfd_coff_swap_filehdr_out(stdoutput, &(headers->filehdr), *where);
57574979 345#ifndef OBJ_COFF_OMIT_OPTIONAL_HEADER
a39116f1 346 *where += bfd_coff_swap_aouthdr_out(stdoutput, &(headers->aouthdr), *where);
57574979 347#endif
a39116f1
RP
348 obj_coff_section_header_append(where, &text_section_header);
349 obj_coff_section_header_append(where, &data_section_header);
350 obj_coff_section_header_append(where, &bss_section_header);
351
57574979
SC
352}
353
354#else
355
fecd2382
RP
356void obj_header_append(where, headers)
357char **where;
358object_headers *headers;
359{
360 tc_headers_hook(headers);
a39116f1 361
d1a9e594 362#ifdef CROSS_COMPILE
fecd2382
RP
363 /* Eventually swap bytes for cross compilation for file header */
364 md_number_to_chars(*where, headers->filehdr.f_magic, sizeof(headers->filehdr.f_magic));
365 *where += sizeof(headers->filehdr.f_magic);
366 md_number_to_chars(*where, headers->filehdr.f_nscns, sizeof(headers->filehdr.f_nscns));
367 *where += sizeof(headers->filehdr.f_nscns);
368 md_number_to_chars(*where, headers->filehdr.f_timdat, sizeof(headers->filehdr.f_timdat));
369 *where += sizeof(headers->filehdr.f_timdat);
370 md_number_to_chars(*where, headers->filehdr.f_symptr, sizeof(headers->filehdr.f_symptr));
371 *where += sizeof(headers->filehdr.f_symptr);
372 md_number_to_chars(*where, headers->filehdr.f_nsyms, sizeof(headers->filehdr.f_nsyms));
373 *where += sizeof(headers->filehdr.f_nsyms);
374 md_number_to_chars(*where, headers->filehdr.f_opthdr, sizeof(headers->filehdr.f_opthdr));
375 *where += sizeof(headers->filehdr.f_opthdr);
376 md_number_to_chars(*where, headers->filehdr.f_flags, sizeof(headers->filehdr.f_flags));
377 *where += sizeof(headers->filehdr.f_flags);
a39116f1 378
fecd2382
RP
379#ifndef OBJ_COFF_OMIT_OPTIONAL_HEADER
380 /* Eventually swap bytes for cross compilation for a.out header */
381 md_number_to_chars(*where, headers->aouthdr.magic, sizeof(headers->aouthdr.magic));
382 *where += sizeof(headers->aouthdr.magic);
383 md_number_to_chars(*where, headers->aouthdr.vstamp, sizeof(headers->aouthdr.vstamp));
384 *where += sizeof(headers->aouthdr.vstamp);
385 md_number_to_chars(*where, headers->aouthdr.tsize, sizeof(headers->aouthdr.tsize));
386 *where += sizeof(headers->aouthdr.tsize);
387 md_number_to_chars(*where, headers->aouthdr.dsize, sizeof(headers->aouthdr.dsize));
388 *where += sizeof(headers->aouthdr.dsize);
389 md_number_to_chars(*where, headers->aouthdr.bsize, sizeof(headers->aouthdr.bsize));
390 *where += sizeof(headers->aouthdr.bsize);
391 md_number_to_chars(*where, headers->aouthdr.entry, sizeof(headers->aouthdr.entry));
392 *where += sizeof(headers->aouthdr.entry);
393 md_number_to_chars(*where, headers->aouthdr.text_start, sizeof(headers->aouthdr.text_start));
394 *where += sizeof(headers->aouthdr.text_start);
395 md_number_to_chars(*where, headers->aouthdr.data_start, sizeof(headers->aouthdr.data_start));
396 *where += sizeof(headers->aouthdr.data_start);
57574979
SC
397 md_number_to_chars(*where, headers->aouthdr.tagentries, sizeof(headers->aouthdr.tagentries));
398 *where += sizeof(headers->aouthdr.tagentries);
fecd2382 399#endif /* OBJ_COFF_OMIT_OPTIONAL_HEADER */
a39116f1 400
d1a9e594 401#else /* CROSS_COMPILE */
a39116f1 402
6d5460ab 403 append(where, (char *) &headers->filehdr, FILHSZ);
fecd2382 404#ifndef OBJ_COFF_OMIT_OPTIONAL_HEADER
6d5460ab 405 append(where, (char *) &headers->aouthdr, AOUTHDRSZ);
fecd2382 406#endif /* OBJ_COFF_OMIT_OPTIONAL_HEADER */
a39116f1 407
d1a9e594 408#endif /* CROSS_COMPILE */
a39116f1 409
fecd2382 410 /* Output the section headers */
57574979
SC
411 obj_coff_section_header_append(where, &text_section_header);
412 obj_coff_section_header_append(where, &data_section_header);
413 obj_coff_section_header_append(where, &bss_section_header);
a39116f1 414
fecd2382
RP
415 return;
416} /* obj_header_append() */
57574979 417#endif
fecd2382
RP
418void obj_symbol_to_chars(where, symbolP)
419char **where;
420symbolS *symbolP;
421{
57574979 422#ifdef BFD_HEADERS
a39116f1
RP
423 unsigned int numaux = symbolP->sy_symbol.ost_entry.n_numaux;
424 unsigned int i;
425
57574979 426 if (S_GET_SEGMENT(symbolP) == SEG_REGISTER) {
a39116f1 427 S_SET_SEGMENT(symbolP, SEG_ABSOLUTE);
57574979 428 }
a39116f1 429 *where += bfd_coff_swap_sym_out(stdoutput, &symbolP->sy_symbol.ost_entry,
57574979 430 *where);
a39116f1
RP
431
432 for (i = 0; i < numaux; i++)
433 {
434 *where += bfd_coff_swap_aux_out(stdoutput,
435 &symbolP->sy_symbol.ost_auxent[i],
436 S_GET_DATA_TYPE(symbolP),
437 S_GET_STORAGE_CLASS(symbolP),
438 *where);
439 }
440
441#else /* BFD_HEADERS */
442 SYMENT *syment = &symbolP->sy_symbol.ost_entry;
443 int i;
444 char numaux = syment->n_numaux;
445 unsigned short type = S_GET_DATA_TYPE(symbolP);
446
d1a9e594 447#ifdef CROSS_COMPILE
a39116f1
RP
448 md_number_to_chars(*where, syment->n_value, sizeof(syment->n_value));
449 *where += sizeof(syment->n_value);
450 md_number_to_chars(*where, syment->n_scnum, sizeof(syment->n_scnum));
451 *where += sizeof(syment->n_scnum);
452 md_number_to_chars(*where, 0, sizeof(short)); /* pad n_flags */
453 *where += sizeof(short);
454 md_number_to_chars(*where, syment->n_type, sizeof(syment->n_type));
455 *where += sizeof(syment->n_type);
456 md_number_to_chars(*where, syment->n_sclass, sizeof(syment->n_sclass));
457 *where += sizeof(syment->n_sclass);
458 md_number_to_chars(*where, syment->n_numaux, sizeof(syment->n_numaux));
459 *where += sizeof(syment->n_numaux);
d1a9e594 460#else /* CROSS_COMPILE */
6d5460ab 461 append(where, (char *) syment, SYMESZ);
d1a9e594 462#endif /* CROSS_COMPILE */
a39116f1
RP
463
464 /* Should do the following : if (.file entry) MD(..)... else if (static entry) MD(..) */
465 if (numaux > OBJ_COFF_MAX_AUXENTRIES) {
466 as_bad("Internal error? too many auxents for symbol");
467 } /* too many auxents */
468
469 for (i = 0; i < numaux; ++i) {
d1a9e594 470#ifdef CROSS_COMPILE
fecd2382 471#if 0 /* This code has never been tested */
a39116f1
RP
472 /* The most common case, x_sym entry. */
473 if ((SF_GET(symbolP) & (SF_FILE | SF_STATICS)) == 0) {
474 md_number_to_chars(*where, auxP->x_sym.x_tagndx, sizeof(auxP->x_sym.x_tagndx));
475 *where += sizeof(auxP->x_sym.x_tagndx);
476 if (ISFCN(type)) {
477 md_number_to_chars(*where, auxP->x_sym.x_misc.x_fsize, sizeof(auxP->x_sym.x_misc.x_fsize));
478 *where += sizeof(auxP->x_sym.x_misc.x_fsize);
479 } else {
480 md_number_to_chars(*where, auxP->x_sym.x_misc.x_lnno, sizeof(auxP->x_sym.x_misc.x_lnno));
481 *where += sizeof(auxP->x_sym.x_misc.x_lnno);
482 md_number_to_chars(*where, auxP->x_sym.x_misc.x_size, sizeof(auxP->x_sym.x_misc.x_size));
483 *where += sizeof(auxP->x_sym.x_misc.x_size);
484 }
485 if (ISARY(type)) {
486 register int index;
487 for (index = 0; index < DIMNUM; index++)
488 md_number_to_chars(*where, auxP->x_sym.x_fcnary.x_ary.x_dimen[index], sizeof(auxP->x_sym.x_fcnary.x_ary.x_dimen[index]));
489 *where += sizeof(auxP->x_sym.x_fcnary.x_ary.x_dimen[index]);
490 } else {
491 md_number_to_chars(*where, auxP->x_sym.x_fcnary.x_fcn.x_lnnoptr, sizeof(auxP->x_sym.x_fcnary.x_fcn.x_lnnoptr));
492 *where += sizeof(auxP->x_sym.x_fcnary.x_fcn.x_lnnoptr);
493 md_number_to_chars(*where, auxP->x_sym.x_fcnary.x_fcn.x_endndx, sizeof(auxP->x_sym.x_fcnary.x_fcn.x_endndx));
494 *where += sizeof(auxP->x_sym.x_fcnary.x_fcn.x_endndx);
495 }
496 md_number_to_chars(*where, auxP->x_sym.x_tvndx, sizeof(auxP->x_sym.x_tvndx));
497 *where += sizeof(auxP->x_sym.x_tvndx);
498 } else if (SF_GET_FILE(symbolP)) { /* .file */
499 ;
500 } else if (SF_GET_STATICS(symbolP)) { /* .text, .data, .bss symbols */
501 md_number_to_chars(*where, auxP->x_scn.x_scnlen, sizeof(auxP->x_scn.x_scnlen));
502 *where += sizeof(auxP->x_scn.x_scnlen);
503 md_number_to_chars(*where, auxP->x_scn.x_nreloc, sizeof(auxP->x_scn.x_nreloc));
504 *where += sizeof(auxP->x_scn.x_nreloc);
505 md_number_to_chars(*where, auxP->x_scn.x_nlinno, sizeof(auxP->x_scn.x_nlinno));
506 *where += sizeof(auxP->x_scn.x_nlinno);
507 }
fecd2382 508#endif /* 0 */
d1a9e594 509#else /* CROSS_COMPILE */
6d5460ab 510 append(where, (char *) &symbolP->sy_symbol.ost_auxent[i], AUXESZ);
d1a9e594 511#endif /* CROSS_COMPILE */
a39116f1
RP
512
513 }; /* for each aux in use */
57574979 514#endif /* BFD_HEADERS */
a39116f1 515 return;
fecd2382
RP
516} /* obj_symbol_to_chars() */
517
57574979
SC
518#ifdef BFD_HEADERS
519static void obj_coff_section_header_append(where, header)
520char **where;
521struct internal_scnhdr *header;
522{
a39116f1 523 *where += bfd_coff_swap_scnhdr_out(stdoutput, header, *where);
57574979
SC
524}
525#else
526static void obj_coff_section_header_append(where, header)
fecd2382
RP
527char **where;
528SCNHDR *header;
529{
d1a9e594 530#ifdef CROSS_COMPILE
57574979
SC
531 memcpy(*where, header->s_name, sizeof(header->s_name));
532 *where += sizeof(header->s_name);
533
534 md_number_to_chars(*where, header->s_paddr, sizeof(header->s_paddr));
535 *where += sizeof(header->s_paddr);
536
537 md_number_to_chars(*where, header->s_vaddr, sizeof(header->s_vaddr));
538 *where += sizeof(header->s_vaddr);
539
540 md_number_to_chars(*where, header->s_size, sizeof(header->s_size));
541 *where += sizeof(header->s_size);
542
543 md_number_to_chars(*where, header->s_scnptr, sizeof(header->s_scnptr));
544 *where += sizeof(header->s_scnptr);
545
546 md_number_to_chars(*where, header->s_relptr, sizeof(header->s_relptr));
547 *where += sizeof(header->s_relptr);
548
549 md_number_to_chars(*where, header->s_lnnoptr, sizeof(header->s_lnnoptr));
550 *where += sizeof(header->s_lnnoptr);
551
552 md_number_to_chars(*where, header->s_nreloc, sizeof(header->s_nreloc));
553 *where += sizeof(header->s_nreloc);
554
555 md_number_to_chars(*where, header->s_nlnno, sizeof(header->s_nlnno));
556 *where += sizeof(header->s_nlnno);
557
558 md_number_to_chars(*where, header->s_flags, sizeof(header->s_flags));
559 *where += sizeof(header->s_flags);
560
561#ifdef TC_I960
562 md_number_to_chars(*where, header->s_align, sizeof(header->s_align));
563 *where += sizeof(header->s_align);
564#endif /* TC_I960 */
a39116f1 565
d1a9e594 566#else /* CROSS_COMPILE */
57574979 567
6d5460ab 568 append(where, (char *) header, SCNHSZ);
57574979 569
d1a9e594 570#endif /* CROSS_COMPILE */
a39116f1 571
57574979
SC
572 return;
573} /* obj_coff_section_header_append() */
fecd2382 574
57574979 575#endif
fecd2382
RP
576void obj_emit_symbols(where, symbol_rootP)
577char **where;
578symbolS *symbol_rootP;
579{
a39116f1
RP
580 symbolS *symbolP;
581 /*
582 * Emit all symbols left in the symbol chain.
583 */
584 for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next(symbolP)) {
585 /* Used to save the offset of the name. It is used to point
586 to the string in memory but must be a file offset. */
587 register char * temp;
588
589 tc_coff_symbol_emit_hook(symbolP);
590
591 temp = S_GET_NAME(symbolP);
592 if (SF_GET_STRING(symbolP)) {
593 S_SET_OFFSET(symbolP, symbolP->sy_name_offset);
594 S_SET_ZEROES(symbolP, 0);
595 } else {
6d5460ab 596 memset(symbolP->sy_symbol.ost_entry.n_name, '\0', SYMNMLEN);
a39116f1
RP
597 strncpy(symbolP->sy_symbol.ost_entry.n_name, temp, SYMNMLEN);
598 }
599 obj_symbol_to_chars(where, symbolP);
600 S_SET_NAME(symbolP,temp);
601 }
fecd2382
RP
602} /* obj_emit_symbols() */
603
604/* Merge a debug symbol containing debug information into a normal symbol. */
605
606void c_symbol_merge(debug, normal)
607symbolS *debug;
608symbolS *normal;
609{
610 S_SET_DATA_TYPE(normal, S_GET_DATA_TYPE(debug));
611 S_SET_STORAGE_CLASS(normal, S_GET_STORAGE_CLASS(debug));
a39116f1 612
fecd2382
RP
613 if (S_GET_NUMBER_AUXILIARY(debug) > S_GET_NUMBER_AUXILIARY(normal)) {
614 S_SET_NUMBER_AUXILIARY(normal, S_GET_NUMBER_AUXILIARY(debug));
615 } /* take the most we have */
a39116f1 616
fecd2382
RP
617 if (S_GET_NUMBER_AUXILIARY(debug) > 0) {
618 memcpy((char*)&normal->sy_symbol.ost_auxent[0], (char*)&debug->sy_symbol.ost_auxent[0], S_GET_NUMBER_AUXILIARY(debug) * AUXESZ);
619 } /* Move all the auxiliary information */
a39116f1 620
fecd2382
RP
621 /* Move the debug flags. */
622 SF_SET_DEBUG_FIELD(normal, SF_GET_DEBUG_FIELD(debug));
623} /* c_symbol_merge() */
624
625static symbolS *previous_file_symbol = NULL;
626
627void c_dot_file_symbol(filename)
628char *filename;
629{
a39116f1
RP
630 symbolS* symbolP;
631
632 symbolP = symbol_new(".file",
633 SEG_DEBUG,
634 0,
635 &zero_address_frag);
636
637 S_SET_STORAGE_CLASS(symbolP, C_FILE);
638 S_SET_NUMBER_AUXILIARY(symbolP, 1);
639 SA_SET_FILE_FNAME(symbolP, filename);
640 SF_SET_DEBUG(symbolP);
641 S_SET_VALUE(symbolP, (long) previous_file_symbol);
642
643 previous_file_symbol = symbolP;
644
645 /* Make sure that the symbol is first on the symbol chain */
646 if (symbol_rootP != symbolP) {
647 if (symbolP == symbol_lastP) {
648 symbol_lastP = symbol_lastP->sy_previous;
649 } /* if it was the last thing on the list */
650
651 symbol_remove(symbolP, &symbol_rootP, &symbol_lastP);
652 symbol_insert(symbolP, symbol_rootP, &symbol_rootP, &symbol_lastP);
653 symbol_rootP = symbolP;
654 } /* if not first on the list */
655
fecd2382
RP
656} /* c_dot_file_symbol() */
657/*
658 * Build a 'section static' symbol.
659 */
660
661char *c_section_symbol(name, value, length, nreloc, nlnno)
662char *name;
663long value;
664long length;
665unsigned short nreloc;
666unsigned short nlnno;
667{
a39116f1
RP
668 symbolS *symbolP;
669
670 symbolP = symbol_new(name,
671 (name[1] == 't'
672 ? SEG_TEXT
673 : (name[1] == 'd'
674 ? SEG_DATA
675 : SEG_BSS)),
676 value,
677 &zero_address_frag);
678
679 S_SET_STORAGE_CLASS(symbolP, C_STAT);
680 S_SET_NUMBER_AUXILIARY(symbolP, 1);
681
682 SA_SET_SCN_SCNLEN(symbolP, length);
683 SA_SET_SCN_NRELOC(symbolP, nreloc);
684 SA_SET_SCN_NLINNO(symbolP, nlnno);
685
686 SF_SET_STATICS(symbolP);
687
688 return (char*)symbolP;
fecd2382
RP
689} /* c_section_symbol() */
690
691void c_section_header(header,
692 name,
693 core_address,
694 size,
695 data_ptr,
696 reloc_ptr,
697 lineno_ptr,
698 reloc_number,
699 lineno_number,
700 alignment)
57574979
SC
701#ifdef BFD_HEADERS
702struct internal_scnhdr *header;
703#else
fecd2382 704SCNHDR *header;
57574979 705#endif
fecd2382
RP
706char *name;
707long core_address;
708long size;
709long data_ptr;
710long reloc_ptr;
711long lineno_ptr;
712long reloc_number;
713long lineno_number;
714long alignment;
715{
716 strncpy(header->s_name, name, 8);
717 header->s_paddr = header->s_vaddr = core_address;
718 header->s_scnptr = ((header->s_size = size) != 0) ? data_ptr : 0;
719 header->s_relptr = reloc_ptr;
720 header->s_lnnoptr = lineno_ptr;
721 header->s_nreloc = reloc_number;
722 header->s_nlnno = lineno_number;
a39116f1 723
fecd2382
RP
724#ifdef OBJ_COFF_SECTION_HEADER_HAS_ALIGNMENT
725#ifdef OBJ_COFF_BROKEN_ALIGNMENT
726 header->s_align = ((name[1] == 'b' || (size > 0)) ? 16 : 0);
727#else
728 header->s_align = ((alignment == 0)
729 ? 0
730 : (1 << alignment));
731#endif /* OBJ_COFF_BROKEN_ALIGNMENT */
732#endif /* OBJ_COFF_SECTION_HEADER_HAS_ALIGNMENT */
a39116f1 733
fecd2382
RP
734 header->s_flags = STYP_REG | (name[1] == 't'
735 ? STYP_TEXT
736 : (name[1] == 'd'
737 ? STYP_DATA
738 : (name[1] == 'b'
739 ? STYP_BSS
740 : STYP_INFO)));
741 return;
742} /* c_section_header() */
743
744/* Line number handling */
745
746int function_lineoff = -1; /* Offset in line#s where the last function
747 started (the odd entry for line #0) */
748int text_lineno_number = 0;
749int our_lineno_number = 0; /* we use this to build pointers from .bf's
750 into the linetable. It should match
751 exactly the values that are later
752 assigned in text_lineno_number by
753 write.c. */
754lineno* lineno_lastP = (lineno*)0;
755
756int
a39116f1 757 c_line_new(paddr, line_number, frag)
fecd2382
RP
758long paddr;
759unsigned short line_number;
760fragS* frag;
761{
a39116f1
RP
762 lineno* new_line = (lineno*)xmalloc(sizeof(lineno));
763
764 new_line->line.l_addr.l_paddr = paddr;
765 new_line->line.l_lnno = line_number;
766 new_line->frag = (char*)frag;
767 new_line->next = (lineno*)0;
768
769 if (lineno_rootP == (lineno*)0)
770 lineno_rootP = new_line;
771 else
772 lineno_lastP->next = new_line;
773 lineno_lastP = new_line;
774 return LINESZ * our_lineno_number++;
fecd2382
RP
775}
776
777void obj_emit_lineno(where, line, file_start)
778char **where;
779lineno *line;
780char *file_start;
781{
57574979
SC
782#ifdef BFD_HEADERS
783 struct bfd_internal_lineno *line_entry;
784#else
fecd2382 785 LINENO *line_entry;
57574979 786#endif
fecd2382
RP
787 for (; line; line = line->next) {
788 line_entry = &line->line;
a39116f1
RP
789
790 /* FIXME-SOMEDAY Resolving the sy_number of function linno's used to be done in
791 write_object_file() but their symbols need a fileptr to the lnno, so
792 I moved this resolution check here. xoxorich. */
793
fecd2382
RP
794 if (line_entry->l_lnno == 0) {
795 /* There is a good chance that the symbol pointed to
796 is not the one that will be emitted and that the
797 sy_number is not accurate. */
a39116f1 798 /* char *name; */
fecd2382 799 symbolS *symbolP;
a39116f1 800
fecd2382 801 symbolP = (symbolS *) line_entry->l_addr.l_symndx;
a39116f1 802
fecd2382
RP
803 line_entry->l_addr.l_symndx = symbolP->sy_number;
804 symbolP->sy_symbol.ost_auxent[0].x_sym.x_fcnary.x_fcn.x_lnnoptr = *where - file_start;
a39116f1 805
fecd2382 806 } /* if this is a function linno */
57574979
SC
807#ifdef BFD_HEADERS
808 *where += bfd_coff_swap_lineno_out(stdoutput, line_entry, *where);
809#else
fecd2382
RP
810 /* No matter which member of the union we process, they are
811 both long. */
d1a9e594 812#ifdef CROSS_COMPILE
fecd2382
RP
813 md_number_to_chars(*where, line_entry->l_addr.l_paddr, sizeof(line_entry->l_addr.l_paddr));
814 *where += sizeof(line_entry->l_addr.l_paddr);
a39116f1 815
fecd2382
RP
816 md_number_to_chars(*where, line_entry->l_lnno, sizeof(line_entry->l_lnno));
817 *where += sizeof(line_entry->l_lnno);
a39116f1
RP
818
819#ifdef TC_I960
820 **where = '0';
821 ++*where;
822 **where = '0';
823 ++*where;
824#endif /* TC_I960 */
825
d1a9e594 826#else /* CROSS_COMPILE */
fecd2382 827 append(where, (char *) line_entry, LINESZ);
d1a9e594 828#endif /* CROSS_COMPILE */
a39116f1 829#endif /* BFD_HEADERS */
fecd2382 830 } /* for each line number */
a39116f1 831
fecd2382
RP
832 return ;
833} /* obj_emit_lineno() */
834
835void obj_symbol_new_hook(symbolP)
836symbolS *symbolP;
837{
838 char underscore = 0; /* Symbol has leading _ */
a39116f1 839
fecd2382
RP
840 /* Effective symbol */
841 /* Store the pointer in the offset. */
842 S_SET_ZEROES(symbolP, 0L);
843 S_SET_DATA_TYPE(symbolP, T_NULL);
844 S_SET_STORAGE_CLASS(symbolP, 0);
845 S_SET_NUMBER_AUXILIARY(symbolP, 0);
846 /* Additional information */
847 symbolP->sy_symbol.ost_flags = 0;
848 /* Auxiliary entries */
6d5460ab 849 memset((char*) &symbolP->sy_symbol.ost_auxent[0], '\0', AUXESZ);
a39116f1
RP
850
851#ifdef STRIP_UNDERSCORE
fecd2382
RP
852 /* Remove leading underscore at the beginning of the symbol.
853 * This is to be compatible with the standard librairies.
854 */
855 if (*S_GET_NAME(symbolP) == '_') {
856 underscore = 1;
857 S_SET_NAME(symbolP, S_GET_NAME(symbolP) + 1);
858 } /* strip underscore */
859#endif /* STRIP_UNDERSCORE */
a39116f1 860
fecd2382
RP
861 if (S_IS_STRING(symbolP))
862 SF_SET_STRING(symbolP);
863 if (!underscore && S_IS_LOCAL(symbolP))
864 SF_SET_LOCAL(symbolP);
a39116f1 865
fecd2382
RP
866 return;
867} /* obj_symbol_new_hook() */
868
a39116f1 869/* stack stuff */
fecd2382
RP
870stack* stack_init(chunk_size, element_size)
871unsigned long chunk_size;
872unsigned long element_size;
873{
874 stack* st;
a39116f1 875
fecd2382
RP
876 if ((st = (stack*)malloc(sizeof(stack))) == (stack*)0)
877 return (stack*)0;
878 if ((st->data = malloc(chunk_size)) == (char*)0) {
879 free(st);
880 return (stack*)0;
881 }
882 st->pointer = 0;
883 st->size = chunk_size;
884 st->chunk_size = chunk_size;
885 st->element_size = element_size;
886 return st;
887} /* stack_init() */
888
889void stack_delete(st)
890stack* st;
891{
a39116f1
RP
892 free(st->data);
893 free(st);
fecd2382
RP
894}
895
896char *stack_push(st, element)
897stack *st;
898char *element;
899{
900 if (st->pointer + st->element_size >= st->size) {
901 st->size += st->chunk_size;
902 if ((st->data = xrealloc(st->data, st->size)) == (char*)0)
903 return (char*)0;
904 }
905 memcpy(st->data + st->pointer, element, st->element_size);
906 st->pointer += st->element_size;
907 return st->data + st->pointer;
908} /* stack_push() */
909
910char* stack_pop(st)
911stack* st;
912{
a39116f1
RP
913 if ((st->pointer -= st->element_size) < 0) {
914 st->pointer = 0;
915 return (char*)0;
916 }
917 return st->data + st->pointer;
fecd2382
RP
918}
919
920char* stack_top(st)
921stack* st;
922{
a39116f1 923 return st->data + st->pointer - st->element_size;
fecd2382
RP
924}
925
926
927/*
928 * Handle .ln directives.
929 */
930
931static void obj_coff_ln() {
932 if (def_symbol_in_progress != NULL) {
933 as_warn(".ln pseudo-op inside .def/.endef: ignored.");
934 demand_empty_rest_of_line();
935 return;
936 } /* wrong context */
a39116f1 937
fecd2382
RP
938 c_line_new(obstack_next_free(&frags) - frag_now->fr_literal,
939 get_absolute_expression(),
940 frag_now);
a39116f1 941
fecd2382
RP
942 demand_empty_rest_of_line();
943 return;
944} /* obj_coff_line() */
945
946/*
947 * def()
948 *
949 * Handle .def directives.
950 *
951 * One might ask : why can't we symbol_new if the symbol does not
952 * already exist and fill it with debug information. Because of
953 * the C_EFCN special symbol. It would clobber the value of the
954 * function symbol before we have a chance to notice that it is
955 * a C_EFCN. And a second reason is that the code is more clear this
956 * way. (at least I think it is :-).
957 *
958 */
959
960#define SKIP_SEMI_COLON() while (*input_line_pointer++ != ';')
961#define SKIP_WHITESPACES() while (*input_line_pointer == ' ' || \
a39116f1
RP
962 *input_line_pointer == '\t') \
963 input_line_pointer++;
fecd2382
RP
964
965static void obj_coff_def(what)
966int what;
967{
a39116f1
RP
968 char name_end; /* Char after the end of name */
969 char *symbol_name; /* Name of the debug symbol */
970 char *symbol_name_copy; /* Temporary copy of the name */
971 unsigned int symbol_name_length;
972 /*$char* directiveP;$ */ /* Name of the pseudo opcode */
973 /*$char directive[MAX_DIRECTIVE];$ */ /* Backup of the directive */
974 /*$char end = 0;$ */ /* If 1, stop parsing */
975
976 if (def_symbol_in_progress != NULL) {
977 as_warn(".def pseudo-op used inside of .def/.endef: ignored.");
978 demand_empty_rest_of_line();
979 return;
980 } /* if not inside .def/.endef */
981
982 SKIP_WHITESPACES();
983
984 def_symbol_in_progress = (symbolS *) obstack_alloc(&notes, sizeof(*def_symbol_in_progress));
6d5460ab 985 memset(def_symbol_in_progress, '\0', sizeof(*def_symbol_in_progress));
a39116f1
RP
986
987 symbol_name = input_line_pointer;
988 name_end = get_symbol_end();
989 symbol_name_length = strlen(symbol_name);
990 symbol_name_copy = xmalloc(symbol_name_length + 1);
991 strcpy(symbol_name_copy, symbol_name);
992
993 /* Initialize the new symbol */
994#ifdef STRIP_UNDERSCORE
995 S_SET_NAME(def_symbol_in_progress, (*symbol_name_copy == '_'
996 ? symbol_name_copy + 1
997 : symbol_name_copy));
fecd2382 998#else /* STRIP_UNDERSCORE */
a39116f1 999 S_SET_NAME(def_symbol_in_progress, symbol_name_copy);
fecd2382 1000#endif /* STRIP_UNDERSCORE */
a39116f1
RP
1001 /* free(symbol_name_copy); */
1002 def_symbol_in_progress->sy_name_offset = ~0;
1003 def_symbol_in_progress->sy_number = ~0;
1004 def_symbol_in_progress->sy_frag = &zero_address_frag;
1005
1006 if (S_IS_STRING(def_symbol_in_progress)) {
1007 SF_SET_STRING(def_symbol_in_progress);
1008 } /* "long" name */
1009
1010 *input_line_pointer = name_end;
1011
1012 demand_empty_rest_of_line();
1013 return;
fecd2382
RP
1014} /* obj_coff_def() */
1015
1016unsigned int dim_index;
1017static void obj_coff_endef() {
1018 symbolS *symbolP;
a39116f1 1019 /* DIM BUG FIX sac@cygnus.com */
fecd2382
RP
1020 dim_index =0;
1021 if (def_symbol_in_progress == NULL) {
1022 as_warn(".endef pseudo-op used outside of .def/.endef: ignored.");
1023 demand_empty_rest_of_line();
1024 return;
1025 } /* if not inside .def/.endef */
a39116f1 1026
fecd2382
RP
1027 /* Set the section number according to storage class. */
1028 switch (S_GET_STORAGE_CLASS(def_symbol_in_progress)) {
1029 case C_STRTAG:
1030 case C_ENTAG:
1031 case C_UNTAG:
1032 SF_SET_TAG(def_symbol_in_progress);
1033 /* intentional fallthrough */
1034 case C_FILE:
1035 case C_TPDEF:
1036 SF_SET_DEBUG(def_symbol_in_progress);
1037 S_SET_SEGMENT(def_symbol_in_progress, SEG_DEBUG);
1038 break;
a39116f1 1039
fecd2382
RP
1040 case C_EFCN:
1041 SF_SET_LOCAL(def_symbol_in_progress); /* Do not emit this symbol. */
1042 /* intentional fallthrough */
1043 case C_BLOCK:
1044 SF_SET_PROCESS(def_symbol_in_progress); /* Will need processing before writing */
1045 /* intentional fallthrough */
1046 case C_FCN:
1047 S_SET_SEGMENT(def_symbol_in_progress, SEG_TEXT);
a39116f1 1048
fecd2382
RP
1049 if (def_symbol_in_progress->sy_symbol.ost_entry.n_name[1] == 'b') { /* .bf */
1050 if (function_lineoff < 0) {
1051 fprintf(stderr, "`.bf' symbol without preceding function\n");
1052 } /* missing function symbol */
1053 SA_GET_SYM_LNNOPTR(def_symbol_in_progress) = function_lineoff;
1054 SF_SET_PROCESS(def_symbol_in_progress); /* Will need relocating */
1055 function_lineoff = -1;
1056 }
1057 break;
a39116f1 1058
fecd2382
RP
1059#ifdef C_AUTOARG
1060 case C_AUTOARG:
1061#endif /* C_AUTOARG */
1062 case C_AUTO:
1063 case C_REG:
1064 case C_MOS:
1065 case C_MOE:
1066 case C_MOU:
1067 case C_ARG:
1068 case C_REGPARM:
1069 case C_FIELD:
1070 case C_EOS:
1071 SF_SET_DEBUG(def_symbol_in_progress);
1072 S_SET_SEGMENT(def_symbol_in_progress, SEG_ABSOLUTE);
1073 break;
a39116f1 1074
fecd2382
RP
1075 case C_EXT:
1076 case C_STAT:
1077 case C_LABEL:
a39116f1 1078 /* Valid but set somewhere else (s_comm, s_lcomm, colon) */
fecd2382 1079 break;
a39116f1 1080
fecd2382
RP
1081 case C_USTATIC:
1082 case C_EXTDEF:
1083 case C_ULABEL:
1084 as_warn("unexpected storage class %d", S_GET_STORAGE_CLASS(def_symbol_in_progress));
1085 break;
1086 } /* switch on storage class */
a39116f1 1087
fecd2382
RP
1088 /* Now that we have built a debug symbol, try to
1089 find if we should merge with an existing symbol
1090 or not. If a symbol is C_EFCN or SEG_ABSOLUTE or
1091 untagged SEG_DEBUG it never merges. */
a39116f1 1092
fecd2382
RP
1093 /* Two cases for functions. Either debug followed
1094 by definition or definition followed by debug.
1095 For definition first, we will merge the debug
1096 symbol into the definition. For debug first, the
1097 lineno entry MUST point to the definition
1098 function or else it will point off into space
1099 when obj_crawl_symbol_chain() merges the debug
1100 symbol into the real symbol. Therefor, let's
1101 presume the debug symbol is a real function
1102 reference. */
a39116f1 1103
fecd2382
RP
1104 /* FIXME-SOON If for some reason the definition
1105 label/symbol is never seen, this will probably
1106 leave an undefined symbol at link time. */
a39116f1 1107
fecd2382
RP
1108 if (S_GET_STORAGE_CLASS(def_symbol_in_progress) == C_EFCN
1109 || (S_GET_SEGMENT(def_symbol_in_progress) == SEG_DEBUG
1110 && !SF_GET_TAG(def_symbol_in_progress))
1111 || S_GET_SEGMENT(def_symbol_in_progress) == SEG_ABSOLUTE
1112 || (symbolP = symbol_find_base(S_GET_NAME(def_symbol_in_progress), DO_NOT_STRIP)) == NULL) {
a39116f1 1113
fecd2382 1114 symbol_append(def_symbol_in_progress, symbol_lastP, &symbol_rootP, &symbol_lastP);
a39116f1 1115
fecd2382
RP
1116 } else {
1117 /* This symbol already exists, merge the
1118 newly created symbol into the old one.
1119 This is not mandatory. The linker can
1120 handle duplicate symbols correctly. But I
1121 guess that it save a *lot* of space if
1122 the assembly file defines a lot of
1123 symbols. [loic] */
a39116f1 1124
fecd2382
RP
1125 /* The debug entry (def_symbol_in_progress)
1126 is merged into the previous definition. */
a39116f1 1127
fecd2382
RP
1128 c_symbol_merge(def_symbol_in_progress, symbolP);
1129 /* FIXME-SOON Should *def_symbol_in_progress be free'd? xoxorich. */
1130 def_symbol_in_progress = symbolP;
a39116f1 1131
fecd2382
RP
1132 if (SF_GET_FUNCTION(def_symbol_in_progress)
1133 || SF_GET_TAG(def_symbol_in_progress)) {
1134 /* For functions, and tags, the symbol *must* be where the debug symbol
1135 appears. Move the existing symbol to the current place. */
1136 /* If it already is at the end of the symbol list, do nothing */
1137 if (def_symbol_in_progress != symbol_lastP) {
1138 symbol_remove(def_symbol_in_progress, &symbol_rootP, &symbol_lastP);
1139 symbol_append(def_symbol_in_progress, symbol_lastP, &symbol_rootP, &symbol_lastP);
1140 } /* if not already in place */
1141 } /* if function */
1142 } /* normal or mergable */
a39116f1 1143
fecd2382
RP
1144 if (SF_GET_TAG(def_symbol_in_progress)
1145 && symbol_find_base(S_GET_NAME(def_symbol_in_progress), DO_NOT_STRIP) == NULL) {
1146 tag_insert(S_GET_NAME(def_symbol_in_progress), def_symbol_in_progress);
1147 } /* If symbol is a {structure,union} tag, associate symbol to its name. */
a39116f1 1148
fecd2382
RP
1149 if (SF_GET_FUNCTION(def_symbol_in_progress)) {
1150 know(sizeof(def_symbol_in_progress) <= sizeof(long));
1151 function_lineoff = c_line_new((long) def_symbol_in_progress, 0, &zero_address_frag);
1152 SF_SET_PROCESS(def_symbol_in_progress);
a39116f1 1153
fecd2382
RP
1154 if (symbolP == NULL) {
1155 /* That is, if this is the first
1156 time we've seen the function... */
1157 symbol_table_insert(def_symbol_in_progress);
1158 } /* definition follows debug */
1159 } /* Create the line number entry pointing to the function being defined */
a39116f1 1160
fecd2382
RP
1161 def_symbol_in_progress = NULL;
1162 demand_empty_rest_of_line();
1163 return;
1164} /* obj_coff_endef() */
fecd2382 1165
a39116f1
RP
1166static void obj_coff_dim()
1167{
1168 register int dim_index;
1169
fecd2382
RP
1170 if (def_symbol_in_progress == NULL) {
1171 as_warn(".dim pseudo-op used outside of .def/.endef: ignored.");
1172 demand_empty_rest_of_line();
1173 return;
1174 } /* if not inside .def/.endef */
a39116f1 1175
fecd2382 1176 S_SET_NUMBER_AUXILIARY(def_symbol_in_progress, 1);
a39116f1 1177
fecd2382
RP
1178 for (dim_index = 0; dim_index < DIMNUM; dim_index++) {
1179 SKIP_WHITESPACES();
1180 SA_SET_SYM_DIMEN(def_symbol_in_progress, dim_index, get_absolute_expression());
a39116f1 1181
fecd2382 1182 switch (*input_line_pointer) {
a39116f1 1183
fecd2382
RP
1184 case ',':
1185 input_line_pointer++;
1186 break;
a39116f1 1187
fecd2382
RP
1188 default:
1189 as_warn("badly formed .dim directive ignored");
1190 /* intentional fallthrough */
a39116f1 1191 case '\n':
fecd2382
RP
1192 case ';':
1193 dim_index = DIMNUM;
1194 break;
1195 } /* switch on following character */
1196 } /* for each dimension */
a39116f1 1197
fecd2382
RP
1198 demand_empty_rest_of_line();
1199 return;
fecd2382 1200} /* obj_coff_dim() */
fecd2382
RP
1201
1202static void obj_coff_line() {
1203 if (def_symbol_in_progress == NULL) {
1204 obj_coff_ln();
1205 return;
1206 } /* if it looks like a stabs style line */
a39116f1 1207
fecd2382
RP
1208 S_SET_NUMBER_AUXILIARY(def_symbol_in_progress, 1);
1209 SA_SET_SYM_LNNO(def_symbol_in_progress, get_absolute_expression());
a39116f1 1210
fecd2382
RP
1211 demand_empty_rest_of_line();
1212 return;
1213} /* obj_coff_line() */
1214
1215static void obj_coff_size() {
1216 if (def_symbol_in_progress == NULL) {
1217 as_warn(".size pseudo-op used outside of .def/.endef ignored.");
1218 demand_empty_rest_of_line();
1219 return;
1220 } /* if not inside .def/.endef */
a39116f1 1221
fecd2382
RP
1222 S_SET_NUMBER_AUXILIARY(def_symbol_in_progress, 1);
1223 SA_SET_SYM_SIZE(def_symbol_in_progress, get_absolute_expression());
1224 demand_empty_rest_of_line();
1225 return;
1226} /* obj_coff_size() */
1227
1228static void obj_coff_scl() {
1229 if (def_symbol_in_progress == NULL) {
1230 as_warn(".scl pseudo-op used outside of .def/.endef ignored.");
1231 demand_empty_rest_of_line();
1232 return;
1233 } /* if not inside .def/.endef */
a39116f1 1234
fecd2382
RP
1235 S_SET_STORAGE_CLASS(def_symbol_in_progress, get_absolute_expression());
1236 demand_empty_rest_of_line();
1237 return;
1238} /* obj_coff_scl() */
1239
1240static void obj_coff_tag() {
1241 char *symbol_name;
1242 char name_end;
a39116f1 1243
fecd2382
RP
1244 if (def_symbol_in_progress == NULL) {
1245 as_warn(".tag pseudo-op used outside of .def/.endef ignored.");
1246 demand_empty_rest_of_line();
1247 return;
1248 } /* if not inside .def/.endef */
a39116f1 1249
fecd2382
RP
1250 S_SET_NUMBER_AUXILIARY(def_symbol_in_progress, 1);
1251 symbol_name = input_line_pointer;
1252 name_end = get_symbol_end();
a39116f1 1253
fecd2382
RP
1254 /* Assume that the symbol referred to by .tag is always defined. */
1255 /* This was a bad assumption. I've added find_or_make. xoxorich. */
1256 SA_SET_SYM_TAGNDX(def_symbol_in_progress, (long) tag_find_or_make(symbol_name));
1257 if (SA_GET_SYM_TAGNDX(def_symbol_in_progress) == 0L) {
1258 as_warn("tag not found for .tag %s", symbol_name);
1259 } /* not defined */
a39116f1 1260
fecd2382
RP
1261 SF_SET_TAGGED(def_symbol_in_progress);
1262 *input_line_pointer = name_end;
a39116f1 1263
fecd2382
RP
1264 demand_empty_rest_of_line();
1265 return;
1266} /* obj_coff_tag() */
1267
1268static void obj_coff_type() {
1269 if (def_symbol_in_progress == NULL) {
1270 as_warn(".type pseudo-op used outside of .def/.endef ignored.");
1271 demand_empty_rest_of_line();
1272 return;
1273 } /* if not inside .def/.endef */
a39116f1 1274
fecd2382 1275 S_SET_DATA_TYPE(def_symbol_in_progress, get_absolute_expression());
a39116f1 1276
fecd2382
RP
1277 if (ISFCN(S_GET_DATA_TYPE(def_symbol_in_progress)) &&
1278 S_GET_STORAGE_CLASS(def_symbol_in_progress) != C_TPDEF) {
1279 SF_SET_FUNCTION(def_symbol_in_progress);
1280 } /* is a function */
a39116f1 1281
fecd2382
RP
1282 demand_empty_rest_of_line();
1283 return;
1284} /* obj_coff_type() */
1285
1286static void obj_coff_val() {
1287 if (def_symbol_in_progress == NULL) {
1288 as_warn(".val pseudo-op used outside of .def/.endef ignored.");
1289 demand_empty_rest_of_line();
1290 return;
1291 } /* if not inside .def/.endef */
a39116f1 1292
fecd2382
RP
1293 if (is_name_beginner(*input_line_pointer)) {
1294 char *symbol_name = input_line_pointer;
1295 char name_end = get_symbol_end();
a39116f1 1296
fecd2382
RP
1297 if (!strcmp(symbol_name, ".")) {
1298 def_symbol_in_progress->sy_frag = frag_now;
1299 S_SET_VALUE(def_symbol_in_progress, obstack_next_free(&frags) - frag_now->fr_literal);
1300 /* If the .val is != from the .def (e.g. statics) */
1301 } else if (strcmp(S_GET_NAME(def_symbol_in_progress), symbol_name)) {
1302 def_symbol_in_progress->sy_forward = symbol_find_or_make(symbol_name);
a39116f1 1303
fecd2382
RP
1304 /* If the segment is undefined when the forward
1305 reference is solved, then copy the segment id
1306 from the forward symbol. */
1307 SF_SET_GET_SEGMENT(def_symbol_in_progress);
1308 }
1309 /* Otherwise, it is the name of a non debug symbol and its value will be calculated later. */
1310 *input_line_pointer = name_end;
1311 } else {
1312 S_SET_VALUE(def_symbol_in_progress, get_absolute_expression());
1313 } /* if symbol based */
a39116f1 1314
fecd2382
RP
1315 demand_empty_rest_of_line();
1316 return;
1317} /* obj_coff_val() */
1318
1319/*
1320 * Maintain a list of the tagnames of the structres.
1321 */
1322
1323static void tag_init() {
a39116f1
RP
1324 tag_hash = hash_new();
1325 return ;
fecd2382
RP
1326} /* tag_init() */
1327
1328static void tag_insert(name, symbolP)
1329char *name;
1330symbolS *symbolP;
1331{
1332 register char * error_string;
a39116f1 1333
fecd2382
RP
1334 if (*(error_string = hash_jam(tag_hash, name, (char *)symbolP))) {
1335 as_fatal("Inserting \"%s\" into structure table failed: %s",
1336 name, error_string);
1337 }
1338 return ;
1339} /* tag_insert() */
1340
1341static symbolS *tag_find_or_make(name)
1342char *name;
1343{
1344 symbolS *symbolP;
a39116f1 1345
fecd2382
RP
1346 if ((symbolP = tag_find(name)) == NULL) {
1347 symbolP = symbol_new(name,
1348 SEG_UNKNOWN,
1349 0,
1350 &zero_address_frag);
a39116f1 1351
fecd2382
RP
1352 tag_insert(S_GET_NAME(symbolP), symbolP);
1353 symbol_table_insert(symbolP);
1354 } /* not found */
a39116f1 1355
fecd2382
RP
1356 return(symbolP);
1357} /* tag_find_or_make() */
1358
1359static symbolS *tag_find(name)
1360char *name;
1361{
a39116f1 1362#ifdef STRIP_UNDERSCORE
fecd2382
RP
1363 if (*name == '_') name++;
1364#endif /* STRIP_UNDERSCORE */
1365 return((symbolS*)hash_find(tag_hash, name));
1366} /* tag_find() */
1367
1368void obj_read_begin_hook() {
a39116f1 1369 /* These had better be the same. Usually 18 bytes. */
57574979 1370#ifndef BFD_HEADERS
fecd2382
RP
1371 know(sizeof(SYMENT) == sizeof(AUXENT));
1372 know(SYMESZ == AUXESZ);
57574979 1373#endif
fecd2382 1374 tag_init();
a39116f1 1375
fecd2382
RP
1376 return;
1377} /* obj_read_begin_hook() */
1378
1379void obj_crawl_symbol_chain(headers)
1380object_headers *headers;
1381{
1382 int symbol_number = 0;
1383 lineno *lineP;
1384 symbolS *last_functionP = NULL;
1385 symbolS *last_tagP;
1386 symbolS *symbolP;
1387 symbolS *symbol_externP = NULL;
1388 symbolS *symbol_extern_lastP = NULL;
a39116f1 1389
fecd2382
RP
1390 /* Initialize the stack used to keep track of the matching .bb .be */
1391 stack* block_stack = stack_init(512, sizeof(symbolS*));
a39116f1 1392
fecd2382
RP
1393 /* JF deal with forward references first... */
1394 for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next(symbolP)) {
a39116f1 1395
fecd2382
RP
1396 if (symbolP->sy_forward) {
1397 S_SET_VALUE(symbolP, (S_GET_VALUE(symbolP)
1398 + S_GET_VALUE(symbolP->sy_forward)
1399 + symbolP->sy_forward->sy_frag->fr_address));
a39116f1 1400
6d5460ab
RP
1401 if (SF_GET_GET_SEGMENT(symbolP) &&
1402 S_GET_SEGMENT(symbolP) == SEG_UNKNOWN) {
fecd2382
RP
1403 S_SET_SEGMENT(symbolP, S_GET_SEGMENT(symbolP->sy_forward));
1404 } /* forward segment also */
a39116f1 1405
fecd2382
RP
1406 symbolP->sy_forward=0;
1407 } /* if it has a forward reference */
1408 } /* walk the symbol chain */
a39116f1 1409
fecd2382 1410 tc_crawl_symbol_chain(headers);
a39116f1 1411
fecd2382
RP
1412 /* The symbol list should be ordered according to the following sequence
1413 * order :
1414 * . .file symbol
1415 * . debug entries for functions
1416 * . fake symbols for .text .data and .bss
1417 * . defined symbols
1418 * . undefined symbols
1419 * But this is not mandatory. The only important point is to put the
1420 * undefined symbols at the end of the list.
1421 */
a39116f1 1422
fecd2382
RP
1423 if (symbol_rootP == NULL
1424 || S_GET_STORAGE_CLASS(symbol_rootP) != C_FILE) {
1425 know(!previous_file_symbol);
1426 c_dot_file_symbol("fake");
1427 } /* Is there a .file symbol ? If not insert one at the beginning. */
a39116f1 1428
fecd2382
RP
1429 /*
1430 * Build up static symbols for .text, .data and .bss
1431 */
1432 dot_text_symbol = (symbolS*)
1433 c_section_symbol(".text",
1434 0,
1435 H_GET_TEXT_SIZE(headers),
1436 0/*text_relocation_number */,
1437 0/*text_lineno_number */);
6d5460ab
RP
1438 symbol_remove(dot_text_symbol, &symbol_rootP, &symbol_lastP);
1439 symbol_append(dot_text_symbol, previous_file_symbol,
1440 &symbol_rootP, &symbol_lastP);
a39116f1 1441
fecd2382
RP
1442 dot_data_symbol = (symbolS*)
1443 c_section_symbol(".data",
1444 H_GET_TEXT_SIZE(headers),
1445 H_GET_DATA_SIZE(headers),
1446 0/*data_relocation_number */,
1447 0); /* There are no data lineno entries */
6d5460ab
RP
1448 symbol_remove(dot_data_symbol, &symbol_rootP, &symbol_lastP);
1449 symbol_append(dot_data_symbol, dot_text_symbol,
1450 &symbol_rootP, &symbol_lastP);
a39116f1 1451
fecd2382
RP
1452 dot_bss_symbol = (symbolS*)
1453 c_section_symbol(".bss",
1454 H_GET_TEXT_SIZE(headers) + H_GET_DATA_SIZE(headers),
1455 H_GET_BSS_SIZE(headers),
1456 0, /* No relocation for a bss section. */
1457 0); /* There are no bss lineno entries */
6d5460ab
RP
1458 symbol_remove(dot_bss_symbol, &symbol_rootP, &symbol_lastP);
1459 symbol_append(dot_bss_symbol, dot_data_symbol,
1460 &symbol_rootP, &symbol_lastP);
a39116f1 1461
fecd2382
RP
1462#if defined(DEBUG)
1463 verify_symbol_chain(symbol_rootP, symbol_lastP);
1464#endif /* DEBUG */
a39116f1 1465
fecd2382
RP
1466 /* Three traversals of symbol chains here. The
1467 first traversal yanks externals into a temporary
1468 chain, removing the externals from the global
1469 chain, numbers symbols, and does some other guck.
1470 The second traversal is on the temporary chain of
1471 externals and just appends them to the global
1472 chain again, numbering them as we go. The third
1473 traversal patches pointers to symbols (using sym
1474 indexes). The last traversal was once done as
1475 part of the first pass, but that fails when a
1476 reference preceeds a definition as the definition
1477 has no number at the time we process the
1478 reference. */
a39116f1 1479
fecd2382
RP
1480 /* Note that symbolP will be NULL at the end of a loop
1481 if an external was at the beginning of the list (it
1482 gets moved off the list). Hence the weird check in
1483 the loop control.
1484 */
57574979
SC
1485 for (symbolP = symbol_rootP;
1486 symbolP;
1487 symbolP = symbolP ? symbol_next(symbolP) : symbol_rootP) {
a39116f1 1488 if (!SF_GET_DEBUG(symbolP)) {
fecd2382
RP
1489 /* Debug symbols do not need all this rubbish */
1490 symbolS* real_symbolP;
a39116f1 1491
fecd2382
RP
1492 /* L* and C_EFCN symbols never merge. */
1493 if (!SF_GET_LOCAL(symbolP)
1494 && (real_symbolP = symbol_find_base(S_GET_NAME(symbolP), DO_NOT_STRIP))
1495 && real_symbolP != symbolP) {
1496 /* FIXME-SOON: where do dups come from? Maybe tag references before definitions? xoxorich. */
1497 /* Move the debug data from the debug symbol to the
1498 real symbol. Do NOT do the oposite (i.e. move from
1499 real symbol to debug symbol and remove real symbol from the
1500 list.) Because some pointers refer to the real symbol
1501 whereas no pointers refer to the debug symbol. */
1502 c_symbol_merge(symbolP, real_symbolP);
1503 /* Replace the current symbol by the real one */
1504 /* The symbols will never be the last or the first
1505 because : 1st symbol is .file and 3 last symbols are
1506 .text, .data, .bss */
1507 symbol_remove(real_symbolP, &symbol_rootP, &symbol_lastP);
1508 symbol_insert(real_symbolP, symbolP, &symbol_rootP, &symbol_lastP);
1509 symbol_remove(symbolP, &symbol_rootP, &symbol_lastP);
1510 symbolP = real_symbolP;
1511 } /* if not local but dup'd */
a39116f1 1512
fecd2382
RP
1513 if (flagseen['R'] && (S_GET_SEGMENT(symbolP) == SEG_DATA)) {
1514 S_SET_SEGMENT(symbolP, SEG_TEXT);
1515 } /* push data into text */
a39116f1 1516
fecd2382 1517 S_SET_VALUE(symbolP, S_GET_VALUE(symbolP) + symbolP->sy_frag->fr_address);
a39116f1 1518
fecd2382
RP
1519 if (!S_IS_DEFINED(symbolP) && !SF_GET_LOCAL(symbolP)) {
1520 S_SET_EXTERNAL(symbolP);
1521 } else if (S_GET_STORAGE_CLASS(symbolP) == C_NULL) {
1522 if (S_GET_SEGMENT(symbolP) == SEG_TEXT){
1523 S_SET_STORAGE_CLASS(symbolP, C_LABEL);
1524 } else {
1525 S_SET_STORAGE_CLASS(symbolP, C_STAT);
1526 }
1527 } /* no storage class yet */
a39116f1 1528
fecd2382
RP
1529 /* Mainly to speed up if not -g */
1530 if (SF_GET_PROCESS(symbolP)) {
1531 /* Handle the nested blocks auxiliary info. */
1532 if (S_GET_STORAGE_CLASS(symbolP) == C_BLOCK) {
1533 if (!strcmp(S_GET_NAME(symbolP), ".bb"))
1534 stack_push(block_stack, (char *) &symbolP);
1535 else { /* .eb */
1536 register symbolS* begin_symbolP;
1537 begin_symbolP = *(symbolS**)stack_pop(block_stack);
1538 if (begin_symbolP == (symbolS*)0)
1539 as_warn("mismatched .eb");
1540 else
1541 SA_SET_SYM_ENDNDX(begin_symbolP, symbol_number+2);
1542 }
1543 }
1544 /* If we are able to identify the type of a function, and we
1545 are out of a function (last_functionP == 0) then, the
1546 function symbol will be associated with an auxiliary
1547 entry. */
1548 if (last_functionP == (symbolS*)0 &&
1549 SF_GET_FUNCTION(symbolP)) {
1550 last_functionP = symbolP;
a39116f1 1551
fecd2382
RP
1552 if (S_GET_NUMBER_AUXILIARY(symbolP) < 1) {
1553 S_SET_NUMBER_AUXILIARY(symbolP, 1);
1554 } /* make it at least 1 */
a39116f1 1555
fecd2382 1556 /* Clobber possible stale .dim information. */
6d5460ab
RP
1557 memset(symbolP->sy_symbol.ost_auxent[0].x_sym.x_fcnary.x_ary.x_dimen,
1558 '\0', sizeof(symbolP->sy_symbol.ost_auxent[0].x_sym.x_fcnary.x_ary.x_dimen));
fecd2382
RP
1559 }
1560 /* The C_FCN doesn't need any additional information.
1561 I don't even know if this is needed for sdb. But the
1562 standard assembler generates it, so...
1563 */
1564 if (S_GET_STORAGE_CLASS(symbolP) == C_EFCN) {
1565 if (last_functionP == (symbolS*)0)
1566 as_fatal("C_EFCN symbol out of scope");
1567 SA_SET_SYM_FSIZE(last_functionP,
1568 (long)(S_GET_VALUE(symbolP) -
1569 S_GET_VALUE(last_functionP)));
1570 SA_SET_SYM_ENDNDX(last_functionP, symbol_number);
1571 last_functionP = (symbolS*)0;
1572 }
1573 }
1574 } else if (SF_GET_TAG(symbolP)) {
1575 /* First descriptor of a structure must point to
1576 the first slot after the structure description. */
1577 last_tagP = symbolP;
a39116f1 1578
fecd2382
RP
1579 } else if (S_GET_STORAGE_CLASS(symbolP) == C_EOS) {
1580 /* +2 take in account the current symbol */
1581 SA_SET_SYM_ENDNDX(last_tagP, symbol_number + 2);
1582 } else if (S_GET_STORAGE_CLASS(symbolP) == C_FILE) {
1583 if (S_GET_VALUE(symbolP)) {
1584 S_SET_VALUE((symbolS *) S_GET_VALUE(symbolP), symbol_number);
1585 S_SET_VALUE(symbolP, 0);
1586 } /* no one points at the first .file symbol */
1587 } /* if debug or tag or eos or file */
a39116f1 1588
fecd2382
RP
1589 /* We must put the external symbols apart. The loader
1590 does not bomb if we do not. But the references in
1591 the endndx field for a .bb symbol are not corrected
1592 if an external symbol is removed between .bb and .be.
1593 I.e in the following case :
1594 [20] .bb endndx = 22
1595 [21] foo external
1596 [22] .be
1597 ld will move the symbol 21 to the end of the list but
1598 endndx will still be 22 instead of 21. */
a39116f1
RP
1599
1600
fecd2382
RP
1601 if (SF_GET_LOCAL(symbolP)) {
1602 /* remove C_EFCN and LOCAL (L...) symbols */
1603 /* next pointer remains valid */
1604 symbol_remove(symbolP, &symbol_rootP, &symbol_lastP);
a39116f1 1605
6d5460ab
RP
1606 } else if (/*!S_IS_DEFINED(symbolP) && !S_IS_DEBUG(symbolP) && !SF_GET_STATICS(symbolP) */
1607 S_GET_STORAGE_CLASS(symbolP) == C_EXT && !SF_GET_FUNCTION(symbolP)) {
fecd2382
RP
1608 /* if external, Remove from the list */
1609 symbolS *hold = symbol_previous(symbolP);
a39116f1 1610
fecd2382
RP
1611 symbol_remove(symbolP, &symbol_rootP, &symbol_lastP);
1612 symbol_clear_list_pointers(symbolP);
1613 symbol_append(symbolP, symbol_extern_lastP, &symbol_externP, &symbol_extern_lastP);
1614 symbolP = hold;
1615 } else {
1616 if (SF_GET_STRING(symbolP)) {
1617 symbolP->sy_name_offset = string_byte_count;
1618 string_byte_count += strlen(S_GET_NAME(symbolP)) + 1;
1619 } else {
1620 symbolP->sy_name_offset = 0;
1621 } /* fix "long" names */
a39116f1 1622
fecd2382
RP
1623 symbolP->sy_number = symbol_number;
1624 symbol_number += 1 + S_GET_NUMBER_AUXILIARY(symbolP);
1625 } /* if local symbol */
1626 } /* traverse the symbol list */
a39116f1 1627
fecd2382
RP
1628 for (symbolP = symbol_externP; symbol_externP;) {
1629 symbolS *tmp = symbol_externP;
a39116f1 1630
fecd2382
RP
1631 /* append */
1632 symbol_remove(tmp, &symbol_externP, &symbol_extern_lastP);
1633 symbol_append(tmp, symbol_lastP, &symbol_rootP, &symbol_lastP);
a39116f1 1634
fecd2382
RP
1635 /* and process */
1636 if (SF_GET_STRING(tmp)) {
1637 tmp->sy_name_offset = string_byte_count;
1638 string_byte_count += strlen(S_GET_NAME(tmp)) + 1;
1639 } else {
1640 tmp->sy_name_offset = 0;
1641 } /* fix "long" names */
a39116f1 1642
fecd2382
RP
1643 tmp->sy_number = symbol_number;
1644 symbol_number += 1 + S_GET_NUMBER_AUXILIARY(tmp);
1645 } /* append the entire extern chain */
a39116f1 1646
fecd2382
RP
1647 /* When a tag reference preceeds the tag definition,
1648 the definition will not have a number at the time
1649 we process the reference during the first
1650 traversal. Thus, a second traversal. */
a39116f1 1651
fecd2382
RP
1652 for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next(symbolP)) {
1653 if (SF_GET_TAGGED(symbolP)) {
1654 SA_SET_SYM_TAGNDX(symbolP, ((symbolS*) SA_GET_SYM_TAGNDX(symbolP))->sy_number);
1655 } /* If the symbol has a tagndx entry, resolve it */
1656 } /* second traversal */
a39116f1 1657
fecd2382
RP
1658 know(symbol_externP == NULL);
1659 know(symbol_extern_lastP == NULL);
a39116f1 1660
fecd2382
RP
1661 /* FIXME-SOMEDAY I'm counting line no's here so we know what to put in the section
1662 headers, and I'm resolving the addresses since I'm not sure how to
1663 do it later. I am NOT resolving the linno's representing functions.
1664 Their symbols need a fileptr pointing to this linno when emitted.
1665 Thus, I resolve them on emit. xoxorich. */
a39116f1 1666
fecd2382
RP
1667 for (lineP = lineno_rootP; lineP; lineP = lineP->next) {
1668 if (lineP->line.l_lnno > 0) {
1669 lineP->line.l_addr.l_paddr += ((fragS*)lineP->frag)->fr_address;
1670 } else {
1671 ;
1672 }
1673 text_lineno_number++;
1674 } /* for each line number */
a39116f1 1675
fecd2382 1676 H_SET_SYMBOL_TABLE_SIZE(headers, symbol_number);
a39116f1 1677
fecd2382
RP
1678 return;
1679} /* obj_crawl_symbol_chain() */
1680
1681/*
1682 * Find strings by crawling along symbol table chain.
1683 */
1684
1685void obj_emit_strings(where)
1686char **where;
1687{
1688 symbolS *symbolP;
a39116f1 1689
d1a9e594 1690#ifdef CROSS_COMPILE
fecd2382
RP
1691 /* Gotta do md_ byte-ordering stuff for string_byte_count first - KWK */
1692 md_number_to_chars(*where, string_byte_count, sizeof(string_byte_count));
57574979 1693 *where += sizeof(string_byte_count);
d1a9e594 1694#else /* CROSS_COMPILE */
fecd2382 1695 append(where, (char *) &string_byte_count, (unsigned long) sizeof(string_byte_count));
d1a9e594 1696#endif /* CROSS_COMPILE */
a39116f1 1697
fecd2382
RP
1698 for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next(symbolP)) {
1699 if (SF_GET_STRING(symbolP)) {
1700 append(where, S_GET_NAME(symbolP), (unsigned long)(strlen(S_GET_NAME(symbolP)) + 1));
1701 } /* if it has a string */
1702 } /* walk the symbol chain */
a39116f1 1703
fecd2382
RP
1704 return;
1705} /* obj_emit_strings() */
1706
1707void obj_pre_write_hook(headers)
1708object_headers *headers;
1709{
1710 register int text_relocation_number = 0;
1711 register int data_relocation_number = 0;
1712 register fixS *fixP;
a39116f1 1713
fecd2382
RP
1714 /* FIXME-SOMEDAY this should be done at
1715 fixup_segment time but I'm going to wait until I
1716 do multiple segments. xoxorich. */
1717 /* Count the number of relocation entries for text and data */
1718 for (fixP = text_fix_root; fixP; fixP = fixP->fx_next) {
1719 if (fixP->fx_addsy) {
1720 ++text_relocation_number;
1721#ifdef TC_I960
1722 /* two relocs per callj under coff. */
1723 if (fixP->fx_callj) {
1724 ++text_relocation_number;
1725 } /* if callj and not already fixed. */
1726#endif /* TC_I960 */
57574979
SC
1727#ifdef TC_A29K
1728 /* Count 2 for a constH */
a39116f1
RP
1729 if (fixP->fx_r_type == RELOC_CONSTH) {
1730 ++text_relocation_number;
1731 }
57574979 1732#endif
a39116f1 1733
fecd2382
RP
1734 } /* if not yet fixed */
1735 } /* for each fix */
a39116f1 1736
fecd2382
RP
1737 SA_SET_SCN_NRELOC(dot_text_symbol, text_relocation_number);
1738 /* Assign the number of line number entries for the text section */
1739 SA_SET_SCN_NLINNO(dot_text_symbol, text_lineno_number);
1740 /* Assign the size of the section */
1741 SA_SET_SCN_SCNLEN(dot_text_symbol, H_GET_TEXT_SIZE(headers));
a39116f1 1742
fecd2382
RP
1743 for (fixP = data_fix_root; fixP; fixP = fixP->fx_next) {
1744 if (fixP->fx_addsy) {
1745 ++data_relocation_number;
1746 } /* if still relocatable */
57574979 1747#ifdef TC_A29K
a39116f1
RP
1748 /* Count 2 for a constH */
1749 if (fixP->fx_r_type == RELOC_CONSTH) {
1750 ++data_relocation_number;
1751 }
57574979 1752#endif
a39116f1 1753
fecd2382 1754 } /* for each fix */
a39116f1
RP
1755
1756
fecd2382
RP
1757 SA_SET_SCN_NRELOC(dot_data_symbol, data_relocation_number);
1758 /* Assign the size of the section */
1759 SA_SET_SCN_SCNLEN(dot_data_symbol, H_GET_DATA_SIZE(headers));
a39116f1 1760
fecd2382
RP
1761 /* Assign the size of the section */
1762 SA_SET_SCN_SCNLEN(dot_bss_symbol, H_GET_BSS_SIZE(headers));
a39116f1
RP
1763
1764 /* pre write hook can add relocs (for 960 and 29k coff) so */
57574979 1765 headers->relocation_size = text_relocation_number * RELSZ +
a39116f1
RP
1766 data_relocation_number *RELSZ;
1767
1768
1769
fecd2382 1770 /* Fill in extra coff fields */
a39116f1 1771
fecd2382
RP
1772 /* Initialize general line number information. */
1773 H_SET_LINENO_SIZE(headers, text_lineno_number * LINESZ);
a39116f1 1774
fecd2382
RP
1775 /* filehdr */
1776 H_SET_FILE_MAGIC_NUMBER(headers, FILE_HEADER_MAGIC);
1777 H_SET_NUMBER_OF_SECTIONS(headers, 3); /* text+data+bss */
57574979 1778#ifndef OBJ_COFF_OMIT_TIMESTAMP
fecd2382 1779 H_SET_TIME_STAMP(headers, (long)time((long*)0));
57574979
SC
1780#else /* OBJ_COFF_OMIT_TIMESTAMP */
1781 H_SET_TIME_STAMP(headers, 0);
1782#endif /* OBJ_COFF_OMIT_TIMESTAMP */
fecd2382 1783 H_SET_SYMBOL_TABLE_POINTER(headers, H_GET_SYMBOL_TABLE_FILE_OFFSET(headers));
57574979 1784#if 0
a39116f1
RP
1785 printf("FILHSZ %x\n", FILHSZ);
1786 printf("OBJ_COFF_AOUTHDRSZ %x\n", OBJ_COFF_AOUTHDRSZ);
1787 printf("section headers %x\n", H_GET_NUMBER_OF_SECTIONS(headers) * SCNHSZ);
1788 printf("get text size %x\n", H_GET_TEXT_SIZE(headers));
1789 printf("get data size %x\n", H_GET_DATA_SIZE(headers));
1790 printf("get relocation size %x\n", H_GET_RELOCATION_SIZE(headers));
1791 printf("get lineno size %x\n", H_GET_LINENO_SIZE(headers));
57574979 1792#endif
fecd2382
RP
1793 /* symbol table size allready set */
1794 H_SET_SIZEOF_OPTIONAL_HEADER(headers, OBJ_COFF_AOUTHDRSZ);
6d5460ab
RP
1795
1796 /* do not added the F_RELFLG for the standard COFF.
1797 * The AIX linker complain on file with relocation info striped flag.
1798 */
1799#ifdef KEEP_RELOC_INFO
1800 H_SET_FLAGS(headers, (text_lineno_number == 0 ? F_LNNO : 0)
1801 | BYTE_ORDERING);
1802#else
fecd2382 1803 H_SET_FLAGS(headers, (text_lineno_number == 0 ? F_LNNO : 0)
57574979 1804 | ((text_relocation_number + data_relocation_number) ? 0 : F_RELFLG)
fecd2382 1805 | BYTE_ORDERING);
6d5460ab 1806#endif
fecd2382
RP
1807 /* aouthdr */
1808 /* magic number allready set */
1809 H_SET_VERSION_STAMP(headers, 0);
1810 /* Text, data, bss size; entry point; text_start and data_start are already set */
a39116f1 1811
fecd2382 1812 /* Build section headers */
a39116f1 1813
fecd2382
RP
1814 c_section_header(&text_section_header,
1815 ".text",
1816 0,
1817 H_GET_TEXT_SIZE(headers),
1818 H_GET_TEXT_FILE_OFFSET(headers),
1819 (SA_GET_SCN_NRELOC(dot_text_symbol)
1820 ? H_GET_RELOCATION_FILE_OFFSET(headers)
1821 : 0),
1822 (text_lineno_number
1823 ? H_GET_LINENO_FILE_OFFSET(headers)
1824 : 0),
1825 SA_GET_SCN_NRELOC(dot_text_symbol),
1826 text_lineno_number,
1827 section_alignment[(int) SEG_TEXT]);
a39116f1 1828
fecd2382
RP
1829 c_section_header(&data_section_header,
1830 ".data",
1831 H_GET_TEXT_SIZE(headers),
1832 H_GET_DATA_SIZE(headers),
1833 (H_GET_DATA_SIZE(headers)
1834 ? H_GET_DATA_FILE_OFFSET(headers)
1835 : 0),
1836 (SA_GET_SCN_NRELOC(dot_data_symbol)
1837 ? (H_GET_RELOCATION_FILE_OFFSET(headers)
1838 + text_section_header.s_nreloc * RELSZ)
1839 : 0),
1840 0, /* No line number information */
1841 SA_GET_SCN_NRELOC(dot_data_symbol),
1842 0, /* No line number information */
1843 section_alignment[(int) SEG_DATA]);
a39116f1 1844
fecd2382
RP
1845 c_section_header(&bss_section_header,
1846 ".bss",
1847 H_GET_TEXT_SIZE(headers) + H_GET_DATA_SIZE(headers),
1848 H_GET_BSS_SIZE(headers),
1849 0, /* No file offset */
1850 0, /* No relocation information */
1851 0, /* No line number information */
1852 0, /* No relocation information */
1853 0, /* No line number information */
1854 section_alignment[(int) SEG_BSS]);
a39116f1 1855
fecd2382
RP
1856 return;
1857} /* obj_pre_write_hook() */
1858
1859/* This is a copy from aout. All I do is neglect to actually build the symbol. */
1860
1861static void obj_coff_stab(what)
1862int what;
1863{
1864 char *string;
1865 expressionS e;
1866 int goof = 0; /* TRUE if we have aborted. */
1867 int length;
1868 int saved_type = 0;
1869 long longint;
1870 symbolS *symbolP = 0;
a39116f1 1871
fecd2382
RP
1872 if (what == 's') {
1873 string = demand_copy_C_string(&length);
1874 SKIP_WHITESPACE();
a39116f1 1875
fecd2382
RP
1876 if (*input_line_pointer == ',') {
1877 input_line_pointer++;
1878 } else {
1879 as_bad("I need a comma after symbol's name");
1880 goof = 1;
1881 } /* better be a comma */
1882 } /* skip the string */
a39116f1 1883
fecd2382
RP
1884 /*
1885 * Input_line_pointer->after ','. String->symbol name.
1886 */
1887 if (!goof) {
1888 if (get_absolute_expression_and_terminator(&longint) != ',') {
1889 as_bad("I want a comma after the n_type expression");
1890 goof = 1;
1891 input_line_pointer--; /* Backup over a non-',' char. */
1892 } /* on error */
1893 } /* no error */
a39116f1 1894
fecd2382
RP
1895 if (!goof) {
1896 if (get_absolute_expression_and_terminator(&longint) != ',') {
1897 as_bad("I want a comma after the n_other expression");
1898 goof = 1;
1899 input_line_pointer--; /* Backup over a non-',' char. */
1900 } /* on error */
1901 } /* no error */
a39116f1 1902
fecd2382
RP
1903 if (!goof) {
1904 get_absolute_expression();
a39116f1 1905
fecd2382
RP
1906 if (what == 's' || what == 'n') {
1907 if (*input_line_pointer != ',') {
1908 as_bad("I want a comma after the n_desc expression");
1909 goof = 1;
1910 } else {
1911 input_line_pointer++;
1912 } /* on goof */
1913 } /* not stabd */
1914 } /* no error */
a39116f1 1915
fecd2382 1916 expression(&e);
a39116f1 1917
fecd2382
RP
1918 if (goof) {
1919 ignore_rest_of_line();
1920 } else {
1921 demand_empty_rest_of_line();
1922 } /* on error */
1923} /* obj_coff_stab() */
1924
1925#ifdef DEBUG
a39116f1 1926/* for debugging */
fecd2382
RP
1927char *s_get_name(s)
1928symbolS *s;
1929{
1930 return((s == NULL) ? "(NULL)" : S_GET_NAME(s));
1931} /* s_get_name() */
1932
1933void symbol_dump() {
1934 symbolS *symbolP;
a39116f1 1935
fecd2382
RP
1936 for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next(symbolP)) {
1937 printf("%3ld: 0x%lx \"%s\" type = %ld, class = %d, segment = %d\n",
1938 symbolP->sy_number,
1939 (unsigned long) symbolP,
1940 S_GET_NAME(symbolP),
1941 (long) S_GET_DATA_TYPE(symbolP),
1942 S_GET_STORAGE_CLASS(symbolP),
1943 (int) S_GET_SEGMENT(symbolP));
1944 } /* traverse symbols */
a39116f1 1945
fecd2382
RP
1946 return;
1947} /* symbol_dump() */
1948#endif /* DEBUG */
1949
57574979 1950
fecd2382
RP
1951/*
1952 * Local Variables:
1953 * comment-column: 0
1954 * fill-column: 131
1955 * End:
1956 */
1957
1958/* end of obj-coff.c */
This page took 0.142182 seconds and 4 git commands to generate.