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