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
;
172 * Crawl along a fixS chain. Emit the segment's relocations.
175 void obj_emit_relocations(where
, fixP
, segment_address_in_file
)
177 fixS
*fixP
; /* Fixup chain for this segment. */
178 relax_addressT segment_address_in_file
;
181 struct internal_reloc ri
;
187 bzero((char *)&ri
,sizeof(ri
));
188 for (; fixP
; fixP
= fixP
->fx_next
) {
189 if (symbolP
= fixP
->fx_addsy
) {
191 ri
.r_type
= (fixP
->fx_pcrel
?
192 (fixP
->fx_size
== 1 ? R_PCRBYTE
:
193 fixP
->fx_size
== 2 ? R_PCRWORD
:
195 (fixP
->fx_size
== 1 ? R_RELBYTE
:
196 fixP
->fx_size
== 2 ? R_RELWORD
:
198 #elif defined(TC_I386)
199 /* FIXME-SOON R_OFF8 & R_DIR16 are a vague guess, completly untested. */
200 ri
.r_type
= (fixP
->fx_pcrel
?
201 (fixP
->fx_size
== 1 ? R_PCRBYTE
:
202 fixP
->fx_size
== 2 ? R_PCRWORD
:
204 (fixP
->fx_size
== 1 ? R_OFF8
:
205 fixP
->fx_size
== 2 ? R_DIR16
:
207 #elif defined(TC_I960)
208 ri
.r_type
= (fixP
->fx_pcrel
211 #elif defined(TC_A29K)
212 ri
.r_type
= tc_coff_fix2rtype(fixP
);
216 #endif /* TC_M68K || TC_I386 */
217 ri
.r_vaddr
= fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
218 /* If symbol associated to relocation entry is a bss symbol
219 or undefined symbol just remember the index of the symbol.
220 Otherwise store the index of the symbol describing the
221 section the symbol belong to. This heuristic speeds up ld.
223 /* Local symbols can generate relocation information. In case
224 of structure return for instance. But they have no symbol
225 number because they won't be emitted in the final object.
226 In the case where they are in the BSS section, this leads
227 to an incorrect r_symndx.
228 Under bsd the loader do not care if the symbol reference is
229 incorrect. But the SYS V ld complains about this. To avoid
230 this we associate the symbol to the associated section,
231 *even* if it is the BSS section. */
232 /* If someone can tell me why the other symbols of the bss
233 section are not associated with the .bss section entry,
234 I'd be gratefull. I guess that it has to do with the special
235 nature of the .bss section. Or maybe this is because the
236 bss symbols are declared in the common section and can
237 be resized later. Can it break code some where ? */
238 ri
.r_symndx
= (S_GET_SEGMENT(symbolP
) == SEG_TEXT
239 ? dot_text_symbol
->sy_number
240 : (S_GET_SEGMENT(symbolP
) == SEG_DATA
241 ? dot_data_symbol
->sy_number
242 : ((SF_GET_LOCAL(symbolP
)
243 ? dot_bss_symbol
->sy_number
244 : symbolP
->sy_number
)))); /* bss or undefined */
246 /* md_ri_to_chars((char *) &ri, ri); */ /* Last step : write md f */
250 *where
+= bfd_coff_swap_reloc_out(stdoutput
, &ri
, *where
);
252 /* The 29k has a special kludge for the high 16 bit reloc.
253 Two relocations are emmited, R_IHIHALF, and R_IHCONST. The second one
254 doesn't contain a symbol, but uses the value for offset */
255 if (ri
.r_type
== R_IHIHALF
) {
256 /* now emit the second bit */
257 ri
.r_type
= R_IHCONST
;
258 ri
.r_symndx
= fixP
->fx_addnumber
;
259 *where
+= bfd_coff_swap_reloc_out(stdoutput
, &ri
, *where
);
265 append(where
, (char *) &ri
, sizeof(ri
));
269 if (fixP
->fx_callj
) {
270 ri
.r_type
= R_OPTCALL
;
272 *where
+= bfd_coff_swap_reloc_out(stdoutput
, &ri
, *where
);
274 append(where
, (char *) &ri
, sizeof(ri
));
278 } /* if it's a callj, do it again for the opcode */
281 } /* if there's a symbol */
282 } /* for each fixP */
285 } /* obj_emit_relocations() */
287 /* Coff file generation & utilities */
290 void obj_header_append(where
, headers
)
292 object_headers
*headers
;
294 tc_headers_hook(headers
);
295 *where
+= bfd_coff_swap_filehdr_out(stdoutput
, &(headers
->filehdr
), *where
);
296 #ifndef OBJ_COFF_OMIT_OPTIONAL_HEADER
297 *where
+= bfd_coff_swap_aouthdr_out(stdoutput
, &(headers
->aouthdr
), *where
);
299 obj_coff_section_header_append(where
, &text_section_header
);
300 obj_coff_section_header_append(where
, &data_section_header
);
301 obj_coff_section_header_append(where
, &bss_section_header
);
307 void obj_header_append(where
, headers
)
309 object_headers
*headers
;
311 tc_headers_hook(headers
);
314 /* Eventually swap bytes for cross compilation for file header */
315 md_number_to_chars(*where
, headers
->filehdr
.f_magic
, sizeof(headers
->filehdr
.f_magic
));
316 *where
+= sizeof(headers
->filehdr
.f_magic
);
317 md_number_to_chars(*where
, headers
->filehdr
.f_nscns
, sizeof(headers
->filehdr
.f_nscns
));
318 *where
+= sizeof(headers
->filehdr
.f_nscns
);
319 md_number_to_chars(*where
, headers
->filehdr
.f_timdat
, sizeof(headers
->filehdr
.f_timdat
));
320 *where
+= sizeof(headers
->filehdr
.f_timdat
);
321 md_number_to_chars(*where
, headers
->filehdr
.f_symptr
, sizeof(headers
->filehdr
.f_symptr
));
322 *where
+= sizeof(headers
->filehdr
.f_symptr
);
323 md_number_to_chars(*where
, headers
->filehdr
.f_nsyms
, sizeof(headers
->filehdr
.f_nsyms
));
324 *where
+= sizeof(headers
->filehdr
.f_nsyms
);
325 md_number_to_chars(*where
, headers
->filehdr
.f_opthdr
, sizeof(headers
->filehdr
.f_opthdr
));
326 *where
+= sizeof(headers
->filehdr
.f_opthdr
);
327 md_number_to_chars(*where
, headers
->filehdr
.f_flags
, sizeof(headers
->filehdr
.f_flags
));
328 *where
+= sizeof(headers
->filehdr
.f_flags
);
330 #ifndef OBJ_COFF_OMIT_OPTIONAL_HEADER
331 /* Eventually swap bytes for cross compilation for a.out header */
332 md_number_to_chars(*where
, headers
->aouthdr
.magic
, sizeof(headers
->aouthdr
.magic
));
333 *where
+= sizeof(headers
->aouthdr
.magic
);
334 md_number_to_chars(*where
, headers
->aouthdr
.vstamp
, sizeof(headers
->aouthdr
.vstamp
));
335 *where
+= sizeof(headers
->aouthdr
.vstamp
);
336 md_number_to_chars(*where
, headers
->aouthdr
.tsize
, sizeof(headers
->aouthdr
.tsize
));
337 *where
+= sizeof(headers
->aouthdr
.tsize
);
338 md_number_to_chars(*where
, headers
->aouthdr
.dsize
, sizeof(headers
->aouthdr
.dsize
));
339 *where
+= sizeof(headers
->aouthdr
.dsize
);
340 md_number_to_chars(*where
, headers
->aouthdr
.bsize
, sizeof(headers
->aouthdr
.bsize
));
341 *where
+= sizeof(headers
->aouthdr
.bsize
);
342 md_number_to_chars(*where
, headers
->aouthdr
.entry
, sizeof(headers
->aouthdr
.entry
));
343 *where
+= sizeof(headers
->aouthdr
.entry
);
344 md_number_to_chars(*where
, headers
->aouthdr
.text_start
, sizeof(headers
->aouthdr
.text_start
));
345 *where
+= sizeof(headers
->aouthdr
.text_start
);
346 md_number_to_chars(*where
, headers
->aouthdr
.data_start
, sizeof(headers
->aouthdr
.data_start
));
347 *where
+= sizeof(headers
->aouthdr
.data_start
);
348 md_number_to_chars(*where
, headers
->aouthdr
.tagentries
, sizeof(headers
->aouthdr
.tagentries
));
349 *where
+= sizeof(headers
->aouthdr
.tagentries
);
350 #endif /* OBJ_COFF_OMIT_OPTIONAL_HEADER */
352 #else /* CROSS_COMPILE */
354 append(where
, (char *) &headers
->filehdr
, sizeof(headers
->filehdr
));
355 #ifndef OBJ_COFF_OMIT_OPTIONAL_HEADER
356 append(where
, (char *) &headers
->aouthdr
, sizeof(headers
->aouthdr
));
357 #endif /* OBJ_COFF_OMIT_OPTIONAL_HEADER */
359 #endif /* CROSS_COMPILE */
361 /* Output the section headers */
362 obj_coff_section_header_append(where
, &text_section_header
);
363 obj_coff_section_header_append(where
, &data_section_header
);
364 obj_coff_section_header_append(where
, &bss_section_header
);
367 } /* obj_header_append() */
369 void obj_symbol_to_chars(where
, symbolP
)
374 unsigned int numaux
= symbolP
->sy_symbol
.ost_entry
.n_numaux
;
377 if (S_GET_SEGMENT(symbolP
) == SEG_REGISTER
) {
378 S_SET_SEGMENT(symbolP
, SEG_ABSOLUTE
);
380 *where
+= bfd_coff_swap_sym_out(stdoutput
, &symbolP
->sy_symbol
.ost_entry
,
383 for (i
= 0; i
< numaux
; i
++)
385 *where
+= bfd_coff_swap_aux_out(stdoutput
,
386 &symbolP
->sy_symbol
.ost_auxent
[i
],
387 S_GET_DATA_TYPE(symbolP
),
388 S_GET_STORAGE_CLASS(symbolP
),
392 #else /* BFD_HEADERS */
393 SYMENT
*syment
= &symbolP
->sy_symbol
.ost_entry
;
395 char numaux
= syment
->n_numaux
;
396 unsigned short type
= S_GET_DATA_TYPE(symbolP
);
399 md_number_to_chars(*where
, syment
->n_value
, sizeof(syment
->n_value
));
400 *where
+= sizeof(syment
->n_value
);
401 md_number_to_chars(*where
, syment
->n_scnum
, sizeof(syment
->n_scnum
));
402 *where
+= sizeof(syment
->n_scnum
);
403 md_number_to_chars(*where
, 0, sizeof(short)); /* pad n_flags */
404 *where
+= sizeof(short);
405 md_number_to_chars(*where
, syment
->n_type
, sizeof(syment
->n_type
));
406 *where
+= sizeof(syment
->n_type
);
407 md_number_to_chars(*where
, syment
->n_sclass
, sizeof(syment
->n_sclass
));
408 *where
+= sizeof(syment
->n_sclass
);
409 md_number_to_chars(*where
, syment
->n_numaux
, sizeof(syment
->n_numaux
));
410 *where
+= sizeof(syment
->n_numaux
);
411 #else /* CROSS_COMPILE */
412 append(where
, (char *) syment
, sizeof(*syment
));
413 #endif /* CROSS_COMPILE */
415 /* Should do the following : if (.file entry) MD(..)... else if (static entry) MD(..) */
416 if (numaux
> OBJ_COFF_MAX_AUXENTRIES
) {
417 as_bad("Internal error? too many auxents for symbol");
418 } /* too many auxents */
420 for (i
= 0; i
< numaux
; ++i
) {
422 #if 0 /* This code has never been tested */
423 /* The most common case, x_sym entry. */
424 if ((SF_GET(symbolP
) & (SF_FILE
| SF_STATICS
)) == 0) {
425 md_number_to_chars(*where
, auxP
->x_sym
.x_tagndx
, sizeof(auxP
->x_sym
.x_tagndx
));
426 *where
+= sizeof(auxP
->x_sym
.x_tagndx
);
428 md_number_to_chars(*where
, auxP
->x_sym
.x_misc
.x_fsize
, sizeof(auxP
->x_sym
.x_misc
.x_fsize
));
429 *where
+= sizeof(auxP
->x_sym
.x_misc
.x_fsize
);
431 md_number_to_chars(*where
, auxP
->x_sym
.x_misc
.x_lnno
, sizeof(auxP
->x_sym
.x_misc
.x_lnno
));
432 *where
+= sizeof(auxP
->x_sym
.x_misc
.x_lnno
);
433 md_number_to_chars(*where
, auxP
->x_sym
.x_misc
.x_size
, sizeof(auxP
->x_sym
.x_misc
.x_size
));
434 *where
+= sizeof(auxP
->x_sym
.x_misc
.x_size
);
438 for (index
= 0; index
< DIMNUM
; index
++)
439 md_number_to_chars(*where
, auxP
->x_sym
.x_fcnary
.x_ary
.x_dimen
[index
], sizeof(auxP
->x_sym
.x_fcnary
.x_ary
.x_dimen
[index
]));
440 *where
+= sizeof(auxP
->x_sym
.x_fcnary
.x_ary
.x_dimen
[index
]);
442 md_number_to_chars(*where
, auxP
->x_sym
.x_fcnary
.x_fcn
.x_lnnoptr
, sizeof(auxP
->x_sym
.x_fcnary
.x_fcn
.x_lnnoptr
));
443 *where
+= sizeof(auxP
->x_sym
.x_fcnary
.x_fcn
.x_lnnoptr
);
444 md_number_to_chars(*where
, auxP
->x_sym
.x_fcnary
.x_fcn
.x_endndx
, sizeof(auxP
->x_sym
.x_fcnary
.x_fcn
.x_endndx
));
445 *where
+= sizeof(auxP
->x_sym
.x_fcnary
.x_fcn
.x_endndx
);
447 md_number_to_chars(*where
, auxP
->x_sym
.x_tvndx
, sizeof(auxP
->x_sym
.x_tvndx
));
448 *where
+= sizeof(auxP
->x_sym
.x_tvndx
);
449 } else if (SF_GET_FILE(symbolP
)) { /* .file */
451 } else if (SF_GET_STATICS(symbolP
)) { /* .text, .data, .bss symbols */
452 md_number_to_chars(*where
, auxP
->x_scn
.x_scnlen
, sizeof(auxP
->x_scn
.x_scnlen
));
453 *where
+= sizeof(auxP
->x_scn
.x_scnlen
);
454 md_number_to_chars(*where
, auxP
->x_scn
.x_nreloc
, sizeof(auxP
->x_scn
.x_nreloc
));
455 *where
+= sizeof(auxP
->x_scn
.x_nreloc
);
456 md_number_to_chars(*where
, auxP
->x_scn
.x_nlinno
, sizeof(auxP
->x_scn
.x_nlinno
));
457 *where
+= sizeof(auxP
->x_scn
.x_nlinno
);
460 #else /* CROSS_COMPILE */
461 append(where
, (char *) &symbolP
->sy_symbol
.ost_auxent
[i
], sizeof(symbolP
->sy_symbol
.ost_auxent
[i
]));
462 #endif /* CROSS_COMPILE */
464 }; /* for each aux in use */
465 #endif /* BFD_HEADERS */
467 } /* obj_symbol_to_chars() */
470 static void obj_coff_section_header_append(where
, header
)
472 struct internal_scnhdr
*header
;
474 *where
+= bfd_coff_swap_scnhdr_out(stdoutput
, header
, *where
);
477 static void obj_coff_section_header_append(where
, header
)
482 memcpy(*where
, header
->s_name
, sizeof(header
->s_name
));
483 *where
+= sizeof(header
->s_name
);
485 md_number_to_chars(*where
, header
->s_paddr
, sizeof(header
->s_paddr
));
486 *where
+= sizeof(header
->s_paddr
);
488 md_number_to_chars(*where
, header
->s_vaddr
, sizeof(header
->s_vaddr
));
489 *where
+= sizeof(header
->s_vaddr
);
491 md_number_to_chars(*where
, header
->s_size
, sizeof(header
->s_size
));
492 *where
+= sizeof(header
->s_size
);
494 md_number_to_chars(*where
, header
->s_scnptr
, sizeof(header
->s_scnptr
));
495 *where
+= sizeof(header
->s_scnptr
);
497 md_number_to_chars(*where
, header
->s_relptr
, sizeof(header
->s_relptr
));
498 *where
+= sizeof(header
->s_relptr
);
500 md_number_to_chars(*where
, header
->s_lnnoptr
, sizeof(header
->s_lnnoptr
));
501 *where
+= sizeof(header
->s_lnnoptr
);
503 md_number_to_chars(*where
, header
->s_nreloc
, sizeof(header
->s_nreloc
));
504 *where
+= sizeof(header
->s_nreloc
);
506 md_number_to_chars(*where
, header
->s_nlnno
, sizeof(header
->s_nlnno
));
507 *where
+= sizeof(header
->s_nlnno
);
509 md_number_to_chars(*where
, header
->s_flags
, sizeof(header
->s_flags
));
510 *where
+= sizeof(header
->s_flags
);
513 md_number_to_chars(*where
, header
->s_align
, sizeof(header
->s_align
));
514 *where
+= sizeof(header
->s_align
);
517 #else /* CROSS_COMPILE */
519 append(where
, (char *) header
, sizeof(*header
));
521 #endif /* CROSS_COMPILE */
524 } /* obj_coff_section_header_append() */
527 void obj_emit_symbols(where
, symbol_rootP
)
529 symbolS
*symbol_rootP
;
533 * Emit all symbols left in the symbol chain.
535 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next(symbolP
)) {
536 /* Used to save the offset of the name. It is used to point
537 to the string in memory but must be a file offset. */
538 register char * temp
;
540 tc_coff_symbol_emit_hook(symbolP
);
542 temp
= S_GET_NAME(symbolP
);
543 if (SF_GET_STRING(symbolP
)) {
544 S_SET_OFFSET(symbolP
, symbolP
->sy_name_offset
);
545 S_SET_ZEROES(symbolP
, 0);
547 bzero(symbolP
->sy_symbol
.ost_entry
.n_name
, SYMNMLEN
);
548 strncpy(symbolP
->sy_symbol
.ost_entry
.n_name
, temp
, SYMNMLEN
);
550 obj_symbol_to_chars(where
, symbolP
);
551 S_SET_NAME(symbolP
,temp
);
553 } /* obj_emit_symbols() */
555 /* Merge a debug symbol containing debug information into a normal symbol. */
557 void c_symbol_merge(debug
, normal
)
561 S_SET_DATA_TYPE(normal
, S_GET_DATA_TYPE(debug
));
562 S_SET_STORAGE_CLASS(normal
, S_GET_STORAGE_CLASS(debug
));
564 if (S_GET_NUMBER_AUXILIARY(debug
) > S_GET_NUMBER_AUXILIARY(normal
)) {
565 S_SET_NUMBER_AUXILIARY(normal
, S_GET_NUMBER_AUXILIARY(debug
));
566 } /* take the most we have */
568 if (S_GET_NUMBER_AUXILIARY(debug
) > 0) {
569 memcpy((char*)&normal
->sy_symbol
.ost_auxent
[0], (char*)&debug
->sy_symbol
.ost_auxent
[0], S_GET_NUMBER_AUXILIARY(debug
) * AUXESZ
);
570 } /* Move all the auxiliary information */
572 /* Move the debug flags. */
573 SF_SET_DEBUG_FIELD(normal
, SF_GET_DEBUG_FIELD(debug
));
574 } /* c_symbol_merge() */
576 static symbolS
*previous_file_symbol
= NULL
;
578 void c_dot_file_symbol(filename
)
583 symbolP
= symbol_new(".file",
588 S_SET_STORAGE_CLASS(symbolP
, C_FILE
);
589 S_SET_NUMBER_AUXILIARY(symbolP
, 1);
590 SA_SET_FILE_FNAME(symbolP
, filename
);
591 SF_SET_DEBUG(symbolP
);
592 S_SET_VALUE(symbolP
, (long) previous_file_symbol
);
594 previous_file_symbol
= symbolP
;
596 /* Make sure that the symbol is first on the symbol chain */
597 if (symbol_rootP
!= symbolP
) {
598 if (symbolP
== symbol_lastP
) {
599 symbol_lastP
= symbol_lastP
->sy_previous
;
600 } /* if it was the last thing on the list */
602 symbol_remove(symbolP
, &symbol_rootP
, &symbol_lastP
);
603 symbol_insert(symbolP
, symbol_rootP
, &symbol_rootP
, &symbol_lastP
);
604 symbol_rootP
= symbolP
;
605 } /* if not first on the list */
607 } /* c_dot_file_symbol() */
609 * Build a 'section static' symbol.
612 char *c_section_symbol(name
, value
, length
, nreloc
, nlnno
)
616 unsigned short nreloc
;
617 unsigned short nlnno
;
621 symbolP
= symbol_new(name
,
630 S_SET_STORAGE_CLASS(symbolP
, C_STAT
);
631 S_SET_NUMBER_AUXILIARY(symbolP
, 1);
633 SA_SET_SCN_SCNLEN(symbolP
, length
);
634 SA_SET_SCN_NRELOC(symbolP
, nreloc
);
635 SA_SET_SCN_NLINNO(symbolP
, nlnno
);
637 SF_SET_STATICS(symbolP
);
639 return (char*)symbolP
;
640 } /* c_section_symbol() */
642 void c_section_header(header
,
653 struct internal_scnhdr
*header
;
667 strncpy(header
->s_name
, name
, 8);
668 header
->s_paddr
= header
->s_vaddr
= core_address
;
669 header
->s_scnptr
= ((header
->s_size
= size
) != 0) ? data_ptr
: 0;
670 header
->s_relptr
= reloc_ptr
;
671 header
->s_lnnoptr
= lineno_ptr
;
672 header
->s_nreloc
= reloc_number
;
673 header
->s_nlnno
= lineno_number
;
675 #ifdef OBJ_COFF_SECTION_HEADER_HAS_ALIGNMENT
676 #ifdef OBJ_COFF_BROKEN_ALIGNMENT
677 header
->s_align
= ((name
[1] == 'b' || (size
> 0)) ? 16 : 0);
679 header
->s_align
= ((alignment
== 0)
682 #endif /* OBJ_COFF_BROKEN_ALIGNMENT */
683 #endif /* OBJ_COFF_SECTION_HEADER_HAS_ALIGNMENT */
685 header
->s_flags
= STYP_REG
| (name
[1] == 't'
693 } /* c_section_header() */
695 /* Line number handling */
697 int function_lineoff
= -1; /* Offset in line#s where the last function
698 started (the odd entry for line #0) */
699 int text_lineno_number
= 0;
700 int our_lineno_number
= 0; /* we use this to build pointers from .bf's
701 into the linetable. It should match
702 exactly the values that are later
703 assigned in text_lineno_number by
705 lineno
* lineno_lastP
= (lineno
*)0;
708 c_line_new(paddr
, line_number
, frag
)
710 unsigned short line_number
;
713 lineno
* new_line
= (lineno
*)xmalloc(sizeof(lineno
));
715 new_line
->line
.l_addr
.l_paddr
= paddr
;
716 new_line
->line
.l_lnno
= line_number
;
717 new_line
->frag
= (char*)frag
;
718 new_line
->next
= (lineno
*)0;
720 if (lineno_rootP
== (lineno
*)0)
721 lineno_rootP
= new_line
;
723 lineno_lastP
->next
= new_line
;
724 lineno_lastP
= new_line
;
725 return LINESZ
* our_lineno_number
++;
728 void obj_emit_lineno(where
, line
, file_start
)
734 struct bfd_internal_lineno
*line_entry
;
738 for (; line
; line
= line
->next
) {
739 line_entry
= &line
->line
;
741 /* FIXME-SOMEDAY Resolving the sy_number of function linno's used to be done in
742 write_object_file() but their symbols need a fileptr to the lnno, so
743 I moved this resolution check here. xoxorich. */
745 if (line_entry
->l_lnno
== 0) {
746 /* There is a good chance that the symbol pointed to
747 is not the one that will be emitted and that the
748 sy_number is not accurate. */
752 symbolP
= (symbolS
*) line_entry
->l_addr
.l_symndx
;
754 line_entry
->l_addr
.l_symndx
= symbolP
->sy_number
;
755 symbolP
->sy_symbol
.ost_auxent
[0].x_sym
.x_fcnary
.x_fcn
.x_lnnoptr
= *where
- file_start
;
757 } /* if this is a function linno */
759 *where
+= bfd_coff_swap_lineno_out(stdoutput
, line_entry
, *where
);
761 /* No matter which member of the union we process, they are
764 md_number_to_chars(*where
, line_entry
->l_addr
.l_paddr
, sizeof(line_entry
->l_addr
.l_paddr
));
765 *where
+= sizeof(line_entry
->l_addr
.l_paddr
);
767 md_number_to_chars(*where
, line_entry
->l_lnno
, sizeof(line_entry
->l_lnno
));
768 *where
+= sizeof(line_entry
->l_lnno
);
777 #else /* CROSS_COMPILE */
778 append(where
, (char *) line_entry
, LINESZ
);
779 #endif /* CROSS_COMPILE */
780 #endif /* BFD_HEADERS */
781 } /* for each line number */
784 } /* obj_emit_lineno() */
786 void obj_symbol_new_hook(symbolP
)
789 char underscore
= 0; /* Symbol has leading _ */
791 /* Effective symbol */
792 /* Store the pointer in the offset. */
793 S_SET_ZEROES(symbolP
, 0L);
794 S_SET_DATA_TYPE(symbolP
, T_NULL
);
795 S_SET_STORAGE_CLASS(symbolP
, 0);
796 S_SET_NUMBER_AUXILIARY(symbolP
, 0);
797 /* Additional information */
798 symbolP
->sy_symbol
.ost_flags
= 0;
799 /* Auxiliary entries */
800 bzero((char*)&symbolP
->sy_symbol
.ost_auxent
[0], AUXESZ
);
802 #ifdef STRIP_UNDERSCORE
803 /* Remove leading underscore at the beginning of the symbol.
804 * This is to be compatible with the standard librairies.
806 if (*S_GET_NAME(symbolP
) == '_') {
808 S_SET_NAME(symbolP
, S_GET_NAME(symbolP
) + 1);
809 } /* strip underscore */
810 #endif /* STRIP_UNDERSCORE */
812 if (S_IS_STRING(symbolP
))
813 SF_SET_STRING(symbolP
);
814 if (!underscore
&& S_IS_LOCAL(symbolP
))
815 SF_SET_LOCAL(symbolP
);
818 } /* obj_symbol_new_hook() */
821 stack
* stack_init(chunk_size
, element_size
)
822 unsigned long chunk_size
;
823 unsigned long element_size
;
827 if ((st
= (stack
*)malloc(sizeof(stack
))) == (stack
*)0)
829 if ((st
->data
= malloc(chunk_size
)) == (char*)0) {
834 st
->size
= chunk_size
;
835 st
->chunk_size
= chunk_size
;
836 st
->element_size
= element_size
;
840 void stack_delete(st
)
847 char *stack_push(st
, element
)
851 if (st
->pointer
+ st
->element_size
>= st
->size
) {
852 st
->size
+= st
->chunk_size
;
853 if ((st
->data
= xrealloc(st
->data
, st
->size
)) == (char*)0)
856 memcpy(st
->data
+ st
->pointer
, element
, st
->element_size
);
857 st
->pointer
+= st
->element_size
;
858 return st
->data
+ st
->pointer
;
864 if ((st
->pointer
-= st
->element_size
) < 0) {
868 return st
->data
+ st
->pointer
;
874 return st
->data
+ st
->pointer
- st
->element_size
;
879 * Handle .ln directives.
882 static void obj_coff_ln() {
883 if (def_symbol_in_progress
!= NULL
) {
884 as_warn(".ln pseudo-op inside .def/.endef: ignored.");
885 demand_empty_rest_of_line();
887 } /* wrong context */
889 c_line_new(obstack_next_free(&frags
) - frag_now
->fr_literal
,
890 get_absolute_expression(),
893 demand_empty_rest_of_line();
895 } /* obj_coff_line() */
900 * Handle .def directives.
902 * One might ask : why can't we symbol_new if the symbol does not
903 * already exist and fill it with debug information. Because of
904 * the C_EFCN special symbol. It would clobber the value of the
905 * function symbol before we have a chance to notice that it is
906 * a C_EFCN. And a second reason is that the code is more clear this
907 * way. (at least I think it is :-).
911 #define SKIP_SEMI_COLON() while (*input_line_pointer++ != ';')
912 #define SKIP_WHITESPACES() while (*input_line_pointer == ' ' || \
913 *input_line_pointer == '\t') \
914 input_line_pointer++;
916 static void obj_coff_def(what
)
919 char name_end
; /* Char after the end of name */
920 char *symbol_name
; /* Name of the debug symbol */
921 char *symbol_name_copy
; /* Temporary copy of the name */
922 unsigned int symbol_name_length
;
923 /*$char* directiveP;$ */ /* Name of the pseudo opcode */
924 /*$char directive[MAX_DIRECTIVE];$ */ /* Backup of the directive */
925 /*$char end = 0;$ */ /* If 1, stop parsing */
927 if (def_symbol_in_progress
!= NULL
) {
928 as_warn(".def pseudo-op used inside of .def/.endef: ignored.");
929 demand_empty_rest_of_line();
931 } /* if not inside .def/.endef */
935 def_symbol_in_progress
= (symbolS
*) obstack_alloc(¬es
, sizeof(*def_symbol_in_progress
));
936 bzero(def_symbol_in_progress
, sizeof(*def_symbol_in_progress
));
938 symbol_name
= input_line_pointer
;
939 name_end
= get_symbol_end();
940 symbol_name_length
= strlen(symbol_name
);
941 symbol_name_copy
= xmalloc(symbol_name_length
+ 1);
942 strcpy(symbol_name_copy
, symbol_name
);
944 /* Initialize the new symbol */
945 #ifdef STRIP_UNDERSCORE
946 S_SET_NAME(def_symbol_in_progress
, (*symbol_name_copy
== '_'
947 ? symbol_name_copy
+ 1
948 : symbol_name_copy
));
949 #else /* STRIP_UNDERSCORE */
950 S_SET_NAME(def_symbol_in_progress
, symbol_name_copy
);
951 #endif /* STRIP_UNDERSCORE */
952 /* free(symbol_name_copy); */
953 def_symbol_in_progress
->sy_name_offset
= ~0;
954 def_symbol_in_progress
->sy_number
= ~0;
955 def_symbol_in_progress
->sy_frag
= &zero_address_frag
;
957 if (S_IS_STRING(def_symbol_in_progress
)) {
958 SF_SET_STRING(def_symbol_in_progress
);
961 *input_line_pointer
= name_end
;
963 demand_empty_rest_of_line();
965 } /* obj_coff_def() */
967 unsigned int dim_index
;
968 static void obj_coff_endef() {
970 /* DIM BUG FIX sac@cygnus.com */
972 if (def_symbol_in_progress
== NULL
) {
973 as_warn(".endef pseudo-op used outside of .def/.endef: ignored.");
974 demand_empty_rest_of_line();
976 } /* if not inside .def/.endef */
978 /* Set the section number according to storage class. */
979 switch (S_GET_STORAGE_CLASS(def_symbol_in_progress
)) {
983 SF_SET_TAG(def_symbol_in_progress
);
984 /* intentional fallthrough */
987 SF_SET_DEBUG(def_symbol_in_progress
);
988 S_SET_SEGMENT(def_symbol_in_progress
, SEG_DEBUG
);
992 SF_SET_LOCAL(def_symbol_in_progress
); /* Do not emit this symbol. */
993 /* intentional fallthrough */
995 SF_SET_PROCESS(def_symbol_in_progress
); /* Will need processing before writing */
996 /* intentional fallthrough */
998 S_SET_SEGMENT(def_symbol_in_progress
, SEG_TEXT
);
1000 if (def_symbol_in_progress
->sy_symbol
.ost_entry
.n_name
[1] == 'b') { /* .bf */
1001 if (function_lineoff
< 0) {
1002 fprintf(stderr
, "`.bf' symbol without preceding function\n");
1003 } /* missing function symbol */
1004 SA_GET_SYM_LNNOPTR(def_symbol_in_progress
) = function_lineoff
;
1005 SF_SET_PROCESS(def_symbol_in_progress
); /* Will need relocating */
1006 function_lineoff
= -1;
1012 #endif /* C_AUTOARG */
1022 SF_SET_DEBUG(def_symbol_in_progress
);
1023 S_SET_SEGMENT(def_symbol_in_progress
, SEG_ABSOLUTE
);
1029 /* Valid but set somewhere else (s_comm, s_lcomm, colon) */
1035 as_warn("unexpected storage class %d", S_GET_STORAGE_CLASS(def_symbol_in_progress
));
1037 } /* switch on storage class */
1039 /* Now that we have built a debug symbol, try to
1040 find if we should merge with an existing symbol
1041 or not. If a symbol is C_EFCN or SEG_ABSOLUTE or
1042 untagged SEG_DEBUG it never merges. */
1044 /* Two cases for functions. Either debug followed
1045 by definition or definition followed by debug.
1046 For definition first, we will merge the debug
1047 symbol into the definition. For debug first, the
1048 lineno entry MUST point to the definition
1049 function or else it will point off into space
1050 when obj_crawl_symbol_chain() merges the debug
1051 symbol into the real symbol. Therefor, let's
1052 presume the debug symbol is a real function
1055 /* FIXME-SOON If for some reason the definition
1056 label/symbol is never seen, this will probably
1057 leave an undefined symbol at link time. */
1059 if (S_GET_STORAGE_CLASS(def_symbol_in_progress
) == C_EFCN
1060 || (S_GET_SEGMENT(def_symbol_in_progress
) == SEG_DEBUG
1061 && !SF_GET_TAG(def_symbol_in_progress
))
1062 || S_GET_SEGMENT(def_symbol_in_progress
) == SEG_ABSOLUTE
1063 || (symbolP
= symbol_find_base(S_GET_NAME(def_symbol_in_progress
), DO_NOT_STRIP
)) == NULL
) {
1065 symbol_append(def_symbol_in_progress
, symbol_lastP
, &symbol_rootP
, &symbol_lastP
);
1068 /* This symbol already exists, merge the
1069 newly created symbol into the old one.
1070 This is not mandatory. The linker can
1071 handle duplicate symbols correctly. But I
1072 guess that it save a *lot* of space if
1073 the assembly file defines a lot of
1076 /* The debug entry (def_symbol_in_progress)
1077 is merged into the previous definition. */
1079 c_symbol_merge(def_symbol_in_progress
, symbolP
);
1080 /* FIXME-SOON Should *def_symbol_in_progress be free'd? xoxorich. */
1081 def_symbol_in_progress
= symbolP
;
1083 if (SF_GET_FUNCTION(def_symbol_in_progress
)
1084 || SF_GET_TAG(def_symbol_in_progress
)) {
1085 /* For functions, and tags, the symbol *must* be where the debug symbol
1086 appears. Move the existing symbol to the current place. */
1087 /* If it already is at the end of the symbol list, do nothing */
1088 if (def_symbol_in_progress
!= symbol_lastP
) {
1089 symbol_remove(def_symbol_in_progress
, &symbol_rootP
, &symbol_lastP
);
1090 symbol_append(def_symbol_in_progress
, symbol_lastP
, &symbol_rootP
, &symbol_lastP
);
1091 } /* if not already in place */
1093 } /* normal or mergable */
1095 if (SF_GET_TAG(def_symbol_in_progress
)
1096 && symbol_find_base(S_GET_NAME(def_symbol_in_progress
), DO_NOT_STRIP
) == NULL
) {
1097 tag_insert(S_GET_NAME(def_symbol_in_progress
), def_symbol_in_progress
);
1098 } /* If symbol is a {structure,union} tag, associate symbol to its name. */
1100 if (SF_GET_FUNCTION(def_symbol_in_progress
)) {
1101 know(sizeof(def_symbol_in_progress
) <= sizeof(long));
1102 function_lineoff
= c_line_new((long) def_symbol_in_progress
, 0, &zero_address_frag
);
1103 SF_SET_PROCESS(def_symbol_in_progress
);
1105 if (symbolP
== NULL
) {
1106 /* That is, if this is the first
1107 time we've seen the function... */
1108 symbol_table_insert(def_symbol_in_progress
);
1109 } /* definition follows debug */
1110 } /* Create the line number entry pointing to the function being defined */
1112 def_symbol_in_progress
= NULL
;
1113 demand_empty_rest_of_line();
1115 } /* obj_coff_endef() */
1117 static void obj_coff_dim()
1119 register int dim_index
;
1121 if (def_symbol_in_progress
== NULL
) {
1122 as_warn(".dim pseudo-op used outside of .def/.endef: ignored.");
1123 demand_empty_rest_of_line();
1125 } /* if not inside .def/.endef */
1127 S_SET_NUMBER_AUXILIARY(def_symbol_in_progress
, 1);
1129 for (dim_index
= 0; dim_index
< DIMNUM
; dim_index
++) {
1131 SA_SET_SYM_DIMEN(def_symbol_in_progress
, dim_index
, get_absolute_expression());
1133 switch (*input_line_pointer
) {
1136 input_line_pointer
++;
1140 as_warn("badly formed .dim directive ignored");
1141 /* intentional fallthrough */
1146 } /* switch on following character */
1147 } /* for each dimension */
1149 demand_empty_rest_of_line();
1151 } /* obj_coff_dim() */
1153 static void obj_coff_line() {
1154 if (def_symbol_in_progress
== NULL
) {
1157 } /* if it looks like a stabs style line */
1159 S_SET_NUMBER_AUXILIARY(def_symbol_in_progress
, 1);
1160 SA_SET_SYM_LNNO(def_symbol_in_progress
, get_absolute_expression());
1162 demand_empty_rest_of_line();
1164 } /* obj_coff_line() */
1166 static void obj_coff_size() {
1167 if (def_symbol_in_progress
== NULL
) {
1168 as_warn(".size pseudo-op used outside of .def/.endef ignored.");
1169 demand_empty_rest_of_line();
1171 } /* if not inside .def/.endef */
1173 S_SET_NUMBER_AUXILIARY(def_symbol_in_progress
, 1);
1174 SA_SET_SYM_SIZE(def_symbol_in_progress
, get_absolute_expression());
1175 demand_empty_rest_of_line();
1177 } /* obj_coff_size() */
1179 static void obj_coff_scl() {
1180 if (def_symbol_in_progress
== NULL
) {
1181 as_warn(".scl pseudo-op used outside of .def/.endef ignored.");
1182 demand_empty_rest_of_line();
1184 } /* if not inside .def/.endef */
1186 S_SET_STORAGE_CLASS(def_symbol_in_progress
, get_absolute_expression());
1187 demand_empty_rest_of_line();
1189 } /* obj_coff_scl() */
1191 static void obj_coff_tag() {
1195 if (def_symbol_in_progress
== NULL
) {
1196 as_warn(".tag pseudo-op used outside of .def/.endef ignored.");
1197 demand_empty_rest_of_line();
1199 } /* if not inside .def/.endef */
1201 S_SET_NUMBER_AUXILIARY(def_symbol_in_progress
, 1);
1202 symbol_name
= input_line_pointer
;
1203 name_end
= get_symbol_end();
1205 /* Assume that the symbol referred to by .tag is always defined. */
1206 /* This was a bad assumption. I've added find_or_make. xoxorich. */
1207 SA_SET_SYM_TAGNDX(def_symbol_in_progress
, (long) tag_find_or_make(symbol_name
));
1208 if (SA_GET_SYM_TAGNDX(def_symbol_in_progress
) == 0L) {
1209 as_warn("tag not found for .tag %s", symbol_name
);
1212 SF_SET_TAGGED(def_symbol_in_progress
);
1213 *input_line_pointer
= name_end
;
1215 demand_empty_rest_of_line();
1217 } /* obj_coff_tag() */
1219 static void obj_coff_type() {
1220 if (def_symbol_in_progress
== NULL
) {
1221 as_warn(".type pseudo-op used outside of .def/.endef ignored.");
1222 demand_empty_rest_of_line();
1224 } /* if not inside .def/.endef */
1226 S_SET_DATA_TYPE(def_symbol_in_progress
, get_absolute_expression());
1228 if (ISFCN(S_GET_DATA_TYPE(def_symbol_in_progress
)) &&
1229 S_GET_STORAGE_CLASS(def_symbol_in_progress
) != C_TPDEF
) {
1230 SF_SET_FUNCTION(def_symbol_in_progress
);
1231 } /* is a function */
1233 demand_empty_rest_of_line();
1235 } /* obj_coff_type() */
1237 static void obj_coff_val() {
1238 if (def_symbol_in_progress
== NULL
) {
1239 as_warn(".val pseudo-op used outside of .def/.endef ignored.");
1240 demand_empty_rest_of_line();
1242 } /* if not inside .def/.endef */
1244 if (is_name_beginner(*input_line_pointer
)) {
1245 char *symbol_name
= input_line_pointer
;
1246 char name_end
= get_symbol_end();
1248 if (!strcmp(symbol_name
, ".")) {
1249 def_symbol_in_progress
->sy_frag
= frag_now
;
1250 S_SET_VALUE(def_symbol_in_progress
, obstack_next_free(&frags
) - frag_now
->fr_literal
);
1251 /* If the .val is != from the .def (e.g. statics) */
1252 } else if (strcmp(S_GET_NAME(def_symbol_in_progress
), symbol_name
)) {
1253 def_symbol_in_progress
->sy_forward
= symbol_find_or_make(symbol_name
);
1255 /* If the segment is undefined when the forward
1256 reference is solved, then copy the segment id
1257 from the forward symbol. */
1258 SF_SET_GET_SEGMENT(def_symbol_in_progress
);
1260 /* Otherwise, it is the name of a non debug symbol and its value will be calculated later. */
1261 *input_line_pointer
= name_end
;
1263 S_SET_VALUE(def_symbol_in_progress
, get_absolute_expression());
1264 } /* if symbol based */
1266 demand_empty_rest_of_line();
1268 } /* obj_coff_val() */
1271 * Maintain a list of the tagnames of the structres.
1274 static void tag_init() {
1275 tag_hash
= hash_new();
1279 static void tag_insert(name
, symbolP
)
1283 register char * error_string
;
1285 if (*(error_string
= hash_jam(tag_hash
, name
, (char *)symbolP
))) {
1286 as_fatal("Inserting \"%s\" into structure table failed: %s",
1287 name
, error_string
);
1290 } /* tag_insert() */
1292 static symbolS
*tag_find_or_make(name
)
1297 if ((symbolP
= tag_find(name
)) == NULL
) {
1298 symbolP
= symbol_new(name
,
1301 &zero_address_frag
);
1303 tag_insert(S_GET_NAME(symbolP
), symbolP
);
1304 symbol_table_insert(symbolP
);
1308 } /* tag_find_or_make() */
1310 static symbolS
*tag_find(name
)
1313 #ifdef STRIP_UNDERSCORE
1314 if (*name
== '_') name
++;
1315 #endif /* STRIP_UNDERSCORE */
1316 return((symbolS
*)hash_find(tag_hash
, name
));
1319 void obj_read_begin_hook() {
1320 /* These had better be the same. Usually 18 bytes. */
1322 know(sizeof(SYMENT
) == sizeof(AUXENT
));
1323 know(SYMESZ
== AUXESZ
);
1328 } /* obj_read_begin_hook() */
1330 void obj_crawl_symbol_chain(headers
)
1331 object_headers
*headers
;
1333 int symbol_number
= 0;
1335 symbolS
*last_functionP
= NULL
;
1338 symbolS
*symbol_externP
= NULL
;
1339 symbolS
*symbol_extern_lastP
= NULL
;
1341 /* Initialize the stack used to keep track of the matching .bb .be */
1342 stack
* block_stack
= stack_init(512, sizeof(symbolS
*));
1344 /* JF deal with forward references first... */
1345 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next(symbolP
)) {
1347 if (symbolP
->sy_forward
) {
1348 S_SET_VALUE(symbolP
, (S_GET_VALUE(symbolP
)
1349 + S_GET_VALUE(symbolP
->sy_forward
)
1350 + symbolP
->sy_forward
->sy_frag
->fr_address
));
1352 if (SF_GET_GET_SEGMENT(symbolP
)) {
1353 S_SET_SEGMENT(symbolP
, S_GET_SEGMENT(symbolP
->sy_forward
));
1354 } /* forward segment also */
1356 symbolP
->sy_forward
=0;
1357 } /* if it has a forward reference */
1358 } /* walk the symbol chain */
1360 tc_crawl_symbol_chain(headers
);
1362 /* The symbol list should be ordered according to the following sequence
1365 * . debug entries for functions
1366 * . fake symbols for .text .data and .bss
1368 * . undefined symbols
1369 * But this is not mandatory. The only important point is to put the
1370 * undefined symbols at the end of the list.
1373 if (symbol_rootP
== NULL
1374 || S_GET_STORAGE_CLASS(symbol_rootP
) != C_FILE
) {
1375 know(!previous_file_symbol
);
1376 c_dot_file_symbol("fake");
1377 } /* Is there a .file symbol ? If not insert one at the beginning. */
1380 * Build up static symbols for .text, .data and .bss
1382 dot_text_symbol
= (symbolS
*)
1383 c_section_symbol(".text",
1385 H_GET_TEXT_SIZE(headers
),
1386 0/*text_relocation_number */,
1387 0/*text_lineno_number */);
1389 dot_data_symbol
= (symbolS
*)
1390 c_section_symbol(".data",
1391 H_GET_TEXT_SIZE(headers
),
1392 H_GET_DATA_SIZE(headers
),
1393 0/*data_relocation_number */,
1394 0); /* There are no data lineno entries */
1396 dot_bss_symbol
= (symbolS
*)
1397 c_section_symbol(".bss",
1398 H_GET_TEXT_SIZE(headers
) + H_GET_DATA_SIZE(headers
),
1399 H_GET_BSS_SIZE(headers
),
1400 0, /* No relocation for a bss section. */
1401 0); /* There are no bss lineno entries */
1404 verify_symbol_chain(symbol_rootP
, symbol_lastP
);
1407 /* Three traversals of symbol chains here. The
1408 first traversal yanks externals into a temporary
1409 chain, removing the externals from the global
1410 chain, numbers symbols, and does some other guck.
1411 The second traversal is on the temporary chain of
1412 externals and just appends them to the global
1413 chain again, numbering them as we go. The third
1414 traversal patches pointers to symbols (using sym
1415 indexes). The last traversal was once done as
1416 part of the first pass, but that fails when a
1417 reference preceeds a definition as the definition
1418 has no number at the time we process the
1421 /* Note that symbolP will be NULL at the end of a loop
1422 if an external was at the beginning of the list (it
1423 gets moved off the list). Hence the weird check in
1426 for (symbolP
= symbol_rootP
;
1428 symbolP
= symbolP
? symbol_next(symbolP
) : symbol_rootP
) {
1429 if (!SF_GET_DEBUG(symbolP
)) {
1430 /* Debug symbols do not need all this rubbish */
1431 symbolS
* real_symbolP
;
1433 /* L* and C_EFCN symbols never merge. */
1434 if (!SF_GET_LOCAL(symbolP
)
1435 && (real_symbolP
= symbol_find_base(S_GET_NAME(symbolP
), DO_NOT_STRIP
))
1436 && real_symbolP
!= symbolP
) {
1437 /* FIXME-SOON: where do dups come from? Maybe tag references before definitions? xoxorich. */
1438 /* Move the debug data from the debug symbol to the
1439 real symbol. Do NOT do the oposite (i.e. move from
1440 real symbol to debug symbol and remove real symbol from the
1441 list.) Because some pointers refer to the real symbol
1442 whereas no pointers refer to the debug symbol. */
1443 c_symbol_merge(symbolP
, real_symbolP
);
1444 /* Replace the current symbol by the real one */
1445 /* The symbols will never be the last or the first
1446 because : 1st symbol is .file and 3 last symbols are
1447 .text, .data, .bss */
1448 symbol_remove(real_symbolP
, &symbol_rootP
, &symbol_lastP
);
1449 symbol_insert(real_symbolP
, symbolP
, &symbol_rootP
, &symbol_lastP
);
1450 symbol_remove(symbolP
, &symbol_rootP
, &symbol_lastP
);
1451 symbolP
= real_symbolP
;
1452 } /* if not local but dup'd */
1454 if (flagseen
['R'] && (S_GET_SEGMENT(symbolP
) == SEG_DATA
)) {
1455 S_SET_SEGMENT(symbolP
, SEG_TEXT
);
1456 } /* push data into text */
1458 S_SET_VALUE(symbolP
, S_GET_VALUE(symbolP
) + symbolP
->sy_frag
->fr_address
);
1460 if (!S_IS_DEFINED(symbolP
) && !SF_GET_LOCAL(symbolP
)) {
1461 S_SET_EXTERNAL(symbolP
);
1462 } else if (S_GET_STORAGE_CLASS(symbolP
) == C_NULL
) {
1463 if (S_GET_SEGMENT(symbolP
) == SEG_TEXT
){
1464 S_SET_STORAGE_CLASS(symbolP
, C_LABEL
);
1466 S_SET_STORAGE_CLASS(symbolP
, C_STAT
);
1468 } /* no storage class yet */
1470 /* Mainly to speed up if not -g */
1471 if (SF_GET_PROCESS(symbolP
)) {
1472 /* Handle the nested blocks auxiliary info. */
1473 if (S_GET_STORAGE_CLASS(symbolP
) == C_BLOCK
) {
1474 if (!strcmp(S_GET_NAME(symbolP
), ".bb"))
1475 stack_push(block_stack
, (char *) &symbolP
);
1477 register symbolS
* begin_symbolP
;
1478 begin_symbolP
= *(symbolS
**)stack_pop(block_stack
);
1479 if (begin_symbolP
== (symbolS
*)0)
1480 as_warn("mismatched .eb");
1482 SA_SET_SYM_ENDNDX(begin_symbolP
, symbol_number
+2);
1485 /* If we are able to identify the type of a function, and we
1486 are out of a function (last_functionP == 0) then, the
1487 function symbol will be associated with an auxiliary
1489 if (last_functionP
== (symbolS
*)0 &&
1490 SF_GET_FUNCTION(symbolP
)) {
1491 last_functionP
= symbolP
;
1493 if (S_GET_NUMBER_AUXILIARY(symbolP
) < 1) {
1494 S_SET_NUMBER_AUXILIARY(symbolP
, 1);
1495 } /* make it at least 1 */
1497 /* Clobber possible stale .dim information. */
1498 bzero(symbolP
->sy_symbol
.ost_auxent
[0].x_sym
.x_fcnary
.x_ary
.x_dimen
,
1499 sizeof(symbolP
->sy_symbol
.ost_auxent
[0].x_sym
.x_fcnary
.x_ary
.x_dimen
));
1501 /* The C_FCN doesn't need any additional information.
1502 I don't even know if this is needed for sdb. But the
1503 standard assembler generates it, so...
1505 if (S_GET_STORAGE_CLASS(symbolP
) == C_EFCN
) {
1506 if (last_functionP
== (symbolS
*)0)
1507 as_fatal("C_EFCN symbol out of scope");
1508 SA_SET_SYM_FSIZE(last_functionP
,
1509 (long)(S_GET_VALUE(symbolP
) -
1510 S_GET_VALUE(last_functionP
)));
1511 SA_SET_SYM_ENDNDX(last_functionP
, symbol_number
);
1512 last_functionP
= (symbolS
*)0;
1515 } else if (SF_GET_TAG(symbolP
)) {
1516 /* First descriptor of a structure must point to
1517 the first slot after the structure description. */
1518 last_tagP
= symbolP
;
1520 } else if (S_GET_STORAGE_CLASS(symbolP
) == C_EOS
) {
1521 /* +2 take in account the current symbol */
1522 SA_SET_SYM_ENDNDX(last_tagP
, symbol_number
+ 2);
1523 } else if (S_GET_STORAGE_CLASS(symbolP
) == C_FILE
) {
1524 if (S_GET_VALUE(symbolP
)) {
1525 S_SET_VALUE((symbolS
*) S_GET_VALUE(symbolP
), symbol_number
);
1526 S_SET_VALUE(symbolP
, 0);
1527 } /* no one points at the first .file symbol */
1528 } /* if debug or tag or eos or file */
1530 /* We must put the external symbols apart. The loader
1531 does not bomb if we do not. But the references in
1532 the endndx field for a .bb symbol are not corrected
1533 if an external symbol is removed between .bb and .be.
1534 I.e in the following case :
1535 [20] .bb endndx = 22
1538 ld will move the symbol 21 to the end of the list but
1539 endndx will still be 22 instead of 21. */
1542 if (SF_GET_LOCAL(symbolP
)) {
1543 /* remove C_EFCN and LOCAL (L...) symbols */
1544 /* next pointer remains valid */
1545 symbol_remove(symbolP
, &symbol_rootP
, &symbol_lastP
);
1547 } else if (!S_IS_DEFINED(symbolP
) && !S_IS_DEBUG(symbolP
) && !SF_GET_STATICS(symbolP
)) {
1548 /* S_GET_STORAGE_CLASS(symbolP) == C_EXT && !SF_GET_FUNCTION(symbolP)) { */
1549 /* if external, Remove from the list */
1550 symbolS
*hold
= symbol_previous(symbolP
);
1552 symbol_remove(symbolP
, &symbol_rootP
, &symbol_lastP
);
1553 symbol_clear_list_pointers(symbolP
);
1554 symbol_append(symbolP
, symbol_extern_lastP
, &symbol_externP
, &symbol_extern_lastP
);
1557 if (SF_GET_STRING(symbolP
)) {
1558 symbolP
->sy_name_offset
= string_byte_count
;
1559 string_byte_count
+= strlen(S_GET_NAME(symbolP
)) + 1;
1561 symbolP
->sy_name_offset
= 0;
1562 } /* fix "long" names */
1564 symbolP
->sy_number
= symbol_number
;
1565 symbol_number
+= 1 + S_GET_NUMBER_AUXILIARY(symbolP
);
1566 } /* if local symbol */
1567 } /* traverse the symbol list */
1569 for (symbolP
= symbol_externP
; symbol_externP
;) {
1570 symbolS
*tmp
= symbol_externP
;
1573 symbol_remove(tmp
, &symbol_externP
, &symbol_extern_lastP
);
1574 symbol_append(tmp
, symbol_lastP
, &symbol_rootP
, &symbol_lastP
);
1577 if (SF_GET_STRING(tmp
)) {
1578 tmp
->sy_name_offset
= string_byte_count
;
1579 string_byte_count
+= strlen(S_GET_NAME(tmp
)) + 1;
1581 tmp
->sy_name_offset
= 0;
1582 } /* fix "long" names */
1584 tmp
->sy_number
= symbol_number
;
1585 symbol_number
+= 1 + S_GET_NUMBER_AUXILIARY(tmp
);
1586 } /* append the entire extern chain */
1588 /* When a tag reference preceeds the tag definition,
1589 the definition will not have a number at the time
1590 we process the reference during the first
1591 traversal. Thus, a second traversal. */
1593 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next(symbolP
)) {
1594 if (SF_GET_TAGGED(symbolP
)) {
1595 SA_SET_SYM_TAGNDX(symbolP
, ((symbolS
*) SA_GET_SYM_TAGNDX(symbolP
))->sy_number
);
1596 } /* If the symbol has a tagndx entry, resolve it */
1597 } /* second traversal */
1599 know(symbol_externP
== NULL
);
1600 know(symbol_extern_lastP
== NULL
);
1602 /* FIXME-SOMEDAY I'm counting line no's here so we know what to put in the section
1603 headers, and I'm resolving the addresses since I'm not sure how to
1604 do it later. I am NOT resolving the linno's representing functions.
1605 Their symbols need a fileptr pointing to this linno when emitted.
1606 Thus, I resolve them on emit. xoxorich. */
1608 for (lineP
= lineno_rootP
; lineP
; lineP
= lineP
->next
) {
1609 if (lineP
->line
.l_lnno
> 0) {
1610 lineP
->line
.l_addr
.l_paddr
+= ((fragS
*)lineP
->frag
)->fr_address
;
1614 text_lineno_number
++;
1615 } /* for each line number */
1617 H_SET_SYMBOL_TABLE_SIZE(headers
, symbol_number
);
1620 } /* obj_crawl_symbol_chain() */
1623 * Find strings by crawling along symbol table chain.
1626 void obj_emit_strings(where
)
1631 #ifdef CROSS_COMPILE
1632 /* Gotta do md_ byte-ordering stuff for string_byte_count first - KWK */
1633 md_number_to_chars(*where
, string_byte_count
, sizeof(string_byte_count
));
1634 *where
+= sizeof(string_byte_count
);
1635 #else /* CROSS_COMPILE */
1636 append(where
, (char *) &string_byte_count
, (unsigned long) sizeof(string_byte_count
));
1637 #endif /* CROSS_COMPILE */
1639 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next(symbolP
)) {
1640 if (SF_GET_STRING(symbolP
)) {
1641 append(where
, S_GET_NAME(symbolP
), (unsigned long)(strlen(S_GET_NAME(symbolP
)) + 1));
1642 } /* if it has a string */
1643 } /* walk the symbol chain */
1646 } /* obj_emit_strings() */
1648 void obj_pre_write_hook(headers
)
1649 object_headers
*headers
;
1651 register int text_relocation_number
= 0;
1652 register int data_relocation_number
= 0;
1653 register fixS
*fixP
;
1655 /* FIXME-SOMEDAY this should be done at
1656 fixup_segment time but I'm going to wait until I
1657 do multiple segments. xoxorich. */
1658 /* Count the number of relocation entries for text and data */
1659 for (fixP
= text_fix_root
; fixP
; fixP
= fixP
->fx_next
) {
1660 if (fixP
->fx_addsy
) {
1661 ++text_relocation_number
;
1663 /* two relocs per callj under coff. */
1664 if (fixP
->fx_callj
) {
1665 ++text_relocation_number
;
1666 } /* if callj and not already fixed. */
1667 #endif /* TC_I960 */
1669 /* Count 2 for a constH */
1670 if (fixP
->fx_r_type
== RELOC_CONSTH
) {
1671 ++text_relocation_number
;
1675 } /* if not yet fixed */
1676 } /* for each fix */
1678 SA_SET_SCN_NRELOC(dot_text_symbol
, text_relocation_number
);
1679 /* Assign the number of line number entries for the text section */
1680 SA_SET_SCN_NLINNO(dot_text_symbol
, text_lineno_number
);
1681 /* Assign the size of the section */
1682 SA_SET_SCN_SCNLEN(dot_text_symbol
, H_GET_TEXT_SIZE(headers
));
1684 for (fixP
= data_fix_root
; fixP
; fixP
= fixP
->fx_next
) {
1685 if (fixP
->fx_addsy
) {
1686 ++data_relocation_number
;
1687 } /* if still relocatable */
1689 /* Count 2 for a constH */
1690 if (fixP
->fx_r_type
== RELOC_CONSTH
) {
1691 ++data_relocation_number
;
1695 } /* for each fix */
1698 SA_SET_SCN_NRELOC(dot_data_symbol
, data_relocation_number
);
1699 /* Assign the size of the section */
1700 SA_SET_SCN_SCNLEN(dot_data_symbol
, H_GET_DATA_SIZE(headers
));
1702 /* Assign the size of the section */
1703 SA_SET_SCN_SCNLEN(dot_bss_symbol
, H_GET_BSS_SIZE(headers
));
1705 /* pre write hook can add relocs (for 960 and 29k coff) so */
1706 headers
->relocation_size
= text_relocation_number
* RELSZ
+
1707 data_relocation_number
*RELSZ
;
1711 /* Fill in extra coff fields */
1713 /* Initialize general line number information. */
1714 H_SET_LINENO_SIZE(headers
, text_lineno_number
* LINESZ
);
1717 H_SET_FILE_MAGIC_NUMBER(headers
, FILE_HEADER_MAGIC
);
1718 H_SET_NUMBER_OF_SECTIONS(headers
, 3); /* text+data+bss */
1719 #ifndef OBJ_COFF_OMIT_TIMESTAMP
1720 H_SET_TIME_STAMP(headers
, (long)time((long*)0));
1721 #else /* OBJ_COFF_OMIT_TIMESTAMP */
1722 H_SET_TIME_STAMP(headers
, 0);
1723 #endif /* OBJ_COFF_OMIT_TIMESTAMP */
1724 H_SET_SYMBOL_TABLE_POINTER(headers
, H_GET_SYMBOL_TABLE_FILE_OFFSET(headers
));
1726 printf("FILHSZ %x\n", FILHSZ
);
1727 printf("OBJ_COFF_AOUTHDRSZ %x\n", OBJ_COFF_AOUTHDRSZ
);
1728 printf("section headers %x\n", H_GET_NUMBER_OF_SECTIONS(headers
) * SCNHSZ
);
1729 printf("get text size %x\n", H_GET_TEXT_SIZE(headers
));
1730 printf("get data size %x\n", H_GET_DATA_SIZE(headers
));
1731 printf("get relocation size %x\n", H_GET_RELOCATION_SIZE(headers
));
1732 printf("get lineno size %x\n", H_GET_LINENO_SIZE(headers
));
1734 /* symbol table size allready set */
1735 H_SET_SIZEOF_OPTIONAL_HEADER(headers
, OBJ_COFF_AOUTHDRSZ
);
1736 H_SET_FLAGS(headers
, (text_lineno_number
== 0 ? F_LNNO
: 0)
1737 | ((text_relocation_number
+ data_relocation_number
) ? 0 : F_RELFLG
)
1741 /* magic number allready set */
1742 H_SET_VERSION_STAMP(headers
, 0);
1743 /* Text, data, bss size; entry point; text_start and data_start are already set */
1745 /* Build section headers */
1747 c_section_header(&text_section_header
,
1750 H_GET_TEXT_SIZE(headers
),
1751 H_GET_TEXT_FILE_OFFSET(headers
),
1752 (SA_GET_SCN_NRELOC(dot_text_symbol
)
1753 ? H_GET_RELOCATION_FILE_OFFSET(headers
)
1756 ? H_GET_LINENO_FILE_OFFSET(headers
)
1758 SA_GET_SCN_NRELOC(dot_text_symbol
),
1760 section_alignment
[(int) SEG_TEXT
]);
1762 c_section_header(&data_section_header
,
1764 H_GET_TEXT_SIZE(headers
),
1765 H_GET_DATA_SIZE(headers
),
1766 (H_GET_DATA_SIZE(headers
)
1767 ? H_GET_DATA_FILE_OFFSET(headers
)
1769 (SA_GET_SCN_NRELOC(dot_data_symbol
)
1770 ? (H_GET_RELOCATION_FILE_OFFSET(headers
)
1771 + text_section_header
.s_nreloc
* RELSZ
)
1773 0, /* No line number information */
1774 SA_GET_SCN_NRELOC(dot_data_symbol
),
1775 0, /* No line number information */
1776 section_alignment
[(int) SEG_DATA
]);
1778 c_section_header(&bss_section_header
,
1780 H_GET_TEXT_SIZE(headers
) + H_GET_DATA_SIZE(headers
),
1781 H_GET_BSS_SIZE(headers
),
1782 0, /* No file offset */
1783 0, /* No relocation information */
1784 0, /* No line number information */
1785 0, /* No relocation information */
1786 0, /* No line number information */
1787 section_alignment
[(int) SEG_BSS
]);
1790 } /* obj_pre_write_hook() */
1792 /* This is a copy from aout. All I do is neglect to actually build the symbol. */
1794 static void obj_coff_stab(what
)
1799 int goof
= 0; /* TRUE if we have aborted. */
1803 symbolS
*symbolP
= 0;
1806 string
= demand_copy_C_string(&length
);
1809 if (*input_line_pointer
== ',') {
1810 input_line_pointer
++;
1812 as_bad("I need a comma after symbol's name");
1814 } /* better be a comma */
1815 } /* skip the string */
1818 * Input_line_pointer->after ','. String->symbol name.
1821 if (get_absolute_expression_and_terminator(&longint
) != ',') {
1822 as_bad("I want a comma after the n_type expression");
1824 input_line_pointer
--; /* Backup over a non-',' char. */
1829 if (get_absolute_expression_and_terminator(&longint
) != ',') {
1830 as_bad("I want a comma after the n_other expression");
1832 input_line_pointer
--; /* Backup over a non-',' char. */
1837 get_absolute_expression();
1839 if (what
== 's' || what
== 'n') {
1840 if (*input_line_pointer
!= ',') {
1841 as_bad("I want a comma after the n_desc expression");
1844 input_line_pointer
++;
1852 ignore_rest_of_line();
1854 demand_empty_rest_of_line();
1856 } /* obj_coff_stab() */
1863 return((s
== NULL
) ? "(NULL)" : S_GET_NAME(s
));
1864 } /* s_get_name() */
1866 void symbol_dump() {
1869 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next(symbolP
)) {
1870 printf("%3ld: 0x%lx \"%s\" type = %ld, class = %d, segment = %d\n",
1872 (unsigned long) symbolP
,
1873 S_GET_NAME(symbolP
),
1874 (long) S_GET_DATA_TYPE(symbolP
),
1875 S_GET_STORAGE_CLASS(symbolP
),
1876 (int) S_GET_SEGMENT(symbolP
));
1877 } /* traverse symbols */
1880 } /* symbol_dump() */
1891 /* end of obj-coff.c */