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