1 /* coff object file format
2 Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc.
4 This file is part of GAS.
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)
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.
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. */
26 const short seg_N_TYPE
[] = { /* in: segT out: N_TYPE bits */
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 */
44 /* Add 4 to the real value to get the index and compensate the negatives */
46 const segT N_TYPE_seg
[32] =
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
64 char *s_get_name(symbolS
*s
);
65 static symbolS
*tag_find_or_make(char *name
);
66 static symbolS
* tag_find(char *name
);
68 static void obj_coff_section_header_append(char **where
, struct internal_scnhdr
*header
);
70 static void obj_coff_section_header_append(char **where
, SCNHDR
*header
);
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
);
86 #else /* not __STDC__ */
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();
106 #endif /* not __STDC__ */
108 static struct hash_control
*tag_hash
;
109 static symbolS
*def_symbol_in_progress
= NULL
;
111 const pseudo_typeS obj_pseudo_table
[] = {
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 },
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 */
136 { "ident", s_ignore
, 0 }, /* we don't yet handle this. */
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 */
148 /* stabs-in-coff (?) debug pseudos (ignored) */
149 { "optim", s_ignore
, 0 }, /* For sun386i cc (?) */
151 { "ABORT", s_abort
, 0 },
153 { NULL
} /* end sentinel */
154 }; /* obj_pseudo_table */
157 /* obj dependant output values */
159 static struct internal_scnhdr bss_section_header
;
160 struct internal_scnhdr data_section_header
;
161 struct internal_scnhdr text_section_header
;
163 static SCNHDR bss_section_header
;
164 SCNHDR data_section_header
;
165 SCNHDR text_section_header
;
169 static int reloc_compare(p1
, p2
)
171 struct internal_reloc
*p1
, *p2
;
176 return (int)(p1
->r_vaddr
- p2
->r_vaddr
);
182 * Crawl along a fixS chain. Emit the segment's relocations.
185 void obj_emit_relocations(where
, fixP
, segment_address_in_file
)
187 fixS
*fixP
; /* Fixup chain for this segment. */
188 relax_addressT segment_address_in_file
;
191 struct internal_reloc
*ri_table
;
199 for (count
= 0, p
= fixP
; p
; p
= p
->fx_next
)
200 if (p
->fx_addsy
) count
++;
205 ri_table
= (struct internal_reloc
*) calloc(sizeof(*ri_table
),count
);
207 ri_table
= (RELOC
*) calloc(sizeof(*ri_table
),count
);
210 as_fatal ("obj_emit_relocations: Could not malloc relocation table");
213 callj_table
= (char *)malloc (sizeof(char)*count
);
215 as_fatal ("obj_emit_relocations: Could not malloc callj table");
218 for (i
= 0; fixP
; fixP
= fixP
->fx_next
) {
219 if (symbolP
= fixP
->fx_addsy
) {
221 ri_table
[i
].r_type
= (fixP
->fx_pcrel
?
222 (fixP
->fx_size
== 1 ? R_PCRBYTE
:
223 fixP
->fx_size
== 2 ? R_PCRWORD
:
225 (fixP
->fx_size
== 1 ? R_RELBYTE
:
226 fixP
->fx_size
== 2 ? R_RELWORD
:
228 #elif defined(TC_I386)
229 /* FIXME-SOON R_OFF8 & R_DIR16 are a vague guess, completly
231 ri_table
[i
].r_type
= (fixP
->fx_pcrel
?
232 (fixP
->fx_size
== 1 ? R_PCRBYTE
:
233 fixP
->fx_size
== 2 ? R_PCRWORD
:
235 (fixP
->fx_size
== 1 ? R_OFF8
:
236 fixP
->fx_size
== 2 ? R_DIR16
:
238 #elif defined(TC_I960)
239 ri_table
[i
].r_type
= (fixP
->fx_pcrel
242 callj_table
[i
] = fixP
->fx_callj
? 1 : 0;
243 #elif defined(TC_A29K)
244 ri_table
[i
].r_type
= tc_coff_fix2rtype(fixP
);
248 #endif /* TC_M68K || TC_I386 */
249 ri_table
[i
].r_vaddr
= (fixP
->fx_frag
->fr_address
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.
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 */
279 /* md_ri_to_chars((char *) &ri, ri); */ /* Last step : write md f */
282 } /* if there's a symbol */
283 } /* for each fixP */
286 * AIX ld prefer to have the reloc table with r_vaddr sorted.
287 * But sorting it should not hurt any other ld.
289 qsort (ri_table
, count
, sizeof(*ri_table
), reloc_compare
);
291 for (i
= 0; i
< count
; i
++)
294 *where
+= bfd_coff_swap_reloc_out(stdoutput
, &ri_table
[i
], *where
);
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
300 if (ri_table
[i
].r_type
== R_IHIHALF
)
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
],
308 # endif /* TC_A29K */
310 #else /* not BFD_HEADERS */
311 append(where
, (char *) &ri_table
[i
], RELSZ
);
312 #endif /* not BFD_HEADERS */
317 ri_table
[i
].r_type
= R_OPTCALL
;
319 *where
+= bfd_coff_swap_reloc_out(stdoutput
, &ri_table
[i
],
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 */
334 } /* obj_emit_relocations() */
336 /* Coff file generation & utilities */
339 void obj_header_append(where
, headers
)
341 object_headers
*headers
;
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
);
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
);
356 void obj_header_append(where
, headers
)
358 object_headers
*headers
;
360 tc_headers_hook(headers
);
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
);
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 */
401 #else /* CROSS_COMPILE */
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 */
408 #endif /* CROSS_COMPILE */
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
);
416 } /* obj_header_append() */
418 void obj_symbol_to_chars(where
, symbolP
)
423 unsigned int numaux
= symbolP
->sy_symbol
.ost_entry
.n_numaux
;
426 if (S_GET_SEGMENT(symbolP
) == SEG_REGISTER
) {
427 S_SET_SEGMENT(symbolP
, SEG_ABSOLUTE
);
429 *where
+= bfd_coff_swap_sym_out(stdoutput
, &symbolP
->sy_symbol
.ost_entry
,
432 for (i
= 0; i
< numaux
; i
++)
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
),
441 #else /* BFD_HEADERS */
442 SYMENT
*syment
= &symbolP
->sy_symbol
.ost_entry
;
444 char numaux
= syment
->n_numaux
;
445 unsigned short type
= S_GET_DATA_TYPE(symbolP
);
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 */
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 */
469 for (i
= 0; i
< numaux
; ++i
) {
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
);
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
);
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
);
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
]);
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
);
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 */
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
);
509 #else /* CROSS_COMPILE */
510 append(where
, (char *) &symbolP
->sy_symbol
.ost_auxent
[i
], AUXESZ
);
511 #endif /* CROSS_COMPILE */
513 }; /* for each aux in use */
514 #endif /* BFD_HEADERS */
516 } /* obj_symbol_to_chars() */
519 static void obj_coff_section_header_append(where
, header
)
521 struct internal_scnhdr
*header
;
523 *where
+= bfd_coff_swap_scnhdr_out(stdoutput
, header
, *where
);
526 static void obj_coff_section_header_append(where
, header
)
531 memcpy(*where
, header
->s_name
, sizeof(header
->s_name
));
532 *where
+= sizeof(header
->s_name
);
534 md_number_to_chars(*where
, header
->s_paddr
, sizeof(header
->s_paddr
));
535 *where
+= sizeof(header
->s_paddr
);
537 md_number_to_chars(*where
, header
->s_vaddr
, sizeof(header
->s_vaddr
));
538 *where
+= sizeof(header
->s_vaddr
);
540 md_number_to_chars(*where
, header
->s_size
, sizeof(header
->s_size
));
541 *where
+= sizeof(header
->s_size
);
543 md_number_to_chars(*where
, header
->s_scnptr
, sizeof(header
->s_scnptr
));
544 *where
+= sizeof(header
->s_scnptr
);
546 md_number_to_chars(*where
, header
->s_relptr
, sizeof(header
->s_relptr
));
547 *where
+= sizeof(header
->s_relptr
);
549 md_number_to_chars(*where
, header
->s_lnnoptr
, sizeof(header
->s_lnnoptr
));
550 *where
+= sizeof(header
->s_lnnoptr
);
552 md_number_to_chars(*where
, header
->s_nreloc
, sizeof(header
->s_nreloc
));
553 *where
+= sizeof(header
->s_nreloc
);
555 md_number_to_chars(*where
, header
->s_nlnno
, sizeof(header
->s_nlnno
));
556 *where
+= sizeof(header
->s_nlnno
);
558 md_number_to_chars(*where
, header
->s_flags
, sizeof(header
->s_flags
));
559 *where
+= sizeof(header
->s_flags
);
562 md_number_to_chars(*where
, header
->s_align
, sizeof(header
->s_align
));
563 *where
+= sizeof(header
->s_align
);
566 #else /* CROSS_COMPILE */
568 append(where
, (char *) header
, SCNHSZ
);
570 #endif /* CROSS_COMPILE */
573 } /* obj_coff_section_header_append() */
576 void obj_emit_symbols(where
, symbol_rootP
)
578 symbolS
*symbol_rootP
;
582 * Emit all symbols left in the symbol chain.
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
;
589 tc_coff_symbol_emit_hook(symbolP
);
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);
596 memset(symbolP
->sy_symbol
.ost_entry
.n_name
, '\0', SYMNMLEN
);
597 strncpy(symbolP
->sy_symbol
.ost_entry
.n_name
, temp
, SYMNMLEN
);
599 obj_symbol_to_chars(where
, symbolP
);
600 S_SET_NAME(symbolP
,temp
);
602 } /* obj_emit_symbols() */
604 /* Merge a debug symbol containing debug information into a normal symbol. */
606 void c_symbol_merge(debug
, normal
)
610 S_SET_DATA_TYPE(normal
, S_GET_DATA_TYPE(debug
));
611 S_SET_STORAGE_CLASS(normal
, S_GET_STORAGE_CLASS(debug
));
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 */
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 */
621 /* Move the debug flags. */
622 SF_SET_DEBUG_FIELD(normal
, SF_GET_DEBUG_FIELD(debug
));
623 } /* c_symbol_merge() */
625 static symbolS
*previous_file_symbol
= NULL
;
627 void c_dot_file_symbol(filename
)
632 symbolP
= symbol_new(".file",
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
);
643 previous_file_symbol
= symbolP
;
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 */
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 */
656 } /* c_dot_file_symbol() */
658 * Build a 'section static' symbol.
661 char *c_section_symbol(name
, value
, length
, nreloc
, nlnno
)
665 unsigned short nreloc
;
666 unsigned short nlnno
;
670 symbolP
= symbol_new(name
,
679 S_SET_STORAGE_CLASS(symbolP
, C_STAT
);
680 S_SET_NUMBER_AUXILIARY(symbolP
, 1);
682 SA_SET_SCN_SCNLEN(symbolP
, length
);
683 SA_SET_SCN_NRELOC(symbolP
, nreloc
);
684 SA_SET_SCN_NLINNO(symbolP
, nlnno
);
686 SF_SET_STATICS(symbolP
);
688 return (char*)symbolP
;
689 } /* c_section_symbol() */
691 void c_section_header(header
,
702 struct internal_scnhdr
*header
;
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
;
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);
728 header
->s_align
= ((alignment
== 0)
731 #endif /* OBJ_COFF_BROKEN_ALIGNMENT */
732 #endif /* OBJ_COFF_SECTION_HEADER_HAS_ALIGNMENT */
734 header
->s_flags
= STYP_REG
| (name
[1] == 't'
742 } /* c_section_header() */
744 /* Line number handling */
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
754 lineno
* lineno_lastP
= (lineno
*)0;
757 c_line_new(paddr
, line_number
, frag
)
759 unsigned short line_number
;
762 lineno
* new_line
= (lineno
*)xmalloc(sizeof(lineno
));
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;
769 if (lineno_rootP
== (lineno
*)0)
770 lineno_rootP
= new_line
;
772 lineno_lastP
->next
= new_line
;
773 lineno_lastP
= new_line
;
774 return LINESZ
* our_lineno_number
++;
777 void obj_emit_lineno(where
, line
, file_start
)
783 struct bfd_internal_lineno
*line_entry
;
787 for (; line
; line
= line
->next
) {
788 line_entry
= &line
->line
;
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. */
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. */
801 symbolP
= (symbolS
*) line_entry
->l_addr
.l_symndx
;
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
;
806 } /* if this is a function linno */
808 *where
+= bfd_coff_swap_lineno_out(stdoutput
, line_entry
, *where
);
810 /* No matter which member of the union we process, they are
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
);
816 md_number_to_chars(*where
, line_entry
->l_lnno
, sizeof(line_entry
->l_lnno
));
817 *where
+= sizeof(line_entry
->l_lnno
);
826 #else /* CROSS_COMPILE */
827 append(where
, (char *) line_entry
, LINESZ
);
828 #endif /* CROSS_COMPILE */
829 #endif /* BFD_HEADERS */
830 } /* for each line number */
833 } /* obj_emit_lineno() */
835 void obj_symbol_new_hook(symbolP
)
838 char underscore
= 0; /* Symbol has leading _ */
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
);
851 #ifdef STRIP_UNDERSCORE
852 /* Remove leading underscore at the beginning of the symbol.
853 * This is to be compatible with the standard librairies.
855 if (*S_GET_NAME(symbolP
) == '_') {
857 S_SET_NAME(symbolP
, S_GET_NAME(symbolP
) + 1);
858 } /* strip underscore */
859 #endif /* STRIP_UNDERSCORE */
861 if (S_IS_STRING(symbolP
))
862 SF_SET_STRING(symbolP
);
863 if (!underscore
&& S_IS_LOCAL(symbolP
))
864 SF_SET_LOCAL(symbolP
);
867 } /* obj_symbol_new_hook() */
870 stack
* stack_init(chunk_size
, element_size
)
871 unsigned long chunk_size
;
872 unsigned long element_size
;
876 if ((st
= (stack
*)malloc(sizeof(stack
))) == (stack
*)0)
878 if ((st
->data
= malloc(chunk_size
)) == (char*)0) {
883 st
->size
= chunk_size
;
884 st
->chunk_size
= chunk_size
;
885 st
->element_size
= element_size
;
889 void stack_delete(st
)
896 char *stack_push(st
, element
)
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)
905 memcpy(st
->data
+ st
->pointer
, element
, st
->element_size
);
906 st
->pointer
+= st
->element_size
;
907 return st
->data
+ st
->pointer
;
913 if ((st
->pointer
-= st
->element_size
) < 0) {
917 return st
->data
+ st
->pointer
;
923 return st
->data
+ st
->pointer
- st
->element_size
;
928 * Handle .ln directives.
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();
936 } /* wrong context */
938 c_line_new(obstack_next_free(&frags
) - frag_now
->fr_literal
,
939 get_absolute_expression(),
942 demand_empty_rest_of_line();
944 } /* obj_coff_line() */
949 * Handle .def directives.
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 :-).
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++;
965 static void obj_coff_def(what
)
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 */
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();
980 } /* if not inside .def/.endef */
984 def_symbol_in_progress
= (symbolS
*) obstack_alloc(¬es
, sizeof(*def_symbol_in_progress
));
985 memset(def_symbol_in_progress
, '\0', sizeof(*def_symbol_in_progress
));
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
);
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
;
1006 if (S_IS_STRING(def_symbol_in_progress
)) {
1007 SF_SET_STRING(def_symbol_in_progress
);
1010 *input_line_pointer
= name_end
;
1012 demand_empty_rest_of_line();
1014 } /* obj_coff_def() */
1016 unsigned int dim_index
;
1017 static void obj_coff_endef() {
1019 /* DIM BUG FIX sac@cygnus.com */
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();
1025 } /* if not inside .def/.endef */
1027 /* Set the section number according to storage class. */
1028 switch (S_GET_STORAGE_CLASS(def_symbol_in_progress
)) {
1032 SF_SET_TAG(def_symbol_in_progress
);
1033 /* intentional fallthrough */
1036 SF_SET_DEBUG(def_symbol_in_progress
);
1037 S_SET_SEGMENT(def_symbol_in_progress
, SEG_DEBUG
);
1041 SF_SET_LOCAL(def_symbol_in_progress
); /* Do not emit this symbol. */
1042 /* intentional fallthrough */
1044 SF_SET_PROCESS(def_symbol_in_progress
); /* Will need processing before writing */
1045 /* intentional fallthrough */
1047 S_SET_SEGMENT(def_symbol_in_progress
, SEG_TEXT
);
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;
1061 #endif /* C_AUTOARG */
1071 SF_SET_DEBUG(def_symbol_in_progress
);
1072 S_SET_SEGMENT(def_symbol_in_progress
, SEG_ABSOLUTE
);
1078 /* Valid but set somewhere else (s_comm, s_lcomm, colon) */
1084 as_warn("unexpected storage class %d", S_GET_STORAGE_CLASS(def_symbol_in_progress
));
1086 } /* switch on storage class */
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. */
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
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. */
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
) {
1114 symbol_append(def_symbol_in_progress
, symbol_lastP
, &symbol_rootP
, &symbol_lastP
);
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
1125 /* The debug entry (def_symbol_in_progress)
1126 is merged into the previous definition. */
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
;
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 */
1142 } /* normal or mergable */
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. */
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
);
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 */
1161 def_symbol_in_progress
= NULL
;
1162 demand_empty_rest_of_line();
1164 } /* obj_coff_endef() */
1166 static void obj_coff_dim()
1168 register int dim_index
;
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();
1174 } /* if not inside .def/.endef */
1176 S_SET_NUMBER_AUXILIARY(def_symbol_in_progress
, 1);
1178 for (dim_index
= 0; dim_index
< DIMNUM
; dim_index
++) {
1180 SA_SET_SYM_DIMEN(def_symbol_in_progress
, dim_index
, get_absolute_expression());
1182 switch (*input_line_pointer
) {
1185 input_line_pointer
++;
1189 as_warn("badly formed .dim directive ignored");
1190 /* intentional fallthrough */
1195 } /* switch on following character */
1196 } /* for each dimension */
1198 demand_empty_rest_of_line();
1200 } /* obj_coff_dim() */
1202 static void obj_coff_line() {
1203 if (def_symbol_in_progress
== NULL
) {
1206 } /* if it looks like a stabs style line */
1208 S_SET_NUMBER_AUXILIARY(def_symbol_in_progress
, 1);
1209 SA_SET_SYM_LNNO(def_symbol_in_progress
, get_absolute_expression());
1211 demand_empty_rest_of_line();
1213 } /* obj_coff_line() */
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();
1220 } /* if not inside .def/.endef */
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();
1226 } /* obj_coff_size() */
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();
1233 } /* if not inside .def/.endef */
1235 S_SET_STORAGE_CLASS(def_symbol_in_progress
, get_absolute_expression());
1236 demand_empty_rest_of_line();
1238 } /* obj_coff_scl() */
1240 static void obj_coff_tag() {
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();
1248 } /* if not inside .def/.endef */
1250 S_SET_NUMBER_AUXILIARY(def_symbol_in_progress
, 1);
1251 symbol_name
= input_line_pointer
;
1252 name_end
= get_symbol_end();
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
);
1261 SF_SET_TAGGED(def_symbol_in_progress
);
1262 *input_line_pointer
= name_end
;
1264 demand_empty_rest_of_line();
1266 } /* obj_coff_tag() */
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();
1273 } /* if not inside .def/.endef */
1275 S_SET_DATA_TYPE(def_symbol_in_progress
, get_absolute_expression());
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 */
1282 demand_empty_rest_of_line();
1284 } /* obj_coff_type() */
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();
1291 } /* if not inside .def/.endef */
1293 if (is_name_beginner(*input_line_pointer
)) {
1294 char *symbol_name
= input_line_pointer
;
1295 char name_end
= get_symbol_end();
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
);
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
);
1309 /* Otherwise, it is the name of a non debug symbol and its value will be calculated later. */
1310 *input_line_pointer
= name_end
;
1312 S_SET_VALUE(def_symbol_in_progress
, get_absolute_expression());
1313 } /* if symbol based */
1315 demand_empty_rest_of_line();
1317 } /* obj_coff_val() */
1320 * Maintain a list of the tagnames of the structres.
1323 static void tag_init() {
1324 tag_hash
= hash_new();
1328 static void tag_insert(name
, symbolP
)
1332 register char * error_string
;
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
);
1339 } /* tag_insert() */
1341 static symbolS
*tag_find_or_make(name
)
1346 if ((symbolP
= tag_find(name
)) == NULL
) {
1347 symbolP
= symbol_new(name
,
1350 &zero_address_frag
);
1352 tag_insert(S_GET_NAME(symbolP
), symbolP
);
1353 symbol_table_insert(symbolP
);
1357 } /* tag_find_or_make() */
1359 static symbolS
*tag_find(name
)
1362 #ifdef STRIP_UNDERSCORE
1363 if (*name
== '_') name
++;
1364 #endif /* STRIP_UNDERSCORE */
1365 return((symbolS
*)hash_find(tag_hash
, name
));
1368 void obj_read_begin_hook() {
1369 /* These had better be the same. Usually 18 bytes. */
1371 know(sizeof(SYMENT
) == sizeof(AUXENT
));
1372 know(SYMESZ
== AUXESZ
);
1377 } /* obj_read_begin_hook() */
1379 void obj_crawl_symbol_chain(headers
)
1380 object_headers
*headers
;
1382 int symbol_number
= 0;
1384 symbolS
*last_functionP
= NULL
;
1387 symbolS
*symbol_externP
= NULL
;
1388 symbolS
*symbol_extern_lastP
= NULL
;
1390 /* Initialize the stack used to keep track of the matching .bb .be */
1391 stack
* block_stack
= stack_init(512, sizeof(symbolS
*));
1393 /* JF deal with forward references first... */
1394 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next(symbolP
)) {
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
));
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 */
1406 symbolP
->sy_forward
=0;
1407 } /* if it has a forward reference */
1408 } /* walk the symbol chain */
1410 tc_crawl_symbol_chain(headers
);
1412 /* The symbol list should be ordered according to the following sequence
1415 * . debug entries for functions
1416 * . fake symbols for .text .data and .bss
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.
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. */
1430 * Build up static symbols for .text, .data and .bss
1432 dot_text_symbol
= (symbolS
*)
1433 c_section_symbol(".text",
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
);
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
);
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
);
1463 verify_symbol_chain(symbol_rootP
, symbol_lastP
);
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
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
1485 for (symbolP
= symbol_rootP
;
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
;
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 */
1513 if (flagseen
['R'] && (S_GET_SEGMENT(symbolP
) == SEG_DATA
)) {
1514 S_SET_SEGMENT(symbolP
, SEG_TEXT
);
1515 } /* push data into text */
1517 S_SET_VALUE(symbolP
, S_GET_VALUE(symbolP
) + symbolP
->sy_frag
->fr_address
);
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
);
1525 S_SET_STORAGE_CLASS(symbolP
, C_STAT
);
1527 } /* no storage class yet */
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
);
1536 register symbolS
* begin_symbolP
;
1537 begin_symbolP
= *(symbolS
**)stack_pop(block_stack
);
1538 if (begin_symbolP
== (symbolS
*)0)
1539 as_warn("mismatched .eb");
1541 SA_SET_SYM_ENDNDX(begin_symbolP
, symbol_number
+2);
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
1548 if (last_functionP
== (symbolS
*)0 &&
1549 SF_GET_FUNCTION(symbolP
)) {
1550 last_functionP
= symbolP
;
1552 if (S_GET_NUMBER_AUXILIARY(symbolP
) < 1) {
1553 S_SET_NUMBER_AUXILIARY(symbolP
, 1);
1554 } /* make it at least 1 */
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
));
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...
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;
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
;
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 */
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
1597 ld will move the symbol 21 to the end of the list but
1598 endndx will still be 22 instead of 21. */
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
);
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
);
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
);
1616 if (SF_GET_STRING(symbolP
)) {
1617 symbolP
->sy_name_offset
= string_byte_count
;
1618 string_byte_count
+= strlen(S_GET_NAME(symbolP
)) + 1;
1620 symbolP
->sy_name_offset
= 0;
1621 } /* fix "long" names */
1623 symbolP
->sy_number
= symbol_number
;
1624 symbol_number
+= 1 + S_GET_NUMBER_AUXILIARY(symbolP
);
1625 } /* if local symbol */
1626 } /* traverse the symbol list */
1628 for (symbolP
= symbol_externP
; symbol_externP
;) {
1629 symbolS
*tmp
= symbol_externP
;
1632 symbol_remove(tmp
, &symbol_externP
, &symbol_extern_lastP
);
1633 symbol_append(tmp
, symbol_lastP
, &symbol_rootP
, &symbol_lastP
);
1636 if (SF_GET_STRING(tmp
)) {
1637 tmp
->sy_name_offset
= string_byte_count
;
1638 string_byte_count
+= strlen(S_GET_NAME(tmp
)) + 1;
1640 tmp
->sy_name_offset
= 0;
1641 } /* fix "long" names */
1643 tmp
->sy_number
= symbol_number
;
1644 symbol_number
+= 1 + S_GET_NUMBER_AUXILIARY(tmp
);
1645 } /* append the entire extern chain */
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. */
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 */
1658 know(symbol_externP
== NULL
);
1659 know(symbol_extern_lastP
== NULL
);
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. */
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
;
1673 text_lineno_number
++;
1674 } /* for each line number */
1676 H_SET_SYMBOL_TABLE_SIZE(headers
, symbol_number
);
1679 } /* obj_crawl_symbol_chain() */
1682 * Find strings by crawling along symbol table chain.
1685 void obj_emit_strings(where
)
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 */
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 */
1705 } /* obj_emit_strings() */
1707 void obj_pre_write_hook(headers
)
1708 object_headers
*headers
;
1710 register int text_relocation_number
= 0;
1711 register int data_relocation_number
= 0;
1712 register fixS
*fixP
;
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
;
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 */
1728 /* Count 2 for a constH */
1729 if (fixP
->fx_r_type
== RELOC_CONSTH
) {
1730 ++text_relocation_number
;
1734 } /* if not yet fixed */
1735 } /* for each fix */
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
));
1743 for (fixP
= data_fix_root
; fixP
; fixP
= fixP
->fx_next
) {
1744 if (fixP
->fx_addsy
) {
1745 ++data_relocation_number
;
1746 } /* if still relocatable */
1748 /* Count 2 for a constH */
1749 if (fixP
->fx_r_type
== RELOC_CONSTH
) {
1750 ++data_relocation_number
;
1754 } /* for each fix */
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
));
1761 /* Assign the size of the section */
1762 SA_SET_SCN_SCNLEN(dot_bss_symbol
, H_GET_BSS_SIZE(headers
));
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
;
1770 /* Fill in extra coff fields */
1772 /* Initialize general line number information. */
1773 H_SET_LINENO_SIZE(headers
, text_lineno_number
* LINESZ
);
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
));
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
));
1793 /* symbol table size allready set */
1794 H_SET_SIZEOF_OPTIONAL_HEADER(headers
, OBJ_COFF_AOUTHDRSZ
);
1796 /* do not added the F_RELFLG for the standard COFF.
1797 * The AIX linker complain on file with relocation info striped flag.
1799 #ifdef KEEP_RELOC_INFO
1800 H_SET_FLAGS(headers
, (text_lineno_number
== 0 ? F_LNNO
: 0)
1803 H_SET_FLAGS(headers
, (text_lineno_number
== 0 ? F_LNNO
: 0)
1804 | ((text_relocation_number
+ data_relocation_number
) ? 0 : F_RELFLG
)
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 */
1812 /* Build section headers */
1814 c_section_header(&text_section_header
,
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
)
1823 ? H_GET_LINENO_FILE_OFFSET(headers
)
1825 SA_GET_SCN_NRELOC(dot_text_symbol
),
1827 section_alignment
[(int) SEG_TEXT
]);
1829 c_section_header(&data_section_header
,
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
)
1836 (SA_GET_SCN_NRELOC(dot_data_symbol
)
1837 ? (H_GET_RELOCATION_FILE_OFFSET(headers
)
1838 + text_section_header
.s_nreloc
* RELSZ
)
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
]);
1845 c_section_header(&bss_section_header
,
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
]);
1857 } /* obj_pre_write_hook() */
1859 /* This is a copy from aout. All I do is neglect to actually build the symbol. */
1861 static void obj_coff_stab(what
)
1866 int goof
= 0; /* TRUE if we have aborted. */
1870 symbolS
*symbolP
= 0;
1873 string
= demand_copy_C_string(&length
);
1876 if (*input_line_pointer
== ',') {
1877 input_line_pointer
++;
1879 as_bad("I need a comma after symbol's name");
1881 } /* better be a comma */
1882 } /* skip the string */
1885 * Input_line_pointer->after ','. String->symbol name.
1888 if (get_absolute_expression_and_terminator(&longint
) != ',') {
1889 as_bad("I want a comma after the n_type expression");
1891 input_line_pointer
--; /* Backup over a non-',' char. */
1896 if (get_absolute_expression_and_terminator(&longint
) != ',') {
1897 as_bad("I want a comma after the n_other expression");
1899 input_line_pointer
--; /* Backup over a non-',' char. */
1904 get_absolute_expression();
1906 if (what
== 's' || what
== 'n') {
1907 if (*input_line_pointer
!= ',') {
1908 as_bad("I want a comma after the n_desc expression");
1911 input_line_pointer
++;
1919 ignore_rest_of_line();
1921 demand_empty_rest_of_line();
1923 } /* obj_coff_stab() */
1930 return((s
== NULL
) ? "(NULL)" : S_GET_NAME(s
));
1931 } /* s_get_name() */
1933 void symbol_dump() {
1936 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next(symbolP
)) {
1937 printf("%3ld: 0x%lx \"%s\" type = %ld, class = %d, segment = %d\n",
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 */
1947 } /* symbol_dump() */
1958 /* end of obj-coff.c */