White space and comment changes, and #ifdef __STDC__ becomes #if
[binutils-gdb.git] / gas / config / obj-coff.c
1 /* coff object file format
2 Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc.
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. */
19
20 #include "as.h"
21
22 #include "obstack.h"
23
24 lineno* lineno_rootP;
25
26 const 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 */
40 C_REGISTER_SECTION, /* SEG_REGISTER */
41 };
42
43
44 /* Add 4 to the real value to get the index and compensate the negatives */
45
46 const segT N_TYPE_seg [32] =
47 {
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 };
61
62 #if __STDC__ == 1
63
64 char *s_get_name(symbolS *s);
65 static symbolS *tag_find_or_make(char *name);
66 static symbolS* tag_find(char *name);
67 #ifdef BFD_HEADERS
68 static void obj_coff_section_header_append(char **where, struct internal_scnhdr *header);
69 #else
70 static void obj_coff_section_header_append(char **where, SCNHDR *header);
71 #endif
72 static void obj_coff_def(int what);
73 static void obj_coff_dim(void);
74 static void obj_coff_endef(void);
75 static void obj_coff_line(void);
76 static void obj_coff_ln(void);
77 static void obj_coff_scl(void);
78 static void obj_coff_size(void);
79 static void obj_coff_stab(int what);
80 static void obj_coff_tag(void);
81 static void obj_coff_type(void);
82 static void obj_coff_val(void);
83 static void tag_init(void);
84 static void tag_insert(char *name, symbolS *symbolP);
85
86 #else /* not __STDC__ */
87
88 char *s_get_name();
89 static symbolS *tag_find();
90 static symbolS *tag_find_or_make();
91 static void obj_coff_section_header_append();
92 static void obj_coff_def();
93 static void obj_coff_dim();
94 static void obj_coff_endef();
95 static void obj_coff_line();
96 static void obj_coff_ln();
97 static void obj_coff_scl();
98 static void obj_coff_size();
99 static void obj_coff_stab();
100 static void obj_coff_tag();
101 static void obj_coff_type();
102 static void obj_coff_val();
103 static void tag_init();
104 static void tag_insert();
105
106 #endif /* not __STDC__ */
107
108 static struct hash_control *tag_hash;
109 static symbolS *def_symbol_in_progress = NULL;
110
111 const 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 */
135
136 { "ident", s_ignore, 0 }, /* we don't yet handle this. */
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. */
142 { "desc", s_ignore, 0 }, /* def */
143 /* { "line", s_ignore, 0 }, */ /* source code line number */
144 { "stabd", obj_coff_stab, 'd' }, /* stabs */
145 { "stabn", obj_coff_stab, 'n' }, /* stabs */
146 { "stabs", obj_coff_stab, 's' }, /* stabs */
147
148 /* stabs-in-coff (?) debug pseudos (ignored) */
149 { "optim", s_ignore, 0 }, /* For sun386i cc (?) */
150 /* other stuff */
151 { "ABORT", s_abort, 0 },
152
153 { NULL} /* end sentinel */
154 }; /* obj_pseudo_table */
155
156
157 /* obj dependant output values */
158 #ifdef BFD_HEADERS
159 static struct internal_scnhdr bss_section_header;
160 struct internal_scnhdr data_section_header;
161 struct internal_scnhdr text_section_header;
162 #else
163 static SCNHDR bss_section_header;
164 SCNHDR data_section_header;
165 SCNHDR text_section_header;
166 #endif
167 /* Relocation. */
168
169 /*
170 * emit_relocations()
171 *
172 * Crawl along a fixS chain. Emit the segment's relocations.
173 */
174
175 void obj_emit_relocations(where, fixP, segment_address_in_file)
176 char **where;
177 fixS *fixP; /* Fixup chain for this segment. */
178 relax_addressT segment_address_in_file;
179 {
180 #ifdef BFD_HEADERS
181 struct internal_reloc ri;
182 #else
183 RELOC ri;
184 #endif
185 symbolS *symbolP;
186
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);
213
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 */
245
246 /* md_ri_to_chars((char *) &ri, ri); */ /* Last step : write md f */
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) {
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);
260 }
261
262 #endif
263
264 #else
265 append(where, (char *) &ri, sizeof(ri));
266 #endif
267
268 #ifdef TC_I960
269 if (fixP->fx_callj) {
270 ri.r_type = R_OPTCALL;
271 #ifdef BFD_HEADERS
272 *where += bfd_coff_swap_reloc_out(stdoutput, &ri, *where);
273 #else
274 append(where, (char *) &ri, sizeof(ri));
275 #endif
276
277
278 } /* if it's a callj, do it again for the opcode */
279 #endif /* TC_I960 */
280
281 } /* if there's a symbol */
282 } /* for each fixP */
283
284 return;
285 } /* obj_emit_relocations() */
286
287 /* Coff file generation & utilities */
288
289 #ifdef BFD_HEADERS
290 void obj_header_append(where, headers)
291 char **where;
292 object_headers *headers;
293 {
294 tc_headers_hook(headers);
295 *where += bfd_coff_swap_filehdr_out(stdoutput, &(headers->filehdr), *where);
296 #ifndef OBJ_COFF_OMIT_OPTIONAL_HEADER
297 *where += bfd_coff_swap_aouthdr_out(stdoutput, &(headers->aouthdr), *where);
298 #endif
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
303 }
304
305 #else
306
307 void obj_header_append(where, headers)
308 char **where;
309 object_headers *headers;
310 {
311 tc_headers_hook(headers);
312
313 #ifdef CROSS_COMPILE
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);
329
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);
348 md_number_to_chars(*where, headers->aouthdr.tagentries, sizeof(headers->aouthdr.tagentries));
349 *where += sizeof(headers->aouthdr.tagentries);
350 #endif /* OBJ_COFF_OMIT_OPTIONAL_HEADER */
351
352 #else /* CROSS_COMPILE */
353
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 */
358
359 #endif /* CROSS_COMPILE */
360
361 /* Output the section headers */
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);
365
366 return;
367 } /* obj_header_append() */
368 #endif
369 void obj_symbol_to_chars(where, symbolP)
370 char **where;
371 symbolS *symbolP;
372 {
373 #ifdef BFD_HEADERS
374 unsigned int numaux = symbolP->sy_symbol.ost_entry.n_numaux;
375 unsigned int i;
376
377 if (S_GET_SEGMENT(symbolP) == SEG_REGISTER) {
378 S_SET_SEGMENT(symbolP, SEG_ABSOLUTE);
379 }
380 *where += bfd_coff_swap_sym_out(stdoutput, &symbolP->sy_symbol.ost_entry,
381 *where);
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
398 #ifdef CROSS_COMPILE
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);
411 #else /* CROSS_COMPILE */
412 append(where, (char *) syment, sizeof(*syment));
413 #endif /* CROSS_COMPILE */
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) {
421 #ifdef CROSS_COMPILE
422 #if 0 /* This code has never been tested */
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 }
459 #endif /* 0 */
460 #else /* CROSS_COMPILE */
461 append(where, (char *) &symbolP->sy_symbol.ost_auxent[i], sizeof(symbolP->sy_symbol.ost_auxent[i]));
462 #endif /* CROSS_COMPILE */
463
464 }; /* for each aux in use */
465 #endif /* BFD_HEADERS */
466 return;
467 } /* obj_symbol_to_chars() */
468
469 #ifdef BFD_HEADERS
470 static void obj_coff_section_header_append(where, header)
471 char **where;
472 struct internal_scnhdr *header;
473 {
474 *where += bfd_coff_swap_scnhdr_out(stdoutput, header, *where);
475 }
476 #else
477 static void obj_coff_section_header_append(where, header)
478 char **where;
479 SCNHDR *header;
480 {
481 #ifdef CROSS_COMPILE
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 */
516
517 #else /* CROSS_COMPILE */
518
519 append(where, (char *) header, sizeof(*header));
520
521 #endif /* CROSS_COMPILE */
522
523 return;
524 } /* obj_coff_section_header_append() */
525
526 #endif
527 void obj_emit_symbols(where, symbol_rootP)
528 char **where;
529 symbolS *symbol_rootP;
530 {
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 }
553 } /* obj_emit_symbols() */
554
555 /* Merge a debug symbol containing debug information into a normal symbol. */
556
557 void c_symbol_merge(debug, normal)
558 symbolS *debug;
559 symbolS *normal;
560 {
561 S_SET_DATA_TYPE(normal, S_GET_DATA_TYPE(debug));
562 S_SET_STORAGE_CLASS(normal, S_GET_STORAGE_CLASS(debug));
563
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 */
567
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 */
571
572 /* Move the debug flags. */
573 SF_SET_DEBUG_FIELD(normal, SF_GET_DEBUG_FIELD(debug));
574 } /* c_symbol_merge() */
575
576 static symbolS *previous_file_symbol = NULL;
577
578 void c_dot_file_symbol(filename)
579 char *filename;
580 {
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
607 } /* c_dot_file_symbol() */
608 /*
609 * Build a 'section static' symbol.
610 */
611
612 char *c_section_symbol(name, value, length, nreloc, nlnno)
613 char *name;
614 long value;
615 long length;
616 unsigned short nreloc;
617 unsigned short nlnno;
618 {
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;
640 } /* c_section_symbol() */
641
642 void 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)
652 #ifdef BFD_HEADERS
653 struct internal_scnhdr *header;
654 #else
655 SCNHDR *header;
656 #endif
657 char *name;
658 long core_address;
659 long size;
660 long data_ptr;
661 long reloc_ptr;
662 long lineno_ptr;
663 long reloc_number;
664 long lineno_number;
665 long 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;
674
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 */
684
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
697 int function_lineoff = -1; /* Offset in line#s where the last function
698 started (the odd entry for line #0) */
699 int text_lineno_number = 0;
700 int 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. */
705 lineno* lineno_lastP = (lineno*)0;
706
707 int
708 c_line_new(paddr, line_number, frag)
709 long paddr;
710 unsigned short line_number;
711 fragS* frag;
712 {
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++;
726 }
727
728 void obj_emit_lineno(where, line, file_start)
729 char **where;
730 lineno *line;
731 char *file_start;
732 {
733 #ifdef BFD_HEADERS
734 struct bfd_internal_lineno *line_entry;
735 #else
736 LINENO *line_entry;
737 #endif
738 for (; line; line = line->next) {
739 line_entry = &line->line;
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
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. */
749 /* char *name; */
750 symbolS *symbolP;
751
752 symbolP = (symbolS *) line_entry->l_addr.l_symndx;
753
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;
756
757 } /* if this is a function linno */
758 #ifdef BFD_HEADERS
759 *where += bfd_coff_swap_lineno_out(stdoutput, line_entry, *where);
760 #else
761 /* No matter which member of the union we process, they are
762 both long. */
763 #ifdef CROSS_COMPILE
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);
766
767 md_number_to_chars(*where, line_entry->l_lnno, sizeof(line_entry->l_lnno));
768 *where += sizeof(line_entry->l_lnno);
769
770 #ifdef TC_I960
771 **where = '0';
772 ++*where;
773 **where = '0';
774 ++*where;
775 #endif /* TC_I960 */
776
777 #else /* CROSS_COMPILE */
778 append(where, (char *) line_entry, LINESZ);
779 #endif /* CROSS_COMPILE */
780 #endif /* BFD_HEADERS */
781 } /* for each line number */
782
783 return ;
784 } /* obj_emit_lineno() */
785
786 void obj_symbol_new_hook(symbolP)
787 symbolS *symbolP;
788 {
789 char underscore = 0; /* Symbol has leading _ */
790
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);
801
802 #ifdef STRIP_UNDERSCORE
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 */
811
812 if (S_IS_STRING(symbolP))
813 SF_SET_STRING(symbolP);
814 if (!underscore && S_IS_LOCAL(symbolP))
815 SF_SET_LOCAL(symbolP);
816
817 return;
818 } /* obj_symbol_new_hook() */
819
820 /* stack stuff */
821 stack* stack_init(chunk_size, element_size)
822 unsigned long chunk_size;
823 unsigned long element_size;
824 {
825 stack* st;
826
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
840 void stack_delete(st)
841 stack* st;
842 {
843 free(st->data);
844 free(st);
845 }
846
847 char *stack_push(st, element)
848 stack *st;
849 char *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
861 char* stack_pop(st)
862 stack* st;
863 {
864 if ((st->pointer -= st->element_size) < 0) {
865 st->pointer = 0;
866 return (char*)0;
867 }
868 return st->data + st->pointer;
869 }
870
871 char* stack_top(st)
872 stack* st;
873 {
874 return st->data + st->pointer - st->element_size;
875 }
876
877
878 /*
879 * Handle .ln directives.
880 */
881
882 static 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 */
888
889 c_line_new(obstack_next_free(&frags) - frag_now->fr_literal,
890 get_absolute_expression(),
891 frag_now);
892
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 == ' ' || \
913 *input_line_pointer == '\t') \
914 input_line_pointer++;
915
916 static void obj_coff_def(what)
917 int what;
918 {
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));
949 #else /* STRIP_UNDERSCORE */
950 S_SET_NAME(def_symbol_in_progress, symbol_name_copy);
951 #endif /* STRIP_UNDERSCORE */
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;
965 } /* obj_coff_def() */
966
967 unsigned int dim_index;
968 static void obj_coff_endef() {
969 symbolS *symbolP;
970 /* DIM BUG FIX sac@cygnus.com */
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 */
977
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;
990
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);
999
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;
1009
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;
1025
1026 case C_EXT:
1027 case C_STAT:
1028 case C_LABEL:
1029 /* Valid but set somewhere else (s_comm, s_lcomm, colon) */
1030 break;
1031
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 */
1038
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. */
1043
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. */
1054
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. */
1058
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) {
1064
1065 symbol_append(def_symbol_in_progress, symbol_lastP, &symbol_rootP, &symbol_lastP);
1066
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] */
1075
1076 /* The debug entry (def_symbol_in_progress)
1077 is merged into the previous definition. */
1078
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;
1082
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 */
1094
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. */
1099
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);
1104
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 */
1111
1112 def_symbol_in_progress = NULL;
1113 demand_empty_rest_of_line();
1114 return;
1115 } /* obj_coff_endef() */
1116
1117 static void obj_coff_dim()
1118 {
1119 register int dim_index;
1120
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 */
1126
1127 S_SET_NUMBER_AUXILIARY(def_symbol_in_progress, 1);
1128
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());
1132
1133 switch (*input_line_pointer) {
1134
1135 case ',':
1136 input_line_pointer++;
1137 break;
1138
1139 default:
1140 as_warn("badly formed .dim directive ignored");
1141 /* intentional fallthrough */
1142 case '\n':
1143 case ';':
1144 dim_index = DIMNUM;
1145 break;
1146 } /* switch on following character */
1147 } /* for each dimension */
1148
1149 demand_empty_rest_of_line();
1150 return;
1151 } /* obj_coff_dim() */
1152
1153 static 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 */
1158
1159 S_SET_NUMBER_AUXILIARY(def_symbol_in_progress, 1);
1160 SA_SET_SYM_LNNO(def_symbol_in_progress, get_absolute_expression());
1161
1162 demand_empty_rest_of_line();
1163 return;
1164 } /* obj_coff_line() */
1165
1166 static 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 */
1172
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
1179 static 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 */
1185
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
1191 static void obj_coff_tag() {
1192 char *symbol_name;
1193 char name_end;
1194
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 */
1200
1201 S_SET_NUMBER_AUXILIARY(def_symbol_in_progress, 1);
1202 symbol_name = input_line_pointer;
1203 name_end = get_symbol_end();
1204
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 */
1211
1212 SF_SET_TAGGED(def_symbol_in_progress);
1213 *input_line_pointer = name_end;
1214
1215 demand_empty_rest_of_line();
1216 return;
1217 } /* obj_coff_tag() */
1218
1219 static 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 */
1225
1226 S_SET_DATA_TYPE(def_symbol_in_progress, get_absolute_expression());
1227
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 */
1232
1233 demand_empty_rest_of_line();
1234 return;
1235 } /* obj_coff_type() */
1236
1237 static 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 */
1243
1244 if (is_name_beginner(*input_line_pointer)) {
1245 char *symbol_name = input_line_pointer;
1246 char name_end = get_symbol_end();
1247
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);
1254
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 */
1265
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
1274 static void tag_init() {
1275 tag_hash = hash_new();
1276 return ;
1277 } /* tag_init() */
1278
1279 static void tag_insert(name, symbolP)
1280 char *name;
1281 symbolS *symbolP;
1282 {
1283 register char * error_string;
1284
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
1292 static symbolS *tag_find_or_make(name)
1293 char *name;
1294 {
1295 symbolS *symbolP;
1296
1297 if ((symbolP = tag_find(name)) == NULL) {
1298 symbolP = symbol_new(name,
1299 SEG_UNKNOWN,
1300 0,
1301 &zero_address_frag);
1302
1303 tag_insert(S_GET_NAME(symbolP), symbolP);
1304 symbol_table_insert(symbolP);
1305 } /* not found */
1306
1307 return(symbolP);
1308 } /* tag_find_or_make() */
1309
1310 static symbolS *tag_find(name)
1311 char *name;
1312 {
1313 #ifdef STRIP_UNDERSCORE
1314 if (*name == '_') name++;
1315 #endif /* STRIP_UNDERSCORE */
1316 return((symbolS*)hash_find(tag_hash, name));
1317 } /* tag_find() */
1318
1319 void obj_read_begin_hook() {
1320 /* These had better be the same. Usually 18 bytes. */
1321 #ifndef BFD_HEADERS
1322 know(sizeof(SYMENT) == sizeof(AUXENT));
1323 know(SYMESZ == AUXESZ);
1324 #endif
1325 tag_init();
1326
1327 return;
1328 } /* obj_read_begin_hook() */
1329
1330 void obj_crawl_symbol_chain(headers)
1331 object_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;
1340
1341 /* Initialize the stack used to keep track of the matching .bb .be */
1342 stack* block_stack = stack_init(512, sizeof(symbolS*));
1343
1344 /* JF deal with forward references first... */
1345 for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next(symbolP)) {
1346
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));
1351
1352 if (SF_GET_GET_SEGMENT(symbolP)) {
1353 S_SET_SEGMENT(symbolP, S_GET_SEGMENT(symbolP->sy_forward));
1354 } /* forward segment also */
1355
1356 symbolP->sy_forward=0;
1357 } /* if it has a forward reference */
1358 } /* walk the symbol chain */
1359
1360 tc_crawl_symbol_chain(headers);
1361
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 */
1372
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. */
1378
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 */);
1388
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 */
1395
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 */
1402
1403 #if defined(DEBUG)
1404 verify_symbol_chain(symbol_rootP, symbol_lastP);
1405 #endif /* DEBUG */
1406
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. */
1420
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 */
1426 for (symbolP = symbol_rootP;
1427 symbolP;
1428 symbolP = symbolP ? symbol_next(symbolP) : symbol_rootP) {
1429 if (!SF_GET_DEBUG(symbolP)) {
1430 /* Debug symbols do not need all this rubbish */
1431 symbolS* real_symbolP;
1432
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 */
1453
1454 if (flagseen['R'] && (S_GET_SEGMENT(symbolP) == SEG_DATA)) {
1455 S_SET_SEGMENT(symbolP, SEG_TEXT);
1456 } /* push data into text */
1457
1458 S_SET_VALUE(symbolP, S_GET_VALUE(symbolP) + symbolP->sy_frag->fr_address);
1459
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 */
1469
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;
1492
1493 if (S_GET_NUMBER_AUXILIARY(symbolP) < 1) {
1494 S_SET_NUMBER_AUXILIARY(symbolP, 1);
1495 } /* make it at least 1 */
1496
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;
1519
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 */
1529
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. */
1540
1541
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);
1546
1547 } else if (!S_IS_DEFINED(symbolP) && !S_IS_DEBUG(symbolP) && !SF_GET_STATICS(symbolP)) {
1548 /* S_GET_STORAGE_CLASS(symbolP) == C_EXT && !SF_GET_FUNCTION(symbolP)) { */
1549 /* if external, Remove from the list */
1550 symbolS *hold = symbol_previous(symbolP);
1551
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 */
1563
1564 symbolP->sy_number = symbol_number;
1565 symbol_number += 1 + S_GET_NUMBER_AUXILIARY(symbolP);
1566 } /* if local symbol */
1567 } /* traverse the symbol list */
1568
1569 for (symbolP = symbol_externP; symbol_externP;) {
1570 symbolS *tmp = symbol_externP;
1571
1572 /* append */
1573 symbol_remove(tmp, &symbol_externP, &symbol_extern_lastP);
1574 symbol_append(tmp, symbol_lastP, &symbol_rootP, &symbol_lastP);
1575
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 */
1583
1584 tmp->sy_number = symbol_number;
1585 symbol_number += 1 + S_GET_NUMBER_AUXILIARY(tmp);
1586 } /* append the entire extern chain */
1587
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. */
1592
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 */
1598
1599 know(symbol_externP == NULL);
1600 know(symbol_extern_lastP == NULL);
1601
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. */
1607
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 */
1616
1617 H_SET_SYMBOL_TABLE_SIZE(headers, symbol_number);
1618
1619 return;
1620 } /* obj_crawl_symbol_chain() */
1621
1622 /*
1623 * Find strings by crawling along symbol table chain.
1624 */
1625
1626 void obj_emit_strings(where)
1627 char **where;
1628 {
1629 symbolS *symbolP;
1630
1631 #ifdef CROSS_COMPILE
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));
1634 *where += sizeof(string_byte_count);
1635 #else /* CROSS_COMPILE */
1636 append(where, (char *) &string_byte_count, (unsigned long) sizeof(string_byte_count));
1637 #endif /* CROSS_COMPILE */
1638
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 */
1644
1645 return;
1646 } /* obj_emit_strings() */
1647
1648 void obj_pre_write_hook(headers)
1649 object_headers *headers;
1650 {
1651 register int text_relocation_number = 0;
1652 register int data_relocation_number = 0;
1653 register fixS *fixP;
1654
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 */
1668 #ifdef TC_A29K
1669 /* Count 2 for a constH */
1670 if (fixP->fx_r_type == RELOC_CONSTH) {
1671 ++text_relocation_number;
1672 }
1673 #endif
1674
1675 } /* if not yet fixed */
1676 } /* for each fix */
1677
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));
1683
1684 for (fixP = data_fix_root; fixP; fixP = fixP->fx_next) {
1685 if (fixP->fx_addsy) {
1686 ++data_relocation_number;
1687 } /* if still relocatable */
1688 #ifdef TC_A29K
1689 /* Count 2 for a constH */
1690 if (fixP->fx_r_type == RELOC_CONSTH) {
1691 ++data_relocation_number;
1692 }
1693 #endif
1694
1695 } /* for each fix */
1696
1697
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));
1701
1702 /* Assign the size of the section */
1703 SA_SET_SCN_SCNLEN(dot_bss_symbol, H_GET_BSS_SIZE(headers));
1704
1705 /* pre write hook can add relocs (for 960 and 29k coff) so */
1706 headers->relocation_size = text_relocation_number * RELSZ +
1707 data_relocation_number *RELSZ;
1708
1709
1710
1711 /* Fill in extra coff fields */
1712
1713 /* Initialize general line number information. */
1714 H_SET_LINENO_SIZE(headers, text_lineno_number * LINESZ);
1715
1716 /* filehdr */
1717 H_SET_FILE_MAGIC_NUMBER(headers, FILE_HEADER_MAGIC);
1718 H_SET_NUMBER_OF_SECTIONS(headers, 3); /* text+data+bss */
1719 #ifndef OBJ_COFF_OMIT_TIMESTAMP
1720 H_SET_TIME_STAMP(headers, (long)time((long*)0));
1721 #else /* OBJ_COFF_OMIT_TIMESTAMP */
1722 H_SET_TIME_STAMP(headers, 0);
1723 #endif /* OBJ_COFF_OMIT_TIMESTAMP */
1724 H_SET_SYMBOL_TABLE_POINTER(headers, H_GET_SYMBOL_TABLE_FILE_OFFSET(headers));
1725 #if 0
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));
1733 #endif
1734 /* symbol table size allready set */
1735 H_SET_SIZEOF_OPTIONAL_HEADER(headers, OBJ_COFF_AOUTHDRSZ);
1736 H_SET_FLAGS(headers, (text_lineno_number == 0 ? F_LNNO : 0)
1737 | ((text_relocation_number + data_relocation_number) ? 0 : F_RELFLG)
1738 | BYTE_ORDERING);
1739
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 */
1744
1745 /* Build section headers */
1746
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]);
1761
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]);
1777
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]);
1788
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
1794 static void obj_coff_stab(what)
1795 int 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;
1804
1805 if (what == 's') {
1806 string = demand_copy_C_string(&length);
1807 SKIP_WHITESPACE();
1808
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 */
1816
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 */
1827
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 */
1835
1836 if (!goof) {
1837 get_absolute_expression();
1838
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 */
1848
1849 expression(&e);
1850
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
1859 /* for debugging */
1860 char *s_get_name(s)
1861 symbolS *s;
1862 {
1863 return((s == NULL) ? "(NULL)" : S_GET_NAME(s));
1864 } /* s_get_name() */
1865
1866 void symbol_dump() {
1867 symbolS *symbolP;
1868
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 */
1878
1879 return;
1880 } /* symbol_dump() */
1881 #endif /* DEBUG */
1882
1883
1884 /*
1885 * Local Variables:
1886 * comment-column: 0
1887 * fill-column: 131
1888 * End:
1889 */
1890
1891 /* end of obj-coff.c */