1 /* coff object file format
2 Copyright (C) 1989, 1990, 1991 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 1, 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. */
28 const short seg_N_TYPE
[] = { /* in: segT out: N_TYPE bits */
33 C_UNDEF_SECTION
, /* SEG_UNKNOWN */
34 C_UNDEF_SECTION
, /* SEG_ABSENT */
35 C_UNDEF_SECTION
, /* SEG_PASS1 */
36 C_UNDEF_SECTION
, /* SEG_GOOF */
37 C_UNDEF_SECTION
, /* SEG_BIG */
38 C_UNDEF_SECTION
, /* SEG_DIFFERENCE */
39 C_DEBUG_SECTION
, /* SEG_DEBUG */
40 C_NTV_SECTION
, /* SEG_NTV */
41 C_PTV_SECTION
, /* SEG_PTV */
45 /* Add 4 to the real value to get the index and compensate the negatives */
47 const segT N_TYPE_seg
[32] =
49 SEG_PTV
, /* C_PTV_SECTION == -4 */
50 SEG_NTV
, /* C_NTV_SECTION == -3 */
51 SEG_DEBUG
, /* C_DEBUG_SECTION == -2 */
52 SEG_ABSOLUTE
, /* C_ABS_SECTION == -1 */
53 SEG_UNKNOWN
, /* C_UNDEF_SECTION == 0 */
54 SEG_TEXT
, /* C_TEXT_SECTION == 1 */
55 SEG_DATA
, /* C_DATA_SECTION == 2 */
56 SEG_BSS
, /* C_BSS_SECTION == 3 */
57 SEG_GOOF
,SEG_GOOF
,SEG_GOOF
,SEG_GOOF
,SEG_GOOF
,SEG_GOOF
,SEG_GOOF
,SEG_GOOF
,
58 SEG_GOOF
,SEG_GOOF
,SEG_GOOF
,SEG_GOOF
,SEG_GOOF
,SEG_GOOF
,SEG_GOOF
,SEG_GOOF
,
59 SEG_GOOF
,SEG_GOOF
,SEG_GOOF
,SEG_GOOF
,SEG_GOOF
,SEG_GOOF
,SEG_GOOF
,SEG_GOOF
64 char *s_get_name(symbolS
*s
);
65 static symbolS
*tag_find_or_make(char *name
);
66 static symbolS
* tag_find(char *name
);
67 static void c_section_header_append(char **where
, SCNHDR
*header
);
68 static void obj_coff_def(int what
);
69 static void obj_coff_dim(void);
70 static void obj_coff_endef(void);
71 static void obj_coff_line(void);
72 static void obj_coff_ln(void);
73 static void obj_coff_scl(void);
74 static void obj_coff_size(void);
75 static void obj_coff_stab(int what
);
76 static void obj_coff_tag(void);
77 static void obj_coff_type(void);
78 static void obj_coff_val(void);
79 static void tag_init(void);
80 static void tag_insert(char *name
, symbolS
*symbolP
);
85 static symbolS
*tag_find();
86 static symbolS
*tag_find_or_make();
87 static void c_section_header_append();
88 static void obj_coff_def();
89 static void obj_coff_dim();
90 static void obj_coff_endef();
91 static void obj_coff_line();
92 static void obj_coff_ln();
93 static void obj_coff_scl();
94 static void obj_coff_size();
95 static void obj_coff_stab();
96 static void obj_coff_tag();
97 static void obj_coff_type();
98 static void obj_coff_val();
99 static void tag_init();
100 static void tag_insert();
102 #endif /* __STDC__ */
104 static struct hash_control
*tag_hash
;
105 static symbolS
*def_symbol_in_progress
= NULL
;
107 const pseudo_typeS obj_pseudo_table
[] = {
109 { "def", obj_coff_def
, 0 },
110 { "dim", obj_coff_dim
, 0 },
111 { "endef", obj_coff_endef
, 0 },
112 { "line", obj_coff_line
, 0 },
113 { "ln", obj_coff_ln
, 0 },
114 { "scl", obj_coff_scl
, 0 },
115 { "size", obj_coff_size
, 0 },
116 { "tag", obj_coff_tag
, 0 },
117 { "type", obj_coff_type
, 0 },
118 { "val", obj_coff_val
, 0 },
120 { "def", s_ignore
, 0 },
121 { "dim", s_ignore
, 0 },
122 { "endef", s_ignore
, 0 },
123 { "line", s_ignore
, 0 },
124 { "ln", s_ignore
, 0 },
125 { "scl", s_ignore
, 0 },
126 { "size", s_ignore
, 0 },
127 { "tag", s_ignore
, 0 },
128 { "type", s_ignore
, 0 },
129 { "val", s_ignore
, 0 },
130 #endif /* ignore debug */
132 /* stabs aka a.out aka b.out directives for debug symbols.
133 Currently ignored silently. Except for .line which we
134 guess at from context. */
135 { "desc", s_ignore
, 0 }, /* def */
136 /* { "line", s_ignore, 0 }, */ /* source code line number */
137 { "stabd", obj_coff_stab
, 'd' }, /* stabs */
138 { "stabn", obj_coff_stab
, 'n' }, /* stabs */
139 { "stabs", obj_coff_stab
, 's' }, /* stabs */
142 { "ABORT", s_abort
, 0 },
143 { "ident", s_ignore
, 0 },
145 { NULL
} /* end sentinel */
146 }; /* obj_pseudo_table */
149 /* obj dependant output values */
150 static SCNHDR bss_section_header
;
151 static SCNHDR data_section_header
;
152 static SCNHDR text_section_header
;
159 * Crawl along a fixS chain. Emit the segment's relocations.
162 void obj_emit_relocations(where
, fixP
, segment_address_in_file
)
164 fixS
*fixP
; /* Fixup chain for this segment. */
165 relax_addressT segment_address_in_file
;
170 bzero((char *)&ri
,sizeof(ri
));
171 for (; fixP
; fixP
= fixP
->fx_next
) {
172 if (symbolP
= fixP
->fx_addsy
) {
174 ri
.r_type
= (fixP
->fx_pcrel
?
175 (fixP
->fx_size
== 1 ? R_PCRBYTE
:
176 fixP
->fx_size
== 2 ? R_PCRWORD
:
178 (fixP
->fx_size
== 1 ? R_RELBYTE
:
179 fixP
->fx_size
== 2 ? R_RELWORD
:
181 #elif defined(TC_I386)
182 /* FIXME-SOON R_OFF8 & R_DIR16 are a vague guess, completly untested. */
183 ri
.r_type
= (fixP
->fx_pcrel
?
184 (fixP
->fx_size
== 1 ? R_PCRBYTE
:
185 fixP
->fx_size
== 2 ? R_PCRWORD
:
187 (fixP
->fx_size
== 1 ? R_OFF8
:
188 fixP
->fx_size
== 2 ? R_DIR16
:
190 #elif defined(TC_I960)
191 ri
.r_type
= (fixP
->fx_pcrel
194 #elif defined(TC_A29K)
195 ri
.r_type
= tc_coff_fix2rtype(fixP
);
198 #endif /* TC_M68K || TC_I386 */
199 ri
.r_vaddr
= fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
200 /* If symbol associated to relocation entry is a bss symbol
201 or undefined symbol just remember the index of the symbol.
202 Otherwise store the index of the symbol describing the
203 section the symbol belong to. This heuristic speeds up ld.
205 /* Local symbols can generate relocation information. In case
206 of structure return for instance. But they have no symbol
207 number because they won't be emitted in the final object.
208 In the case where they are in the BSS section, this leads
209 to an incorrect r_symndx.
210 Under bsd the loader do not care if the symbol reference is
211 incorrect. But the SYS V ld complains about this. To avoid
212 this we associate the symbol to the associated section,
213 *even* if it is the BSS section. */
214 /* If someone can tell me why the other symbols of the bss
215 section are not associated with the .bss section entry,
216 I'd be gratefull. I guess that it has to do with the special
217 nature of the .bss section. Or maybe this is because the
218 bss symbols are declared in the common section and can
219 be resized later. Can it break code some where ? */
220 ri
.r_symndx
= (S_GET_SEGMENT(symbolP
) == SEG_TEXT
221 ? dot_text_symbol
->sy_number
222 : (S_GET_SEGMENT(symbolP
) == SEG_DATA
223 ? dot_data_symbol
->sy_number
224 : ((SF_GET_LOCAL(symbolP
)
225 ? dot_bss_symbol
->sy_number
226 : symbolP
->sy_number
)))); /* bss or undefined */
228 /* md_ri_to_chars((char *) &ri, ri); */ /* Last step : write md f */
229 append(where
, (char *) &ri
, sizeof(ri
));
232 if (fixP
->fx_callj
) {
233 ri
.r_type
= R_OPTCALL
;
234 append(where
, (char *) &ri
, sizeof(ri
));
235 } /* if it's a callj, do it again for the opcode */
238 } /* if there's a symbol */
239 } /* for each fixP */
242 } /* obj_emit_relocations() */
244 /* Coff file generation & utilities */
246 void obj_header_append(where
, headers
)
248 object_headers
*headers
;
250 tc_headers_hook(headers
);
252 #ifdef CROSS_ASSEMBLE
253 /* Eventually swap bytes for cross compilation for file header */
254 md_number_to_chars(*where
, headers
->filehdr
.f_magic
, sizeof(headers
->filehdr
.f_magic
));
255 *where
+= sizeof(headers
->filehdr
.f_magic
);
256 md_number_to_chars(*where
, headers
->filehdr
.f_nscns
, sizeof(headers
->filehdr
.f_nscns
));
257 *where
+= sizeof(headers
->filehdr
.f_nscns
);
258 md_number_to_chars(*where
, headers
->filehdr
.f_timdat
, sizeof(headers
->filehdr
.f_timdat
));
259 *where
+= sizeof(headers
->filehdr
.f_timdat
);
260 md_number_to_chars(*where
, headers
->filehdr
.f_symptr
, sizeof(headers
->filehdr
.f_symptr
));
261 *where
+= sizeof(headers
->filehdr
.f_symptr
);
262 md_number_to_chars(*where
, headers
->filehdr
.f_nsyms
, sizeof(headers
->filehdr
.f_nsyms
));
263 *where
+= sizeof(headers
->filehdr
.f_nsyms
);
264 md_number_to_chars(*where
, headers
->filehdr
.f_opthdr
, sizeof(headers
->filehdr
.f_opthdr
));
265 *where
+= sizeof(headers
->filehdr
.f_opthdr
);
266 md_number_to_chars(*where
, headers
->filehdr
.f_flags
, sizeof(headers
->filehdr
.f_flags
));
267 *where
+= sizeof(headers
->filehdr
.f_flags
);
269 #ifndef OBJ_COFF_OMIT_OPTIONAL_HEADER
270 /* Eventually swap bytes for cross compilation for a.out header */
271 md_number_to_chars(*where
, headers
->aouthdr
.magic
, sizeof(headers
->aouthdr
.magic
));
272 *where
+= sizeof(headers
->aouthdr
.magic
);
273 md_number_to_chars(*where
, headers
->aouthdr
.vstamp
, sizeof(headers
->aouthdr
.vstamp
));
274 *where
+= sizeof(headers
->aouthdr
.vstamp
);
275 md_number_to_chars(*where
, headers
->aouthdr
.tsize
, sizeof(headers
->aouthdr
.tsize
));
276 *where
+= sizeof(headers
->aouthdr
.tsize
);
277 md_number_to_chars(*where
, headers
->aouthdr
.dsize
, sizeof(headers
->aouthdr
.dsize
));
278 *where
+= sizeof(headers
->aouthdr
.dsize
);
279 md_number_to_chars(*where
, headers
->aouthdr
.bsize
, sizeof(headers
->aouthdr
.bsize
));
280 *where
+= sizeof(headers
->aouthdr
.bsize
);
281 md_number_to_chars(*where
, headers
->aouthdr
.entry
, sizeof(headers
->aouthdr
.entry
));
282 *where
+= sizeof(headers
->aouthdr
.entry
);
283 md_number_to_chars(*where
, headers
->aouthdr
.text_start
, sizeof(headers
->aouthdr
.text_start
));
284 *where
+= sizeof(headers
->aouthdr
.text_start
);
285 md_number_to_chars(*where
, headers
->aouthdr
.data_start
, sizeof(headers
->aouthdr
.data_start
));
286 *where
+= sizeof(headers
->aouthdr
.data_start
);
287 #endif /* OBJ_COFF_OMIT_OPTIONAL_HEADER */
289 #else /* CROSS_ASSEMBLE */
291 append(where
, (char *) &headers
->filehdr
, sizeof(headers
->filehdr
));
292 #ifndef OBJ_COFF_OMIT_OPTIONAL_HEADER
293 append(where
, (char *) &headers
->aouthdr
, sizeof(headers
->aouthdr
));
294 #endif /* OBJ_COFF_OMIT_OPTIONAL_HEADER */
296 #endif /* CROSS_ASSEMBLE */
298 /* Output the section headers */
299 c_section_header_append(where
, &text_section_header
);
300 c_section_header_append(where
, &data_section_header
);
301 c_section_header_append(where
, &bss_section_header
);
304 } /* obj_header_append() */
306 void obj_symbol_to_chars(where
, symbolP
)
310 SYMENT
*syment
= &symbolP
->sy_symbol
.ost_entry
;
312 char numaux
= syment
->n_numaux
;
313 unsigned short type
= S_GET_DATA_TYPE(symbolP
);
315 #ifdef CROSS_ASSEMBLE
316 md_number_to_chars(*where
, syment
->n_value
, sizeof(syment
->n_value
));
317 *where
+= sizeof(syment
->n_value
);
318 md_number_to_chars(*where
, syment
->n_scnum
, sizeof(syment
->n_scnum
));
319 *where
+= sizeof(syment
->n_scnum
);
320 md_number_to_chars(*where
, syment
->n_type
, sizeof(syment
->n_type
));
321 *where
+= sizeof(syment
->n_type
);
322 md_number_to_chars(*where
, syment
->n_sclass
, sizeof(syment
->n_sclass
));
323 *where
+= sizeof(syment
->n_sclass
);
324 md_number_to_chars(*where
, syment
->n_numaux
, sizeof(syment
->n_numaux
));
325 *where
+= sizeof(syment
->n_numaux
);
326 #else /* CROSS_ASSEMBLE */
327 append(where
, (char *) syment
, sizeof(*syment
));
328 #endif /* CROSS_ASSEMBLE */
330 /* Should do the following : if (.file entry) MD(..)... else if (static entry) MD(..) */
331 if (numaux
> OBJ_COFF_MAX_AUXENTRIES
) {
332 as_bad("Internal error? too many auxents for symbol");
333 } /* too many auxents */
335 for (i
= 0; i
< numaux
; ++i
) {
336 #ifdef CROSS_ASSEMBLE
337 #if 0 /* This code has never been tested */
338 /* The most common case, x_sym entry. */
339 if ((SF_GET(symbolP
) & (SF_FILE
| SF_STATICS
)) == 0) {
340 md_number_to_chars(*where
, auxP
->x_sym
.x_tagndx
, sizeof(auxP
->x_sym
.x_tagndx
));
341 *where
+= sizeof(auxP
->x_sym
.x_tagndx
);
343 md_number_to_chars(*where
, auxP
->x_sym
.x_misc
.x_fsize
, sizeof(auxP
->x_sym
.x_misc
.x_fsize
));
344 *where
+= sizeof(auxP
->x_sym
.x_misc
.x_fsize
);
346 md_number_to_chars(*where
, auxP
->x_sym
.x_misc
.x_lnno
, sizeof(auxP
->x_sym
.x_misc
.x_lnno
));
347 *where
+= sizeof(auxP
->x_sym
.x_misc
.x_lnno
);
348 md_number_to_chars(*where
, auxP
->x_sym
.x_misc
.x_size
, sizeof(auxP
->x_sym
.x_misc
.x_size
));
349 *where
+= sizeof(auxP
->x_sym
.x_misc
.x_size
);
353 for (index
= 0; index
< DIMNUM
; index
++)
354 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
]));
355 *where
+= sizeof(auxP
->x_sym
.x_fcnary
.x_ary
.x_dimen
[index
]);
357 md_number_to_chars(*where
, auxP
->x_sym
.x_fcnary
.x_fcn
.x_lnnoptr
, sizeof(auxP
->x_sym
.x_fcnary
.x_fcn
.x_lnnoptr
));
358 *where
+= sizeof(auxP
->x_sym
.x_fcnary
.x_fcn
.x_lnnoptr
);
359 md_number_to_chars(*where
, auxP
->x_sym
.x_fcnary
.x_fcn
.x_endndx
, sizeof(auxP
->x_sym
.x_fcnary
.x_fcn
.x_endndx
));
360 *where
+= sizeof(auxP
->x_sym
.x_fcnary
.x_fcn
.x_endndx
);
362 md_number_to_chars(*where
, auxP
->x_sym
.x_tvndx
, sizeof(auxP
->x_sym
.x_tvndx
));
363 *where
+= sizeof(auxP
->x_sym
.x_tvndx
);
364 } else if (SF_GET_FILE(symbolP
)) { /* .file */
366 } else if (SF_GET_STATICS(symbolP
)) { /* .text, .data, .bss symbols */
367 md_number_to_chars(*where
, auxP
->x_scn
.x_scnlen
, sizeof(auxP
->x_scn
.x_scnlen
));
368 *where
+= sizeof(auxP
->x_scn
.x_scnlen
);
369 md_number_to_chars(*where
, auxP
->x_scn
.x_nreloc
, sizeof(auxP
->x_scn
.x_nreloc
));
370 *where
+= sizeof(auxP
->x_scn
.x_nreloc
);
371 md_number_to_chars(*where
, auxP
->x_scn
.x_nlinno
, sizeof(auxP
->x_scn
.x_nlinno
));
372 *where
+= sizeof(auxP
->x_scn
.x_nlinno
);
375 #else /* CROSS_ASSEMBLE */
376 append(where
, (char *) &symbolP
->sy_symbol
.ost_auxent
[i
], sizeof(symbolP
->sy_symbol
.ost_auxent
[i
]));
377 #endif /* CROSS_ASSEMBLE */
379 }; /* for each aux in use */
382 } /* obj_symbol_to_chars() */
384 static void c_section_header_append(where
, header
)
388 #ifdef CROSS_ASSEMBLE
389 md_number_to_chars(*where
, header
->s_paddr
, sizeof(header
->s_paddr
));
390 *where
+= sizeof(header
->s_paddr
);
392 md_number_to_chars(*where
, header
->s_vaddr
, sizeof(header
->s_vaddr
));
393 *where
+= sizeof(header
->s_vaddr
);
395 md_number_to_chars(*where
, header
->s_size
, sizeof(header
->s_size
));
396 *where
+= sizeof(header
->s_size
);
398 md_number_to_chars(*where
, header
->s_scnptr
, sizeof(header
->s_scnptr
));
399 *where
+= sizeof(header
->s_scnptr
);
401 md_number_to_chars(*where
, header
->s_relptr
, sizeof(header
->s_relptr
));
402 *where
+= sizeof(header
->s_relptr
);
404 md_number_to_chars(*where
, header
->s_lnnoptr
, sizeof(header
->s_lnnoptr
));
405 *where
+= sizeof(header
->s_lnnoptr
);
407 md_number_to_chars(*where
, header
->s_nreloc
, sizeof(header
->s_nreloc
));
408 *where
+= sizeof(header
->s_nreloc
);
410 md_number_to_chars(*where
, header
->s_nlnno
, sizeof(header
->s_nlnno
));
411 *where
+= sizeof(header
->s_nlnno
);
413 md_number_to_chars(*where
, header
->s_flags
, sizeof(header
->s_flags
));
414 *where
+= sizeof(header
->s_flags
);
416 #else /* CROSS_ASSEMBLE */
418 append(where
, (char *) header
, sizeof(*header
));
420 #endif /* CROSS_ASSEMBLE */
423 } /* c_section_header_append() */
426 void obj_emit_symbols(where
, symbol_rootP
)
428 symbolS
*symbol_rootP
;
432 * Emit all symbols left in the symbol chain.
434 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next(symbolP
)) {
435 /* Used to save the offset of the name. It is used to point
436 to the string in memory but must be a file offset. */
437 register char * temp
;
439 tc_coff_symbol_emit_hook(symbolP
);
441 temp
= S_GET_NAME(symbolP
);
442 if (SF_GET_STRING(symbolP
)) {
443 S_SET_OFFSET(symbolP
, symbolP
->sy_name_offset
);
444 S_SET_ZEROES(symbolP
, 0);
446 bzero(symbolP
->sy_symbol
.ost_entry
.n_name
, SYMNMLEN
);
447 strncpy(symbolP
->sy_symbol
.ost_entry
.n_name
, temp
, SYMNMLEN
);
449 obj_symbol_to_chars(where
, symbolP
);
450 S_SET_NAME(symbolP
,temp
);
452 } /* obj_emit_symbols() */
454 /* Merge a debug symbol containing debug information into a normal symbol. */
456 void c_symbol_merge(debug
, normal
)
460 S_SET_DATA_TYPE(normal
, S_GET_DATA_TYPE(debug
));
461 S_SET_STORAGE_CLASS(normal
, S_GET_STORAGE_CLASS(debug
));
463 if (S_GET_NUMBER_AUXILIARY(debug
) > S_GET_NUMBER_AUXILIARY(normal
)) {
464 S_SET_NUMBER_AUXILIARY(normal
, S_GET_NUMBER_AUXILIARY(debug
));
465 } /* take the most we have */
467 if (S_GET_NUMBER_AUXILIARY(debug
) > 0) {
468 memcpy((char*)&normal
->sy_symbol
.ost_auxent
[0], (char*)&debug
->sy_symbol
.ost_auxent
[0], S_GET_NUMBER_AUXILIARY(debug
) * AUXESZ
);
469 } /* Move all the auxiliary information */
471 /* Move the debug flags. */
472 SF_SET_DEBUG_FIELD(normal
, SF_GET_DEBUG_FIELD(debug
));
473 } /* c_symbol_merge() */
475 static symbolS
*previous_file_symbol
= NULL
;
477 void c_dot_file_symbol(filename
)
482 symbolP
= symbol_new(".file",
487 S_SET_STORAGE_CLASS(symbolP
, C_FILE
);
488 S_SET_NUMBER_AUXILIARY(symbolP
, 1);
489 SA_SET_FILE_FNAME(symbolP
, filename
);
490 SF_SET_DEBUG(symbolP
);
491 S_SET_VALUE(symbolP
, (long) previous_file_symbol
);
493 previous_file_symbol
= symbolP
;
495 /* Make sure that the symbol is first on the symbol chain */
496 if (symbol_rootP
!= symbolP
) {
497 if (symbolP
== symbol_lastP
) {
498 symbol_lastP
= symbol_lastP
->sy_previous
;
499 } /* if it was the last thing on the list */
501 symbol_remove(symbolP
, &symbol_rootP
, &symbol_lastP
);
502 symbol_insert(symbolP
, symbol_rootP
, &symbol_rootP
, &symbol_lastP
);
503 symbol_rootP
= symbolP
;
504 } /* if not first on the list */
506 } /* c_dot_file_symbol() */
508 * Build a 'section static' symbol.
511 char *c_section_symbol(name
, value
, length
, nreloc
, nlnno
)
515 unsigned short nreloc
;
516 unsigned short nlnno
;
520 symbolP
= symbol_new(name
,
529 S_SET_STORAGE_CLASS(symbolP
, C_STAT
);
530 S_SET_NUMBER_AUXILIARY(symbolP
, 1);
532 SA_SET_SCN_SCNLEN(symbolP
, length
);
533 SA_SET_SCN_NRELOC(symbolP
, nreloc
);
534 SA_SET_SCN_NLINNO(symbolP
, nlnno
);
536 SF_SET_STATICS(symbolP
);
538 return (char*)symbolP
;
539 } /* c_section_symbol() */
541 void c_section_header(header
,
562 strncpy(header
->s_name
, name
, 8);
563 header
->s_paddr
= header
->s_vaddr
= core_address
;
564 header
->s_scnptr
= ((header
->s_size
= size
) != 0) ? data_ptr
: 0;
565 header
->s_relptr
= reloc_ptr
;
566 header
->s_lnnoptr
= lineno_ptr
;
567 header
->s_nreloc
= reloc_number
;
568 header
->s_nlnno
= lineno_number
;
570 #ifdef OBJ_COFF_SECTION_HEADER_HAS_ALIGNMENT
571 #ifdef OBJ_COFF_BROKEN_ALIGNMENT
572 header
->s_align
= ((name
[1] == 'b' || (size
> 0)) ? 16 : 0);
574 header
->s_align
= ((alignment
== 0)
577 #endif /* OBJ_COFF_BROKEN_ALIGNMENT */
578 #endif /* OBJ_COFF_SECTION_HEADER_HAS_ALIGNMENT */
580 header
->s_flags
= STYP_REG
| (name
[1] == 't'
588 } /* c_section_header() */
590 /* Line number handling */
592 int function_lineoff
= -1; /* Offset in line#s where the last function
593 started (the odd entry for line #0) */
594 int text_lineno_number
= 0;
595 int our_lineno_number
= 0; /* we use this to build pointers from .bf's
596 into the linetable. It should match
597 exactly the values that are later
598 assigned in text_lineno_number by
600 lineno
* lineno_lastP
= (lineno
*)0;
603 c_line_new(paddr
, line_number
, frag
)
605 unsigned short line_number
;
608 lineno
* new_line
= (lineno
*)xmalloc(sizeof(lineno
));
610 new_line
->line
.l_addr
.l_paddr
= paddr
;
611 new_line
->line
.l_lnno
= line_number
;
612 new_line
->frag
= (char*)frag
;
613 new_line
->next
= (lineno
*)0;
615 if (lineno_rootP
== (lineno
*)0)
616 lineno_rootP
= new_line
;
618 lineno_lastP
->next
= new_line
;
619 lineno_lastP
= new_line
;
620 return LINESZ
* our_lineno_number
++;
623 void obj_emit_lineno(where
, line
, file_start
)
630 for (; line
; line
= line
->next
) {
631 line_entry
= &line
->line
;
633 /* FIXME-SOMEDAY Resolving the sy_number of function linno's used to be done in
634 write_object_file() but their symbols need a fileptr to the lnno, so
635 I moved this resolution check here. xoxorich. */
637 if (line_entry
->l_lnno
== 0) {
638 /* There is a good chance that the symbol pointed to
639 is not the one that will be emitted and that the
640 sy_number is not accurate. */
644 symbolP
= (symbolS
*) line_entry
->l_addr
.l_symndx
;
646 line_entry
->l_addr
.l_symndx
= symbolP
->sy_number
;
647 symbolP
->sy_symbol
.ost_auxent
[0].x_sym
.x_fcnary
.x_fcn
.x_lnnoptr
= *where
- file_start
;
649 } /* if this is a function linno */
651 /* No matter which member of the union we process, they are
653 #ifdef CROSS_ASSEMBLE
654 md_number_to_chars(*where
, line_entry
->l_addr
.l_paddr
, sizeof(line_entry
->l_addr
.l_paddr
));
655 *where
+= sizeof(line_entry
->l_addr
.l_paddr
);
657 md_number_to_chars(*where
, line_entry
->l_lnno
, sizeof(line_entry
->l_lnno
));
658 *where
+= sizeof(line_entry
->l_lnno
);
659 #else /* CROSS_ASSEMBLE */
660 append(where
, (char *) line_entry
, LINESZ
);
661 #endif /* CROSS_ASSEMBLE */
663 } /* for each line number */
666 } /* obj_emit_lineno() */
668 void obj_symbol_new_hook(symbolP
)
671 char underscore
= 0; /* Symbol has leading _ */
673 /* Effective symbol */
674 /* Store the pointer in the offset. */
675 S_SET_ZEROES(symbolP
, 0L);
676 S_SET_DATA_TYPE(symbolP
, T_NULL
);
677 S_SET_STORAGE_CLASS(symbolP
, 0);
678 S_SET_NUMBER_AUXILIARY(symbolP
, 0);
679 /* Additional information */
680 symbolP
->sy_symbol
.ost_flags
= 0;
681 /* Auxiliary entries */
682 bzero((char*)&symbolP
->sy_symbol
.ost_auxent
[0], AUXESZ
);
685 /* Remove leading underscore at the beginning of the symbol.
686 * This is to be compatible with the standard librairies.
688 if (*S_GET_NAME(symbolP
) == '_') {
690 S_SET_NAME(symbolP
, S_GET_NAME(symbolP
) + 1);
691 } /* strip underscore */
692 #endif /* STRIP_UNDERSCORE */
694 if (S_IS_STRING(symbolP
))
695 SF_SET_STRING(symbolP
);
696 if (!underscore
&& S_IS_LOCAL(symbolP
))
697 SF_SET_LOCAL(symbolP
);
700 } /* obj_symbol_new_hook() */
703 stack
* stack_init(chunk_size
, element_size
)
704 unsigned long chunk_size
;
705 unsigned long element_size
;
709 if ((st
= (stack
*)malloc(sizeof(stack
))) == (stack
*)0)
711 if ((st
->data
= malloc(chunk_size
)) == (char*)0) {
716 st
->size
= chunk_size
;
717 st
->chunk_size
= chunk_size
;
718 st
->element_size
= element_size
;
722 void stack_delete(st
)
729 char *stack_push(st
, element
)
733 if (st
->pointer
+ st
->element_size
>= st
->size
) {
734 st
->size
+= st
->chunk_size
;
735 if ((st
->data
= xrealloc(st
->data
, st
->size
)) == (char*)0)
738 memcpy(st
->data
+ st
->pointer
, element
, st
->element_size
);
739 st
->pointer
+= st
->element_size
;
740 return st
->data
+ st
->pointer
;
746 if ((st
->pointer
-= st
->element_size
) < 0) {
750 return st
->data
+ st
->pointer
;
756 return st
->data
+ st
->pointer
- st
->element_size
;
761 * Handle .ln directives.
764 static void obj_coff_ln() {
765 if (def_symbol_in_progress
!= NULL
) {
766 as_warn(".ln pseudo-op inside .def/.endef: ignored.");
767 demand_empty_rest_of_line();
769 } /* wrong context */
771 c_line_new(obstack_next_free(&frags
) - frag_now
->fr_literal
,
772 get_absolute_expression(),
775 demand_empty_rest_of_line();
777 } /* obj_coff_line() */
782 * Handle .def directives.
784 * One might ask : why can't we symbol_new if the symbol does not
785 * already exist and fill it with debug information. Because of
786 * the C_EFCN special symbol. It would clobber the value of the
787 * function symbol before we have a chance to notice that it is
788 * a C_EFCN. And a second reason is that the code is more clear this
789 * way. (at least I think it is :-).
793 #define SKIP_SEMI_COLON() while (*input_line_pointer++ != ';')
794 #define SKIP_WHITESPACES() while (*input_line_pointer == ' ' || \
795 *input_line_pointer == '\t') \
796 input_line_pointer++;
798 static void obj_coff_def(what
)
801 char name_end
; /* Char after the end of name */
802 char *symbol_name
; /* Name of the debug symbol */
803 char *symbol_name_copy
; /* Temporary copy of the name */
804 unsigned int symbol_name_length
;
805 /*$char* directiveP;$ */ /* Name of the pseudo opcode */
806 /*$char directive[MAX_DIRECTIVE];$ */ /* Backup of the directive */
807 /*$char end = 0;$ */ /* If 1, stop parsing */
809 if (def_symbol_in_progress
!= NULL
) {
810 as_warn(".def pseudo-op used inside of .def/.endef: ignored.");
811 demand_empty_rest_of_line();
813 } /* if not inside .def/.endef */
817 def_symbol_in_progress
= (symbolS
*) obstack_alloc(¬es
, sizeof(*def_symbol_in_progress
));
818 bzero(def_symbol_in_progress
, sizeof(*def_symbol_in_progress
));
820 symbol_name
= input_line_pointer
;
821 name_end
= get_symbol_end();
822 symbol_name_length
= strlen(symbol_name
);
823 symbol_name_copy
= xmalloc(symbol_name_length
+ 1);
824 strcpy(symbol_name_copy
, symbol_name
);
826 /* Initialize the new symbol */
828 S_SET_NAME(def_symbol_in_progress
, (*symbol_name_copy
== '_'
829 ? symbol_name_copy
+ 1
830 : symbol_name_copy
));
831 #else /* STRIP_UNDERSCORE */
832 S_SET_NAME(def_symbol_in_progress
, symbol_name_copy
);
833 #endif /* STRIP_UNDERSCORE */
834 /* free(symbol_name_copy); */
835 def_symbol_in_progress
->sy_name_offset
= ~0;
836 def_symbol_in_progress
->sy_number
= ~0;
837 def_symbol_in_progress
->sy_frag
= &zero_address_frag
;
839 if (S_IS_STRING(def_symbol_in_progress
)) {
840 SF_SET_STRING(def_symbol_in_progress
);
843 *input_line_pointer
= name_end
;
845 demand_empty_rest_of_line();
847 } /* obj_coff_def() */
849 unsigned int dim_index
;
850 static void obj_coff_endef() {
852 /* DIM BUG FIX sac@cygnus.com */
854 if (def_symbol_in_progress
== NULL
) {
855 as_warn(".endef pseudo-op used outside of .def/.endef: ignored.");
856 demand_empty_rest_of_line();
858 } /* if not inside .def/.endef */
860 /* Set the section number according to storage class. */
861 switch (S_GET_STORAGE_CLASS(def_symbol_in_progress
)) {
865 SF_SET_TAG(def_symbol_in_progress
);
866 /* intentional fallthrough */
869 SF_SET_DEBUG(def_symbol_in_progress
);
870 S_SET_SEGMENT(def_symbol_in_progress
, SEG_DEBUG
);
874 SF_SET_LOCAL(def_symbol_in_progress
); /* Do not emit this symbol. */
875 /* intentional fallthrough */
877 SF_SET_PROCESS(def_symbol_in_progress
); /* Will need processing before writing */
878 /* intentional fallthrough */
880 S_SET_SEGMENT(def_symbol_in_progress
, SEG_TEXT
);
882 if (def_symbol_in_progress
->sy_symbol
.ost_entry
.n_name
[1] == 'b') { /* .bf */
883 if (function_lineoff
< 0) {
884 fprintf(stderr
, "`.bf' symbol without preceding function\n");
885 } /* missing function symbol */
886 SA_GET_SYM_LNNOPTR(def_symbol_in_progress
) = function_lineoff
;
887 SF_SET_PROCESS(def_symbol_in_progress
); /* Will need relocating */
888 function_lineoff
= -1;
894 #endif /* C_AUTOARG */
904 SF_SET_DEBUG(def_symbol_in_progress
);
905 S_SET_SEGMENT(def_symbol_in_progress
, SEG_ABSOLUTE
);
911 /* Valid but set somewhere else (s_comm, s_lcomm, colon) */
917 as_warn("unexpected storage class %d", S_GET_STORAGE_CLASS(def_symbol_in_progress
));
919 } /* switch on storage class */
921 /* Now that we have built a debug symbol, try to
922 find if we should merge with an existing symbol
923 or not. If a symbol is C_EFCN or SEG_ABSOLUTE or
924 untagged SEG_DEBUG it never merges. */
926 /* Two cases for functions. Either debug followed
927 by definition or definition followed by debug.
928 For definition first, we will merge the debug
929 symbol into the definition. For debug first, the
930 lineno entry MUST point to the definition
931 function or else it will point off into space
932 when obj_crawl_symbol_chain() merges the debug
933 symbol into the real symbol. Therefor, let's
934 presume the debug symbol is a real function
937 /* FIXME-SOON If for some reason the definition
938 label/symbol is never seen, this will probably
939 leave an undefined symbol at link time. */
941 if (S_GET_STORAGE_CLASS(def_symbol_in_progress
) == C_EFCN
942 || (S_GET_SEGMENT(def_symbol_in_progress
) == SEG_DEBUG
943 && !SF_GET_TAG(def_symbol_in_progress
))
944 || S_GET_SEGMENT(def_symbol_in_progress
) == SEG_ABSOLUTE
945 || (symbolP
= symbol_find_base(S_GET_NAME(def_symbol_in_progress
), DO_NOT_STRIP
)) == NULL
) {
947 symbol_append(def_symbol_in_progress
, symbol_lastP
, &symbol_rootP
, &symbol_lastP
);
950 /* This symbol already exists, merge the
951 newly created symbol into the old one.
952 This is not mandatory. The linker can
953 handle duplicate symbols correctly. But I
954 guess that it save a *lot* of space if
955 the assembly file defines a lot of
958 /* The debug entry (def_symbol_in_progress)
959 is merged into the previous definition. */
961 c_symbol_merge(def_symbol_in_progress
, symbolP
);
962 /* FIXME-SOON Should *def_symbol_in_progress be free'd? xoxorich. */
963 def_symbol_in_progress
= symbolP
;
965 if (SF_GET_FUNCTION(def_symbol_in_progress
)
966 || SF_GET_TAG(def_symbol_in_progress
)) {
967 /* For functions, and tags, the symbol *must* be where the debug symbol
968 appears. Move the existing symbol to the current place. */
969 /* If it already is at the end of the symbol list, do nothing */
970 if (def_symbol_in_progress
!= symbol_lastP
) {
971 symbol_remove(def_symbol_in_progress
, &symbol_rootP
, &symbol_lastP
);
972 symbol_append(def_symbol_in_progress
, symbol_lastP
, &symbol_rootP
, &symbol_lastP
);
973 } /* if not already in place */
975 } /* normal or mergable */
977 if (SF_GET_TAG(def_symbol_in_progress
)
978 && symbol_find_base(S_GET_NAME(def_symbol_in_progress
), DO_NOT_STRIP
) == NULL
) {
979 tag_insert(S_GET_NAME(def_symbol_in_progress
), def_symbol_in_progress
);
980 } /* If symbol is a {structure,union} tag, associate symbol to its name. */
982 if (SF_GET_FUNCTION(def_symbol_in_progress
)) {
983 know(sizeof(def_symbol_in_progress
) <= sizeof(long));
984 function_lineoff
= c_line_new((long) def_symbol_in_progress
, 0, &zero_address_frag
);
985 SF_SET_PROCESS(def_symbol_in_progress
);
987 if (symbolP
== NULL
) {
988 /* That is, if this is the first
989 time we've seen the function... */
990 symbol_table_insert(def_symbol_in_progress
);
991 } /* definition follows debug */
992 } /* Create the line number entry pointing to the function being defined */
994 def_symbol_in_progress
= NULL
;
995 demand_empty_rest_of_line();
997 } /* obj_coff_endef() */
999 This code expects all the dims to be after one another
, and that is
not true
1002 static void obj_coff_dim() {
1003 register int dim_index
;
1005 if (def_symbol_in_progress
== NULL
) {
1006 as_warn(".dim pseudo-op used outside of .def/.endef: ignored.");
1007 demand_empty_rest_of_line();
1009 } /* if not inside .def/.endef */
1011 S_SET_NUMBER_AUXILIARY(def_symbol_in_progress
, 1);
1013 for (dim_index
= 0; dim_index
< DIMNUM
; dim_index
++) {
1015 SA_SET_SYM_DIMEN(def_symbol_in_progress
, dim_index
, get_absolute_expression());
1017 switch (*input_line_pointer
) {
1020 input_line_pointer
++;
1024 as_warn("badly formed .dim directive ignored");
1025 /* intentional fallthrough */
1029 } /* switch on following character */
1030 } /* for each dimension */
1032 demand_empty_rest_of_line();
1034 } /* obj_coff_dim() */
1040 if (def_symbol_in_progress
== NULL
) {
1041 as_warn(".dim pseudo-op used outside of .def/.endef: ignored.");
1042 demand_empty_rest_of_line();
1044 } /* if not inside .def/.endef */
1047 S_SET_NUMBER_AUXILIARY(def_symbol_in_progress
, 1);
1049 /* Grab as many dims as we can fit, until ; or full */
1050 while (dim_index
< DIMNUM
)
1053 SA_SET_SYM_DIMEN(def_symbol_in_progress
, dim_index
, get_absolute_expression());
1055 if (*input_line_pointer
== ';') break;
1056 if (*input_line_pointer
!= ',') {
1057 as_warn("badly formed .dim directive ignored");
1060 input_line_pointer
++;
1062 demand_empty_rest_of_line();
1064 } /* obj_coff_dim() */
1067 static void obj_coff_line() {
1068 if (def_symbol_in_progress
== NULL
) {
1071 } /* if it looks like a stabs style line */
1073 S_SET_NUMBER_AUXILIARY(def_symbol_in_progress
, 1);
1074 SA_SET_SYM_LNNO(def_symbol_in_progress
, get_absolute_expression());
1076 demand_empty_rest_of_line();
1078 } /* obj_coff_line() */
1080 static void obj_coff_size() {
1081 if (def_symbol_in_progress
== NULL
) {
1082 as_warn(".size pseudo-op used outside of .def/.endef ignored.");
1083 demand_empty_rest_of_line();
1085 } /* if not inside .def/.endef */
1087 S_SET_NUMBER_AUXILIARY(def_symbol_in_progress
, 1);
1088 SA_SET_SYM_SIZE(def_symbol_in_progress
, get_absolute_expression());
1089 demand_empty_rest_of_line();
1091 } /* obj_coff_size() */
1093 static void obj_coff_scl() {
1094 if (def_symbol_in_progress
== NULL
) {
1095 as_warn(".scl pseudo-op used outside of .def/.endef ignored.");
1096 demand_empty_rest_of_line();
1098 } /* if not inside .def/.endef */
1100 S_SET_STORAGE_CLASS(def_symbol_in_progress
, get_absolute_expression());
1101 demand_empty_rest_of_line();
1103 } /* obj_coff_scl() */
1105 static void obj_coff_tag() {
1109 if (def_symbol_in_progress
== NULL
) {
1110 as_warn(".tag pseudo-op used outside of .def/.endef ignored.");
1111 demand_empty_rest_of_line();
1113 } /* if not inside .def/.endef */
1115 S_SET_NUMBER_AUXILIARY(def_symbol_in_progress
, 1);
1116 symbol_name
= input_line_pointer
;
1117 name_end
= get_symbol_end();
1119 /* Assume that the symbol referred to by .tag is always defined. */
1120 /* This was a bad assumption. I've added find_or_make. xoxorich. */
1121 SA_SET_SYM_TAGNDX(def_symbol_in_progress
, (long) tag_find_or_make(symbol_name
));
1122 if (SA_GET_SYM_TAGNDX(def_symbol_in_progress
) == 0L) {
1123 as_warn("tag not found for .tag %s", symbol_name
);
1126 SF_SET_TAGGED(def_symbol_in_progress
);
1127 *input_line_pointer
= name_end
;
1129 demand_empty_rest_of_line();
1131 } /* obj_coff_tag() */
1133 static void obj_coff_type() {
1134 if (def_symbol_in_progress
== NULL
) {
1135 as_warn(".type pseudo-op used outside of .def/.endef ignored.");
1136 demand_empty_rest_of_line();
1138 } /* if not inside .def/.endef */
1140 S_SET_DATA_TYPE(def_symbol_in_progress
, get_absolute_expression());
1142 if (ISFCN(S_GET_DATA_TYPE(def_symbol_in_progress
)) &&
1143 S_GET_STORAGE_CLASS(def_symbol_in_progress
) != C_TPDEF
) {
1144 SF_SET_FUNCTION(def_symbol_in_progress
);
1145 } /* is a function */
1147 demand_empty_rest_of_line();
1149 } /* obj_coff_type() */
1151 static void obj_coff_val() {
1152 if (def_symbol_in_progress
== NULL
) {
1153 as_warn(".val pseudo-op used outside of .def/.endef ignored.");
1154 demand_empty_rest_of_line();
1156 } /* if not inside .def/.endef */
1158 if (is_name_beginner(*input_line_pointer
)) {
1159 char *symbol_name
= input_line_pointer
;
1160 char name_end
= get_symbol_end();
1162 if (!strcmp(symbol_name
, ".")) {
1163 def_symbol_in_progress
->sy_frag
= frag_now
;
1164 S_SET_VALUE(def_symbol_in_progress
, obstack_next_free(&frags
) - frag_now
->fr_literal
);
1165 /* If the .val is != from the .def (e.g. statics) */
1166 } else if (strcmp(S_GET_NAME(def_symbol_in_progress
), symbol_name
)) {
1167 def_symbol_in_progress
->sy_forward
= symbol_find_or_make(symbol_name
);
1169 /* If the segment is undefined when the forward
1170 reference is solved, then copy the segment id
1171 from the forward symbol. */
1172 SF_SET_GET_SEGMENT(def_symbol_in_progress
);
1174 /* Otherwise, it is the name of a non debug symbol and its value will be calculated later. */
1175 *input_line_pointer
= name_end
;
1177 S_SET_VALUE(def_symbol_in_progress
, get_absolute_expression());
1178 } /* if symbol based */
1180 demand_empty_rest_of_line();
1182 } /* obj_coff_val() */
1185 * Maintain a list of the tagnames of the structres.
1188 static void tag_init() {
1189 tag_hash
= hash_new();
1193 static void tag_insert(name
, symbolP
)
1197 register char * error_string
;
1199 if (*(error_string
= hash_jam(tag_hash
, name
, (char *)symbolP
))) {
1200 as_fatal("Inserting \"%s\" into structure table failed: %s",
1201 name
, error_string
);
1204 } /* tag_insert() */
1206 static symbolS
*tag_find_or_make(name
)
1211 if ((symbolP
= tag_find(name
)) == NULL
) {
1212 symbolP
= symbol_new(name
,
1215 &zero_address_frag
);
1217 tag_insert(S_GET_NAME(symbolP
), symbolP
);
1218 symbol_table_insert(symbolP
);
1222 } /* tag_find_or_make() */
1224 static symbolS
*tag_find(name
)
1227 #if STRIP_UNDERSCORE
1228 if (*name
== '_') name
++;
1229 #endif /* STRIP_UNDERSCORE */
1230 return((symbolS
*)hash_find(tag_hash
, name
));
1233 void obj_read_begin_hook() {
1234 /* These had better be the same. Usually 18 bytes. */
1235 know(sizeof(SYMENT
) == sizeof(AUXENT
));
1236 know(SYMESZ
== AUXESZ
);
1241 } /* obj_read_begin_hook() */
1243 void obj_crawl_symbol_chain(headers
)
1244 object_headers
*headers
;
1246 int symbol_number
= 0;
1248 symbolS
*last_functionP
= NULL
;
1251 symbolS
*symbol_externP
= NULL
;
1252 symbolS
*symbol_extern_lastP
= NULL
;
1254 /* Initialize the stack used to keep track of the matching .bb .be */
1255 stack
* block_stack
= stack_init(512, sizeof(symbolS
*));
1257 /* JF deal with forward references first... */
1258 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next(symbolP
)) {
1259 if (symbolP
->sy_forward
) {
1260 S_SET_VALUE(symbolP
, (S_GET_VALUE(symbolP
)
1261 + S_GET_VALUE(symbolP
->sy_forward
)
1262 + symbolP
->sy_forward
->sy_frag
->fr_address
));
1264 if (SF_GET_GET_SEGMENT(symbolP
)) {
1265 S_SET_SEGMENT(symbolP
, S_GET_SEGMENT(symbolP
->sy_forward
));
1266 } /* forward segment also */
1268 symbolP
->sy_forward
=0;
1269 } /* if it has a forward reference */
1270 } /* walk the symbol chain */
1272 tc_crawl_symbol_chain(headers
);
1274 /* The symbol list should be ordered according to the following sequence
1277 * . debug entries for functions
1278 * . fake symbols for .text .data and .bss
1280 * . undefined symbols
1281 * But this is not mandatory. The only important point is to put the
1282 * undefined symbols at the end of the list.
1285 if (symbol_rootP
== NULL
1286 || S_GET_STORAGE_CLASS(symbol_rootP
) != C_FILE
) {
1287 know(!previous_file_symbol
);
1288 c_dot_file_symbol("fake");
1289 } /* Is there a .file symbol ? If not insert one at the beginning. */
1292 * Build up static symbols for .text, .data and .bss
1294 dot_text_symbol
= (symbolS
*)
1295 c_section_symbol(".text",
1297 H_GET_TEXT_SIZE(headers
),
1298 0/*text_relocation_number */,
1299 0/*text_lineno_number */);
1301 dot_data_symbol
= (symbolS
*)
1302 c_section_symbol(".data",
1303 H_GET_TEXT_SIZE(headers
),
1304 H_GET_DATA_SIZE(headers
),
1305 0/*data_relocation_number */,
1306 0); /* There are no data lineno entries */
1308 dot_bss_symbol
= (symbolS
*)
1309 c_section_symbol(".bss",
1310 H_GET_TEXT_SIZE(headers
) + H_GET_DATA_SIZE(headers
),
1311 H_GET_BSS_SIZE(headers
),
1312 0, /* No relocation for a bss section. */
1313 0); /* There are no bss lineno entries */
1316 verify_symbol_chain(symbol_rootP
, symbol_lastP
);
1319 /* Three traversals of symbol chains here. The
1320 first traversal yanks externals into a temporary
1321 chain, removing the externals from the global
1322 chain, numbers symbols, and does some other guck.
1323 The second traversal is on the temporary chain of
1324 externals and just appends them to the global
1325 chain again, numbering them as we go. The third
1326 traversal patches pointers to symbols (using sym
1327 indexes). The last traversal was once done as
1328 part of the first pass, but that fails when a
1329 reference preceeds a definition as the definition
1330 has no number at the time we process the
1333 /* Note that symbolP will be NULL at the end of a loop
1334 if an external was at the beginning of the list (it
1335 gets moved off the list). Hence the weird check in
1338 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbolP
? symbol_next(symbolP
) : symbol_rootP
) {
1340 if (!SF_GET_DEBUG(symbolP
)) {
1341 /* Debug symbols do not need all this rubbish */
1342 symbolS
* real_symbolP
;
1344 /* L* and C_EFCN symbols never merge. */
1345 if (!SF_GET_LOCAL(symbolP
)
1346 && (real_symbolP
= symbol_find_base(S_GET_NAME(symbolP
), DO_NOT_STRIP
))
1347 && real_symbolP
!= symbolP
) {
1348 /* FIXME-SOON: where do dups come from? Maybe tag references before definitions? xoxorich. */
1349 /* Move the debug data from the debug symbol to the
1350 real symbol. Do NOT do the oposite (i.e. move from
1351 real symbol to debug symbol and remove real symbol from the
1352 list.) Because some pointers refer to the real symbol
1353 whereas no pointers refer to the debug symbol. */
1354 c_symbol_merge(symbolP
, real_symbolP
);
1355 /* Replace the current symbol by the real one */
1356 /* The symbols will never be the last or the first
1357 because : 1st symbol is .file and 3 last symbols are
1358 .text, .data, .bss */
1359 symbol_remove(real_symbolP
, &symbol_rootP
, &symbol_lastP
);
1360 symbol_insert(real_symbolP
, symbolP
, &symbol_rootP
, &symbol_lastP
);
1361 symbol_remove(symbolP
, &symbol_rootP
, &symbol_lastP
);
1362 symbolP
= real_symbolP
;
1363 } /* if not local but dup'd */
1365 if (flagseen
['R'] && (S_GET_SEGMENT(symbolP
) == SEG_DATA
)) {
1366 S_SET_SEGMENT(symbolP
, SEG_TEXT
);
1367 } /* push data into text */
1369 S_SET_VALUE(symbolP
, S_GET_VALUE(symbolP
) + symbolP
->sy_frag
->fr_address
);
1371 if (!S_IS_DEFINED(symbolP
) && !SF_GET_LOCAL(symbolP
)) {
1372 S_SET_EXTERNAL(symbolP
);
1373 } else if (S_GET_STORAGE_CLASS(symbolP
) == C_NULL
) {
1374 if (S_GET_SEGMENT(symbolP
) == SEG_TEXT
){
1375 S_SET_STORAGE_CLASS(symbolP
, C_LABEL
);
1377 S_SET_STORAGE_CLASS(symbolP
, C_STAT
);
1379 } /* no storage class yet */
1381 /* Mainly to speed up if not -g */
1382 if (SF_GET_PROCESS(symbolP
)) {
1383 /* Handle the nested blocks auxiliary info. */
1384 if (S_GET_STORAGE_CLASS(symbolP
) == C_BLOCK
) {
1385 if (!strcmp(S_GET_NAME(symbolP
), ".bb"))
1386 stack_push(block_stack
, (char *) &symbolP
);
1388 register symbolS
* begin_symbolP
;
1389 begin_symbolP
= *(symbolS
**)stack_pop(block_stack
);
1390 if (begin_symbolP
== (symbolS
*)0)
1391 as_warn("mismatched .eb");
1393 SA_SET_SYM_ENDNDX(begin_symbolP
, symbol_number
+2);
1396 /* If we are able to identify the type of a function, and we
1397 are out of a function (last_functionP == 0) then, the
1398 function symbol will be associated with an auxiliary
1400 if (last_functionP
== (symbolS
*)0 &&
1401 SF_GET_FUNCTION(symbolP
)) {
1402 last_functionP
= symbolP
;
1404 if (S_GET_NUMBER_AUXILIARY(symbolP
) < 1) {
1405 S_SET_NUMBER_AUXILIARY(symbolP
, 1);
1406 } /* make it at least 1 */
1408 /* Clobber possible stale .dim information. */
1409 bzero(symbolP
->sy_symbol
.ost_auxent
[0].x_sym
.x_fcnary
.x_ary
.x_dimen
,
1410 sizeof(symbolP
->sy_symbol
.ost_auxent
[0].x_sym
.x_fcnary
.x_ary
.x_dimen
));
1412 /* The C_FCN doesn't need any additional information.
1413 I don't even know if this is needed for sdb. But the
1414 standard assembler generates it, so...
1416 if (S_GET_STORAGE_CLASS(symbolP
) == C_EFCN
) {
1417 if (last_functionP
== (symbolS
*)0)
1418 as_fatal("C_EFCN symbol out of scope");
1419 SA_SET_SYM_FSIZE(last_functionP
,
1420 (long)(S_GET_VALUE(symbolP
) -
1421 S_GET_VALUE(last_functionP
)));
1422 SA_SET_SYM_ENDNDX(last_functionP
, symbol_number
);
1423 last_functionP
= (symbolS
*)0;
1426 } else if (SF_GET_TAG(symbolP
)) {
1427 /* First descriptor of a structure must point to
1428 the first slot after the structure description. */
1429 last_tagP
= symbolP
;
1431 } else if (S_GET_STORAGE_CLASS(symbolP
) == C_EOS
) {
1432 /* +2 take in account the current symbol */
1433 SA_SET_SYM_ENDNDX(last_tagP
, symbol_number
+ 2);
1434 } else if (S_GET_STORAGE_CLASS(symbolP
) == C_FILE
) {
1435 if (S_GET_VALUE(symbolP
)) {
1436 S_SET_VALUE((symbolS
*) S_GET_VALUE(symbolP
), symbol_number
);
1437 S_SET_VALUE(symbolP
, 0);
1438 } /* no one points at the first .file symbol */
1439 } /* if debug or tag or eos or file */
1441 /* We must put the external symbols apart. The loader
1442 does not bomb if we do not. But the references in
1443 the endndx field for a .bb symbol are not corrected
1444 if an external symbol is removed between .bb and .be.
1445 I.e in the following case :
1446 [20] .bb endndx = 22
1449 ld will move the symbol 21 to the end of the list but
1450 endndx will still be 22 instead of 21. */
1452 if (SF_GET_LOCAL(symbolP
)) {
1453 /* remove C_EFCN and LOCAL (L...) symbols */
1454 /* next pointer remains valid */
1455 symbol_remove(symbolP
, &symbol_rootP
, &symbol_lastP
);
1457 } else if (!S_IS_DEFINED(symbolP
) && !S_IS_DEBUG(symbolP
) && !SF_GET_STATICS(symbolP
)) {
1458 /* S_GET_STORAGE_CLASS(symbolP) == C_EXT && !SF_GET_FUNCTION(symbolP)) { */
1459 /* if external, Remove from the list */
1460 symbolS
*hold
= symbol_previous(symbolP
);
1462 symbol_remove(symbolP
, &symbol_rootP
, &symbol_lastP
);
1463 symbol_clear_list_pointers(symbolP
);
1464 symbol_append(symbolP
, symbol_extern_lastP
, &symbol_externP
, &symbol_extern_lastP
);
1467 if (SF_GET_STRING(symbolP
)) {
1468 symbolP
->sy_name_offset
= string_byte_count
;
1469 string_byte_count
+= strlen(S_GET_NAME(symbolP
)) + 1;
1471 symbolP
->sy_name_offset
= 0;
1472 } /* fix "long" names */
1474 symbolP
->sy_number
= symbol_number
;
1475 symbol_number
+= 1 + S_GET_NUMBER_AUXILIARY(symbolP
);
1476 } /* if local symbol */
1477 } /* traverse the symbol list */
1479 for (symbolP
= symbol_externP
; symbol_externP
;) {
1480 symbolS
*tmp
= symbol_externP
;
1483 symbol_remove(tmp
, &symbol_externP
, &symbol_extern_lastP
);
1484 symbol_append(tmp
, symbol_lastP
, &symbol_rootP
, &symbol_lastP
);
1487 if (SF_GET_STRING(tmp
)) {
1488 tmp
->sy_name_offset
= string_byte_count
;
1489 string_byte_count
+= strlen(S_GET_NAME(tmp
)) + 1;
1491 tmp
->sy_name_offset
= 0;
1492 } /* fix "long" names */
1494 tmp
->sy_number
= symbol_number
;
1495 symbol_number
+= 1 + S_GET_NUMBER_AUXILIARY(tmp
);
1496 } /* append the entire extern chain */
1498 /* When a tag reference preceeds the tag definition,
1499 the definition will not have a number at the time
1500 we process the reference during the first
1501 traversal. Thus, a second traversal. */
1503 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next(symbolP
)) {
1504 if (SF_GET_TAGGED(symbolP
)) {
1505 SA_SET_SYM_TAGNDX(symbolP
, ((symbolS
*) SA_GET_SYM_TAGNDX(symbolP
))->sy_number
);
1506 } /* If the symbol has a tagndx entry, resolve it */
1507 } /* second traversal */
1509 know(symbol_externP
== NULL
);
1510 know(symbol_extern_lastP
== NULL
);
1512 /* FIXME-SOMEDAY I'm counting line no's here so we know what to put in the section
1513 headers, and I'm resolving the addresses since I'm not sure how to
1514 do it later. I am NOT resolving the linno's representing functions.
1515 Their symbols need a fileptr pointing to this linno when emitted.
1516 Thus, I resolve them on emit. xoxorich. */
1518 for (lineP
= lineno_rootP
; lineP
; lineP
= lineP
->next
) {
1519 if (lineP
->line
.l_lnno
> 0) {
1520 lineP
->line
.l_addr
.l_paddr
+= ((fragS
*)lineP
->frag
)->fr_address
;
1524 text_lineno_number
++;
1525 } /* for each line number */
1527 H_SET_SYMBOL_TABLE_SIZE(headers
, symbol_number
);
1530 } /* obj_crawl_symbol_chain() */
1533 * Find strings by crawling along symbol table chain.
1536 void obj_emit_strings(where
)
1541 #ifdef CROSS_ASSEMBLE
1542 /* Gotta do md_ byte-ordering stuff for string_byte_count first - KWK */
1543 md_number_to_chars(*where
, string_byte_count
, sizeof(string_byte_count
));
1544 where
+= sizeof(string_byte_count
);
1545 #else /* CROSS_ASSEMBLE */
1546 append(where
, (char *) &string_byte_count
, (unsigned long) sizeof(string_byte_count
));
1547 #endif /* CROSS_ASSEMBLE */
1549 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next(symbolP
)) {
1550 if (SF_GET_STRING(symbolP
)) {
1551 append(where
, S_GET_NAME(symbolP
), (unsigned long)(strlen(S_GET_NAME(symbolP
)) + 1));
1552 } /* if it has a string */
1553 } /* walk the symbol chain */
1556 } /* obj_emit_strings() */
1558 void obj_pre_write_hook(headers
)
1559 object_headers
*headers
;
1561 register int text_relocation_number
= 0;
1562 register int data_relocation_number
= 0;
1563 register fixS
*fixP
;
1565 /* FIXME-SOMEDAY this should be done at
1566 fixup_segment time but I'm going to wait until I
1567 do multiple segments. xoxorich. */
1568 /* Count the number of relocation entries for text and data */
1569 for (fixP
= text_fix_root
; fixP
; fixP
= fixP
->fx_next
) {
1570 if (fixP
->fx_addsy
) {
1571 ++text_relocation_number
;
1573 /* two relocs per callj under coff. */
1574 if (fixP
->fx_callj
) {
1575 ++text_relocation_number
;
1576 } /* if callj and not already fixed. */
1577 #endif /* TC_I960 */
1579 } /* if not yet fixed */
1580 } /* for each fix */
1582 SA_SET_SCN_NRELOC(dot_text_symbol
, text_relocation_number
);
1583 /* Assign the number of line number entries for the text section */
1584 SA_SET_SCN_NLINNO(dot_text_symbol
, text_lineno_number
);
1585 /* Assign the size of the section */
1586 SA_SET_SCN_SCNLEN(dot_text_symbol
, H_GET_TEXT_SIZE(headers
));
1588 for (fixP
= data_fix_root
; fixP
; fixP
= fixP
->fx_next
) {
1589 if (fixP
->fx_addsy
) {
1590 ++data_relocation_number
;
1591 } /* if still relocatable */
1592 } /* for each fix */
1594 SA_SET_SCN_NRELOC(dot_data_symbol
, data_relocation_number
);
1595 /* Assign the size of the section */
1596 SA_SET_SCN_SCNLEN(dot_data_symbol
, H_GET_DATA_SIZE(headers
));
1598 /* Assign the size of the section */
1599 SA_SET_SCN_SCNLEN(dot_bss_symbol
, H_GET_BSS_SIZE(headers
));
1601 /* Fill in extra coff fields */
1603 /* Initialize general line number information. */
1604 H_SET_LINENO_SIZE(headers
, text_lineno_number
* LINESZ
);
1607 H_SET_FILE_MAGIC_NUMBER(headers
, FILE_HEADER_MAGIC
);
1608 H_SET_NUMBER_OF_SECTIONS(headers
, 3); /* text+data+bss */
1609 H_SET_TIME_STAMP(headers
, (long)time((long*)0));
1610 H_SET_SYMBOL_TABLE_POINTER(headers
, H_GET_SYMBOL_TABLE_FILE_OFFSET(headers
));
1611 /* symbol table size allready set */
1612 H_SET_SIZEOF_OPTIONAL_HEADER(headers
, OBJ_COFF_AOUTHDRSZ
);
1613 #ifndef OBJ_COFF_IGNORE_EXEC_FLAG
1614 H_SET_FLAGS(headers
, (text_lineno_number
== 0 ? F_LNNO
: 0)
1615 | ((text_relocation_number
+ data_relocation_number
) ? 0 : F_EXEC
)
1617 #else /* OBJ_COFF_IGNORE_EXEC_FLAG */
1618 H_SET_FLAGS(headers
, (text_lineno_number
== 0 ? F_LNNO
: 0)
1620 #endif /* OBJ_COFF_IGNORE_EXEC_FLAG */
1623 /* magic number allready set */
1624 H_SET_VERSION_STAMP(headers
, 0);
1625 /* Text, data, bss size; entry point; text_start and data_start are already set */
1627 /* Build section headers */
1629 c_section_header(&text_section_header
,
1632 H_GET_TEXT_SIZE(headers
),
1633 H_GET_TEXT_FILE_OFFSET(headers
),
1634 (SA_GET_SCN_NRELOC(dot_text_symbol
)
1635 ? H_GET_RELOCATION_FILE_OFFSET(headers
)
1638 ? H_GET_LINENO_FILE_OFFSET(headers
)
1640 SA_GET_SCN_NRELOC(dot_text_symbol
),
1642 section_alignment
[(int) SEG_TEXT
]);
1644 c_section_header(&data_section_header
,
1646 H_GET_TEXT_SIZE(headers
),
1647 H_GET_DATA_SIZE(headers
),
1648 (H_GET_DATA_SIZE(headers
)
1649 ? H_GET_DATA_FILE_OFFSET(headers
)
1651 (SA_GET_SCN_NRELOC(dot_data_symbol
)
1652 ? (H_GET_RELOCATION_FILE_OFFSET(headers
)
1653 + text_section_header
.s_nreloc
* RELSZ
)
1655 0, /* No line number information */
1656 SA_GET_SCN_NRELOC(dot_data_symbol
),
1657 0, /* No line number information */
1658 section_alignment
[(int) SEG_DATA
]);
1660 c_section_header(&bss_section_header
,
1662 H_GET_TEXT_SIZE(headers
) + H_GET_DATA_SIZE(headers
),
1663 H_GET_BSS_SIZE(headers
),
1664 0, /* No file offset */
1665 0, /* No relocation information */
1666 0, /* No line number information */
1667 0, /* No relocation information */
1668 0, /* No line number information */
1669 section_alignment
[(int) SEG_BSS
]);
1672 } /* obj_pre_write_hook() */
1674 /* This is a copy from aout. All I do is neglect to actually build the symbol. */
1676 static void obj_coff_stab(what
)
1681 int goof
= 0; /* TRUE if we have aborted. */
1685 symbolS
*symbolP
= 0;
1688 string
= demand_copy_C_string(&length
);
1691 if (*input_line_pointer
== ',') {
1692 input_line_pointer
++;
1694 as_bad("I need a comma after symbol's name");
1696 } /* better be a comma */
1697 } /* skip the string */
1700 * Input_line_pointer->after ','. String->symbol name.
1703 if (get_absolute_expression_and_terminator(&longint
) != ',') {
1704 as_bad("I want a comma after the n_type expression");
1706 input_line_pointer
--; /* Backup over a non-',' char. */
1711 if (get_absolute_expression_and_terminator(&longint
) != ',') {
1712 as_bad("I want a comma after the n_other expression");
1714 input_line_pointer
--; /* Backup over a non-',' char. */
1719 get_absolute_expression();
1721 if (what
== 's' || what
== 'n') {
1722 if (*input_line_pointer
!= ',') {
1723 as_bad("I want a comma after the n_desc expression");
1726 input_line_pointer
++;
1734 ignore_rest_of_line();
1736 demand_empty_rest_of_line();
1738 } /* obj_coff_stab() */
1745 return((s
== NULL
) ? "(NULL)" : S_GET_NAME(s
));
1746 } /* s_get_name() */
1748 void symbol_dump() {
1751 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next(symbolP
)) {
1752 printf("%3ld: 0x%lx \"%s\" type = %ld, class = %d, segment = %d\n",
1754 (unsigned long) symbolP
,
1755 S_GET_NAME(symbolP
),
1756 (long) S_GET_DATA_TYPE(symbolP
),
1757 S_GET_STORAGE_CLASS(symbolP
),
1758 (int) S_GET_SEGMENT(symbolP
));
1759 } /* traverse symbols */
1762 } /* symbol_dump() */
1772 /* end of obj-coff.c */