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 { "ident", s_ignore
, 0 }, /* we don't yet handle this. */
135 /* stabs aka a.out aka b.out directives for debug symbols.
136 Currently ignored silently. Except for .line at which
137 we guess from context. */
138 { "desc", s_ignore
, 0 }, /* def */
139 /* { "line", s_ignore, 0 }, */ /* source code line number */
140 { "stabd", obj_coff_stab
, 'd' }, /* stabs */
141 { "stabn", obj_coff_stab
, 'n' }, /* stabs */
142 { "stabs", obj_coff_stab
, 's' }, /* stabs */
144 /* stabs-in-coff (?) debug pseudos (ignored) */
145 { "optim", s_ignore
, 0 }, /* For sun386i cc (?) */
147 { "ABORT", s_abort
, 0 },
149 { NULL
} /* end sentinel */
150 }; /* obj_pseudo_table */
153 /* obj dependant output values */
154 static SCNHDR bss_section_header
;
155 static SCNHDR data_section_header
;
156 static SCNHDR text_section_header
;
163 * Crawl along a fixS chain. Emit the segment's relocations.
166 void obj_emit_relocations(where
, fixP
, segment_address_in_file
)
168 fixS
*fixP
; /* Fixup chain for this segment. */
169 relax_addressT segment_address_in_file
;
174 bzero((char *)&ri
,sizeof(ri
));
175 for (; fixP
; fixP
= fixP
->fx_next
) {
176 if (symbolP
= fixP
->fx_addsy
) {
178 ri
.r_type
= (fixP
->fx_pcrel
?
179 (fixP
->fx_size
== 1 ? R_PCRBYTE
:
180 fixP
->fx_size
== 2 ? R_PCRWORD
:
182 (fixP
->fx_size
== 1 ? R_RELBYTE
:
183 fixP
->fx_size
== 2 ? R_RELWORD
:
185 #elif defined(TC_I386)
186 /* FIXME-SOON R_OFF8 & R_DIR16 are a vague guess, completly untested. */
187 ri
.r_type
= (fixP
->fx_pcrel
?
188 (fixP
->fx_size
== 1 ? R_PCRBYTE
:
189 fixP
->fx_size
== 2 ? R_PCRWORD
:
191 (fixP
->fx_size
== 1 ? R_OFF8
:
192 fixP
->fx_size
== 2 ? R_DIR16
:
194 #elif defined(TC_I960)
195 ri
.r_type
= (fixP
->fx_pcrel
198 #elif defined(TC_A29K)
199 ri
.r_type
= tc_coff_fix2rtype(fixP
);
202 #endif /* TC_M68K || TC_I386 */
203 ri
.r_vaddr
= fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
204 /* If symbol associated to relocation entry is a bss symbol
205 or undefined symbol just remember the index of the symbol.
206 Otherwise store the index of the symbol describing the
207 section the symbol belong to. This heuristic speeds up ld.
209 /* Local symbols can generate relocation information. In case
210 of structure return for instance. But they have no symbol
211 number because they won't be emitted in the final object.
212 In the case where they are in the BSS section, this leads
213 to an incorrect r_symndx.
214 Under bsd the loader do not care if the symbol reference is
215 incorrect. But the SYS V ld complains about this. To avoid
216 this we associate the symbol to the associated section,
217 *even* if it is the BSS section. */
218 /* If someone can tell me why the other symbols of the bss
219 section are not associated with the .bss section entry,
220 I'd be gratefull. I guess that it has to do with the special
221 nature of the .bss section. Or maybe this is because the
222 bss symbols are declared in the common section and can
223 be resized later. Can it break code some where ? */
224 ri
.r_symndx
= (S_GET_SEGMENT(symbolP
) == SEG_TEXT
225 ? dot_text_symbol
->sy_number
226 : (S_GET_SEGMENT(symbolP
) == SEG_DATA
227 ? dot_data_symbol
->sy_number
228 : ((SF_GET_LOCAL(symbolP
)
229 ? dot_bss_symbol
->sy_number
230 : symbolP
->sy_number
)))); /* bss or undefined */
232 /* md_ri_to_chars((char *) &ri, ri); */ /* Last step : write md f */
233 append(where
, (char *) &ri
, sizeof(ri
));
236 if (fixP
->fx_callj
) {
237 ri
.r_type
= R_OPTCALL
;
238 append(where
, (char *) &ri
, sizeof(ri
));
239 } /* if it's a callj, do it again for the opcode */
242 } /* if there's a symbol */
243 } /* for each fixP */
246 } /* obj_emit_relocations() */
248 /* Coff file generation & utilities */
250 void obj_header_append(where
, headers
)
252 object_headers
*headers
;
254 tc_headers_hook(headers
);
257 /* Eventually swap bytes for cross compilation for file header */
258 md_number_to_chars(*where
, headers
->filehdr
.f_magic
, sizeof(headers
->filehdr
.f_magic
));
259 *where
+= sizeof(headers
->filehdr
.f_magic
);
260 md_number_to_chars(*where
, headers
->filehdr
.f_nscns
, sizeof(headers
->filehdr
.f_nscns
));
261 *where
+= sizeof(headers
->filehdr
.f_nscns
);
262 md_number_to_chars(*where
, headers
->filehdr
.f_timdat
, sizeof(headers
->filehdr
.f_timdat
));
263 *where
+= sizeof(headers
->filehdr
.f_timdat
);
264 md_number_to_chars(*where
, headers
->filehdr
.f_symptr
, sizeof(headers
->filehdr
.f_symptr
));
265 *where
+= sizeof(headers
->filehdr
.f_symptr
);
266 md_number_to_chars(*where
, headers
->filehdr
.f_nsyms
, sizeof(headers
->filehdr
.f_nsyms
));
267 *where
+= sizeof(headers
->filehdr
.f_nsyms
);
268 md_number_to_chars(*where
, headers
->filehdr
.f_opthdr
, sizeof(headers
->filehdr
.f_opthdr
));
269 *where
+= sizeof(headers
->filehdr
.f_opthdr
);
270 md_number_to_chars(*where
, headers
->filehdr
.f_flags
, sizeof(headers
->filehdr
.f_flags
));
271 *where
+= sizeof(headers
->filehdr
.f_flags
);
273 #ifndef OBJ_COFF_OMIT_OPTIONAL_HEADER
274 /* Eventually swap bytes for cross compilation for a.out header */
275 md_number_to_chars(*where
, headers
->aouthdr
.magic
, sizeof(headers
->aouthdr
.magic
));
276 *where
+= sizeof(headers
->aouthdr
.magic
);
277 md_number_to_chars(*where
, headers
->aouthdr
.vstamp
, sizeof(headers
->aouthdr
.vstamp
));
278 *where
+= sizeof(headers
->aouthdr
.vstamp
);
279 md_number_to_chars(*where
, headers
->aouthdr
.tsize
, sizeof(headers
->aouthdr
.tsize
));
280 *where
+= sizeof(headers
->aouthdr
.tsize
);
281 md_number_to_chars(*where
, headers
->aouthdr
.dsize
, sizeof(headers
->aouthdr
.dsize
));
282 *where
+= sizeof(headers
->aouthdr
.dsize
);
283 md_number_to_chars(*where
, headers
->aouthdr
.bsize
, sizeof(headers
->aouthdr
.bsize
));
284 *where
+= sizeof(headers
->aouthdr
.bsize
);
285 md_number_to_chars(*where
, headers
->aouthdr
.entry
, sizeof(headers
->aouthdr
.entry
));
286 *where
+= sizeof(headers
->aouthdr
.entry
);
287 md_number_to_chars(*where
, headers
->aouthdr
.text_start
, sizeof(headers
->aouthdr
.text_start
));
288 *where
+= sizeof(headers
->aouthdr
.text_start
);
289 md_number_to_chars(*where
, headers
->aouthdr
.data_start
, sizeof(headers
->aouthdr
.data_start
));
290 *where
+= sizeof(headers
->aouthdr
.data_start
);
291 #endif /* OBJ_COFF_OMIT_OPTIONAL_HEADER */
293 #else /* CROSS_COMPILE */
295 append(where
, (char *) &headers
->filehdr
, sizeof(headers
->filehdr
));
296 #ifndef OBJ_COFF_OMIT_OPTIONAL_HEADER
297 append(where
, (char *) &headers
->aouthdr
, sizeof(headers
->aouthdr
));
298 #endif /* OBJ_COFF_OMIT_OPTIONAL_HEADER */
300 #endif /* CROSS_COMPILE */
302 /* Output the section headers */
303 c_section_header_append(where
, &text_section_header
);
304 c_section_header_append(where
, &data_section_header
);
305 c_section_header_append(where
, &bss_section_header
);
308 } /* obj_header_append() */
310 void obj_symbol_to_chars(where
, symbolP
)
314 SYMENT
*syment
= &symbolP
->sy_symbol
.ost_entry
;
316 char numaux
= syment
->n_numaux
;
317 unsigned short type
= S_GET_DATA_TYPE(symbolP
);
320 md_number_to_chars(*where
, syment
->n_value
, sizeof(syment
->n_value
));
321 *where
+= sizeof(syment
->n_value
);
322 md_number_to_chars(*where
, syment
->n_scnum
, sizeof(syment
->n_scnum
));
323 *where
+= sizeof(syment
->n_scnum
);
324 md_number_to_chars(*where
, syment
->n_type
, sizeof(syment
->n_type
));
325 *where
+= sizeof(syment
->n_type
);
326 md_number_to_chars(*where
, syment
->n_sclass
, sizeof(syment
->n_sclass
));
327 *where
+= sizeof(syment
->n_sclass
);
328 md_number_to_chars(*where
, syment
->n_numaux
, sizeof(syment
->n_numaux
));
329 *where
+= sizeof(syment
->n_numaux
);
330 #else /* CROSS_COMPILE */
331 append(where
, (char *) syment
, sizeof(*syment
));
332 #endif /* CROSS_COMPILE */
334 /* Should do the following : if (.file entry) MD(..)... else if (static entry) MD(..) */
335 if (numaux
> OBJ_COFF_MAX_AUXENTRIES
) {
336 as_bad("Internal error? too many auxents for symbol");
337 } /* too many auxents */
339 for (i
= 0; i
< numaux
; ++i
) {
341 #if 0 /* This code has never been tested */
342 /* The most common case, x_sym entry. */
343 if ((SF_GET(symbolP
) & (SF_FILE
| SF_STATICS
)) == 0) {
344 md_number_to_chars(*where
, auxP
->x_sym
.x_tagndx
, sizeof(auxP
->x_sym
.x_tagndx
));
345 *where
+= sizeof(auxP
->x_sym
.x_tagndx
);
347 md_number_to_chars(*where
, auxP
->x_sym
.x_misc
.x_fsize
, sizeof(auxP
->x_sym
.x_misc
.x_fsize
));
348 *where
+= sizeof(auxP
->x_sym
.x_misc
.x_fsize
);
350 md_number_to_chars(*where
, auxP
->x_sym
.x_misc
.x_lnno
, sizeof(auxP
->x_sym
.x_misc
.x_lnno
));
351 *where
+= sizeof(auxP
->x_sym
.x_misc
.x_lnno
);
352 md_number_to_chars(*where
, auxP
->x_sym
.x_misc
.x_size
, sizeof(auxP
->x_sym
.x_misc
.x_size
));
353 *where
+= sizeof(auxP
->x_sym
.x_misc
.x_size
);
357 for (index
= 0; index
< DIMNUM
; index
++)
358 md_number_to_chars(*where
, auxP
->x_sym
.x_fcnary
.x_ary
.x_dimen
[index
], sizeof(auxP
->x_sym
.x_fcnary
.x_ary
.x_dimen
[index
]));
359 *where
+= sizeof(auxP
->x_sym
.x_fcnary
.x_ary
.x_dimen
[index
]);
361 md_number_to_chars(*where
, auxP
->x_sym
.x_fcnary
.x_fcn
.x_lnnoptr
, sizeof(auxP
->x_sym
.x_fcnary
.x_fcn
.x_lnnoptr
));
362 *where
+= sizeof(auxP
->x_sym
.x_fcnary
.x_fcn
.x_lnnoptr
);
363 md_number_to_chars(*where
, auxP
->x_sym
.x_fcnary
.x_fcn
.x_endndx
, sizeof(auxP
->x_sym
.x_fcnary
.x_fcn
.x_endndx
));
364 *where
+= sizeof(auxP
->x_sym
.x_fcnary
.x_fcn
.x_endndx
);
366 md_number_to_chars(*where
, auxP
->x_sym
.x_tvndx
, sizeof(auxP
->x_sym
.x_tvndx
));
367 *where
+= sizeof(auxP
->x_sym
.x_tvndx
);
368 } else if (SF_GET_FILE(symbolP
)) { /* .file */
370 } else if (SF_GET_STATICS(symbolP
)) { /* .text, .data, .bss symbols */
371 md_number_to_chars(*where
, auxP
->x_scn
.x_scnlen
, sizeof(auxP
->x_scn
.x_scnlen
));
372 *where
+= sizeof(auxP
->x_scn
.x_scnlen
);
373 md_number_to_chars(*where
, auxP
->x_scn
.x_nreloc
, sizeof(auxP
->x_scn
.x_nreloc
));
374 *where
+= sizeof(auxP
->x_scn
.x_nreloc
);
375 md_number_to_chars(*where
, auxP
->x_scn
.x_nlinno
, sizeof(auxP
->x_scn
.x_nlinno
));
376 *where
+= sizeof(auxP
->x_scn
.x_nlinno
);
379 #else /* CROSS_COMPILE */
380 append(where
, (char *) &symbolP
->sy_symbol
.ost_auxent
[i
], sizeof(symbolP
->sy_symbol
.ost_auxent
[i
]));
381 #endif /* CROSS_COMPILE */
383 }; /* for each aux in use */
386 } /* obj_symbol_to_chars() */
388 static void c_section_header_append(where
, header
)
393 md_number_to_chars(*where
, header
->s_paddr
, sizeof(header
->s_paddr
));
394 *where
+= sizeof(header
->s_paddr
);
396 md_number_to_chars(*where
, header
->s_vaddr
, sizeof(header
->s_vaddr
));
397 *where
+= sizeof(header
->s_vaddr
);
399 md_number_to_chars(*where
, header
->s_size
, sizeof(header
->s_size
));
400 *where
+= sizeof(header
->s_size
);
402 md_number_to_chars(*where
, header
->s_scnptr
, sizeof(header
->s_scnptr
));
403 *where
+= sizeof(header
->s_scnptr
);
405 md_number_to_chars(*where
, header
->s_relptr
, sizeof(header
->s_relptr
));
406 *where
+= sizeof(header
->s_relptr
);
408 md_number_to_chars(*where
, header
->s_lnnoptr
, sizeof(header
->s_lnnoptr
));
409 *where
+= sizeof(header
->s_lnnoptr
);
411 md_number_to_chars(*where
, header
->s_nreloc
, sizeof(header
->s_nreloc
));
412 *where
+= sizeof(header
->s_nreloc
);
414 md_number_to_chars(*where
, header
->s_nlnno
, sizeof(header
->s_nlnno
));
415 *where
+= sizeof(header
->s_nlnno
);
417 md_number_to_chars(*where
, header
->s_flags
, sizeof(header
->s_flags
));
418 *where
+= sizeof(header
->s_flags
);
420 #else /* CROSS_COMPILE */
422 append(where
, (char *) header
, sizeof(*header
));
424 #endif /* CROSS_COMPILE */
427 } /* c_section_header_append() */
430 void obj_emit_symbols(where
, symbol_rootP
)
432 symbolS
*symbol_rootP
;
436 * Emit all symbols left in the symbol chain.
438 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next(symbolP
)) {
439 /* Used to save the offset of the name. It is used to point
440 to the string in memory but must be a file offset. */
441 register char * temp
;
443 tc_coff_symbol_emit_hook(symbolP
);
445 temp
= S_GET_NAME(symbolP
);
446 if (SF_GET_STRING(symbolP
)) {
447 S_SET_OFFSET(symbolP
, symbolP
->sy_name_offset
);
448 S_SET_ZEROES(symbolP
, 0);
450 bzero(symbolP
->sy_symbol
.ost_entry
.n_name
, SYMNMLEN
);
451 strncpy(symbolP
->sy_symbol
.ost_entry
.n_name
, temp
, SYMNMLEN
);
453 obj_symbol_to_chars(where
, symbolP
);
454 S_SET_NAME(symbolP
,temp
);
456 } /* obj_emit_symbols() */
458 /* Merge a debug symbol containing debug information into a normal symbol. */
460 void c_symbol_merge(debug
, normal
)
464 S_SET_DATA_TYPE(normal
, S_GET_DATA_TYPE(debug
));
465 S_SET_STORAGE_CLASS(normal
, S_GET_STORAGE_CLASS(debug
));
467 if (S_GET_NUMBER_AUXILIARY(debug
) > S_GET_NUMBER_AUXILIARY(normal
)) {
468 S_SET_NUMBER_AUXILIARY(normal
, S_GET_NUMBER_AUXILIARY(debug
));
469 } /* take the most we have */
471 if (S_GET_NUMBER_AUXILIARY(debug
) > 0) {
472 memcpy((char*)&normal
->sy_symbol
.ost_auxent
[0], (char*)&debug
->sy_symbol
.ost_auxent
[0], S_GET_NUMBER_AUXILIARY(debug
) * AUXESZ
);
473 } /* Move all the auxiliary information */
475 /* Move the debug flags. */
476 SF_SET_DEBUG_FIELD(normal
, SF_GET_DEBUG_FIELD(debug
));
477 } /* c_symbol_merge() */
479 static symbolS
*previous_file_symbol
= NULL
;
481 void c_dot_file_symbol(filename
)
486 symbolP
= symbol_new(".file",
491 S_SET_STORAGE_CLASS(symbolP
, C_FILE
);
492 S_SET_NUMBER_AUXILIARY(symbolP
, 1);
493 SA_SET_FILE_FNAME(symbolP
, filename
);
494 SF_SET_DEBUG(symbolP
);
495 S_SET_VALUE(symbolP
, (long) previous_file_symbol
);
497 previous_file_symbol
= symbolP
;
499 /* Make sure that the symbol is first on the symbol chain */
500 if (symbol_rootP
!= symbolP
) {
501 if (symbolP
== symbol_lastP
) {
502 symbol_lastP
= symbol_lastP
->sy_previous
;
503 } /* if it was the last thing on the list */
505 symbol_remove(symbolP
, &symbol_rootP
, &symbol_lastP
);
506 symbol_insert(symbolP
, symbol_rootP
, &symbol_rootP
, &symbol_lastP
);
507 symbol_rootP
= symbolP
;
508 } /* if not first on the list */
510 } /* c_dot_file_symbol() */
512 * Build a 'section static' symbol.
515 char *c_section_symbol(name
, value
, length
, nreloc
, nlnno
)
519 unsigned short nreloc
;
520 unsigned short nlnno
;
524 symbolP
= symbol_new(name
,
533 S_SET_STORAGE_CLASS(symbolP
, C_STAT
);
534 S_SET_NUMBER_AUXILIARY(symbolP
, 1);
536 SA_SET_SCN_SCNLEN(symbolP
, length
);
537 SA_SET_SCN_NRELOC(symbolP
, nreloc
);
538 SA_SET_SCN_NLINNO(symbolP
, nlnno
);
540 SF_SET_STATICS(symbolP
);
542 return (char*)symbolP
;
543 } /* c_section_symbol() */
545 void c_section_header(header
,
566 strncpy(header
->s_name
, name
, 8);
567 header
->s_paddr
= header
->s_vaddr
= core_address
;
568 header
->s_scnptr
= ((header
->s_size
= size
) != 0) ? data_ptr
: 0;
569 header
->s_relptr
= reloc_ptr
;
570 header
->s_lnnoptr
= lineno_ptr
;
571 header
->s_nreloc
= reloc_number
;
572 header
->s_nlnno
= lineno_number
;
574 #ifdef OBJ_COFF_SECTION_HEADER_HAS_ALIGNMENT
575 #ifdef OBJ_COFF_BROKEN_ALIGNMENT
576 header
->s_align
= ((name
[1] == 'b' || (size
> 0)) ? 16 : 0);
578 header
->s_align
= ((alignment
== 0)
581 #endif /* OBJ_COFF_BROKEN_ALIGNMENT */
582 #endif /* OBJ_COFF_SECTION_HEADER_HAS_ALIGNMENT */
584 header
->s_flags
= STYP_REG
| (name
[1] == 't'
592 } /* c_section_header() */
594 /* Line number handling */
596 int function_lineoff
= -1; /* Offset in line#s where the last function
597 started (the odd entry for line #0) */
598 int text_lineno_number
= 0;
599 int our_lineno_number
= 0; /* we use this to build pointers from .bf's
600 into the linetable. It should match
601 exactly the values that are later
602 assigned in text_lineno_number by
604 lineno
* lineno_lastP
= (lineno
*)0;
607 c_line_new(paddr
, line_number
, frag
)
609 unsigned short line_number
;
612 lineno
* new_line
= (lineno
*)xmalloc(sizeof(lineno
));
614 new_line
->line
.l_addr
.l_paddr
= paddr
;
615 new_line
->line
.l_lnno
= line_number
;
616 new_line
->frag
= (char*)frag
;
617 new_line
->next
= (lineno
*)0;
619 if (lineno_rootP
== (lineno
*)0)
620 lineno_rootP
= new_line
;
622 lineno_lastP
->next
= new_line
;
623 lineno_lastP
= new_line
;
624 return LINESZ
* our_lineno_number
++;
627 void obj_emit_lineno(where
, line
, file_start
)
634 for (; line
; line
= line
->next
) {
635 line_entry
= &line
->line
;
637 /* FIXME-SOMEDAY Resolving the sy_number of function linno's used to be done in
638 write_object_file() but their symbols need a fileptr to the lnno, so
639 I moved this resolution check here. xoxorich. */
641 if (line_entry
->l_lnno
== 0) {
642 /* There is a good chance that the symbol pointed to
643 is not the one that will be emitted and that the
644 sy_number is not accurate. */
648 symbolP
= (symbolS
*) line_entry
->l_addr
.l_symndx
;
650 line_entry
->l_addr
.l_symndx
= symbolP
->sy_number
;
651 symbolP
->sy_symbol
.ost_auxent
[0].x_sym
.x_fcnary
.x_fcn
.x_lnnoptr
= *where
- file_start
;
653 } /* if this is a function linno */
655 /* No matter which member of the union we process, they are
658 md_number_to_chars(*where
, line_entry
->l_addr
.l_paddr
, sizeof(line_entry
->l_addr
.l_paddr
));
659 *where
+= sizeof(line_entry
->l_addr
.l_paddr
);
661 md_number_to_chars(*where
, line_entry
->l_lnno
, sizeof(line_entry
->l_lnno
));
662 *where
+= sizeof(line_entry
->l_lnno
);
663 #else /* CROSS_COMPILE */
664 append(where
, (char *) line_entry
, LINESZ
);
665 #endif /* CROSS_COMPILE */
667 } /* for each line number */
670 } /* obj_emit_lineno() */
672 void obj_symbol_new_hook(symbolP
)
675 char underscore
= 0; /* Symbol has leading _ */
677 /* Effective symbol */
678 /* Store the pointer in the offset. */
679 S_SET_ZEROES(symbolP
, 0L);
680 S_SET_DATA_TYPE(symbolP
, T_NULL
);
681 S_SET_STORAGE_CLASS(symbolP
, 0);
682 S_SET_NUMBER_AUXILIARY(symbolP
, 0);
683 /* Additional information */
684 symbolP
->sy_symbol
.ost_flags
= 0;
685 /* Auxiliary entries */
686 bzero((char*)&symbolP
->sy_symbol
.ost_auxent
[0], AUXESZ
);
689 /* Remove leading underscore at the beginning of the symbol.
690 * This is to be compatible with the standard librairies.
692 if (*S_GET_NAME(symbolP
) == '_') {
694 S_SET_NAME(symbolP
, S_GET_NAME(symbolP
) + 1);
695 } /* strip underscore */
696 #endif /* STRIP_UNDERSCORE */
698 if (S_IS_STRING(symbolP
))
699 SF_SET_STRING(symbolP
);
700 if (!underscore
&& S_IS_LOCAL(symbolP
))
701 SF_SET_LOCAL(symbolP
);
704 } /* obj_symbol_new_hook() */
707 stack
* stack_init(chunk_size
, element_size
)
708 unsigned long chunk_size
;
709 unsigned long element_size
;
713 if ((st
= (stack
*)malloc(sizeof(stack
))) == (stack
*)0)
715 if ((st
->data
= malloc(chunk_size
)) == (char*)0) {
720 st
->size
= chunk_size
;
721 st
->chunk_size
= chunk_size
;
722 st
->element_size
= element_size
;
726 void stack_delete(st
)
733 char *stack_push(st
, element
)
737 if (st
->pointer
+ st
->element_size
>= st
->size
) {
738 st
->size
+= st
->chunk_size
;
739 if ((st
->data
= xrealloc(st
->data
, st
->size
)) == (char*)0)
742 memcpy(st
->data
+ st
->pointer
, element
, st
->element_size
);
743 st
->pointer
+= st
->element_size
;
744 return st
->data
+ st
->pointer
;
750 if ((st
->pointer
-= st
->element_size
) < 0) {
754 return st
->data
+ st
->pointer
;
760 return st
->data
+ st
->pointer
- st
->element_size
;
765 * Handle .ln directives.
768 static void obj_coff_ln() {
769 if (def_symbol_in_progress
!= NULL
) {
770 as_warn(".ln pseudo-op inside .def/.endef: ignored.");
771 demand_empty_rest_of_line();
773 } /* wrong context */
775 c_line_new(obstack_next_free(&frags
) - frag_now
->fr_literal
,
776 get_absolute_expression(),
779 demand_empty_rest_of_line();
781 } /* obj_coff_line() */
786 * Handle .def directives.
788 * One might ask : why can't we symbol_new if the symbol does not
789 * already exist and fill it with debug information. Because of
790 * the C_EFCN special symbol. It would clobber the value of the
791 * function symbol before we have a chance to notice that it is
792 * a C_EFCN. And a second reason is that the code is more clear this
793 * way. (at least I think it is :-).
797 #define SKIP_SEMI_COLON() while (*input_line_pointer++ != ';')
798 #define SKIP_WHITESPACES() while (*input_line_pointer == ' ' || \
799 *input_line_pointer == '\t') \
800 input_line_pointer++;
802 static void obj_coff_def(what
)
805 char name_end
; /* Char after the end of name */
806 char *symbol_name
; /* Name of the debug symbol */
807 char *symbol_name_copy
; /* Temporary copy of the name */
808 unsigned int symbol_name_length
;
809 /*$char* directiveP;$ */ /* Name of the pseudo opcode */
810 /*$char directive[MAX_DIRECTIVE];$ */ /* Backup of the directive */
811 /*$char end = 0;$ */ /* If 1, stop parsing */
813 if (def_symbol_in_progress
!= NULL
) {
814 as_warn(".def pseudo-op used inside of .def/.endef: ignored.");
815 demand_empty_rest_of_line();
817 } /* if not inside .def/.endef */
821 def_symbol_in_progress
= (symbolS
*) obstack_alloc(¬es
, sizeof(*def_symbol_in_progress
));
822 bzero(def_symbol_in_progress
, sizeof(*def_symbol_in_progress
));
824 symbol_name
= input_line_pointer
;
825 name_end
= get_symbol_end();
826 symbol_name_length
= strlen(symbol_name
);
827 symbol_name_copy
= xmalloc(symbol_name_length
+ 1);
828 strcpy(symbol_name_copy
, symbol_name
);
830 /* Initialize the new symbol */
832 S_SET_NAME(def_symbol_in_progress
, (*symbol_name_copy
== '_'
833 ? symbol_name_copy
+ 1
834 : symbol_name_copy
));
835 #else /* STRIP_UNDERSCORE */
836 S_SET_NAME(def_symbol_in_progress
, symbol_name_copy
);
837 #endif /* STRIP_UNDERSCORE */
838 /* free(symbol_name_copy); */
839 def_symbol_in_progress
->sy_name_offset
= ~0;
840 def_symbol_in_progress
->sy_number
= ~0;
841 def_symbol_in_progress
->sy_frag
= &zero_address_frag
;
843 if (S_IS_STRING(def_symbol_in_progress
)) {
844 SF_SET_STRING(def_symbol_in_progress
);
847 *input_line_pointer
= name_end
;
849 demand_empty_rest_of_line();
851 } /* obj_coff_def() */
853 unsigned int dim_index
;
854 static void obj_coff_endef() {
856 /* DIM BUG FIX sac@cygnus.com */
858 if (def_symbol_in_progress
== NULL
) {
859 as_warn(".endef pseudo-op used outside of .def/.endef: ignored.");
860 demand_empty_rest_of_line();
862 } /* if not inside .def/.endef */
864 /* Set the section number according to storage class. */
865 switch (S_GET_STORAGE_CLASS(def_symbol_in_progress
)) {
869 SF_SET_TAG(def_symbol_in_progress
);
870 /* intentional fallthrough */
873 SF_SET_DEBUG(def_symbol_in_progress
);
874 S_SET_SEGMENT(def_symbol_in_progress
, SEG_DEBUG
);
878 SF_SET_LOCAL(def_symbol_in_progress
); /* Do not emit this symbol. */
879 /* intentional fallthrough */
881 SF_SET_PROCESS(def_symbol_in_progress
); /* Will need processing before writing */
882 /* intentional fallthrough */
884 S_SET_SEGMENT(def_symbol_in_progress
, SEG_TEXT
);
886 if (def_symbol_in_progress
->sy_symbol
.ost_entry
.n_name
[1] == 'b') { /* .bf */
887 if (function_lineoff
< 0) {
888 fprintf(stderr
, "`.bf' symbol without preceding function\n");
889 } /* missing function symbol */
890 SA_GET_SYM_LNNOPTR(def_symbol_in_progress
) = function_lineoff
;
891 SF_SET_PROCESS(def_symbol_in_progress
); /* Will need relocating */
892 function_lineoff
= -1;
898 #endif /* C_AUTOARG */
908 SF_SET_DEBUG(def_symbol_in_progress
);
909 S_SET_SEGMENT(def_symbol_in_progress
, SEG_ABSOLUTE
);
915 /* Valid but set somewhere else (s_comm, s_lcomm, colon) */
921 as_warn("unexpected storage class %d", S_GET_STORAGE_CLASS(def_symbol_in_progress
));
923 } /* switch on storage class */
925 /* Now that we have built a debug symbol, try to
926 find if we should merge with an existing symbol
927 or not. If a symbol is C_EFCN or SEG_ABSOLUTE or
928 untagged SEG_DEBUG it never merges. */
930 /* Two cases for functions. Either debug followed
931 by definition or definition followed by debug.
932 For definition first, we will merge the debug
933 symbol into the definition. For debug first, the
934 lineno entry MUST point to the definition
935 function or else it will point off into space
936 when obj_crawl_symbol_chain() merges the debug
937 symbol into the real symbol. Therefor, let's
938 presume the debug symbol is a real function
941 /* FIXME-SOON If for some reason the definition
942 label/symbol is never seen, this will probably
943 leave an undefined symbol at link time. */
945 if (S_GET_STORAGE_CLASS(def_symbol_in_progress
) == C_EFCN
946 || (S_GET_SEGMENT(def_symbol_in_progress
) == SEG_DEBUG
947 && !SF_GET_TAG(def_symbol_in_progress
))
948 || S_GET_SEGMENT(def_symbol_in_progress
) == SEG_ABSOLUTE
949 || (symbolP
= symbol_find_base(S_GET_NAME(def_symbol_in_progress
), DO_NOT_STRIP
)) == NULL
) {
951 symbol_append(def_symbol_in_progress
, symbol_lastP
, &symbol_rootP
, &symbol_lastP
);
954 /* This symbol already exists, merge the
955 newly created symbol into the old one.
956 This is not mandatory. The linker can
957 handle duplicate symbols correctly. But I
958 guess that it save a *lot* of space if
959 the assembly file defines a lot of
962 /* The debug entry (def_symbol_in_progress)
963 is merged into the previous definition. */
965 c_symbol_merge(def_symbol_in_progress
, symbolP
);
966 /* FIXME-SOON Should *def_symbol_in_progress be free'd? xoxorich. */
967 def_symbol_in_progress
= symbolP
;
969 if (SF_GET_FUNCTION(def_symbol_in_progress
)
970 || SF_GET_TAG(def_symbol_in_progress
)) {
971 /* For functions, and tags, the symbol *must* be where the debug symbol
972 appears. Move the existing symbol to the current place. */
973 /* If it already is at the end of the symbol list, do nothing */
974 if (def_symbol_in_progress
!= symbol_lastP
) {
975 symbol_remove(def_symbol_in_progress
, &symbol_rootP
, &symbol_lastP
);
976 symbol_append(def_symbol_in_progress
, symbol_lastP
, &symbol_rootP
, &symbol_lastP
);
977 } /* if not already in place */
979 } /* normal or mergable */
981 if (SF_GET_TAG(def_symbol_in_progress
)
982 && symbol_find_base(S_GET_NAME(def_symbol_in_progress
), DO_NOT_STRIP
) == NULL
) {
983 tag_insert(S_GET_NAME(def_symbol_in_progress
), def_symbol_in_progress
);
984 } /* If symbol is a {structure,union} tag, associate symbol to its name. */
986 if (SF_GET_FUNCTION(def_symbol_in_progress
)) {
987 know(sizeof(def_symbol_in_progress
) <= sizeof(long));
988 function_lineoff
= c_line_new((long) def_symbol_in_progress
, 0, &zero_address_frag
);
989 SF_SET_PROCESS(def_symbol_in_progress
);
991 if (symbolP
== NULL
) {
992 /* That is, if this is the first
993 time we've seen the function... */
994 symbol_table_insert(def_symbol_in_progress
);
995 } /* definition follows debug */
996 } /* Create the line number entry pointing to the function being defined */
998 def_symbol_in_progress
= NULL
;
999 demand_empty_rest_of_line();
1001 } /* obj_coff_endef() */
1003 This code expects all the dims to be after one another
, and that is
not true
1006 static void obj_coff_dim() {
1007 register int dim_index
;
1009 if (def_symbol_in_progress
== NULL
) {
1010 as_warn(".dim pseudo-op used outside of .def/.endef: ignored.");
1011 demand_empty_rest_of_line();
1013 } /* if not inside .def/.endef */
1015 S_SET_NUMBER_AUXILIARY(def_symbol_in_progress
, 1);
1017 for (dim_index
= 0; dim_index
< DIMNUM
; dim_index
++) {
1019 SA_SET_SYM_DIMEN(def_symbol_in_progress
, dim_index
, get_absolute_expression());
1021 switch (*input_line_pointer
) {
1024 input_line_pointer
++;
1028 as_warn("badly formed .dim directive ignored");
1029 /* intentional fallthrough */
1033 } /* switch on following character */
1034 } /* for each dimension */
1036 demand_empty_rest_of_line();
1038 } /* obj_coff_dim() */
1044 if (def_symbol_in_progress
== NULL
) {
1045 as_warn(".dim pseudo-op used outside of .def/.endef: ignored.");
1046 demand_empty_rest_of_line();
1048 } /* if not inside .def/.endef */
1051 S_SET_NUMBER_AUXILIARY(def_symbol_in_progress
, 1);
1053 /* Grab as many dims as we can fit, until ; or full */
1054 while (dim_index
< DIMNUM
)
1057 SA_SET_SYM_DIMEN(def_symbol_in_progress
, dim_index
, get_absolute_expression());
1059 if (*input_line_pointer
== ';') break;
1060 if (*input_line_pointer
!= ',') {
1061 as_warn("badly formed .dim directive ignored");
1064 input_line_pointer
++;
1066 demand_empty_rest_of_line();
1068 } /* obj_coff_dim() */
1071 static void obj_coff_line() {
1072 if (def_symbol_in_progress
== NULL
) {
1075 } /* if it looks like a stabs style line */
1077 S_SET_NUMBER_AUXILIARY(def_symbol_in_progress
, 1);
1078 SA_SET_SYM_LNNO(def_symbol_in_progress
, get_absolute_expression());
1080 demand_empty_rest_of_line();
1082 } /* obj_coff_line() */
1084 static void obj_coff_size() {
1085 if (def_symbol_in_progress
== NULL
) {
1086 as_warn(".size pseudo-op used outside of .def/.endef ignored.");
1087 demand_empty_rest_of_line();
1089 } /* if not inside .def/.endef */
1091 S_SET_NUMBER_AUXILIARY(def_symbol_in_progress
, 1);
1092 SA_SET_SYM_SIZE(def_symbol_in_progress
, get_absolute_expression());
1093 demand_empty_rest_of_line();
1095 } /* obj_coff_size() */
1097 static void obj_coff_scl() {
1098 if (def_symbol_in_progress
== NULL
) {
1099 as_warn(".scl pseudo-op used outside of .def/.endef ignored.");
1100 demand_empty_rest_of_line();
1102 } /* if not inside .def/.endef */
1104 S_SET_STORAGE_CLASS(def_symbol_in_progress
, get_absolute_expression());
1105 demand_empty_rest_of_line();
1107 } /* obj_coff_scl() */
1109 static void obj_coff_tag() {
1113 if (def_symbol_in_progress
== NULL
) {
1114 as_warn(".tag pseudo-op used outside of .def/.endef ignored.");
1115 demand_empty_rest_of_line();
1117 } /* if not inside .def/.endef */
1119 S_SET_NUMBER_AUXILIARY(def_symbol_in_progress
, 1);
1120 symbol_name
= input_line_pointer
;
1121 name_end
= get_symbol_end();
1123 /* Assume that the symbol referred to by .tag is always defined. */
1124 /* This was a bad assumption. I've added find_or_make. xoxorich. */
1125 SA_SET_SYM_TAGNDX(def_symbol_in_progress
, (long) tag_find_or_make(symbol_name
));
1126 if (SA_GET_SYM_TAGNDX(def_symbol_in_progress
) == 0L) {
1127 as_warn("tag not found for .tag %s", symbol_name
);
1130 SF_SET_TAGGED(def_symbol_in_progress
);
1131 *input_line_pointer
= name_end
;
1133 demand_empty_rest_of_line();
1135 } /* obj_coff_tag() */
1137 static void obj_coff_type() {
1138 if (def_symbol_in_progress
== NULL
) {
1139 as_warn(".type pseudo-op used outside of .def/.endef ignored.");
1140 demand_empty_rest_of_line();
1142 } /* if not inside .def/.endef */
1144 S_SET_DATA_TYPE(def_symbol_in_progress
, get_absolute_expression());
1146 if (ISFCN(S_GET_DATA_TYPE(def_symbol_in_progress
)) &&
1147 S_GET_STORAGE_CLASS(def_symbol_in_progress
) != C_TPDEF
) {
1148 SF_SET_FUNCTION(def_symbol_in_progress
);
1149 } /* is a function */
1151 demand_empty_rest_of_line();
1153 } /* obj_coff_type() */
1155 static void obj_coff_val() {
1156 if (def_symbol_in_progress
== NULL
) {
1157 as_warn(".val pseudo-op used outside of .def/.endef ignored.");
1158 demand_empty_rest_of_line();
1160 } /* if not inside .def/.endef */
1162 if (is_name_beginner(*input_line_pointer
)) {
1163 char *symbol_name
= input_line_pointer
;
1164 char name_end
= get_symbol_end();
1166 if (!strcmp(symbol_name
, ".")) {
1167 def_symbol_in_progress
->sy_frag
= frag_now
;
1168 S_SET_VALUE(def_symbol_in_progress
, obstack_next_free(&frags
) - frag_now
->fr_literal
);
1169 /* If the .val is != from the .def (e.g. statics) */
1170 } else if (strcmp(S_GET_NAME(def_symbol_in_progress
), symbol_name
)) {
1171 def_symbol_in_progress
->sy_forward
= symbol_find_or_make(symbol_name
);
1173 /* If the segment is undefined when the forward
1174 reference is solved, then copy the segment id
1175 from the forward symbol. */
1176 SF_SET_GET_SEGMENT(def_symbol_in_progress
);
1178 /* Otherwise, it is the name of a non debug symbol and its value will be calculated later. */
1179 *input_line_pointer
= name_end
;
1181 S_SET_VALUE(def_symbol_in_progress
, get_absolute_expression());
1182 } /* if symbol based */
1184 demand_empty_rest_of_line();
1186 } /* obj_coff_val() */
1189 * Maintain a list of the tagnames of the structres.
1192 static void tag_init() {
1193 tag_hash
= hash_new();
1197 static void tag_insert(name
, symbolP
)
1201 register char * error_string
;
1203 if (*(error_string
= hash_jam(tag_hash
, name
, (char *)symbolP
))) {
1204 as_fatal("Inserting \"%s\" into structure table failed: %s",
1205 name
, error_string
);
1208 } /* tag_insert() */
1210 static symbolS
*tag_find_or_make(name
)
1215 if ((symbolP
= tag_find(name
)) == NULL
) {
1216 symbolP
= symbol_new(name
,
1219 &zero_address_frag
);
1221 tag_insert(S_GET_NAME(symbolP
), symbolP
);
1222 symbol_table_insert(symbolP
);
1226 } /* tag_find_or_make() */
1228 static symbolS
*tag_find(name
)
1231 #if STRIP_UNDERSCORE
1232 if (*name
== '_') name
++;
1233 #endif /* STRIP_UNDERSCORE */
1234 return((symbolS
*)hash_find(tag_hash
, name
));
1237 void obj_read_begin_hook() {
1238 /* These had better be the same. Usually 18 bytes. */
1239 know(sizeof(SYMENT
) == sizeof(AUXENT
));
1240 know(SYMESZ
== AUXESZ
);
1245 } /* obj_read_begin_hook() */
1247 void obj_crawl_symbol_chain(headers
)
1248 object_headers
*headers
;
1250 int symbol_number
= 0;
1252 symbolS
*last_functionP
= NULL
;
1255 symbolS
*symbol_externP
= NULL
;
1256 symbolS
*symbol_extern_lastP
= NULL
;
1258 /* Initialize the stack used to keep track of the matching .bb .be */
1259 stack
* block_stack
= stack_init(512, sizeof(symbolS
*));
1261 /* JF deal with forward references first... */
1262 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next(symbolP
)) {
1263 if (symbolP
->sy_forward
) {
1264 S_SET_VALUE(symbolP
, (S_GET_VALUE(symbolP
)
1265 + S_GET_VALUE(symbolP
->sy_forward
)
1266 + symbolP
->sy_forward
->sy_frag
->fr_address
));
1268 if (SF_GET_GET_SEGMENT(symbolP
)) {
1269 S_SET_SEGMENT(symbolP
, S_GET_SEGMENT(symbolP
->sy_forward
));
1270 } /* forward segment also */
1272 symbolP
->sy_forward
=0;
1273 } /* if it has a forward reference */
1274 } /* walk the symbol chain */
1276 tc_crawl_symbol_chain(headers
);
1278 /* The symbol list should be ordered according to the following sequence
1281 * . debug entries for functions
1282 * . fake symbols for .text .data and .bss
1284 * . undefined symbols
1285 * But this is not mandatory. The only important point is to put the
1286 * undefined symbols at the end of the list.
1289 if (symbol_rootP
== NULL
1290 || S_GET_STORAGE_CLASS(symbol_rootP
) != C_FILE
) {
1291 know(!previous_file_symbol
);
1292 c_dot_file_symbol("fake");
1293 } /* Is there a .file symbol ? If not insert one at the beginning. */
1296 * Build up static symbols for .text, .data and .bss
1298 dot_text_symbol
= (symbolS
*)
1299 c_section_symbol(".text",
1301 H_GET_TEXT_SIZE(headers
),
1302 0/*text_relocation_number */,
1303 0/*text_lineno_number */);
1305 dot_data_symbol
= (symbolS
*)
1306 c_section_symbol(".data",
1307 H_GET_TEXT_SIZE(headers
),
1308 H_GET_DATA_SIZE(headers
),
1309 0/*data_relocation_number */,
1310 0); /* There are no data lineno entries */
1312 dot_bss_symbol
= (symbolS
*)
1313 c_section_symbol(".bss",
1314 H_GET_TEXT_SIZE(headers
) + H_GET_DATA_SIZE(headers
),
1315 H_GET_BSS_SIZE(headers
),
1316 0, /* No relocation for a bss section. */
1317 0); /* There are no bss lineno entries */
1320 verify_symbol_chain(symbol_rootP
, symbol_lastP
);
1323 /* Three traversals of symbol chains here. The
1324 first traversal yanks externals into a temporary
1325 chain, removing the externals from the global
1326 chain, numbers symbols, and does some other guck.
1327 The second traversal is on the temporary chain of
1328 externals and just appends them to the global
1329 chain again, numbering them as we go. The third
1330 traversal patches pointers to symbols (using sym
1331 indexes). The last traversal was once done as
1332 part of the first pass, but that fails when a
1333 reference preceeds a definition as the definition
1334 has no number at the time we process the
1337 /* Note that symbolP will be NULL at the end of a loop
1338 if an external was at the beginning of the list (it
1339 gets moved off the list). Hence the weird check in
1342 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbolP
? symbol_next(symbolP
) : symbol_rootP
) {
1344 if (!SF_GET_DEBUG(symbolP
)) {
1345 /* Debug symbols do not need all this rubbish */
1346 symbolS
* real_symbolP
;
1348 /* L* and C_EFCN symbols never merge. */
1349 if (!SF_GET_LOCAL(symbolP
)
1350 && (real_symbolP
= symbol_find_base(S_GET_NAME(symbolP
), DO_NOT_STRIP
))
1351 && real_symbolP
!= symbolP
) {
1352 /* FIXME-SOON: where do dups come from? Maybe tag references before definitions? xoxorich. */
1353 /* Move the debug data from the debug symbol to the
1354 real symbol. Do NOT do the oposite (i.e. move from
1355 real symbol to debug symbol and remove real symbol from the
1356 list.) Because some pointers refer to the real symbol
1357 whereas no pointers refer to the debug symbol. */
1358 c_symbol_merge(symbolP
, real_symbolP
);
1359 /* Replace the current symbol by the real one */
1360 /* The symbols will never be the last or the first
1361 because : 1st symbol is .file and 3 last symbols are
1362 .text, .data, .bss */
1363 symbol_remove(real_symbolP
, &symbol_rootP
, &symbol_lastP
);
1364 symbol_insert(real_symbolP
, symbolP
, &symbol_rootP
, &symbol_lastP
);
1365 symbol_remove(symbolP
, &symbol_rootP
, &symbol_lastP
);
1366 symbolP
= real_symbolP
;
1367 } /* if not local but dup'd */
1369 if (flagseen
['R'] && (S_GET_SEGMENT(symbolP
) == SEG_DATA
)) {
1370 S_SET_SEGMENT(symbolP
, SEG_TEXT
);
1371 } /* push data into text */
1373 S_SET_VALUE(symbolP
, S_GET_VALUE(symbolP
) + symbolP
->sy_frag
->fr_address
);
1375 if (!S_IS_DEFINED(symbolP
) && !SF_GET_LOCAL(symbolP
)) {
1376 S_SET_EXTERNAL(symbolP
);
1377 } else if (S_GET_STORAGE_CLASS(symbolP
) == C_NULL
) {
1378 if (S_GET_SEGMENT(symbolP
) == SEG_TEXT
){
1379 S_SET_STORAGE_CLASS(symbolP
, C_LABEL
);
1381 S_SET_STORAGE_CLASS(symbolP
, C_STAT
);
1383 } /* no storage class yet */
1385 /* Mainly to speed up if not -g */
1386 if (SF_GET_PROCESS(symbolP
)) {
1387 /* Handle the nested blocks auxiliary info. */
1388 if (S_GET_STORAGE_CLASS(symbolP
) == C_BLOCK
) {
1389 if (!strcmp(S_GET_NAME(symbolP
), ".bb"))
1390 stack_push(block_stack
, (char *) &symbolP
);
1392 register symbolS
* begin_symbolP
;
1393 begin_symbolP
= *(symbolS
**)stack_pop(block_stack
);
1394 if (begin_symbolP
== (symbolS
*)0)
1395 as_warn("mismatched .eb");
1397 SA_SET_SYM_ENDNDX(begin_symbolP
, symbol_number
+2);
1400 /* If we are able to identify the type of a function, and we
1401 are out of a function (last_functionP == 0) then, the
1402 function symbol will be associated with an auxiliary
1404 if (last_functionP
== (symbolS
*)0 &&
1405 SF_GET_FUNCTION(symbolP
)) {
1406 last_functionP
= symbolP
;
1408 if (S_GET_NUMBER_AUXILIARY(symbolP
) < 1) {
1409 S_SET_NUMBER_AUXILIARY(symbolP
, 1);
1410 } /* make it at least 1 */
1412 /* Clobber possible stale .dim information. */
1413 bzero(symbolP
->sy_symbol
.ost_auxent
[0].x_sym
.x_fcnary
.x_ary
.x_dimen
,
1414 sizeof(symbolP
->sy_symbol
.ost_auxent
[0].x_sym
.x_fcnary
.x_ary
.x_dimen
));
1416 /* The C_FCN doesn't need any additional information.
1417 I don't even know if this is needed for sdb. But the
1418 standard assembler generates it, so...
1420 if (S_GET_STORAGE_CLASS(symbolP
) == C_EFCN
) {
1421 if (last_functionP
== (symbolS
*)0)
1422 as_fatal("C_EFCN symbol out of scope");
1423 SA_SET_SYM_FSIZE(last_functionP
,
1424 (long)(S_GET_VALUE(symbolP
) -
1425 S_GET_VALUE(last_functionP
)));
1426 SA_SET_SYM_ENDNDX(last_functionP
, symbol_number
);
1427 last_functionP
= (symbolS
*)0;
1430 } else if (SF_GET_TAG(symbolP
)) {
1431 /* First descriptor of a structure must point to
1432 the first slot after the structure description. */
1433 last_tagP
= symbolP
;
1435 } else if (S_GET_STORAGE_CLASS(symbolP
) == C_EOS
) {
1436 /* +2 take in account the current symbol */
1437 SA_SET_SYM_ENDNDX(last_tagP
, symbol_number
+ 2);
1438 } else if (S_GET_STORAGE_CLASS(symbolP
) == C_FILE
) {
1439 if (S_GET_VALUE(symbolP
)) {
1440 S_SET_VALUE((symbolS
*) S_GET_VALUE(symbolP
), symbol_number
);
1441 S_SET_VALUE(symbolP
, 0);
1442 } /* no one points at the first .file symbol */
1443 } /* if debug or tag or eos or file */
1445 /* We must put the external symbols apart. The loader
1446 does not bomb if we do not. But the references in
1447 the endndx field for a .bb symbol are not corrected
1448 if an external symbol is removed between .bb and .be.
1449 I.e in the following case :
1450 [20] .bb endndx = 22
1453 ld will move the symbol 21 to the end of the list but
1454 endndx will still be 22 instead of 21. */
1456 if (SF_GET_LOCAL(symbolP
)) {
1457 /* remove C_EFCN and LOCAL (L...) symbols */
1458 /* next pointer remains valid */
1459 symbol_remove(symbolP
, &symbol_rootP
, &symbol_lastP
);
1461 } else if (!S_IS_DEFINED(symbolP
) && !S_IS_DEBUG(symbolP
) && !SF_GET_STATICS(symbolP
)) {
1462 /* S_GET_STORAGE_CLASS(symbolP) == C_EXT && !SF_GET_FUNCTION(symbolP)) { */
1463 /* if external, Remove from the list */
1464 symbolS
*hold
= symbol_previous(symbolP
);
1466 symbol_remove(symbolP
, &symbol_rootP
, &symbol_lastP
);
1467 symbol_clear_list_pointers(symbolP
);
1468 symbol_append(symbolP
, symbol_extern_lastP
, &symbol_externP
, &symbol_extern_lastP
);
1471 if (SF_GET_STRING(symbolP
)) {
1472 symbolP
->sy_name_offset
= string_byte_count
;
1473 string_byte_count
+= strlen(S_GET_NAME(symbolP
)) + 1;
1475 symbolP
->sy_name_offset
= 0;
1476 } /* fix "long" names */
1478 symbolP
->sy_number
= symbol_number
;
1479 symbol_number
+= 1 + S_GET_NUMBER_AUXILIARY(symbolP
);
1480 } /* if local symbol */
1481 } /* traverse the symbol list */
1483 for (symbolP
= symbol_externP
; symbol_externP
;) {
1484 symbolS
*tmp
= symbol_externP
;
1487 symbol_remove(tmp
, &symbol_externP
, &symbol_extern_lastP
);
1488 symbol_append(tmp
, symbol_lastP
, &symbol_rootP
, &symbol_lastP
);
1491 if (SF_GET_STRING(tmp
)) {
1492 tmp
->sy_name_offset
= string_byte_count
;
1493 string_byte_count
+= strlen(S_GET_NAME(tmp
)) + 1;
1495 tmp
->sy_name_offset
= 0;
1496 } /* fix "long" names */
1498 tmp
->sy_number
= symbol_number
;
1499 symbol_number
+= 1 + S_GET_NUMBER_AUXILIARY(tmp
);
1500 } /* append the entire extern chain */
1502 /* When a tag reference preceeds the tag definition,
1503 the definition will not have a number at the time
1504 we process the reference during the first
1505 traversal. Thus, a second traversal. */
1507 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next(symbolP
)) {
1508 if (SF_GET_TAGGED(symbolP
)) {
1509 SA_SET_SYM_TAGNDX(symbolP
, ((symbolS
*) SA_GET_SYM_TAGNDX(symbolP
))->sy_number
);
1510 } /* If the symbol has a tagndx entry, resolve it */
1511 } /* second traversal */
1513 know(symbol_externP
== NULL
);
1514 know(symbol_extern_lastP
== NULL
);
1516 /* FIXME-SOMEDAY I'm counting line no's here so we know what to put in the section
1517 headers, and I'm resolving the addresses since I'm not sure how to
1518 do it later. I am NOT resolving the linno's representing functions.
1519 Their symbols need a fileptr pointing to this linno when emitted.
1520 Thus, I resolve them on emit. xoxorich. */
1522 for (lineP
= lineno_rootP
; lineP
; lineP
= lineP
->next
) {
1523 if (lineP
->line
.l_lnno
> 0) {
1524 lineP
->line
.l_addr
.l_paddr
+= ((fragS
*)lineP
->frag
)->fr_address
;
1528 text_lineno_number
++;
1529 } /* for each line number */
1531 H_SET_SYMBOL_TABLE_SIZE(headers
, symbol_number
);
1534 } /* obj_crawl_symbol_chain() */
1537 * Find strings by crawling along symbol table chain.
1540 void obj_emit_strings(where
)
1545 #ifdef CROSS_COMPILE
1546 /* Gotta do md_ byte-ordering stuff for string_byte_count first - KWK */
1547 md_number_to_chars(*where
, string_byte_count
, sizeof(string_byte_count
));
1548 where
+= sizeof(string_byte_count
);
1549 #else /* CROSS_COMPILE */
1550 append(where
, (char *) &string_byte_count
, (unsigned long) sizeof(string_byte_count
));
1551 #endif /* CROSS_COMPILE */
1553 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next(symbolP
)) {
1554 if (SF_GET_STRING(symbolP
)) {
1555 append(where
, S_GET_NAME(symbolP
), (unsigned long)(strlen(S_GET_NAME(symbolP
)) + 1));
1556 } /* if it has a string */
1557 } /* walk the symbol chain */
1560 } /* obj_emit_strings() */
1562 void obj_pre_write_hook(headers
)
1563 object_headers
*headers
;
1565 register int text_relocation_number
= 0;
1566 register int data_relocation_number
= 0;
1567 register fixS
*fixP
;
1569 /* FIXME-SOMEDAY this should be done at
1570 fixup_segment time but I'm going to wait until I
1571 do multiple segments. xoxorich. */
1572 /* Count the number of relocation entries for text and data */
1573 for (fixP
= text_fix_root
; fixP
; fixP
= fixP
->fx_next
) {
1574 if (fixP
->fx_addsy
) {
1575 ++text_relocation_number
;
1577 /* two relocs per callj under coff. */
1578 if (fixP
->fx_callj
) {
1579 ++text_relocation_number
;
1580 } /* if callj and not already fixed. */
1581 #endif /* TC_I960 */
1583 } /* if not yet fixed */
1584 } /* for each fix */
1586 SA_SET_SCN_NRELOC(dot_text_symbol
, text_relocation_number
);
1587 /* Assign the number of line number entries for the text section */
1588 SA_SET_SCN_NLINNO(dot_text_symbol
, text_lineno_number
);
1589 /* Assign the size of the section */
1590 SA_SET_SCN_SCNLEN(dot_text_symbol
, H_GET_TEXT_SIZE(headers
));
1592 for (fixP
= data_fix_root
; fixP
; fixP
= fixP
->fx_next
) {
1593 if (fixP
->fx_addsy
) {
1594 ++data_relocation_number
;
1595 } /* if still relocatable */
1596 } /* for each fix */
1598 SA_SET_SCN_NRELOC(dot_data_symbol
, data_relocation_number
);
1599 /* Assign the size of the section */
1600 SA_SET_SCN_SCNLEN(dot_data_symbol
, H_GET_DATA_SIZE(headers
));
1602 /* Assign the size of the section */
1603 SA_SET_SCN_SCNLEN(dot_bss_symbol
, H_GET_BSS_SIZE(headers
));
1605 /* Fill in extra coff fields */
1607 /* Initialize general line number information. */
1608 H_SET_LINENO_SIZE(headers
, text_lineno_number
* LINESZ
);
1611 H_SET_FILE_MAGIC_NUMBER(headers
, FILE_HEADER_MAGIC
);
1612 H_SET_NUMBER_OF_SECTIONS(headers
, 3); /* text+data+bss */
1613 H_SET_TIME_STAMP(headers
, (long)time((long*)0));
1614 H_SET_SYMBOL_TABLE_POINTER(headers
, H_GET_SYMBOL_TABLE_FILE_OFFSET(headers
));
1615 /* symbol table size allready set */
1616 H_SET_SIZEOF_OPTIONAL_HEADER(headers
, OBJ_COFF_AOUTHDRSZ
);
1617 #ifndef OBJ_COFF_IGNORE_EXEC_FLAG
1618 H_SET_FLAGS(headers
, (text_lineno_number
== 0 ? F_LNNO
: 0)
1619 | ((text_relocation_number
+ data_relocation_number
) ? 0 : F_EXEC
)
1621 #else /* OBJ_COFF_IGNORE_EXEC_FLAG */
1622 H_SET_FLAGS(headers
, (text_lineno_number
== 0 ? F_LNNO
: 0)
1624 #endif /* OBJ_COFF_IGNORE_EXEC_FLAG */
1627 /* magic number allready set */
1628 H_SET_VERSION_STAMP(headers
, 0);
1629 /* Text, data, bss size; entry point; text_start and data_start are already set */
1631 /* Build section headers */
1633 c_section_header(&text_section_header
,
1636 H_GET_TEXT_SIZE(headers
),
1637 H_GET_TEXT_FILE_OFFSET(headers
),
1638 (SA_GET_SCN_NRELOC(dot_text_symbol
)
1639 ? H_GET_RELOCATION_FILE_OFFSET(headers
)
1642 ? H_GET_LINENO_FILE_OFFSET(headers
)
1644 SA_GET_SCN_NRELOC(dot_text_symbol
),
1646 section_alignment
[(int) SEG_TEXT
]);
1648 c_section_header(&data_section_header
,
1650 H_GET_TEXT_SIZE(headers
),
1651 H_GET_DATA_SIZE(headers
),
1652 (H_GET_DATA_SIZE(headers
)
1653 ? H_GET_DATA_FILE_OFFSET(headers
)
1655 (SA_GET_SCN_NRELOC(dot_data_symbol
)
1656 ? (H_GET_RELOCATION_FILE_OFFSET(headers
)
1657 + text_section_header
.s_nreloc
* RELSZ
)
1659 0, /* No line number information */
1660 SA_GET_SCN_NRELOC(dot_data_symbol
),
1661 0, /* No line number information */
1662 section_alignment
[(int) SEG_DATA
]);
1664 c_section_header(&bss_section_header
,
1666 H_GET_TEXT_SIZE(headers
) + H_GET_DATA_SIZE(headers
),
1667 H_GET_BSS_SIZE(headers
),
1668 0, /* No file offset */
1669 0, /* No relocation information */
1670 0, /* No line number information */
1671 0, /* No relocation information */
1672 0, /* No line number information */
1673 section_alignment
[(int) SEG_BSS
]);
1676 } /* obj_pre_write_hook() */
1678 /* This is a copy from aout. All I do is neglect to actually build the symbol. */
1680 static void obj_coff_stab(what
)
1685 int goof
= 0; /* TRUE if we have aborted. */
1689 symbolS
*symbolP
= 0;
1692 string
= demand_copy_C_string(&length
);
1695 if (*input_line_pointer
== ',') {
1696 input_line_pointer
++;
1698 as_bad("I need a comma after symbol's name");
1700 } /* better be a comma */
1701 } /* skip the string */
1704 * Input_line_pointer->after ','. String->symbol name.
1707 if (get_absolute_expression_and_terminator(&longint
) != ',') {
1708 as_bad("I want a comma after the n_type expression");
1710 input_line_pointer
--; /* Backup over a non-',' char. */
1715 if (get_absolute_expression_and_terminator(&longint
) != ',') {
1716 as_bad("I want a comma after the n_other expression");
1718 input_line_pointer
--; /* Backup over a non-',' char. */
1723 get_absolute_expression();
1725 if (what
== 's' || what
== 'n') {
1726 if (*input_line_pointer
!= ',') {
1727 as_bad("I want a comma after the n_desc expression");
1730 input_line_pointer
++;
1738 ignore_rest_of_line();
1740 demand_empty_rest_of_line();
1742 } /* obj_coff_stab() */
1749 return((s
== NULL
) ? "(NULL)" : S_GET_NAME(s
));
1750 } /* s_get_name() */
1752 void symbol_dump() {
1755 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next(symbolP
)) {
1756 printf("%3ld: 0x%lx \"%s\" type = %ld, class = %d, segment = %d\n",
1758 (unsigned long) symbolP
,
1759 S_GET_NAME(symbolP
),
1760 (long) S_GET_DATA_TYPE(symbolP
),
1761 S_GET_STORAGE_CLASS(symbolP
),
1762 (int) S_GET_SEGMENT(symbolP
));
1763 } /* traverse symbols */
1766 } /* symbol_dump() */
1776 /* end of obj-coff.c */