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