Imported intl subdir from GNU gettext 0.10.32
[deliverable/binutils-gdb.git] / gas / config / obj-coff.c
CommitLineData
3a69b3ac 1/* coff object file format
2 Copyright (C) 1989, 1990, 1991 Free Software Foundation, Inc.
3
4This file is part of GAS.
5
6GAS is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 1, or (at your option)
9any later version.
10
11GAS is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GAS; see the file COPYING. If not, write to
18the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20/* $Id$ */
21
22#include "as.h"
23
24#include "obstack.h"
25
26lineno* lineno_rootP;
27
28const short seg_N_TYPE[] = { /* in: segT out: N_TYPE bits */
29 C_ABS_SECTION,
30 C_TEXT_SECTION,
31 C_DATA_SECTION,
32 C_BSS_SECTION,
33 C_UNDEF_SECTION, /* SEG_UNKNOWN */
34 C_UNDEF_SECTION, /* SEG_ABSENT */
35 C_UNDEF_SECTION, /* SEG_PASS1 */
36 C_UNDEF_SECTION, /* SEG_GOOF */
37 C_UNDEF_SECTION, /* SEG_BIG */
38 C_UNDEF_SECTION, /* SEG_DIFFERENCE */
39 C_DEBUG_SECTION, /* SEG_DEBUG */
40 C_NTV_SECTION, /* SEG_NTV */
41 C_PTV_SECTION, /* SEG_PTV */
42};
43
44
45/* Add 4 to the real value to get the index and compensate the negatives */
46
47const segT N_TYPE_seg [32] =
48{
49 SEG_PTV, /* C_PTV_SECTION == -4 */
50 SEG_NTV, /* C_NTV_SECTION == -3 */
51 SEG_DEBUG, /* C_DEBUG_SECTION == -2 */
52 SEG_ABSOLUTE, /* C_ABS_SECTION == -1 */
53 SEG_UNKNOWN, /* C_UNDEF_SECTION == 0 */
54 SEG_TEXT, /* C_TEXT_SECTION == 1 */
55 SEG_DATA, /* C_DATA_SECTION == 2 */
56 SEG_BSS, /* C_BSS_SECTION == 3 */
57 SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,
58 SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,
59 SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF
60};
61
62#ifdef __STDC__
63
64char *s_get_name(symbolS *s);
65static symbolS *tag_find_or_make(char *name);
66static symbolS* tag_find(char *name);
67static void c_section_header_append(char **where, SCNHDR *header);
68static void obj_coff_def(int what);
69static void obj_coff_dim(void);
70static void obj_coff_endef(void);
71static void obj_coff_line(void);
72static void obj_coff_ln(void);
73static void obj_coff_scl(void);
74static void obj_coff_size(void);
75static void obj_coff_stab(int what);
76static void obj_coff_tag(void);
77static void obj_coff_type(void);
78static void obj_coff_val(void);
79static void tag_init(void);
80static void tag_insert(char *name, symbolS *symbolP);
81
82#else
83
84char *s_get_name();
85static symbolS *tag_find();
86static symbolS *tag_find_or_make();
87static void c_section_header_append();
88static void obj_coff_def();
89static void obj_coff_dim();
90static void obj_coff_endef();
91static void obj_coff_line();
92static void obj_coff_ln();
93static void obj_coff_scl();
94static void obj_coff_size();
95static void obj_coff_stab();
96static void obj_coff_tag();
97static void obj_coff_type();
98static void obj_coff_val();
99static void tag_init();
100static void tag_insert();
101
102#endif /* __STDC__ */
103
104static struct hash_control *tag_hash;
105static symbolS *def_symbol_in_progress = NULL;
106
107const pseudo_typeS obj_pseudo_table[] = {
108#ifndef IGNORE_DEBUG
109 { "def", obj_coff_def, 0 },
110 { "dim", obj_coff_dim, 0 },
111 { "endef", obj_coff_endef, 0 },
112 { "line", obj_coff_line, 0 },
113 { "ln", obj_coff_ln, 0 },
114 { "scl", obj_coff_scl, 0 },
115 { "size", obj_coff_size, 0 },
116 { "tag", obj_coff_tag, 0 },
117 { "type", obj_coff_type, 0 },
118 { "val", obj_coff_val, 0 },
119#else
120 { "def", s_ignore, 0 },
121 { "dim", s_ignore, 0 },
122 { "endef", s_ignore, 0 },
123 { "line", s_ignore, 0 },
124 { "ln", s_ignore, 0 },
125 { "scl", s_ignore, 0 },
126 { "size", s_ignore, 0 },
127 { "tag", s_ignore, 0 },
128 { "type", s_ignore, 0 },
129 { "val", s_ignore, 0 },
130#endif /* ignore debug */
131
132 /* 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 */
140
141 /* other stuff */
142 { "ABORT", s_abort, 0 },
143 { "ident", s_ignore, 0 },
144
145 { NULL} /* end sentinel */
146}; /* obj_pseudo_table */
147
148
149 /* obj dependant output values */
150static SCNHDR bss_section_header;
151static SCNHDR data_section_header;
152static SCNHDR text_section_header;
153
154/* Relocation. */
155
156/*
157 * emit_relocations()
158 *
159 * Crawl along a fixS chain. Emit the segment's relocations.
160 */
161
162void obj_emit_relocations(where, fixP, segment_address_in_file)
163char **where;
164fixS *fixP; /* Fixup chain for this segment. */
165relax_addressT segment_address_in_file;
166{
167 RELOC ri;
168 symbolS *symbolP;
169
170 bzero((char *)&ri,sizeof(ri));
171 for (; fixP; fixP = fixP->fx_next) {
172 if (symbolP = fixP->fx_addsy) {
173#if defined(TC_M68K)
174 ri.r_type = (fixP->fx_pcrel ?
175 (fixP->fx_size == 1 ? R_PCRBYTE :
176 fixP->fx_size == 2 ? R_PCRWORD :
177 R_PCRLONG):
178 (fixP->fx_size == 1 ? R_RELBYTE :
179 fixP->fx_size == 2 ? R_RELWORD :
180 R_RELLONG));
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 :
186 R_PCRLONG):
187 (fixP->fx_size == 1 ? R_OFF8 :
188 fixP->fx_size == 2 ? R_DIR16 :
189 R_DIR32));
190#elif defined(TC_I960)
191 ri.r_type = (fixP->fx_pcrel
192 ? R_IPRMED
193 : R_RELLONG);
194#elif defined(TC_A29K)
195 ri.r_type = tc_coff_fix2rtype(fixP);
196#else
197 you lose
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.
204 */
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 */
227
228 /* md_ri_to_chars((char *) &ri, ri); */ /* Last step : write md f */
229 append(where, (char *) &ri, sizeof(ri));
230
231#ifdef TC_I960
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 */
236#endif /* TC_I960 */
237
238 } /* if there's a symbol */
239 } /* for each fixP */
240
241 return;
242} /* obj_emit_relocations() */
243
244/* Coff file generation & utilities */
245
246void obj_header_append(where, headers)
247char **where;
248object_headers *headers;
249{
250 tc_headers_hook(headers);
251
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);
268
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 */
288
289#else /* CROSS_ASSEMBLE */
290
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 */
295
296#endif /* CROSS_ASSEMBLE */
297
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);
302
303 return;
304} /* obj_header_append() */
305
306void obj_symbol_to_chars(where, symbolP)
307char **where;
308symbolS *symbolP;
309{
310 SYMENT *syment = &symbolP->sy_symbol.ost_entry;
311 int i;
312 char numaux = syment->n_numaux;
313 unsigned short type = S_GET_DATA_TYPE(symbolP);
314
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 */
329
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 */
334
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);
342 if (ISFCN(type)) {
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);
345 } else {
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);
350 }
351 if (ISARY(type)) {
352 register int index;
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]);
356 } else {
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);
361 }
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 */
365 ;
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);
373 }
374#endif /* 0 */
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 */
378
379 }; /* for each aux in use */
380
381 return;
382} /* obj_symbol_to_chars() */
383
384static void c_section_header_append(where, header)
385char **where;
386SCNHDR *header;
387{
388#ifdef CROSS_ASSEMBLE
389 md_number_to_chars(*where, header->s_paddr, sizeof(header->s_paddr));
390 *where += sizeof(header->s_paddr);
391
392 md_number_to_chars(*where, header->s_vaddr, sizeof(header->s_vaddr));
393 *where += sizeof(header->s_vaddr);
394
395 md_number_to_chars(*where, header->s_size, sizeof(header->s_size));
396 *where += sizeof(header->s_size);
397
398 md_number_to_chars(*where, header->s_scnptr, sizeof(header->s_scnptr));
399 *where += sizeof(header->s_scnptr);
400
401 md_number_to_chars(*where, header->s_relptr, sizeof(header->s_relptr));
402 *where += sizeof(header->s_relptr);
403
404 md_number_to_chars(*where, header->s_lnnoptr, sizeof(header->s_lnnoptr));
405 *where += sizeof(header->s_lnnoptr);
406
407 md_number_to_chars(*where, header->s_nreloc, sizeof(header->s_nreloc));
408 *where += sizeof(header->s_nreloc);
409
410 md_number_to_chars(*where, header->s_nlnno, sizeof(header->s_nlnno));
411 *where += sizeof(header->s_nlnno);
412
413 md_number_to_chars(*where, header->s_flags, sizeof(header->s_flags));
414 *where += sizeof(header->s_flags);
415
416#else /* CROSS_ASSEMBLE */
417
418 append(where, (char *) header, sizeof(*header));
419
420#endif /* CROSS_ASSEMBLE */
421
422 return;
423} /* c_section_header_append() */
424
425
426void obj_emit_symbols(where, symbol_rootP)
427char **where;
428symbolS *symbol_rootP;
429{
430 symbolS *symbolP;
431 /*
432 * Emit all symbols left in the symbol chain.
433 */
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;
438
439 tc_coff_symbol_emit_hook(symbolP);
440
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);
445 } else {
446 bzero(symbolP->sy_symbol.ost_entry.n_name, SYMNMLEN);
447 strncpy(symbolP->sy_symbol.ost_entry.n_name, temp, SYMNMLEN);
448 }
449 obj_symbol_to_chars(where, symbolP);
450 S_SET_NAME(symbolP,temp);
451 }
452} /* obj_emit_symbols() */
453
454/* Merge a debug symbol containing debug information into a normal symbol. */
455
456void c_symbol_merge(debug, normal)
457symbolS *debug;
458symbolS *normal;
459{
460 S_SET_DATA_TYPE(normal, S_GET_DATA_TYPE(debug));
461 S_SET_STORAGE_CLASS(normal, S_GET_STORAGE_CLASS(debug));
462
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 */
466
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 */
470
471 /* Move the debug flags. */
472 SF_SET_DEBUG_FIELD(normal, SF_GET_DEBUG_FIELD(debug));
473} /* c_symbol_merge() */
474
475static symbolS *previous_file_symbol = NULL;
476
477void c_dot_file_symbol(filename)
478char *filename;
479{
480 symbolS* symbolP;
481
482 symbolP = symbol_new(".file",
483 SEG_DEBUG,
484 0,
485 &zero_address_frag);
486
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);
492
493 previous_file_symbol = symbolP;
494
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 */
500
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 */
505
506} /* c_dot_file_symbol() */
507/*
508 * Build a 'section static' symbol.
509 */
510
511char *c_section_symbol(name, value, length, nreloc, nlnno)
512char *name;
513long value;
514long length;
515unsigned short nreloc;
516unsigned short nlnno;
517{
518 symbolS *symbolP;
519
520 symbolP = symbol_new(name,
521 (name[1] == 't'
522 ? SEG_TEXT
523 : (name[1] == 'd'
524 ? SEG_DATA
525 : SEG_BSS)),
526 value,
527 &zero_address_frag);
528
529 S_SET_STORAGE_CLASS(symbolP, C_STAT);
530 S_SET_NUMBER_AUXILIARY(symbolP, 1);
531
532 SA_SET_SCN_SCNLEN(symbolP, length);
533 SA_SET_SCN_NRELOC(symbolP, nreloc);
534 SA_SET_SCN_NLINNO(symbolP, nlnno);
535
536 SF_SET_STATICS(symbolP);
537
538 return (char*)symbolP;
539} /* c_section_symbol() */
540
541void c_section_header(header,
542 name,
543 core_address,
544 size,
545 data_ptr,
546 reloc_ptr,
547 lineno_ptr,
548 reloc_number,
549 lineno_number,
550 alignment)
551SCNHDR *header;
552char *name;
553long core_address;
554long size;
555long data_ptr;
556long reloc_ptr;
557long lineno_ptr;
558long reloc_number;
559long lineno_number;
560long alignment;
561{
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;
569
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);
573#else
574 header->s_align = ((alignment == 0)
575 ? 0
576 : (1 << alignment));
577#endif /* OBJ_COFF_BROKEN_ALIGNMENT */
578#endif /* OBJ_COFF_SECTION_HEADER_HAS_ALIGNMENT */
579
580 header->s_flags = STYP_REG | (name[1] == 't'
581 ? STYP_TEXT
582 : (name[1] == 'd'
583 ? STYP_DATA
584 : (name[1] == 'b'
585 ? STYP_BSS
586 : STYP_INFO)));
587 return;
588} /* c_section_header() */
589
590/* Line number handling */
591
592int function_lineoff = -1; /* Offset in line#s where the last function
593 started (the odd entry for line #0) */
594int text_lineno_number = 0;
595int 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
599 write.c. */
600lineno* lineno_lastP = (lineno*)0;
601
602int
603c_line_new(paddr, line_number, frag)
604long paddr;
605unsigned short line_number;
606fragS* frag;
607{
608 lineno* new_line = (lineno*)xmalloc(sizeof(lineno));
609
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;
614
615 if (lineno_rootP == (lineno*)0)
616 lineno_rootP = new_line;
617 else
618 lineno_lastP->next = new_line;
619 lineno_lastP = new_line;
620 return LINESZ * our_lineno_number++;
621}
622
623void obj_emit_lineno(where, line, file_start)
624char **where;
625lineno *line;
626char *file_start;
627{
628 LINENO *line_entry;
629
630 for (; line; line = line->next) {
631 line_entry = &line->line;
632
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. */
636
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. */
641/* char *name; */
642 symbolS *symbolP;
643
644 symbolP = (symbolS *) line_entry->l_addr.l_symndx;
645
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;
648
649 } /* if this is a function linno */
650
651 /* No matter which member of the union we process, they are
652 both long. */
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);
656
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 */
662
663 } /* for each line number */
664
665 return ;
666} /* obj_emit_lineno() */
667
668void obj_symbol_new_hook(symbolP)
669symbolS *symbolP;
670{
671 char underscore = 0; /* Symbol has leading _ */
672
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);
683
684#if STRIP_UNDERSCORE
685 /* Remove leading underscore at the beginning of the symbol.
686 * This is to be compatible with the standard librairies.
687 */
688 if (*S_GET_NAME(symbolP) == '_') {
689 underscore = 1;
690 S_SET_NAME(symbolP, S_GET_NAME(symbolP) + 1);
691 } /* strip underscore */
692#endif /* STRIP_UNDERSCORE */
693
694 if (S_IS_STRING(symbolP))
695 SF_SET_STRING(symbolP);
696 if (!underscore && S_IS_LOCAL(symbolP))
697 SF_SET_LOCAL(symbolP);
698
699 return;
700} /* obj_symbol_new_hook() */
701
702 /* stack stuff */
703stack* stack_init(chunk_size, element_size)
704unsigned long chunk_size;
705unsigned long element_size;
706{
707 stack* st;
708
709 if ((st = (stack*)malloc(sizeof(stack))) == (stack*)0)
710 return (stack*)0;
711 if ((st->data = malloc(chunk_size)) == (char*)0) {
712 free(st);
713 return (stack*)0;
714 }
715 st->pointer = 0;
716 st->size = chunk_size;
717 st->chunk_size = chunk_size;
718 st->element_size = element_size;
719 return st;
720} /* stack_init() */
721
722void stack_delete(st)
723stack* st;
724{
725 free(st->data);
726 free(st);
727}
728
729char *stack_push(st, element)
730stack *st;
731char *element;
732{
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)
736 return (char*)0;
737 }
738 memcpy(st->data + st->pointer, element, st->element_size);
739 st->pointer += st->element_size;
740 return st->data + st->pointer;
741} /* stack_push() */
742
743char* stack_pop(st)
744stack* st;
745{
746 if ((st->pointer -= st->element_size) < 0) {
747 st->pointer = 0;
748 return (char*)0;
749 }
750 return st->data + st->pointer;
751}
752
753char* stack_top(st)
754stack* st;
755{
756 return st->data + st->pointer - st->element_size;
757}
758
759
760/*
761 * Handle .ln directives.
762 */
763
764static 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();
768 return;
769 } /* wrong context */
770
771 c_line_new(obstack_next_free(&frags) - frag_now->fr_literal,
772 get_absolute_expression(),
773 frag_now);
774
775 demand_empty_rest_of_line();
776 return;
777} /* obj_coff_line() */
778
779/*
780 * def()
781 *
782 * Handle .def directives.
783 *
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 :-).
790 *
791 */
792
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++;
797
798static void obj_coff_def(what)
799int what;
800{
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 */
808
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();
812 return;
813 } /* if not inside .def/.endef */
814
815 SKIP_WHITESPACES();
816
817 def_symbol_in_progress = (symbolS *) obstack_alloc(&notes, sizeof(*def_symbol_in_progress));
818 bzero(def_symbol_in_progress, sizeof(*def_symbol_in_progress));
819
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);
825
826 /* Initialize the new symbol */
827#if STRIP_UNDERSCORE
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;
838
839 if (S_IS_STRING(def_symbol_in_progress)) {
840 SF_SET_STRING(def_symbol_in_progress);
841 } /* "long" name */
842
843 *input_line_pointer = name_end;
844
845 demand_empty_rest_of_line();
846 return;
847} /* obj_coff_def() */
848
849unsigned int dim_index;
850static void obj_coff_endef() {
851 symbolS *symbolP;
852/* DIM BUG FIX sac@cygnus.com */
853 dim_index =0;
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();
857 return;
858 } /* if not inside .def/.endef */
859
860 /* Set the section number according to storage class. */
861 switch (S_GET_STORAGE_CLASS(def_symbol_in_progress)) {
862 case C_STRTAG:
863 case C_ENTAG:
864 case C_UNTAG:
865 SF_SET_TAG(def_symbol_in_progress);
866 /* intentional fallthrough */
867 case C_FILE:
868 case C_TPDEF:
869 SF_SET_DEBUG(def_symbol_in_progress);
870 S_SET_SEGMENT(def_symbol_in_progress, SEG_DEBUG);
871 break;
872
873 case C_EFCN:
874 SF_SET_LOCAL(def_symbol_in_progress); /* Do not emit this symbol. */
875 /* intentional fallthrough */
876 case C_BLOCK:
877 SF_SET_PROCESS(def_symbol_in_progress); /* Will need processing before writing */
878 /* intentional fallthrough */
879 case C_FCN:
880 S_SET_SEGMENT(def_symbol_in_progress, SEG_TEXT);
881
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;
889 }
890 break;
891
892#ifdef C_AUTOARG
893 case C_AUTOARG:
894#endif /* C_AUTOARG */
895 case C_AUTO:
896 case C_REG:
897 case C_MOS:
898 case C_MOE:
899 case C_MOU:
900 case C_ARG:
901 case C_REGPARM:
902 case C_FIELD:
903 case C_EOS:
904 SF_SET_DEBUG(def_symbol_in_progress);
905 S_SET_SEGMENT(def_symbol_in_progress, SEG_ABSOLUTE);
906 break;
907
908 case C_EXT:
909 case C_STAT:
910 case C_LABEL:
911 /* Valid but set somewhere else (s_comm, s_lcomm, colon) */
912 break;
913
914 case C_USTATIC:
915 case C_EXTDEF:
916 case C_ULABEL:
917 as_warn("unexpected storage class %d", S_GET_STORAGE_CLASS(def_symbol_in_progress));
918 break;
919 } /* switch on storage class */
920
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. */
925
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
935 reference. */
936
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. */
940
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) {
946
947 symbol_append(def_symbol_in_progress, symbol_lastP, &symbol_rootP, &symbol_lastP);
948
949 } else {
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
956 symbols. [loic] */
957
958 /* The debug entry (def_symbol_in_progress)
959 is merged into the previous definition. */
960
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;
964
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 */
974 } /* if function */
975 } /* normal or mergable */
976
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. */
981
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);
986
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 */
993
994 def_symbol_in_progress = NULL;
995 demand_empty_rest_of_line();
996 return;
997} /* obj_coff_endef() */
998#if 0
999This code expects all the dims to be after one another, and that is not true
1000for gcc960
1001sac@cygnus.com
1002static void obj_coff_dim() {
1003 register int dim_index;
1004
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();
1008 return;
1009 } /* if not inside .def/.endef */
1010
1011 S_SET_NUMBER_AUXILIARY(def_symbol_in_progress, 1);
1012
1013 for (dim_index = 0; dim_index < DIMNUM; dim_index++) {
1014 SKIP_WHITESPACES();
1015 SA_SET_SYM_DIMEN(def_symbol_in_progress, dim_index, get_absolute_expression());
1016
1017 switch (*input_line_pointer) {
1018
1019 case ',':
1020 input_line_pointer++;
1021 break;
1022
1023 default:
1024 as_warn("badly formed .dim directive ignored");
1025 /* intentional fallthrough */
1026 case ';':
1027 dim_index = DIMNUM;
1028 break;
1029 } /* switch on following character */
1030 } /* for each dimension */
1031
1032 demand_empty_rest_of_line();
1033 return;
1034} /* obj_coff_dim() */
1035#else
1036
1037static void
1038obj_coff_dim()
1039{
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();
1043 return;
1044 } /* if not inside .def/.endef */
1045
1046
1047 S_SET_NUMBER_AUXILIARY(def_symbol_in_progress, 1);
1048
1049 /* Grab as many dims as we can fit, until ; or full */
1050 while (dim_index < DIMNUM)
1051 {
1052 SKIP_WHITESPACES();
1053 SA_SET_SYM_DIMEN(def_symbol_in_progress, dim_index, get_absolute_expression());
1054 dim_index++;
1055 if (*input_line_pointer == ';') break;
1056 if (*input_line_pointer != ',') {
1057 as_warn("badly formed .dim directive ignored");
1058 break;
1059 }
1060 input_line_pointer++;
1061 }
1062 demand_empty_rest_of_line();
1063 return;
1064} /* obj_coff_dim() */
1065#endif
1066
1067static void obj_coff_line() {
1068 if (def_symbol_in_progress == NULL) {
1069 obj_coff_ln();
1070 return;
1071 } /* if it looks like a stabs style line */
1072
1073 S_SET_NUMBER_AUXILIARY(def_symbol_in_progress, 1);
1074 SA_SET_SYM_LNNO(def_symbol_in_progress, get_absolute_expression());
1075
1076 demand_empty_rest_of_line();
1077 return;
1078} /* obj_coff_line() */
1079
1080static 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();
1084 return;
1085 } /* if not inside .def/.endef */
1086
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();
1090 return;
1091} /* obj_coff_size() */
1092
1093static 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();
1097 return;
1098 } /* if not inside .def/.endef */
1099
1100 S_SET_STORAGE_CLASS(def_symbol_in_progress, get_absolute_expression());
1101 demand_empty_rest_of_line();
1102 return;
1103} /* obj_coff_scl() */
1104
1105static void obj_coff_tag() {
1106 char *symbol_name;
1107 char name_end;
1108
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();
1112 return;
1113 } /* if not inside .def/.endef */
1114
1115 S_SET_NUMBER_AUXILIARY(def_symbol_in_progress, 1);
1116 symbol_name = input_line_pointer;
1117 name_end = get_symbol_end();
1118
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);
1124 } /* not defined */
1125
1126 SF_SET_TAGGED(def_symbol_in_progress);
1127 *input_line_pointer = name_end;
1128
1129 demand_empty_rest_of_line();
1130 return;
1131} /* obj_coff_tag() */
1132
1133static 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();
1137 return;
1138 } /* if not inside .def/.endef */
1139
1140 S_SET_DATA_TYPE(def_symbol_in_progress, get_absolute_expression());
1141
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 */
1146
1147 demand_empty_rest_of_line();
1148 return;
1149} /* obj_coff_type() */
1150
1151static 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();
1155 return;
1156 } /* if not inside .def/.endef */
1157
1158 if (is_name_beginner(*input_line_pointer)) {
1159 char *symbol_name = input_line_pointer;
1160 char name_end = get_symbol_end();
1161
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);
1168
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);
1173 }
1174 /* Otherwise, it is the name of a non debug symbol and its value will be calculated later. */
1175 *input_line_pointer = name_end;
1176 } else {
1177 S_SET_VALUE(def_symbol_in_progress, get_absolute_expression());
1178 } /* if symbol based */
1179
1180 demand_empty_rest_of_line();
1181 return;
1182} /* obj_coff_val() */
1183
1184/*
1185 * Maintain a list of the tagnames of the structres.
1186 */
1187
1188static void tag_init() {
1189 tag_hash = hash_new();
1190 return ;
1191} /* tag_init() */
1192
1193static void tag_insert(name, symbolP)
1194char *name;
1195symbolS *symbolP;
1196{
1197 register char * error_string;
1198
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);
1202 }
1203 return ;
1204} /* tag_insert() */
1205
1206static symbolS *tag_find_or_make(name)
1207char *name;
1208{
1209 symbolS *symbolP;
1210
1211 if ((symbolP = tag_find(name)) == NULL) {
1212 symbolP = symbol_new(name,
1213 SEG_UNKNOWN,
1214 0,
1215 &zero_address_frag);
1216
1217 tag_insert(S_GET_NAME(symbolP), symbolP);
1218 symbol_table_insert(symbolP);
1219 } /* not found */
1220
1221 return(symbolP);
1222} /* tag_find_or_make() */
1223
1224static symbolS *tag_find(name)
1225char *name;
1226{
1227#if STRIP_UNDERSCORE
1228 if (*name == '_') name++;
1229#endif /* STRIP_UNDERSCORE */
1230 return((symbolS*)hash_find(tag_hash, name));
1231} /* tag_find() */
1232
1233void obj_read_begin_hook() {
1234 /* These had better be the same. Usually 18 bytes. */
1235 know(sizeof(SYMENT) == sizeof(AUXENT));
1236 know(SYMESZ == AUXESZ);
1237
1238 tag_init();
1239
1240 return;
1241} /* obj_read_begin_hook() */
1242
1243void obj_crawl_symbol_chain(headers)
1244object_headers *headers;
1245{
1246 int symbol_number = 0;
1247 lineno *lineP;
1248 symbolS *last_functionP = NULL;
1249 symbolS *last_tagP;
1250 symbolS *symbolP;
1251 symbolS *symbol_externP = NULL;
1252 symbolS *symbol_extern_lastP = NULL;
1253
1254 /* Initialize the stack used to keep track of the matching .bb .be */
1255 stack* block_stack = stack_init(512, sizeof(symbolS*));
1256
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));
1263
1264 if (SF_GET_GET_SEGMENT(symbolP)) {
1265 S_SET_SEGMENT(symbolP, S_GET_SEGMENT(symbolP->sy_forward));
1266 } /* forward segment also */
1267
1268 symbolP->sy_forward=0;
1269 } /* if it has a forward reference */
1270 } /* walk the symbol chain */
1271
1272 tc_crawl_symbol_chain(headers);
1273
1274 /* The symbol list should be ordered according to the following sequence
1275 * order :
1276 * . .file symbol
1277 * . debug entries for functions
1278 * . fake symbols for .text .data and .bss
1279 * . defined symbols
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.
1283 */
1284
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. */
1290
1291 /*
1292 * Build up static symbols for .text, .data and .bss
1293 */
1294 dot_text_symbol = (symbolS*)
1295 c_section_symbol(".text",
1296 0,
1297 H_GET_TEXT_SIZE(headers),
1298 0/*text_relocation_number */,
1299 0/*text_lineno_number */);
1300
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 */
1307
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 */
1314
1315#if defined(DEBUG)
1316 verify_symbol_chain(symbol_rootP, symbol_lastP);
1317#endif /* DEBUG */
1318
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
1331 reference. */
1332
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
1336 the loop control.
1337 */
1338 for (symbolP = symbol_rootP; symbolP; symbolP = symbolP ? symbol_next(symbolP) : symbol_rootP) {
1339
1340 if (!SF_GET_DEBUG(symbolP)) {
1341 /* Debug symbols do not need all this rubbish */
1342 symbolS* real_symbolP;
1343
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 */
1364
1365 if (flagseen['R'] && (S_GET_SEGMENT(symbolP) == SEG_DATA)) {
1366 S_SET_SEGMENT(symbolP, SEG_TEXT);
1367 } /* push data into text */
1368
1369 S_SET_VALUE(symbolP, S_GET_VALUE(symbolP) + symbolP->sy_frag->fr_address);
1370
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);
1376 } else {
1377 S_SET_STORAGE_CLASS(symbolP, C_STAT);
1378 }
1379 } /* no storage class yet */
1380
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);
1387 else { /* .eb */
1388 register symbolS* begin_symbolP;
1389 begin_symbolP = *(symbolS**)stack_pop(block_stack);
1390 if (begin_symbolP == (symbolS*)0)
1391 as_warn("mismatched .eb");
1392 else
1393 SA_SET_SYM_ENDNDX(begin_symbolP, symbol_number+2);
1394 }
1395 }
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
1399 entry. */
1400 if (last_functionP == (symbolS*)0 &&
1401 SF_GET_FUNCTION(symbolP)) {
1402 last_functionP = symbolP;
1403
1404 if (S_GET_NUMBER_AUXILIARY(symbolP) < 1) {
1405 S_SET_NUMBER_AUXILIARY(symbolP, 1);
1406 } /* make it at least 1 */
1407
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));
1411 }
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...
1415 */
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;
1424 }
1425 }
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;
1430
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 */
1440
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
1447 [21] foo external
1448 [22] .be
1449 ld will move the symbol 21 to the end of the list but
1450 endndx will still be 22 instead of 21. */
1451
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);
1456
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);
1461
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);
1465 symbolP = hold;
1466 } else {
1467 if (SF_GET_STRING(symbolP)) {
1468 symbolP->sy_name_offset = string_byte_count;
1469 string_byte_count += strlen(S_GET_NAME(symbolP)) + 1;
1470 } else {
1471 symbolP->sy_name_offset = 0;
1472 } /* fix "long" names */
1473
1474 symbolP->sy_number = symbol_number;
1475 symbol_number += 1 + S_GET_NUMBER_AUXILIARY(symbolP);
1476 } /* if local symbol */
1477 } /* traverse the symbol list */
1478
1479 for (symbolP = symbol_externP; symbol_externP;) {
1480 symbolS *tmp = symbol_externP;
1481
1482 /* append */
1483 symbol_remove(tmp, &symbol_externP, &symbol_extern_lastP);
1484 symbol_append(tmp, symbol_lastP, &symbol_rootP, &symbol_lastP);
1485
1486 /* and process */
1487 if (SF_GET_STRING(tmp)) {
1488 tmp->sy_name_offset = string_byte_count;
1489 string_byte_count += strlen(S_GET_NAME(tmp)) + 1;
1490 } else {
1491 tmp->sy_name_offset = 0;
1492 } /* fix "long" names */
1493
1494 tmp->sy_number = symbol_number;
1495 symbol_number += 1 + S_GET_NUMBER_AUXILIARY(tmp);
1496 } /* append the entire extern chain */
1497
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. */
1502
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 */
1508
1509 know(symbol_externP == NULL);
1510 know(symbol_extern_lastP == NULL);
1511
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. */
1517
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;
1521 } else {
1522 ;
1523 }
1524 text_lineno_number++;
1525 } /* for each line number */
1526
1527 H_SET_SYMBOL_TABLE_SIZE(headers, symbol_number);
1528
1529 return;
1530} /* obj_crawl_symbol_chain() */
1531
1532/*
1533 * Find strings by crawling along symbol table chain.
1534 */
1535
1536void obj_emit_strings(where)
1537char **where;
1538{
1539 symbolS *symbolP;
1540
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 */
1548
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 */
1554
1555 return;
1556} /* obj_emit_strings() */
1557
1558void obj_pre_write_hook(headers)
1559object_headers *headers;
1560{
1561 register int text_relocation_number = 0;
1562 register int data_relocation_number = 0;
1563 register fixS *fixP;
1564
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;
1572#ifdef TC_I960
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 */
1578
1579 } /* if not yet fixed */
1580 } /* for each fix */
1581
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));
1587
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 */
1593
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));
1597
1598 /* Assign the size of the section */
1599 SA_SET_SCN_SCNLEN(dot_bss_symbol, H_GET_BSS_SIZE(headers));
1600
1601 /* Fill in extra coff fields */
1602
1603 /* Initialize general line number information. */
1604 H_SET_LINENO_SIZE(headers, text_lineno_number * LINESZ);
1605
1606 /* filehdr */
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)
1616 | BYTE_ORDERING);
1617#else /* OBJ_COFF_IGNORE_EXEC_FLAG */
1618 H_SET_FLAGS(headers, (text_lineno_number == 0 ? F_LNNO : 0)
1619 | BYTE_ORDERING);
1620#endif /* OBJ_COFF_IGNORE_EXEC_FLAG */
1621
1622 /* aouthdr */
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 */
1626
1627 /* Build section headers */
1628
1629 c_section_header(&text_section_header,
1630 ".text",
1631 0,
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)
1636 : 0),
1637 (text_lineno_number
1638 ? H_GET_LINENO_FILE_OFFSET(headers)
1639 : 0),
1640 SA_GET_SCN_NRELOC(dot_text_symbol),
1641 text_lineno_number,
1642 section_alignment[(int) SEG_TEXT]);
1643
1644 c_section_header(&data_section_header,
1645 ".data",
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)
1650 : 0),
1651 (SA_GET_SCN_NRELOC(dot_data_symbol)
1652 ? (H_GET_RELOCATION_FILE_OFFSET(headers)
1653 + text_section_header.s_nreloc * RELSZ)
1654 : 0),
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]);
1659
1660 c_section_header(&bss_section_header,
1661 ".bss",
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]);
1670
1671 return;
1672} /* obj_pre_write_hook() */
1673
1674/* This is a copy from aout. All I do is neglect to actually build the symbol. */
1675
1676static void obj_coff_stab(what)
1677int what;
1678{
1679 char *string;
1680 expressionS e;
1681 int goof = 0; /* TRUE if we have aborted. */
1682 int length;
1683 int saved_type = 0;
1684 long longint;
1685 symbolS *symbolP = 0;
1686
1687 if (what == 's') {
1688 string = demand_copy_C_string(&length);
1689 SKIP_WHITESPACE();
1690
1691 if (*input_line_pointer == ',') {
1692 input_line_pointer++;
1693 } else {
1694 as_bad("I need a comma after symbol's name");
1695 goof = 1;
1696 } /* better be a comma */
1697 } /* skip the string */
1698
1699 /*
1700 * Input_line_pointer->after ','. String->symbol name.
1701 */
1702 if (!goof) {
1703 if (get_absolute_expression_and_terminator(&longint) != ',') {
1704 as_bad("I want a comma after the n_type expression");
1705 goof = 1;
1706 input_line_pointer--; /* Backup over a non-',' char. */
1707 } /* on error */
1708 } /* no error */
1709
1710 if (!goof) {
1711 if (get_absolute_expression_and_terminator(&longint) != ',') {
1712 as_bad("I want a comma after the n_other expression");
1713 goof = 1;
1714 input_line_pointer--; /* Backup over a non-',' char. */
1715 } /* on error */
1716 } /* no error */
1717
1718 if (!goof) {
1719 get_absolute_expression();
1720
1721 if (what == 's' || what == 'n') {
1722 if (*input_line_pointer != ',') {
1723 as_bad("I want a comma after the n_desc expression");
1724 goof = 1;
1725 } else {
1726 input_line_pointer++;
1727 } /* on goof */
1728 } /* not stabd */
1729 } /* no error */
1730
1731 expression(&e);
1732
1733 if (goof) {
1734 ignore_rest_of_line();
1735 } else {
1736 demand_empty_rest_of_line();
1737 } /* on error */
1738} /* obj_coff_stab() */
1739
1740#ifdef DEBUG
1741 /* for debugging */
1742char *s_get_name(s)
1743symbolS *s;
1744{
1745 return((s == NULL) ? "(NULL)" : S_GET_NAME(s));
1746} /* s_get_name() */
1747
1748void symbol_dump() {
1749 symbolS *symbolP;
1750
1751 for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next(symbolP)) {
1752 printf("%3ld: 0x%lx \"%s\" type = %ld, class = %d, segment = %d\n",
1753 symbolP->sy_number,
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 */
1760
1761 return;
1762} /* symbol_dump() */
1763#endif /* DEBUG */
1764
1765/*
1766 * Local Variables:
1767 * comment-column: 0
1768 * fill-column: 131
1769 * End:
1770 */
1771
1772/* end of obj-coff.c */
This page took 0.130973 seconds and 4 git commands to generate.