Make sure that 29k relocs are done right.
[deliverable/binutils-gdb.git] / gas / config / obj-coff.c
CommitLineData
fecd2382
RP
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
57574979 8the Free Software Foundation; either version 2, or (at your option)
fecd2382
RP
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 */
57574979 42 C_REGISTER_SECTION, /* SEG_REGISTER */
fecd2382
RP
43};
44
45
46/* Add 4 to the real value to get the index and compensate the negatives */
47
48const segT N_TYPE_seg [32] =
49{
50 SEG_PTV, /* C_PTV_SECTION == -4 */
51 SEG_NTV, /* C_NTV_SECTION == -3 */
52 SEG_DEBUG, /* C_DEBUG_SECTION == -2 */
53 SEG_ABSOLUTE, /* C_ABS_SECTION == -1 */
54 SEG_UNKNOWN, /* C_UNDEF_SECTION == 0 */
55 SEG_TEXT, /* C_TEXT_SECTION == 1 */
56 SEG_DATA, /* C_DATA_SECTION == 2 */
57 SEG_BSS, /* C_BSS_SECTION == 3 */
57574979 58 SEG_REGISTER, /* C_REGISTER_SECTION == 4 */
fecd2382
RP
59 SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,
60 SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,
57574979 61 SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF
fecd2382
RP
62};
63
64#ifdef __STDC__
65
66char *s_get_name(symbolS *s);
67static symbolS *tag_find_or_make(char *name);
68static symbolS* tag_find(char *name);
57574979
SC
69#ifdef BFD_HEADERS
70static void obj_coff_section_header_append(char **where, struct internal_scnhdr *header);
71#else
72static void obj_coff_section_header_append(char **where, SCNHDR *header);
73#endif
fecd2382
RP
74static void obj_coff_def(int what);
75static void obj_coff_dim(void);
76static void obj_coff_endef(void);
77static void obj_coff_line(void);
78static void obj_coff_ln(void);
79static void obj_coff_scl(void);
80static void obj_coff_size(void);
81static void obj_coff_stab(int what);
82static void obj_coff_tag(void);
83static void obj_coff_type(void);
84static void obj_coff_val(void);
85static void tag_init(void);
86static void tag_insert(char *name, symbolS *symbolP);
87
88#else
89
90char *s_get_name();
91static symbolS *tag_find();
92static symbolS *tag_find_or_make();
57574979 93static void obj_coff_section_header_append();
fecd2382
RP
94static void obj_coff_def();
95static void obj_coff_dim();
96static void obj_coff_endef();
97static void obj_coff_line();
98static void obj_coff_ln();
99static void obj_coff_scl();
100static void obj_coff_size();
101static void obj_coff_stab();
102static void obj_coff_tag();
103static void obj_coff_type();
104static void obj_coff_val();
105static void tag_init();
106static void tag_insert();
107
108#endif /* __STDC__ */
109
110static struct hash_control *tag_hash;
111static symbolS *def_symbol_in_progress = NULL;
112
113const pseudo_typeS obj_pseudo_table[] = {
114#ifndef IGNORE_DEBUG
115 { "def", obj_coff_def, 0 },
116 { "dim", obj_coff_dim, 0 },
117 { "endef", obj_coff_endef, 0 },
118 { "line", obj_coff_line, 0 },
119 { "ln", obj_coff_ln, 0 },
120 { "scl", obj_coff_scl, 0 },
121 { "size", obj_coff_size, 0 },
122 { "tag", obj_coff_tag, 0 },
123 { "type", obj_coff_type, 0 },
124 { "val", obj_coff_val, 0 },
125#else
126 { "def", s_ignore, 0 },
127 { "dim", s_ignore, 0 },
128 { "endef", s_ignore, 0 },
129 { "line", s_ignore, 0 },
130 { "ln", s_ignore, 0 },
131 { "scl", s_ignore, 0 },
132 { "size", s_ignore, 0 },
133 { "tag", s_ignore, 0 },
134 { "type", s_ignore, 0 },
135 { "val", s_ignore, 0 },
136#endif /* ignore debug */
137
d1a9e594
RP
138 { "ident", s_ignore, 0 }, /* we don't yet handle this. */
139
140
fecd2382 141 /* stabs aka a.out aka b.out directives for debug symbols.
d1a9e594
RP
142 Currently ignored silently. Except for .line at which
143 we guess from context. */
fecd2382
RP
144 { "desc", s_ignore, 0 }, /* def */
145/* { "line", s_ignore, 0 }, */ /* source code line number */
146 { "stabd", obj_coff_stab, 'd' }, /* stabs */
147 { "stabn", obj_coff_stab, 'n' }, /* stabs */
148 { "stabs", obj_coff_stab, 's' }, /* stabs */
149
d1a9e594
RP
150 /* stabs-in-coff (?) debug pseudos (ignored) */
151 { "optim", s_ignore, 0 }, /* For sun386i cc (?) */
fecd2382
RP
152 /* other stuff */
153 { "ABORT", s_abort, 0 },
fecd2382
RP
154
155 { NULL} /* end sentinel */
156}; /* obj_pseudo_table */
157
158
159 /* obj dependant output values */
57574979
SC
160#ifdef BFD_HEADERS
161static struct internal_scnhdr bss_section_header;
162struct internal_scnhdr data_section_header;
163struct internal_scnhdr text_section_header;
164#else
fecd2382 165static SCNHDR bss_section_header;
57574979
SC
166SCNHDR data_section_header;
167SCNHDR text_section_header;
168#endif
fecd2382
RP
169/* Relocation. */
170
171/*
172 * emit_relocations()
173 *
174 * Crawl along a fixS chain. Emit the segment's relocations.
175 */
176
177void obj_emit_relocations(where, fixP, segment_address_in_file)
178char **where;
179fixS *fixP; /* Fixup chain for this segment. */
180relax_addressT segment_address_in_file;
181{
57574979
SC
182#ifdef BFD_HEADERS
183 struct internal_reloc ri;
184#else
fecd2382 185 RELOC ri;
57574979 186#endif
fecd2382
RP
187 symbolS *symbolP;
188
189 bzero((char *)&ri,sizeof(ri));
190 for (; fixP; fixP = fixP->fx_next) {
191 if (symbolP = fixP->fx_addsy) {
192#if defined(TC_M68K)
193 ri.r_type = (fixP->fx_pcrel ?
194 (fixP->fx_size == 1 ? R_PCRBYTE :
195 fixP->fx_size == 2 ? R_PCRWORD :
196 R_PCRLONG):
197 (fixP->fx_size == 1 ? R_RELBYTE :
198 fixP->fx_size == 2 ? R_RELWORD :
199 R_RELLONG));
200#elif defined(TC_I386)
201 /* FIXME-SOON R_OFF8 & R_DIR16 are a vague guess, completly untested. */
202 ri.r_type = (fixP->fx_pcrel ?
203 (fixP->fx_size == 1 ? R_PCRBYTE :
204 fixP->fx_size == 2 ? R_PCRWORD :
205 R_PCRLONG):
206 (fixP->fx_size == 1 ? R_OFF8 :
207 fixP->fx_size == 2 ? R_DIR16 :
208 R_DIR32));
209#elif defined(TC_I960)
210 ri.r_type = (fixP->fx_pcrel
211 ? R_IPRMED
212 : R_RELLONG);
213#elif defined(TC_A29K)
214 ri.r_type = tc_coff_fix2rtype(fixP);
57574979 215
fecd2382
RP
216#else
217 you lose
218#endif /* TC_M68K || TC_I386 */
219 ri.r_vaddr = fixP->fx_frag->fr_address + fixP->fx_where;
220 /* If symbol associated to relocation entry is a bss symbol
221 or undefined symbol just remember the index of the symbol.
222 Otherwise store the index of the symbol describing the
223 section the symbol belong to. This heuristic speeds up ld.
224 */
225 /* Local symbols can generate relocation information. In case
226 of structure return for instance. But they have no symbol
227 number because they won't be emitted in the final object.
228 In the case where they are in the BSS section, this leads
229 to an incorrect r_symndx.
230 Under bsd the loader do not care if the symbol reference is
231 incorrect. But the SYS V ld complains about this. To avoid
232 this we associate the symbol to the associated section,
233 *even* if it is the BSS section. */
234 /* If someone can tell me why the other symbols of the bss
235 section are not associated with the .bss section entry,
236 I'd be gratefull. I guess that it has to do with the special
237 nature of the .bss section. Or maybe this is because the
238 bss symbols are declared in the common section and can
239 be resized later. Can it break code some where ? */
240 ri.r_symndx = (S_GET_SEGMENT(symbolP) == SEG_TEXT
241 ? dot_text_symbol->sy_number
242 : (S_GET_SEGMENT(symbolP) == SEG_DATA
243 ? dot_data_symbol->sy_number
244 : ((SF_GET_LOCAL(symbolP)
245 ? dot_bss_symbol->sy_number
246 : symbolP->sy_number)))); /* bss or undefined */
247
248 /* md_ri_to_chars((char *) &ri, ri); */ /* Last step : write md f */
57574979
SC
249
250
251#ifdef BFD_HEADERS
252 *where += bfd_coff_swap_reloc_out(stdoutput, &ri, *where);
253#if defined(TC_A29K)
254 /* The 29k has a special kludge for the high 16 bit reloc.
255 Two relocations are emmited, R_IHIHALF, and R_IHCONST. The second one
256 doesn't contain a symbol, but uses the value for offset */
257 if (ri.r_type == R_IHIHALF) {
065114de
SC
258 /* now emit the second bit */
259 ri.r_type = R_IHCONST;
260 ri.r_symndx = fixP->fx_addnumber;
261 *where += bfd_coff_swap_reloc_out(stdoutput, &ri, *where);
57574979
SC
262 }
263
264#endif
265
266#else
fecd2382 267 append(where, (char *) &ri, sizeof(ri));
57574979 268#endif
fecd2382
RP
269
270#ifdef TC_I960
271 if (fixP->fx_callj) {
272 ri.r_type = R_OPTCALL;
57574979
SC
273#ifdef BFD_HEADERS
274 *where += bfd_coff_swap_reloc_out(stdoutput, &ri, *where);
275#else
276 append(where, (char *) &ri, sizeof(ri));
277#endif
278
279
fecd2382
RP
280 } /* if it's a callj, do it again for the opcode */
281#endif /* TC_I960 */
282
283 } /* if there's a symbol */
284 } /* for each fixP */
285
286 return;
287} /* obj_emit_relocations() */
288
289/* Coff file generation & utilities */
290
57574979
SC
291#ifdef BFD_HEADERS
292void obj_header_append(where, headers)
293char **where;
294object_headers *headers;
295{
296 tc_headers_hook(headers);
297 *where += bfd_coff_swap_filehdr_out(stdoutput, &(headers->filehdr), *where);
298#ifndef OBJ_COFF_OMIT_OPTIONAL_HEADER
299 *where += bfd_coff_swap_aouthdr_out(stdoutput, &(headers->aouthdr), *where);
300#endif
301 obj_coff_section_header_append(where, &text_section_header);
302 obj_coff_section_header_append(where, &data_section_header);
303 obj_coff_section_header_append(where, &bss_section_header);
304
305}
306
307#else
308
fecd2382
RP
309void obj_header_append(where, headers)
310char **where;
311object_headers *headers;
312{
313 tc_headers_hook(headers);
314
d1a9e594 315#ifdef CROSS_COMPILE
fecd2382
RP
316 /* Eventually swap bytes for cross compilation for file header */
317 md_number_to_chars(*where, headers->filehdr.f_magic, sizeof(headers->filehdr.f_magic));
318 *where += sizeof(headers->filehdr.f_magic);
319 md_number_to_chars(*where, headers->filehdr.f_nscns, sizeof(headers->filehdr.f_nscns));
320 *where += sizeof(headers->filehdr.f_nscns);
321 md_number_to_chars(*where, headers->filehdr.f_timdat, sizeof(headers->filehdr.f_timdat));
322 *where += sizeof(headers->filehdr.f_timdat);
323 md_number_to_chars(*where, headers->filehdr.f_symptr, sizeof(headers->filehdr.f_symptr));
324 *where += sizeof(headers->filehdr.f_symptr);
325 md_number_to_chars(*where, headers->filehdr.f_nsyms, sizeof(headers->filehdr.f_nsyms));
326 *where += sizeof(headers->filehdr.f_nsyms);
327 md_number_to_chars(*where, headers->filehdr.f_opthdr, sizeof(headers->filehdr.f_opthdr));
328 *where += sizeof(headers->filehdr.f_opthdr);
329 md_number_to_chars(*where, headers->filehdr.f_flags, sizeof(headers->filehdr.f_flags));
330 *where += sizeof(headers->filehdr.f_flags);
331
332#ifndef OBJ_COFF_OMIT_OPTIONAL_HEADER
333 /* Eventually swap bytes for cross compilation for a.out header */
334 md_number_to_chars(*where, headers->aouthdr.magic, sizeof(headers->aouthdr.magic));
335 *where += sizeof(headers->aouthdr.magic);
336 md_number_to_chars(*where, headers->aouthdr.vstamp, sizeof(headers->aouthdr.vstamp));
337 *where += sizeof(headers->aouthdr.vstamp);
338 md_number_to_chars(*where, headers->aouthdr.tsize, sizeof(headers->aouthdr.tsize));
339 *where += sizeof(headers->aouthdr.tsize);
340 md_number_to_chars(*where, headers->aouthdr.dsize, sizeof(headers->aouthdr.dsize));
341 *where += sizeof(headers->aouthdr.dsize);
342 md_number_to_chars(*where, headers->aouthdr.bsize, sizeof(headers->aouthdr.bsize));
343 *where += sizeof(headers->aouthdr.bsize);
344 md_number_to_chars(*where, headers->aouthdr.entry, sizeof(headers->aouthdr.entry));
345 *where += sizeof(headers->aouthdr.entry);
346 md_number_to_chars(*where, headers->aouthdr.text_start, sizeof(headers->aouthdr.text_start));
347 *where += sizeof(headers->aouthdr.text_start);
348 md_number_to_chars(*where, headers->aouthdr.data_start, sizeof(headers->aouthdr.data_start));
349 *where += sizeof(headers->aouthdr.data_start);
57574979
SC
350 md_number_to_chars(*where, headers->aouthdr.tagentries, sizeof(headers->aouthdr.tagentries));
351 *where += sizeof(headers->aouthdr.tagentries);
fecd2382
RP
352#endif /* OBJ_COFF_OMIT_OPTIONAL_HEADER */
353
d1a9e594 354#else /* CROSS_COMPILE */
fecd2382
RP
355
356 append(where, (char *) &headers->filehdr, sizeof(headers->filehdr));
357#ifndef OBJ_COFF_OMIT_OPTIONAL_HEADER
358 append(where, (char *) &headers->aouthdr, sizeof(headers->aouthdr));
359#endif /* OBJ_COFF_OMIT_OPTIONAL_HEADER */
360
d1a9e594 361#endif /* CROSS_COMPILE */
fecd2382
RP
362
363 /* Output the section headers */
57574979
SC
364 obj_coff_section_header_append(where, &text_section_header);
365 obj_coff_section_header_append(where, &data_section_header);
366 obj_coff_section_header_append(where, &bss_section_header);
fecd2382
RP
367
368 return;
369} /* obj_header_append() */
57574979 370#endif
fecd2382
RP
371void obj_symbol_to_chars(where, symbolP)
372char **where;
373symbolS *symbolP;
374{
57574979
SC
375#ifdef BFD_HEADERS
376 unsigned int numaux = symbolP->sy_symbol.ost_entry.n_numaux;
377 unsigned int i;
378
379 if (S_GET_SEGMENT(symbolP) == SEG_REGISTER) {
380 S_SET_SEGMENT(symbolP, SEG_ABSOLUTE);
381 }
382 *where += bfd_coff_swap_sym_out(stdoutput, &symbolP->sy_symbol.ost_entry,
383 *where);
384
385 for (i = 0; i < numaux; i++)
386 {
387 *where += bfd_coff_swap_aux_out(stdoutput,
388 &symbolP->sy_symbol.ost_auxent[i],
389 S_GET_DATA_TYPE(symbolP),
390 S_GET_STORAGE_CLASS(symbolP),
391 *where);
392 }
393
394#else
395 SYMENT *syment = &symbolP->sy_symbol.ost_entry;
396 int i;
397 char numaux = syment->n_numaux;
398 unsigned short type = S_GET_DATA_TYPE(symbolP);
fecd2382 399
d1a9e594 400#ifdef CROSS_COMPILE
57574979
SC
401 md_number_to_chars(*where, syment->n_value, sizeof(syment->n_value));
402 *where += sizeof(syment->n_value);
403 md_number_to_chars(*where, syment->n_scnum, sizeof(syment->n_scnum));
404 *where += sizeof(syment->n_scnum);
405 md_number_to_chars(*where, syment->n_type, sizeof(syment->n_type));
406 *where += sizeof(syment->n_type);
407 md_number_to_chars(*where, syment->n_sclass, sizeof(syment->n_sclass));
408 *where += sizeof(syment->n_sclass);
409 md_number_to_chars(*where, syment->n_numaux, sizeof(syment->n_numaux));
410 *where += sizeof(syment->n_numaux);
d1a9e594 411#else /* CROSS_COMPILE */
57574979 412 append(where, (char *) syment, sizeof(*syment));
d1a9e594 413#endif /* CROSS_COMPILE */
fecd2382 414
57574979
SC
415 /* Should do the following : if (.file entry) MD(..)... else if (static entry) MD(..) */
416 if (numaux > OBJ_COFF_MAX_AUXENTRIES) {
417 as_bad("Internal error? too many auxents for symbol");
418 } /* too many auxents */
fecd2382 419
57574979 420 for (i = 0; i < numaux; ++i) {
d1a9e594 421#ifdef CROSS_COMPILE
fecd2382 422#if 0 /* This code has never been tested */
57574979
SC
423 /* The most common case, x_sym entry. */
424 if ((SF_GET(symbolP) & (SF_FILE | SF_STATICS)) == 0) {
425 md_number_to_chars(*where, auxP->x_sym.x_tagndx, sizeof(auxP->x_sym.x_tagndx));
426 *where += sizeof(auxP->x_sym.x_tagndx);
427 if (ISFCN(type)) {
428 md_number_to_chars(*where, auxP->x_sym.x_misc.x_fsize, sizeof(auxP->x_sym.x_misc.x_fsize));
429 *where += sizeof(auxP->x_sym.x_misc.x_fsize);
430 } else {
431 md_number_to_chars(*where, auxP->x_sym.x_misc.x_lnno, sizeof(auxP->x_sym.x_misc.x_lnno));
432 *where += sizeof(auxP->x_sym.x_misc.x_lnno);
433 md_number_to_chars(*where, auxP->x_sym.x_misc.x_size, sizeof(auxP->x_sym.x_misc.x_size));
434 *where += sizeof(auxP->x_sym.x_misc.x_size);
435 }
436 if (ISARY(type)) {
437 register int index;
438 for (index = 0; index < DIMNUM; index++)
439 md_number_to_chars(*where, auxP->x_sym.x_fcnary.x_ary.x_dimen[index], sizeof(auxP->x_sym.x_fcnary.x_ary.x_dimen[index]));
440 *where += sizeof(auxP->x_sym.x_fcnary.x_ary.x_dimen[index]);
441 } else {
442 md_number_to_chars(*where, auxP->x_sym.x_fcnary.x_fcn.x_lnnoptr, sizeof(auxP->x_sym.x_fcnary.x_fcn.x_lnnoptr));
443 *where += sizeof(auxP->x_sym.x_fcnary.x_fcn.x_lnnoptr);
444 md_number_to_chars(*where, auxP->x_sym.x_fcnary.x_fcn.x_endndx, sizeof(auxP->x_sym.x_fcnary.x_fcn.x_endndx));
445 *where += sizeof(auxP->x_sym.x_fcnary.x_fcn.x_endndx);
446 }
447 md_number_to_chars(*where, auxP->x_sym.x_tvndx, sizeof(auxP->x_sym.x_tvndx));
448 *where += sizeof(auxP->x_sym.x_tvndx);
449 } else if (SF_GET_FILE(symbolP)) { /* .file */
450 ;
451 } else if (SF_GET_STATICS(symbolP)) { /* .text, .data, .bss symbols */
452 md_number_to_chars(*where, auxP->x_scn.x_scnlen, sizeof(auxP->x_scn.x_scnlen));
453 *where += sizeof(auxP->x_scn.x_scnlen);
454 md_number_to_chars(*where, auxP->x_scn.x_nreloc, sizeof(auxP->x_scn.x_nreloc));
455 *where += sizeof(auxP->x_scn.x_nreloc);
456 md_number_to_chars(*where, auxP->x_scn.x_nlinno, sizeof(auxP->x_scn.x_nlinno));
457 *where += sizeof(auxP->x_scn.x_nlinno);
458 }
fecd2382 459#endif /* 0 */
d1a9e594 460#else /* CROSS_COMPILE */
57574979 461 append(where, (char *) &symbolP->sy_symbol.ost_auxent[i], sizeof(symbolP->sy_symbol.ost_auxent[i]));
d1a9e594 462#endif /* CROSS_COMPILE */
fecd2382 463
57574979
SC
464 }; /* for each aux in use */
465#endif /* BFD_HEADERS */
466 return;
fecd2382
RP
467} /* obj_symbol_to_chars() */
468
57574979
SC
469#ifdef BFD_HEADERS
470static void obj_coff_section_header_append(where, header)
471char **where;
472struct internal_scnhdr *header;
473{
474 *where += bfd_coff_swap_scnhdr_out(stdoutput, header, *where);
475}
476#else
477static void obj_coff_section_header_append(where, header)
fecd2382
RP
478char **where;
479SCNHDR *header;
480{
d1a9e594 481#ifdef CROSS_COMPILE
57574979
SC
482 memcpy(*where, header->s_name, sizeof(header->s_name));
483 *where += sizeof(header->s_name);
484
485 md_number_to_chars(*where, header->s_paddr, sizeof(header->s_paddr));
486 *where += sizeof(header->s_paddr);
487
488 md_number_to_chars(*where, header->s_vaddr, sizeof(header->s_vaddr));
489 *where += sizeof(header->s_vaddr);
490
491 md_number_to_chars(*where, header->s_size, sizeof(header->s_size));
492 *where += sizeof(header->s_size);
493
494 md_number_to_chars(*where, header->s_scnptr, sizeof(header->s_scnptr));
495 *where += sizeof(header->s_scnptr);
496
497 md_number_to_chars(*where, header->s_relptr, sizeof(header->s_relptr));
498 *where += sizeof(header->s_relptr);
499
500 md_number_to_chars(*where, header->s_lnnoptr, sizeof(header->s_lnnoptr));
501 *where += sizeof(header->s_lnnoptr);
502
503 md_number_to_chars(*where, header->s_nreloc, sizeof(header->s_nreloc));
504 *where += sizeof(header->s_nreloc);
505
506 md_number_to_chars(*where, header->s_nlnno, sizeof(header->s_nlnno));
507 *where += sizeof(header->s_nlnno);
508
509 md_number_to_chars(*where, header->s_flags, sizeof(header->s_flags));
510 *where += sizeof(header->s_flags);
511
512#ifdef TC_I960
513 md_number_to_chars(*where, header->s_align, sizeof(header->s_align));
514 *where += sizeof(header->s_align);
515#endif /* TC_I960 */
fecd2382 516
d1a9e594 517#else /* CROSS_COMPILE */
57574979
SC
518
519 append(where, (char *) header, sizeof(*header));
520
d1a9e594 521#endif /* CROSS_COMPILE */
fecd2382 522
57574979
SC
523 return;
524} /* obj_coff_section_header_append() */
fecd2382 525
57574979 526#endif
fecd2382
RP
527void obj_emit_symbols(where, symbol_rootP)
528char **where;
529symbolS *symbol_rootP;
530{
531 symbolS *symbolP;
532 /*
533 * Emit all symbols left in the symbol chain.
534 */
535 for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next(symbolP)) {
536 /* Used to save the offset of the name. It is used to point
537 to the string in memory but must be a file offset. */
538 register char * temp;
539
540 tc_coff_symbol_emit_hook(symbolP);
541
542 temp = S_GET_NAME(symbolP);
543 if (SF_GET_STRING(symbolP)) {
544 S_SET_OFFSET(symbolP, symbolP->sy_name_offset);
545 S_SET_ZEROES(symbolP, 0);
546 } else {
547 bzero(symbolP->sy_symbol.ost_entry.n_name, SYMNMLEN);
548 strncpy(symbolP->sy_symbol.ost_entry.n_name, temp, SYMNMLEN);
549 }
550 obj_symbol_to_chars(where, symbolP);
551 S_SET_NAME(symbolP,temp);
552 }
553} /* obj_emit_symbols() */
554
555/* Merge a debug symbol containing debug information into a normal symbol. */
556
557void c_symbol_merge(debug, normal)
558symbolS *debug;
559symbolS *normal;
560{
561 S_SET_DATA_TYPE(normal, S_GET_DATA_TYPE(debug));
562 S_SET_STORAGE_CLASS(normal, S_GET_STORAGE_CLASS(debug));
563
564 if (S_GET_NUMBER_AUXILIARY(debug) > S_GET_NUMBER_AUXILIARY(normal)) {
565 S_SET_NUMBER_AUXILIARY(normal, S_GET_NUMBER_AUXILIARY(debug));
566 } /* take the most we have */
567
568 if (S_GET_NUMBER_AUXILIARY(debug) > 0) {
569 memcpy((char*)&normal->sy_symbol.ost_auxent[0], (char*)&debug->sy_symbol.ost_auxent[0], S_GET_NUMBER_AUXILIARY(debug) * AUXESZ);
570 } /* Move all the auxiliary information */
571
572 /* Move the debug flags. */
573 SF_SET_DEBUG_FIELD(normal, SF_GET_DEBUG_FIELD(debug));
574} /* c_symbol_merge() */
575
576static symbolS *previous_file_symbol = NULL;
577
578void c_dot_file_symbol(filename)
579char *filename;
580{
581 symbolS* symbolP;
582
583 symbolP = symbol_new(".file",
584 SEG_DEBUG,
585 0,
586 &zero_address_frag);
587
588 S_SET_STORAGE_CLASS(symbolP, C_FILE);
589 S_SET_NUMBER_AUXILIARY(symbolP, 1);
590 SA_SET_FILE_FNAME(symbolP, filename);
591 SF_SET_DEBUG(symbolP);
592 S_SET_VALUE(symbolP, (long) previous_file_symbol);
593
594 previous_file_symbol = symbolP;
595
596 /* Make sure that the symbol is first on the symbol chain */
597 if (symbol_rootP != symbolP) {
598 if (symbolP == symbol_lastP) {
599 symbol_lastP = symbol_lastP->sy_previous;
600 } /* if it was the last thing on the list */
601
602 symbol_remove(symbolP, &symbol_rootP, &symbol_lastP);
603 symbol_insert(symbolP, symbol_rootP, &symbol_rootP, &symbol_lastP);
604 symbol_rootP = symbolP;
605 } /* if not first on the list */
606
607} /* c_dot_file_symbol() */
608/*
609 * Build a 'section static' symbol.
610 */
611
612char *c_section_symbol(name, value, length, nreloc, nlnno)
613char *name;
614long value;
615long length;
616unsigned short nreloc;
617unsigned short nlnno;
618{
619 symbolS *symbolP;
620
621 symbolP = symbol_new(name,
622 (name[1] == 't'
623 ? SEG_TEXT
624 : (name[1] == 'd'
625 ? SEG_DATA
626 : SEG_BSS)),
627 value,
628 &zero_address_frag);
629
630 S_SET_STORAGE_CLASS(symbolP, C_STAT);
631 S_SET_NUMBER_AUXILIARY(symbolP, 1);
632
633 SA_SET_SCN_SCNLEN(symbolP, length);
634 SA_SET_SCN_NRELOC(symbolP, nreloc);
635 SA_SET_SCN_NLINNO(symbolP, nlnno);
636
637 SF_SET_STATICS(symbolP);
638
639 return (char*)symbolP;
640} /* c_section_symbol() */
641
642void c_section_header(header,
643 name,
644 core_address,
645 size,
646 data_ptr,
647 reloc_ptr,
648 lineno_ptr,
649 reloc_number,
650 lineno_number,
651 alignment)
57574979
SC
652#ifdef BFD_HEADERS
653struct internal_scnhdr *header;
654#else
fecd2382 655SCNHDR *header;
57574979 656#endif
fecd2382
RP
657char *name;
658long core_address;
659long size;
660long data_ptr;
661long reloc_ptr;
662long lineno_ptr;
663long reloc_number;
664long lineno_number;
665long alignment;
666{
667 strncpy(header->s_name, name, 8);
668 header->s_paddr = header->s_vaddr = core_address;
669 header->s_scnptr = ((header->s_size = size) != 0) ? data_ptr : 0;
670 header->s_relptr = reloc_ptr;
671 header->s_lnnoptr = lineno_ptr;
672 header->s_nreloc = reloc_number;
673 header->s_nlnno = lineno_number;
674
675#ifdef OBJ_COFF_SECTION_HEADER_HAS_ALIGNMENT
676#ifdef OBJ_COFF_BROKEN_ALIGNMENT
677 header->s_align = ((name[1] == 'b' || (size > 0)) ? 16 : 0);
678#else
679 header->s_align = ((alignment == 0)
680 ? 0
681 : (1 << alignment));
682#endif /* OBJ_COFF_BROKEN_ALIGNMENT */
683#endif /* OBJ_COFF_SECTION_HEADER_HAS_ALIGNMENT */
684
685 header->s_flags = STYP_REG | (name[1] == 't'
686 ? STYP_TEXT
687 : (name[1] == 'd'
688 ? STYP_DATA
689 : (name[1] == 'b'
690 ? STYP_BSS
691 : STYP_INFO)));
692 return;
693} /* c_section_header() */
694
695/* Line number handling */
696
697int function_lineoff = -1; /* Offset in line#s where the last function
698 started (the odd entry for line #0) */
699int text_lineno_number = 0;
700int our_lineno_number = 0; /* we use this to build pointers from .bf's
701 into the linetable. It should match
702 exactly the values that are later
703 assigned in text_lineno_number by
704 write.c. */
705lineno* lineno_lastP = (lineno*)0;
706
707int
708c_line_new(paddr, line_number, frag)
709long paddr;
710unsigned short line_number;
711fragS* frag;
712{
713 lineno* new_line = (lineno*)xmalloc(sizeof(lineno));
714
715 new_line->line.l_addr.l_paddr = paddr;
716 new_line->line.l_lnno = line_number;
717 new_line->frag = (char*)frag;
718 new_line->next = (lineno*)0;
719
720 if (lineno_rootP == (lineno*)0)
721 lineno_rootP = new_line;
722 else
723 lineno_lastP->next = new_line;
724 lineno_lastP = new_line;
725 return LINESZ * our_lineno_number++;
726}
727
728void obj_emit_lineno(where, line, file_start)
729char **where;
730lineno *line;
731char *file_start;
732{
57574979
SC
733#ifdef BFD_HEADERS
734 struct bfd_internal_lineno *line_entry;
735#else
fecd2382 736 LINENO *line_entry;
57574979 737#endif
fecd2382
RP
738 for (; line; line = line->next) {
739 line_entry = &line->line;
740
741 /* FIXME-SOMEDAY Resolving the sy_number of function linno's used to be done in
742 write_object_file() but their symbols need a fileptr to the lnno, so
743 I moved this resolution check here. xoxorich. */
744
745 if (line_entry->l_lnno == 0) {
746 /* There is a good chance that the symbol pointed to
747 is not the one that will be emitted and that the
748 sy_number is not accurate. */
749/* char *name; */
750 symbolS *symbolP;
751
752 symbolP = (symbolS *) line_entry->l_addr.l_symndx;
753
754 line_entry->l_addr.l_symndx = symbolP->sy_number;
755 symbolP->sy_symbol.ost_auxent[0].x_sym.x_fcnary.x_fcn.x_lnnoptr = *where - file_start;
756
757 } /* if this is a function linno */
57574979
SC
758#ifdef BFD_HEADERS
759 *where += bfd_coff_swap_lineno_out(stdoutput, line_entry, *where);
760#else
fecd2382
RP
761 /* No matter which member of the union we process, they are
762 both long. */
d1a9e594 763#ifdef CROSS_COMPILE
fecd2382
RP
764 md_number_to_chars(*where, line_entry->l_addr.l_paddr, sizeof(line_entry->l_addr.l_paddr));
765 *where += sizeof(line_entry->l_addr.l_paddr);
766
767 md_number_to_chars(*where, line_entry->l_lnno, sizeof(line_entry->l_lnno));
768 *where += sizeof(line_entry->l_lnno);
d1a9e594 769#else /* CROSS_COMPILE */
fecd2382 770 append(where, (char *) line_entry, LINESZ);
d1a9e594 771#endif /* CROSS_COMPILE */
57574979 772#endif
fecd2382
RP
773 } /* for each line number */
774
775 return ;
776} /* obj_emit_lineno() */
777
778void obj_symbol_new_hook(symbolP)
779symbolS *symbolP;
780{
781 char underscore = 0; /* Symbol has leading _ */
782
783 /* Effective symbol */
784 /* Store the pointer in the offset. */
785 S_SET_ZEROES(symbolP, 0L);
786 S_SET_DATA_TYPE(symbolP, T_NULL);
787 S_SET_STORAGE_CLASS(symbolP, 0);
788 S_SET_NUMBER_AUXILIARY(symbolP, 0);
789 /* Additional information */
790 symbolP->sy_symbol.ost_flags = 0;
791 /* Auxiliary entries */
792 bzero((char*)&symbolP->sy_symbol.ost_auxent[0], AUXESZ);
793
794#if STRIP_UNDERSCORE
795 /* Remove leading underscore at the beginning of the symbol.
796 * This is to be compatible with the standard librairies.
797 */
798 if (*S_GET_NAME(symbolP) == '_') {
799 underscore = 1;
800 S_SET_NAME(symbolP, S_GET_NAME(symbolP) + 1);
801 } /* strip underscore */
802#endif /* STRIP_UNDERSCORE */
803
804 if (S_IS_STRING(symbolP))
805 SF_SET_STRING(symbolP);
806 if (!underscore && S_IS_LOCAL(symbolP))
807 SF_SET_LOCAL(symbolP);
808
809 return;
810} /* obj_symbol_new_hook() */
811
812 /* stack stuff */
813stack* stack_init(chunk_size, element_size)
814unsigned long chunk_size;
815unsigned long element_size;
816{
817 stack* st;
818
819 if ((st = (stack*)malloc(sizeof(stack))) == (stack*)0)
820 return (stack*)0;
821 if ((st->data = malloc(chunk_size)) == (char*)0) {
822 free(st);
823 return (stack*)0;
824 }
825 st->pointer = 0;
826 st->size = chunk_size;
827 st->chunk_size = chunk_size;
828 st->element_size = element_size;
829 return st;
830} /* stack_init() */
831
832void stack_delete(st)
833stack* st;
834{
835 free(st->data);
836 free(st);
837}
838
839char *stack_push(st, element)
840stack *st;
841char *element;
842{
843 if (st->pointer + st->element_size >= st->size) {
844 st->size += st->chunk_size;
845 if ((st->data = xrealloc(st->data, st->size)) == (char*)0)
846 return (char*)0;
847 }
848 memcpy(st->data + st->pointer, element, st->element_size);
849 st->pointer += st->element_size;
850 return st->data + st->pointer;
851} /* stack_push() */
852
853char* stack_pop(st)
854stack* st;
855{
856 if ((st->pointer -= st->element_size) < 0) {
857 st->pointer = 0;
858 return (char*)0;
859 }
860 return st->data + st->pointer;
861}
862
863char* stack_top(st)
864stack* st;
865{
866 return st->data + st->pointer - st->element_size;
867}
868
869
870/*
871 * Handle .ln directives.
872 */
873
874static void obj_coff_ln() {
875 if (def_symbol_in_progress != NULL) {
876 as_warn(".ln pseudo-op inside .def/.endef: ignored.");
877 demand_empty_rest_of_line();
878 return;
879 } /* wrong context */
880
881 c_line_new(obstack_next_free(&frags) - frag_now->fr_literal,
882 get_absolute_expression(),
883 frag_now);
884
885 demand_empty_rest_of_line();
886 return;
887} /* obj_coff_line() */
888
889/*
890 * def()
891 *
892 * Handle .def directives.
893 *
894 * One might ask : why can't we symbol_new if the symbol does not
895 * already exist and fill it with debug information. Because of
896 * the C_EFCN special symbol. It would clobber the value of the
897 * function symbol before we have a chance to notice that it is
898 * a C_EFCN. And a second reason is that the code is more clear this
899 * way. (at least I think it is :-).
900 *
901 */
902
903#define SKIP_SEMI_COLON() while (*input_line_pointer++ != ';')
904#define SKIP_WHITESPACES() while (*input_line_pointer == ' ' || \
905 *input_line_pointer == '\t') \
906 input_line_pointer++;
907
908static void obj_coff_def(what)
909int what;
910{
911 char name_end; /* Char after the end of name */
912 char *symbol_name; /* Name of the debug symbol */
913 char *symbol_name_copy; /* Temporary copy of the name */
914 unsigned int symbol_name_length;
915 /*$char* directiveP;$ */ /* Name of the pseudo opcode */
916 /*$char directive[MAX_DIRECTIVE];$ */ /* Backup of the directive */
917 /*$char end = 0;$ */ /* If 1, stop parsing */
918
919 if (def_symbol_in_progress != NULL) {
920 as_warn(".def pseudo-op used inside of .def/.endef: ignored.");
921 demand_empty_rest_of_line();
922 return;
923 } /* if not inside .def/.endef */
924
925 SKIP_WHITESPACES();
926
927 def_symbol_in_progress = (symbolS *) obstack_alloc(&notes, sizeof(*def_symbol_in_progress));
928 bzero(def_symbol_in_progress, sizeof(*def_symbol_in_progress));
929
930 symbol_name = input_line_pointer;
931 name_end = get_symbol_end();
932 symbol_name_length = strlen(symbol_name);
933 symbol_name_copy = xmalloc(symbol_name_length + 1);
934 strcpy(symbol_name_copy, symbol_name);
935
936 /* Initialize the new symbol */
937#if STRIP_UNDERSCORE
938 S_SET_NAME(def_symbol_in_progress, (*symbol_name_copy == '_'
939 ? symbol_name_copy + 1
940 : symbol_name_copy));
941#else /* STRIP_UNDERSCORE */
942 S_SET_NAME(def_symbol_in_progress, symbol_name_copy);
943#endif /* STRIP_UNDERSCORE */
944 /* free(symbol_name_copy); */
945 def_symbol_in_progress->sy_name_offset = ~0;
946 def_symbol_in_progress->sy_number = ~0;
947 def_symbol_in_progress->sy_frag = &zero_address_frag;
948
949 if (S_IS_STRING(def_symbol_in_progress)) {
950 SF_SET_STRING(def_symbol_in_progress);
951 } /* "long" name */
952
953 *input_line_pointer = name_end;
954
955 demand_empty_rest_of_line();
956 return;
957} /* obj_coff_def() */
958
959unsigned int dim_index;
960static void obj_coff_endef() {
961 symbolS *symbolP;
962/* DIM BUG FIX sac@cygnus.com */
963 dim_index =0;
964 if (def_symbol_in_progress == NULL) {
965 as_warn(".endef pseudo-op used outside of .def/.endef: ignored.");
966 demand_empty_rest_of_line();
967 return;
968 } /* if not inside .def/.endef */
969
970 /* Set the section number according to storage class. */
971 switch (S_GET_STORAGE_CLASS(def_symbol_in_progress)) {
972 case C_STRTAG:
973 case C_ENTAG:
974 case C_UNTAG:
975 SF_SET_TAG(def_symbol_in_progress);
976 /* intentional fallthrough */
977 case C_FILE:
978 case C_TPDEF:
979 SF_SET_DEBUG(def_symbol_in_progress);
980 S_SET_SEGMENT(def_symbol_in_progress, SEG_DEBUG);
981 break;
982
983 case C_EFCN:
984 SF_SET_LOCAL(def_symbol_in_progress); /* Do not emit this symbol. */
985 /* intentional fallthrough */
986 case C_BLOCK:
987 SF_SET_PROCESS(def_symbol_in_progress); /* Will need processing before writing */
988 /* intentional fallthrough */
989 case C_FCN:
990 S_SET_SEGMENT(def_symbol_in_progress, SEG_TEXT);
991
992 if (def_symbol_in_progress->sy_symbol.ost_entry.n_name[1] == 'b') { /* .bf */
993 if (function_lineoff < 0) {
994 fprintf(stderr, "`.bf' symbol without preceding function\n");
995 } /* missing function symbol */
996 SA_GET_SYM_LNNOPTR(def_symbol_in_progress) = function_lineoff;
997 SF_SET_PROCESS(def_symbol_in_progress); /* Will need relocating */
998 function_lineoff = -1;
999 }
1000 break;
1001
1002#ifdef C_AUTOARG
1003 case C_AUTOARG:
1004#endif /* C_AUTOARG */
1005 case C_AUTO:
1006 case C_REG:
1007 case C_MOS:
1008 case C_MOE:
1009 case C_MOU:
1010 case C_ARG:
1011 case C_REGPARM:
1012 case C_FIELD:
1013 case C_EOS:
1014 SF_SET_DEBUG(def_symbol_in_progress);
1015 S_SET_SEGMENT(def_symbol_in_progress, SEG_ABSOLUTE);
1016 break;
1017
1018 case C_EXT:
1019 case C_STAT:
1020 case C_LABEL:
1021 /* Valid but set somewhere else (s_comm, s_lcomm, colon) */
1022 break;
1023
1024 case C_USTATIC:
1025 case C_EXTDEF:
1026 case C_ULABEL:
1027 as_warn("unexpected storage class %d", S_GET_STORAGE_CLASS(def_symbol_in_progress));
1028 break;
1029 } /* switch on storage class */
1030
1031 /* Now that we have built a debug symbol, try to
1032 find if we should merge with an existing symbol
1033 or not. If a symbol is C_EFCN or SEG_ABSOLUTE or
1034 untagged SEG_DEBUG it never merges. */
1035
1036 /* Two cases for functions. Either debug followed
1037 by definition or definition followed by debug.
1038 For definition first, we will merge the debug
1039 symbol into the definition. For debug first, the
1040 lineno entry MUST point to the definition
1041 function or else it will point off into space
1042 when obj_crawl_symbol_chain() merges the debug
1043 symbol into the real symbol. Therefor, let's
1044 presume the debug symbol is a real function
1045 reference. */
1046
1047 /* FIXME-SOON If for some reason the definition
1048 label/symbol is never seen, this will probably
1049 leave an undefined symbol at link time. */
1050
1051 if (S_GET_STORAGE_CLASS(def_symbol_in_progress) == C_EFCN
1052 || (S_GET_SEGMENT(def_symbol_in_progress) == SEG_DEBUG
1053 && !SF_GET_TAG(def_symbol_in_progress))
1054 || S_GET_SEGMENT(def_symbol_in_progress) == SEG_ABSOLUTE
1055 || (symbolP = symbol_find_base(S_GET_NAME(def_symbol_in_progress), DO_NOT_STRIP)) == NULL) {
1056
1057 symbol_append(def_symbol_in_progress, symbol_lastP, &symbol_rootP, &symbol_lastP);
1058
1059 } else {
1060 /* This symbol already exists, merge the
1061 newly created symbol into the old one.
1062 This is not mandatory. The linker can
1063 handle duplicate symbols correctly. But I
1064 guess that it save a *lot* of space if
1065 the assembly file defines a lot of
1066 symbols. [loic] */
1067
1068 /* The debug entry (def_symbol_in_progress)
1069 is merged into the previous definition. */
1070
1071 c_symbol_merge(def_symbol_in_progress, symbolP);
1072 /* FIXME-SOON Should *def_symbol_in_progress be free'd? xoxorich. */
1073 def_symbol_in_progress = symbolP;
1074
1075 if (SF_GET_FUNCTION(def_symbol_in_progress)
1076 || SF_GET_TAG(def_symbol_in_progress)) {
1077 /* For functions, and tags, the symbol *must* be where the debug symbol
1078 appears. Move the existing symbol to the current place. */
1079 /* If it already is at the end of the symbol list, do nothing */
1080 if (def_symbol_in_progress != symbol_lastP) {
1081 symbol_remove(def_symbol_in_progress, &symbol_rootP, &symbol_lastP);
1082 symbol_append(def_symbol_in_progress, symbol_lastP, &symbol_rootP, &symbol_lastP);
1083 } /* if not already in place */
1084 } /* if function */
1085 } /* normal or mergable */
1086
1087 if (SF_GET_TAG(def_symbol_in_progress)
1088 && symbol_find_base(S_GET_NAME(def_symbol_in_progress), DO_NOT_STRIP) == NULL) {
1089 tag_insert(S_GET_NAME(def_symbol_in_progress), def_symbol_in_progress);
1090 } /* If symbol is a {structure,union} tag, associate symbol to its name. */
1091
1092 if (SF_GET_FUNCTION(def_symbol_in_progress)) {
1093 know(sizeof(def_symbol_in_progress) <= sizeof(long));
1094 function_lineoff = c_line_new((long) def_symbol_in_progress, 0, &zero_address_frag);
1095 SF_SET_PROCESS(def_symbol_in_progress);
1096
1097 if (symbolP == NULL) {
1098 /* That is, if this is the first
1099 time we've seen the function... */
1100 symbol_table_insert(def_symbol_in_progress);
1101 } /* definition follows debug */
1102 } /* Create the line number entry pointing to the function being defined */
1103
1104 def_symbol_in_progress = NULL;
1105 demand_empty_rest_of_line();
1106 return;
1107} /* obj_coff_endef() */
57574979
SC
1108#ifndef TC_I960
1109/*This code expects all the dims to be after one another, and that is not true
fecd2382 1110for gcc960
57574979 1111sac@cygnus.com */
fecd2382
RP
1112static void obj_coff_dim() {
1113 register int dim_index;
1114
1115 if (def_symbol_in_progress == NULL) {
1116 as_warn(".dim pseudo-op used outside of .def/.endef: ignored.");
1117 demand_empty_rest_of_line();
1118 return;
1119 } /* if not inside .def/.endef */
1120
1121 S_SET_NUMBER_AUXILIARY(def_symbol_in_progress, 1);
1122
1123 for (dim_index = 0; dim_index < DIMNUM; dim_index++) {
1124 SKIP_WHITESPACES();
1125 SA_SET_SYM_DIMEN(def_symbol_in_progress, dim_index, get_absolute_expression());
1126
1127 switch (*input_line_pointer) {
1128
1129 case ',':
1130 input_line_pointer++;
1131 break;
1132
1133 default:
1134 as_warn("badly formed .dim directive ignored");
1135 /* intentional fallthrough */
1136 case ';':
1137 dim_index = DIMNUM;
1138 break;
1139 } /* switch on following character */
1140 } /* for each dimension */
1141
1142 demand_empty_rest_of_line();
1143 return;
1144} /* obj_coff_dim() */
1145#else
1146
1147static void
1148obj_coff_dim()
1149{
1150 if (def_symbol_in_progress == NULL) {
1151 as_warn(".dim pseudo-op used outside of .def/.endef: ignored.");
1152 demand_empty_rest_of_line();
1153 return;
1154 } /* if not inside .def/.endef */
1155
1156
1157 S_SET_NUMBER_AUXILIARY(def_symbol_in_progress, 1);
1158
1159 /* Grab as many dims as we can fit, until ; or full */
1160 while (dim_index < DIMNUM)
1161 {
1162 SKIP_WHITESPACES();
1163 SA_SET_SYM_DIMEN(def_symbol_in_progress, dim_index, get_absolute_expression());
1164 dim_index++;
1165 if (*input_line_pointer == ';') break;
1166 if (*input_line_pointer != ',') {
1167 as_warn("badly formed .dim directive ignored");
1168 break;
1169 }
1170 input_line_pointer++;
1171 }
1172 demand_empty_rest_of_line();
1173 return;
1174} /* obj_coff_dim() */
1175#endif
1176
1177static void obj_coff_line() {
1178 if (def_symbol_in_progress == NULL) {
1179 obj_coff_ln();
1180 return;
1181 } /* if it looks like a stabs style line */
1182
1183 S_SET_NUMBER_AUXILIARY(def_symbol_in_progress, 1);
1184 SA_SET_SYM_LNNO(def_symbol_in_progress, get_absolute_expression());
1185
1186 demand_empty_rest_of_line();
1187 return;
1188} /* obj_coff_line() */
1189
1190static void obj_coff_size() {
1191 if (def_symbol_in_progress == NULL) {
1192 as_warn(".size pseudo-op used outside of .def/.endef ignored.");
1193 demand_empty_rest_of_line();
1194 return;
1195 } /* if not inside .def/.endef */
1196
1197 S_SET_NUMBER_AUXILIARY(def_symbol_in_progress, 1);
1198 SA_SET_SYM_SIZE(def_symbol_in_progress, get_absolute_expression());
1199 demand_empty_rest_of_line();
1200 return;
1201} /* obj_coff_size() */
1202
1203static void obj_coff_scl() {
1204 if (def_symbol_in_progress == NULL) {
1205 as_warn(".scl pseudo-op used outside of .def/.endef ignored.");
1206 demand_empty_rest_of_line();
1207 return;
1208 } /* if not inside .def/.endef */
1209
1210 S_SET_STORAGE_CLASS(def_symbol_in_progress, get_absolute_expression());
1211 demand_empty_rest_of_line();
1212 return;
1213} /* obj_coff_scl() */
1214
1215static void obj_coff_tag() {
1216 char *symbol_name;
1217 char name_end;
1218
1219 if (def_symbol_in_progress == NULL) {
1220 as_warn(".tag pseudo-op used outside of .def/.endef ignored.");
1221 demand_empty_rest_of_line();
1222 return;
1223 } /* if not inside .def/.endef */
1224
1225 S_SET_NUMBER_AUXILIARY(def_symbol_in_progress, 1);
1226 symbol_name = input_line_pointer;
1227 name_end = get_symbol_end();
1228
1229 /* Assume that the symbol referred to by .tag is always defined. */
1230 /* This was a bad assumption. I've added find_or_make. xoxorich. */
1231 SA_SET_SYM_TAGNDX(def_symbol_in_progress, (long) tag_find_or_make(symbol_name));
1232 if (SA_GET_SYM_TAGNDX(def_symbol_in_progress) == 0L) {
1233 as_warn("tag not found for .tag %s", symbol_name);
1234 } /* not defined */
1235
1236 SF_SET_TAGGED(def_symbol_in_progress);
1237 *input_line_pointer = name_end;
1238
1239 demand_empty_rest_of_line();
1240 return;
1241} /* obj_coff_tag() */
1242
1243static void obj_coff_type() {
1244 if (def_symbol_in_progress == NULL) {
1245 as_warn(".type pseudo-op used outside of .def/.endef ignored.");
1246 demand_empty_rest_of_line();
1247 return;
1248 } /* if not inside .def/.endef */
1249
1250 S_SET_DATA_TYPE(def_symbol_in_progress, get_absolute_expression());
1251
1252 if (ISFCN(S_GET_DATA_TYPE(def_symbol_in_progress)) &&
1253 S_GET_STORAGE_CLASS(def_symbol_in_progress) != C_TPDEF) {
1254 SF_SET_FUNCTION(def_symbol_in_progress);
1255 } /* is a function */
1256
1257 demand_empty_rest_of_line();
1258 return;
1259} /* obj_coff_type() */
1260
1261static void obj_coff_val() {
1262 if (def_symbol_in_progress == NULL) {
1263 as_warn(".val pseudo-op used outside of .def/.endef ignored.");
1264 demand_empty_rest_of_line();
1265 return;
1266 } /* if not inside .def/.endef */
1267
1268 if (is_name_beginner(*input_line_pointer)) {
1269 char *symbol_name = input_line_pointer;
1270 char name_end = get_symbol_end();
1271
1272 if (!strcmp(symbol_name, ".")) {
1273 def_symbol_in_progress->sy_frag = frag_now;
1274 S_SET_VALUE(def_symbol_in_progress, obstack_next_free(&frags) - frag_now->fr_literal);
1275 /* If the .val is != from the .def (e.g. statics) */
1276 } else if (strcmp(S_GET_NAME(def_symbol_in_progress), symbol_name)) {
1277 def_symbol_in_progress->sy_forward = symbol_find_or_make(symbol_name);
1278
1279 /* If the segment is undefined when the forward
1280 reference is solved, then copy the segment id
1281 from the forward symbol. */
1282 SF_SET_GET_SEGMENT(def_symbol_in_progress);
1283 }
1284 /* Otherwise, it is the name of a non debug symbol and its value will be calculated later. */
1285 *input_line_pointer = name_end;
1286 } else {
1287 S_SET_VALUE(def_symbol_in_progress, get_absolute_expression());
1288 } /* if symbol based */
1289
1290 demand_empty_rest_of_line();
1291 return;
1292} /* obj_coff_val() */
1293
1294/*
1295 * Maintain a list of the tagnames of the structres.
1296 */
1297
1298static void tag_init() {
1299 tag_hash = hash_new();
1300 return ;
1301} /* tag_init() */
1302
1303static void tag_insert(name, symbolP)
1304char *name;
1305symbolS *symbolP;
1306{
1307 register char * error_string;
1308
1309 if (*(error_string = hash_jam(tag_hash, name, (char *)symbolP))) {
1310 as_fatal("Inserting \"%s\" into structure table failed: %s",
1311 name, error_string);
1312 }
1313 return ;
1314} /* tag_insert() */
1315
1316static symbolS *tag_find_or_make(name)
1317char *name;
1318{
1319 symbolS *symbolP;
1320
1321 if ((symbolP = tag_find(name)) == NULL) {
1322 symbolP = symbol_new(name,
1323 SEG_UNKNOWN,
1324 0,
1325 &zero_address_frag);
1326
1327 tag_insert(S_GET_NAME(symbolP), symbolP);
1328 symbol_table_insert(symbolP);
1329 } /* not found */
1330
1331 return(symbolP);
1332} /* tag_find_or_make() */
1333
1334static symbolS *tag_find(name)
1335char *name;
1336{
1337#if STRIP_UNDERSCORE
1338 if (*name == '_') name++;
1339#endif /* STRIP_UNDERSCORE */
1340 return((symbolS*)hash_find(tag_hash, name));
1341} /* tag_find() */
1342
1343void obj_read_begin_hook() {
1344 /* These had better be the same. Usually 18 bytes. */
57574979 1345#ifndef BFD_HEADERS
fecd2382
RP
1346 know(sizeof(SYMENT) == sizeof(AUXENT));
1347 know(SYMESZ == AUXESZ);
57574979 1348#endif
fecd2382
RP
1349 tag_init();
1350
1351 return;
1352} /* obj_read_begin_hook() */
1353
1354void obj_crawl_symbol_chain(headers)
1355object_headers *headers;
1356{
1357 int symbol_number = 0;
1358 lineno *lineP;
1359 symbolS *last_functionP = NULL;
1360 symbolS *last_tagP;
1361 symbolS *symbolP;
1362 symbolS *symbol_externP = NULL;
1363 symbolS *symbol_extern_lastP = NULL;
1364
1365 /* Initialize the stack used to keep track of the matching .bb .be */
1366 stack* block_stack = stack_init(512, sizeof(symbolS*));
1367
1368 /* JF deal with forward references first... */
1369 for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next(symbolP)) {
57574979 1370
fecd2382
RP
1371 if (symbolP->sy_forward) {
1372 S_SET_VALUE(symbolP, (S_GET_VALUE(symbolP)
1373 + S_GET_VALUE(symbolP->sy_forward)
1374 + symbolP->sy_forward->sy_frag->fr_address));
1375
1376 if (SF_GET_GET_SEGMENT(symbolP)) {
1377 S_SET_SEGMENT(symbolP, S_GET_SEGMENT(symbolP->sy_forward));
1378 } /* forward segment also */
1379
1380 symbolP->sy_forward=0;
1381 } /* if it has a forward reference */
1382 } /* walk the symbol chain */
1383
1384 tc_crawl_symbol_chain(headers);
1385
1386 /* The symbol list should be ordered according to the following sequence
1387 * order :
1388 * . .file symbol
1389 * . debug entries for functions
1390 * . fake symbols for .text .data and .bss
1391 * . defined symbols
1392 * . undefined symbols
1393 * But this is not mandatory. The only important point is to put the
1394 * undefined symbols at the end of the list.
1395 */
1396
1397 if (symbol_rootP == NULL
1398 || S_GET_STORAGE_CLASS(symbol_rootP) != C_FILE) {
1399 know(!previous_file_symbol);
1400 c_dot_file_symbol("fake");
1401 } /* Is there a .file symbol ? If not insert one at the beginning. */
1402
1403 /*
1404 * Build up static symbols for .text, .data and .bss
1405 */
1406 dot_text_symbol = (symbolS*)
1407 c_section_symbol(".text",
1408 0,
1409 H_GET_TEXT_SIZE(headers),
1410 0/*text_relocation_number */,
1411 0/*text_lineno_number */);
1412
1413 dot_data_symbol = (symbolS*)
1414 c_section_symbol(".data",
1415 H_GET_TEXT_SIZE(headers),
1416 H_GET_DATA_SIZE(headers),
1417 0/*data_relocation_number */,
1418 0); /* There are no data lineno entries */
1419
1420 dot_bss_symbol = (symbolS*)
1421 c_section_symbol(".bss",
1422 H_GET_TEXT_SIZE(headers) + H_GET_DATA_SIZE(headers),
1423 H_GET_BSS_SIZE(headers),
1424 0, /* No relocation for a bss section. */
1425 0); /* There are no bss lineno entries */
1426
1427#if defined(DEBUG)
1428 verify_symbol_chain(symbol_rootP, symbol_lastP);
1429#endif /* DEBUG */
1430
1431 /* Three traversals of symbol chains here. The
1432 first traversal yanks externals into a temporary
1433 chain, removing the externals from the global
1434 chain, numbers symbols, and does some other guck.
1435 The second traversal is on the temporary chain of
1436 externals and just appends them to the global
1437 chain again, numbering them as we go. The third
1438 traversal patches pointers to symbols (using sym
1439 indexes). The last traversal was once done as
1440 part of the first pass, but that fails when a
1441 reference preceeds a definition as the definition
1442 has no number at the time we process the
1443 reference. */
1444
1445 /* Note that symbolP will be NULL at the end of a loop
1446 if an external was at the beginning of the list (it
1447 gets moved off the list). Hence the weird check in
1448 the loop control.
1449 */
57574979
SC
1450 for (symbolP = symbol_rootP;
1451 symbolP;
1452 symbolP = symbolP ? symbol_next(symbolP) : symbol_rootP) {
1453 if (!SF_GET_DEBUG(symbolP)) {
fecd2382
RP
1454 /* Debug symbols do not need all this rubbish */
1455 symbolS* real_symbolP;
1456
1457 /* L* and C_EFCN symbols never merge. */
1458 if (!SF_GET_LOCAL(symbolP)
1459 && (real_symbolP = symbol_find_base(S_GET_NAME(symbolP), DO_NOT_STRIP))
1460 && real_symbolP != symbolP) {
1461 /* FIXME-SOON: where do dups come from? Maybe tag references before definitions? xoxorich. */
1462 /* Move the debug data from the debug symbol to the
1463 real symbol. Do NOT do the oposite (i.e. move from
1464 real symbol to debug symbol and remove real symbol from the
1465 list.) Because some pointers refer to the real symbol
1466 whereas no pointers refer to the debug symbol. */
1467 c_symbol_merge(symbolP, real_symbolP);
1468 /* Replace the current symbol by the real one */
1469 /* The symbols will never be the last or the first
1470 because : 1st symbol is .file and 3 last symbols are
1471 .text, .data, .bss */
1472 symbol_remove(real_symbolP, &symbol_rootP, &symbol_lastP);
1473 symbol_insert(real_symbolP, symbolP, &symbol_rootP, &symbol_lastP);
1474 symbol_remove(symbolP, &symbol_rootP, &symbol_lastP);
1475 symbolP = real_symbolP;
1476 } /* if not local but dup'd */
1477
1478 if (flagseen['R'] && (S_GET_SEGMENT(symbolP) == SEG_DATA)) {
1479 S_SET_SEGMENT(symbolP, SEG_TEXT);
1480 } /* push data into text */
1481
1482 S_SET_VALUE(symbolP, S_GET_VALUE(symbolP) + symbolP->sy_frag->fr_address);
1483
1484 if (!S_IS_DEFINED(symbolP) && !SF_GET_LOCAL(symbolP)) {
1485 S_SET_EXTERNAL(symbolP);
1486 } else if (S_GET_STORAGE_CLASS(symbolP) == C_NULL) {
1487 if (S_GET_SEGMENT(symbolP) == SEG_TEXT){
1488 S_SET_STORAGE_CLASS(symbolP, C_LABEL);
1489 } else {
1490 S_SET_STORAGE_CLASS(symbolP, C_STAT);
1491 }
1492 } /* no storage class yet */
1493
1494 /* Mainly to speed up if not -g */
1495 if (SF_GET_PROCESS(symbolP)) {
1496 /* Handle the nested blocks auxiliary info. */
1497 if (S_GET_STORAGE_CLASS(symbolP) == C_BLOCK) {
1498 if (!strcmp(S_GET_NAME(symbolP), ".bb"))
1499 stack_push(block_stack, (char *) &symbolP);
1500 else { /* .eb */
1501 register symbolS* begin_symbolP;
1502 begin_symbolP = *(symbolS**)stack_pop(block_stack);
1503 if (begin_symbolP == (symbolS*)0)
1504 as_warn("mismatched .eb");
1505 else
1506 SA_SET_SYM_ENDNDX(begin_symbolP, symbol_number+2);
1507 }
1508 }
1509 /* If we are able to identify the type of a function, and we
1510 are out of a function (last_functionP == 0) then, the
1511 function symbol will be associated with an auxiliary
1512 entry. */
1513 if (last_functionP == (symbolS*)0 &&
1514 SF_GET_FUNCTION(symbolP)) {
1515 last_functionP = symbolP;
1516
1517 if (S_GET_NUMBER_AUXILIARY(symbolP) < 1) {
1518 S_SET_NUMBER_AUXILIARY(symbolP, 1);
1519 } /* make it at least 1 */
1520
1521 /* Clobber possible stale .dim information. */
1522 bzero(symbolP->sy_symbol.ost_auxent[0].x_sym.x_fcnary.x_ary.x_dimen,
1523 sizeof(symbolP->sy_symbol.ost_auxent[0].x_sym.x_fcnary.x_ary.x_dimen));
1524 }
1525 /* The C_FCN doesn't need any additional information.
1526 I don't even know if this is needed for sdb. But the
1527 standard assembler generates it, so...
1528 */
1529 if (S_GET_STORAGE_CLASS(symbolP) == C_EFCN) {
1530 if (last_functionP == (symbolS*)0)
1531 as_fatal("C_EFCN symbol out of scope");
1532 SA_SET_SYM_FSIZE(last_functionP,
1533 (long)(S_GET_VALUE(symbolP) -
1534 S_GET_VALUE(last_functionP)));
1535 SA_SET_SYM_ENDNDX(last_functionP, symbol_number);
1536 last_functionP = (symbolS*)0;
1537 }
1538 }
1539 } else if (SF_GET_TAG(symbolP)) {
1540 /* First descriptor of a structure must point to
1541 the first slot after the structure description. */
1542 last_tagP = symbolP;
1543
1544 } else if (S_GET_STORAGE_CLASS(symbolP) == C_EOS) {
1545 /* +2 take in account the current symbol */
1546 SA_SET_SYM_ENDNDX(last_tagP, symbol_number + 2);
1547 } else if (S_GET_STORAGE_CLASS(symbolP) == C_FILE) {
1548 if (S_GET_VALUE(symbolP)) {
1549 S_SET_VALUE((symbolS *) S_GET_VALUE(symbolP), symbol_number);
1550 S_SET_VALUE(symbolP, 0);
1551 } /* no one points at the first .file symbol */
1552 } /* if debug or tag or eos or file */
1553
1554 /* We must put the external symbols apart. The loader
1555 does not bomb if we do not. But the references in
1556 the endndx field for a .bb symbol are not corrected
1557 if an external symbol is removed between .bb and .be.
1558 I.e in the following case :
1559 [20] .bb endndx = 22
1560 [21] foo external
1561 [22] .be
1562 ld will move the symbol 21 to the end of the list but
1563 endndx will still be 22 instead of 21. */
1564
57574979 1565
fecd2382
RP
1566 if (SF_GET_LOCAL(symbolP)) {
1567 /* remove C_EFCN and LOCAL (L...) symbols */
1568 /* next pointer remains valid */
1569 symbol_remove(symbolP, &symbol_rootP, &symbol_lastP);
1570
1571 } else if (!S_IS_DEFINED(symbolP) && !S_IS_DEBUG(symbolP) && !SF_GET_STATICS(symbolP)) {
1572/* S_GET_STORAGE_CLASS(symbolP) == C_EXT && !SF_GET_FUNCTION(symbolP)) { */
1573 /* if external, Remove from the list */
1574 symbolS *hold = symbol_previous(symbolP);
1575
1576 symbol_remove(symbolP, &symbol_rootP, &symbol_lastP);
1577 symbol_clear_list_pointers(symbolP);
1578 symbol_append(symbolP, symbol_extern_lastP, &symbol_externP, &symbol_extern_lastP);
1579 symbolP = hold;
1580 } else {
1581 if (SF_GET_STRING(symbolP)) {
1582 symbolP->sy_name_offset = string_byte_count;
1583 string_byte_count += strlen(S_GET_NAME(symbolP)) + 1;
1584 } else {
1585 symbolP->sy_name_offset = 0;
1586 } /* fix "long" names */
1587
1588 symbolP->sy_number = symbol_number;
1589 symbol_number += 1 + S_GET_NUMBER_AUXILIARY(symbolP);
1590 } /* if local symbol */
1591 } /* traverse the symbol list */
1592
1593 for (symbolP = symbol_externP; symbol_externP;) {
1594 symbolS *tmp = symbol_externP;
1595
1596 /* append */
1597 symbol_remove(tmp, &symbol_externP, &symbol_extern_lastP);
1598 symbol_append(tmp, symbol_lastP, &symbol_rootP, &symbol_lastP);
1599
1600 /* and process */
1601 if (SF_GET_STRING(tmp)) {
1602 tmp->sy_name_offset = string_byte_count;
1603 string_byte_count += strlen(S_GET_NAME(tmp)) + 1;
1604 } else {
1605 tmp->sy_name_offset = 0;
1606 } /* fix "long" names */
1607
1608 tmp->sy_number = symbol_number;
1609 symbol_number += 1 + S_GET_NUMBER_AUXILIARY(tmp);
1610 } /* append the entire extern chain */
1611
1612 /* When a tag reference preceeds the tag definition,
1613 the definition will not have a number at the time
1614 we process the reference during the first
1615 traversal. Thus, a second traversal. */
1616
1617 for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next(symbolP)) {
1618 if (SF_GET_TAGGED(symbolP)) {
1619 SA_SET_SYM_TAGNDX(symbolP, ((symbolS*) SA_GET_SYM_TAGNDX(symbolP))->sy_number);
1620 } /* If the symbol has a tagndx entry, resolve it */
1621 } /* second traversal */
1622
1623 know(symbol_externP == NULL);
1624 know(symbol_extern_lastP == NULL);
1625
1626 /* FIXME-SOMEDAY I'm counting line no's here so we know what to put in the section
1627 headers, and I'm resolving the addresses since I'm not sure how to
1628 do it later. I am NOT resolving the linno's representing functions.
1629 Their symbols need a fileptr pointing to this linno when emitted.
1630 Thus, I resolve them on emit. xoxorich. */
1631
1632 for (lineP = lineno_rootP; lineP; lineP = lineP->next) {
1633 if (lineP->line.l_lnno > 0) {
1634 lineP->line.l_addr.l_paddr += ((fragS*)lineP->frag)->fr_address;
1635 } else {
1636 ;
1637 }
1638 text_lineno_number++;
1639 } /* for each line number */
1640
1641 H_SET_SYMBOL_TABLE_SIZE(headers, symbol_number);
1642
1643 return;
1644} /* obj_crawl_symbol_chain() */
1645
1646/*
1647 * Find strings by crawling along symbol table chain.
1648 */
1649
1650void obj_emit_strings(where)
1651char **where;
1652{
1653 symbolS *symbolP;
1654
d1a9e594 1655#ifdef CROSS_COMPILE
fecd2382
RP
1656 /* Gotta do md_ byte-ordering stuff for string_byte_count first - KWK */
1657 md_number_to_chars(*where, string_byte_count, sizeof(string_byte_count));
57574979 1658 *where += sizeof(string_byte_count);
d1a9e594 1659#else /* CROSS_COMPILE */
fecd2382 1660 append(where, (char *) &string_byte_count, (unsigned long) sizeof(string_byte_count));
d1a9e594 1661#endif /* CROSS_COMPILE */
fecd2382
RP
1662
1663 for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next(symbolP)) {
1664 if (SF_GET_STRING(symbolP)) {
1665 append(where, S_GET_NAME(symbolP), (unsigned long)(strlen(S_GET_NAME(symbolP)) + 1));
1666 } /* if it has a string */
1667 } /* walk the symbol chain */
1668
1669 return;
1670} /* obj_emit_strings() */
1671
1672void obj_pre_write_hook(headers)
1673object_headers *headers;
1674{
1675 register int text_relocation_number = 0;
1676 register int data_relocation_number = 0;
1677 register fixS *fixP;
1678
1679 /* FIXME-SOMEDAY this should be done at
1680 fixup_segment time but I'm going to wait until I
1681 do multiple segments. xoxorich. */
1682 /* Count the number of relocation entries for text and data */
1683 for (fixP = text_fix_root; fixP; fixP = fixP->fx_next) {
1684 if (fixP->fx_addsy) {
1685 ++text_relocation_number;
1686#ifdef TC_I960
1687 /* two relocs per callj under coff. */
1688 if (fixP->fx_callj) {
1689 ++text_relocation_number;
1690 } /* if callj and not already fixed. */
1691#endif /* TC_I960 */
57574979
SC
1692#ifdef TC_A29K
1693 /* Count 2 for a constH */
1694 if (fixP->fx_r_type == RELOC_CONSTH) {
1695 ++text_relocation_number;
1696 }
1697#endif
fecd2382
RP
1698
1699 } /* if not yet fixed */
1700 } /* for each fix */
1701
1702 SA_SET_SCN_NRELOC(dot_text_symbol, text_relocation_number);
1703 /* Assign the number of line number entries for the text section */
1704 SA_SET_SCN_NLINNO(dot_text_symbol, text_lineno_number);
1705 /* Assign the size of the section */
1706 SA_SET_SCN_SCNLEN(dot_text_symbol, H_GET_TEXT_SIZE(headers));
1707
1708 for (fixP = data_fix_root; fixP; fixP = fixP->fx_next) {
1709 if (fixP->fx_addsy) {
1710 ++data_relocation_number;
1711 } /* if still relocatable */
57574979
SC
1712#ifdef TC_A29K
1713 /* Count 2 for a constH */
1714 if (fixP->fx_r_type == RELOC_CONSTH) {
1715 ++data_relocation_number;
1716 }
1717#endif
1718
fecd2382
RP
1719 } /* for each fix */
1720
57574979 1721
fecd2382
RP
1722 SA_SET_SCN_NRELOC(dot_data_symbol, data_relocation_number);
1723 /* Assign the size of the section */
1724 SA_SET_SCN_SCNLEN(dot_data_symbol, H_GET_DATA_SIZE(headers));
1725
1726 /* Assign the size of the section */
1727 SA_SET_SCN_SCNLEN(dot_bss_symbol, H_GET_BSS_SIZE(headers));
1728
57574979
SC
1729 /* pre write hook can add relocs (for 960 and 29k coff) so */
1730 headers->relocation_size = text_relocation_number * RELSZ +
1731 data_relocation_number *RELSZ;
1732
1733
1734
fecd2382
RP
1735 /* Fill in extra coff fields */
1736
1737 /* Initialize general line number information. */
1738 H_SET_LINENO_SIZE(headers, text_lineno_number * LINESZ);
1739
1740 /* filehdr */
1741 H_SET_FILE_MAGIC_NUMBER(headers, FILE_HEADER_MAGIC);
1742 H_SET_NUMBER_OF_SECTIONS(headers, 3); /* text+data+bss */
57574979 1743#ifndef OBJ_COFF_OMIT_TIMESTAMP
fecd2382 1744 H_SET_TIME_STAMP(headers, (long)time((long*)0));
57574979
SC
1745#else /* OBJ_COFF_OMIT_TIMESTAMP */
1746 H_SET_TIME_STAMP(headers, 0);
1747#endif /* OBJ_COFF_OMIT_TIMESTAMP */
fecd2382 1748 H_SET_SYMBOL_TABLE_POINTER(headers, H_GET_SYMBOL_TABLE_FILE_OFFSET(headers));
57574979
SC
1749#if 0
1750printf("FILHSZ %x\n", FILHSZ);
1751printf("OBJ_COFF_AOUTHDRSZ %x\n", OBJ_COFF_AOUTHDRSZ);
1752printf("section headers %x\n", H_GET_NUMBER_OF_SECTIONS(headers) * SCNHSZ);
1753printf("get text size %x\n", H_GET_TEXT_SIZE(headers));
1754printf("get data size %x\n", H_GET_DATA_SIZE(headers));
1755printf("get relocation size %x\n", H_GET_RELOCATION_SIZE(headers));
1756printf("get lineno size %x\n", H_GET_LINENO_SIZE(headers));
1757#endif
fecd2382
RP
1758 /* symbol table size allready set */
1759 H_SET_SIZEOF_OPTIONAL_HEADER(headers, OBJ_COFF_AOUTHDRSZ);
fecd2382 1760 H_SET_FLAGS(headers, (text_lineno_number == 0 ? F_LNNO : 0)
57574979 1761 | ((text_relocation_number + data_relocation_number) ? 0 : F_RELFLG)
fecd2382 1762 | BYTE_ORDERING);
fecd2382
RP
1763
1764 /* aouthdr */
1765 /* magic number allready set */
1766 H_SET_VERSION_STAMP(headers, 0);
1767 /* Text, data, bss size; entry point; text_start and data_start are already set */
1768
1769 /* Build section headers */
1770
1771 c_section_header(&text_section_header,
1772 ".text",
1773 0,
1774 H_GET_TEXT_SIZE(headers),
1775 H_GET_TEXT_FILE_OFFSET(headers),
1776 (SA_GET_SCN_NRELOC(dot_text_symbol)
1777 ? H_GET_RELOCATION_FILE_OFFSET(headers)
1778 : 0),
1779 (text_lineno_number
1780 ? H_GET_LINENO_FILE_OFFSET(headers)
1781 : 0),
1782 SA_GET_SCN_NRELOC(dot_text_symbol),
1783 text_lineno_number,
1784 section_alignment[(int) SEG_TEXT]);
1785
1786 c_section_header(&data_section_header,
1787 ".data",
1788 H_GET_TEXT_SIZE(headers),
1789 H_GET_DATA_SIZE(headers),
1790 (H_GET_DATA_SIZE(headers)
1791 ? H_GET_DATA_FILE_OFFSET(headers)
1792 : 0),
1793 (SA_GET_SCN_NRELOC(dot_data_symbol)
1794 ? (H_GET_RELOCATION_FILE_OFFSET(headers)
1795 + text_section_header.s_nreloc * RELSZ)
1796 : 0),
1797 0, /* No line number information */
1798 SA_GET_SCN_NRELOC(dot_data_symbol),
1799 0, /* No line number information */
1800 section_alignment[(int) SEG_DATA]);
1801
1802 c_section_header(&bss_section_header,
1803 ".bss",
1804 H_GET_TEXT_SIZE(headers) + H_GET_DATA_SIZE(headers),
1805 H_GET_BSS_SIZE(headers),
1806 0, /* No file offset */
1807 0, /* No relocation information */
1808 0, /* No line number information */
1809 0, /* No relocation information */
1810 0, /* No line number information */
1811 section_alignment[(int) SEG_BSS]);
1812
1813 return;
1814} /* obj_pre_write_hook() */
1815
1816/* This is a copy from aout. All I do is neglect to actually build the symbol. */
1817
1818static void obj_coff_stab(what)
1819int what;
1820{
1821 char *string;
1822 expressionS e;
1823 int goof = 0; /* TRUE if we have aborted. */
1824 int length;
1825 int saved_type = 0;
1826 long longint;
1827 symbolS *symbolP = 0;
1828
1829 if (what == 's') {
1830 string = demand_copy_C_string(&length);
1831 SKIP_WHITESPACE();
1832
1833 if (*input_line_pointer == ',') {
1834 input_line_pointer++;
1835 } else {
1836 as_bad("I need a comma after symbol's name");
1837 goof = 1;
1838 } /* better be a comma */
1839 } /* skip the string */
1840
1841 /*
1842 * Input_line_pointer->after ','. String->symbol name.
1843 */
1844 if (!goof) {
1845 if (get_absolute_expression_and_terminator(&longint) != ',') {
1846 as_bad("I want a comma after the n_type expression");
1847 goof = 1;
1848 input_line_pointer--; /* Backup over a non-',' char. */
1849 } /* on error */
1850 } /* no error */
1851
1852 if (!goof) {
1853 if (get_absolute_expression_and_terminator(&longint) != ',') {
1854 as_bad("I want a comma after the n_other expression");
1855 goof = 1;
1856 input_line_pointer--; /* Backup over a non-',' char. */
1857 } /* on error */
1858 } /* no error */
1859
1860 if (!goof) {
1861 get_absolute_expression();
1862
1863 if (what == 's' || what == 'n') {
1864 if (*input_line_pointer != ',') {
1865 as_bad("I want a comma after the n_desc expression");
1866 goof = 1;
1867 } else {
1868 input_line_pointer++;
1869 } /* on goof */
1870 } /* not stabd */
1871 } /* no error */
1872
1873 expression(&e);
1874
1875 if (goof) {
1876 ignore_rest_of_line();
1877 } else {
1878 demand_empty_rest_of_line();
1879 } /* on error */
1880} /* obj_coff_stab() */
1881
1882#ifdef DEBUG
1883 /* for debugging */
1884char *s_get_name(s)
1885symbolS *s;
1886{
1887 return((s == NULL) ? "(NULL)" : S_GET_NAME(s));
1888} /* s_get_name() */
1889
1890void symbol_dump() {
1891 symbolS *symbolP;
1892
1893 for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next(symbolP)) {
1894 printf("%3ld: 0x%lx \"%s\" type = %ld, class = %d, segment = %d\n",
1895 symbolP->sy_number,
1896 (unsigned long) symbolP,
1897 S_GET_NAME(symbolP),
1898 (long) S_GET_DATA_TYPE(symbolP),
1899 S_GET_STORAGE_CLASS(symbolP),
1900 (int) S_GET_SEGMENT(symbolP));
1901 } /* traverse symbols */
1902
1903 return;
1904} /* symbol_dump() */
1905#endif /* DEBUG */
1906
57574979 1907
fecd2382
RP
1908/*
1909 * Local Variables:
1910 * comment-column: 0
1911 * fill-column: 131
1912 * End:
1913 */
1914
1915/* end of obj-coff.c */
This page took 0.105659 seconds and 4 git commands to generate.