Commit | Line | Data |
---|---|---|
fecd2382 | 1 | /* coff object file format |
a87b3269 | 2 | Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc. |
355afbcd | 3 | |
a39116f1 | 4 | This file is part of GAS. |
355afbcd | 5 | |
a39116f1 RP |
6 | GAS is free software; you can redistribute it and/or modify |
7 | it under the terms of the GNU General Public License as published by | |
8 | the Free Software Foundation; either version 2, or (at your option) | |
9 | any later version. | |
355afbcd | 10 | |
a39116f1 RP |
11 | GAS is distributed in the hope that it will be useful, |
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | GNU General Public License for more details. | |
355afbcd | 15 | |
a39116f1 RP |
16 | You should have received a copy of the GNU General Public License |
17 | along with GAS; see the file COPYING. If not, write to | |
18 | the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ | |
fecd2382 | 19 | |
fecd2382 RP |
20 | #include "as.h" |
21 | ||
22 | #include "obstack.h" | |
23 | ||
85051959 | 24 | #ifndef BFD_ASSEMBLER |
355afbcd KR |
25 | lineno *lineno_rootP; |
26 | ||
27 | const short seg_N_TYPE[] = | |
28 | { /* 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 | 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 | ||
355afbcd | 48 | const segT N_TYPE_seg[32] = |
fecd2382 | 49 | { |
355afbcd KR |
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 */ | |
58 | SEG_REGISTER, /* C_REGISTER_SECTION == 4 */ | |
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, | |
61 | SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF | |
62 | }; | |
85051959 | 63 | #endif |
355afbcd KR |
64 | |
65 | char *s_get_name PARAMS ((symbolS * s)); | |
66 | static symbolS *tag_find_or_make PARAMS ((char *name)); | |
67 | static symbolS *tag_find PARAMS ((char *name)); | |
57574979 | 68 | #ifdef BFD_HEADERS |
355afbcd | 69 | static void obj_coff_section_header_append PARAMS ((char **where, struct internal_scnhdr * header)); |
57574979 | 70 | #else |
355afbcd | 71 | static void obj_coff_section_header_append PARAMS ((char **where, SCNHDR * header)); |
57574979 | 72 | #endif |
355afbcd KR |
73 | static void obj_coff_def PARAMS ((int what)); |
74 | static void obj_coff_dim PARAMS ((void)); | |
75 | static void obj_coff_endef PARAMS ((void)); | |
76 | static void obj_coff_line PARAMS ((void)); | |
85051959 | 77 | static void obj_coff_ln PARAMS ((int)); |
355afbcd KR |
78 | static void obj_coff_scl PARAMS ((void)); |
79 | static void obj_coff_size PARAMS ((void)); | |
80 | static void obj_coff_stab PARAMS ((int what)); | |
81 | static void obj_coff_tag PARAMS ((void)); | |
82 | static void obj_coff_type PARAMS ((void)); | |
83 | static void obj_coff_val PARAMS ((void)); | |
84 | static void tag_init PARAMS ((void)); | |
85 | static void tag_insert PARAMS ((char *name, symbolS * symbolP)); | |
86 | ||
85051959 ILT |
87 | #ifdef BFD_ASSEMBLER |
88 | static void SA_SET_SYM_ENDNDX PARAMS ((symbolS *, symbolS *)); | |
89 | static void SA_SET_SYM_TAGNDX PARAMS ((symbolS *, symbolS *)); | |
90 | #endif | |
91 | ||
355afbcd | 92 | int line_base; |
fecd2382 RP |
93 | |
94 | static struct hash_control *tag_hash; | |
355afbcd | 95 | static symbolS *def_symbol_in_progress; |
fecd2382 | 96 | |
355afbcd KR |
97 | const pseudo_typeS obj_pseudo_table[] = |
98 | { | |
fecd2382 | 99 | #ifndef IGNORE_DEBUG |
355afbcd KR |
100 | {"def", obj_coff_def, 0}, |
101 | {"dim", obj_coff_dim, 0}, | |
102 | {"endef", obj_coff_endef, 0}, | |
103 | {"line", obj_coff_line, 0}, | |
104 | {"ln", obj_coff_ln, 0}, | |
85051959 | 105 | {"appline", obj_coff_ln, 1}, |
355afbcd KR |
106 | {"scl", obj_coff_scl, 0}, |
107 | {"size", obj_coff_size, 0}, | |
108 | {"tag", obj_coff_tag, 0}, | |
109 | {"type", obj_coff_type, 0}, | |
110 | {"val", obj_coff_val, 0}, | |
fecd2382 | 111 | #else |
355afbcd KR |
112 | {"def", s_ignore, 0}, |
113 | {"dim", s_ignore, 0}, | |
114 | {"endef", s_ignore, 0}, | |
115 | {"line", s_ignore, 0}, | |
116 | {"ln", s_ignore, 0}, | |
117 | {"scl", s_ignore, 0}, | |
118 | {"size", s_ignore, 0}, | |
119 | {"tag", s_ignore, 0}, | |
120 | {"type", s_ignore, 0}, | |
121 | {"val", s_ignore, 0}, | |
fecd2382 | 122 | #endif /* ignore debug */ |
355afbcd KR |
123 | |
124 | {"ident", s_ignore, 0}, /* we don't yet handle this. */ | |
125 | ||
126 | ||
85051959 ILT |
127 | /* stabs aka a.out aka b.out directives for debug symbols. |
128 | Currently ignored silently. Except for .line at which | |
129 | we guess from context. */ | |
355afbcd | 130 | {"desc", s_ignore, 0}, /* def */ |
355afbcd KR |
131 | {"stabd", obj_coff_stab, 'd'},/* stabs */ |
132 | {"stabn", obj_coff_stab, 'n'},/* stabs */ | |
133 | {"stabs", obj_coff_stab, 's'},/* stabs */ | |
134 | ||
85051959 | 135 | /* stabs-in-coff (?) debug pseudos (ignored) */ |
355afbcd | 136 | {"optim", s_ignore, 0}, /* For sun386i cc (?) */ |
85051959 | 137 | /* other stuff */ |
355afbcd KR |
138 | {"ABORT", s_abort, 0}, |
139 | ||
140 | {NULL} /* end sentinel */ | |
141 | }; /* obj_pseudo_table */ | |
fecd2382 | 142 | |
85051959 ILT |
143 | #ifdef BFD_ASSEMBLER |
144 | struct line_no { | |
145 | struct line_no *next; | |
146 | fragS *frag; | |
147 | alent l; | |
148 | }; | |
149 | #endif | |
150 | ||
151 | #define GET_FILENAME_STRING(X) \ | |
152 | ((char*)(&((X)->sy_symbol.ost_auxent->x_file.x_n.x_offset))[1]) | |
fecd2382 | 153 | |
a39116f1 | 154 | /* obj dependant output values */ |
85051959 | 155 | #ifndef BFD_ASSEMBLER |
57574979 SC |
156 | #ifdef BFD_HEADERS |
157 | static struct internal_scnhdr bss_section_header; | |
158 | struct internal_scnhdr data_section_header; | |
159 | struct internal_scnhdr text_section_header; | |
160 | #else | |
fecd2382 | 161 | static SCNHDR bss_section_header; |
57574979 SC |
162 | SCNHDR data_section_header; |
163 | SCNHDR text_section_header; | |
164 | #endif | |
85051959 ILT |
165 | #endif |
166 | ||
167 | #ifdef BFD_ASSEMBLER | |
168 | ||
169 | /* @@ Ick. */ | |
170 | static segT | |
171 | fetch_coff_debug_section () | |
172 | { | |
173 | static segT debug_section; | |
174 | if (!debug_section) | |
175 | { | |
176 | CONST asymbol *s; | |
177 | s = bfd_make_debug_symbol (stdoutput, (char *) 0, 0); | |
178 | assert (s != 0); | |
179 | debug_section = s->section; | |
180 | } | |
181 | return debug_section; | |
182 | } | |
183 | ||
184 | static void | |
185 | SA_SET_SYM_ENDNDX (sym, val) | |
186 | symbolS *sym; | |
187 | symbolS *val; | |
188 | { | |
189 | combined_entry_type *entry, *p; | |
190 | ||
191 | entry = &coffsymbol (sym->bsym)->native[1]; | |
192 | p = coffsymbol (val->bsym)->native; | |
193 | entry->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.p = p; | |
194 | entry->fix_end = 1; | |
195 | } | |
196 | ||
197 | static void | |
198 | SA_SET_SYM_TAGNDX (sym, val) | |
199 | symbolS *sym; | |
200 | symbolS *val; | |
201 | { | |
202 | combined_entry_type *entry, *p; | |
203 | ||
204 | entry = &coffsymbol (sym->bsym)->native[1]; | |
205 | p = coffsymbol (val->bsym)->native; | |
206 | entry->u.auxent.x_sym.x_tagndx.p = p; | |
207 | entry->fix_tag = 1; | |
208 | } | |
209 | ||
210 | #else /* ! BFD_ASSEMBLER */ | |
211 | ||
fecd2382 RP |
212 | /* Relocation. */ |
213 | ||
355afbcd KR |
214 | static int |
215 | reloc_compare (p1, p2) | |
6d5460ab | 216 | #ifdef BFD_HEADERS |
355afbcd | 217 | struct internal_reloc *p1, *p2; |
6d5460ab | 218 | #else |
355afbcd | 219 | RELOC *p1, *p2; |
6d5460ab RP |
220 | #endif |
221 | { | |
355afbcd | 222 | return (int) (p1->r_vaddr - p2->r_vaddr); |
6d5460ab RP |
223 | } |
224 | ||
fecd2382 RP |
225 | /* |
226 | * emit_relocations() | |
227 | * | |
228 | * Crawl along a fixS chain. Emit the segment's relocations. | |
229 | */ | |
230 | ||
355afbcd KR |
231 | void |
232 | obj_emit_relocations (where, fixP, segment_address_in_file) | |
233 | char **where; | |
234 | fixS *fixP; /* Fixup chain for this segment. */ | |
235 | relax_addressT segment_address_in_file; | |
fecd2382 | 236 | { |
57574979 | 237 | #ifdef BFD_HEADERS |
355afbcd | 238 | struct internal_reloc *ri_table; |
57574979 | 239 | #else |
355afbcd KR |
240 | RELOC *ri_table; |
241 | #endif | |
242 | #ifdef TC_I960 | |
243 | char *callj_table; | |
57574979 | 244 | #endif |
355afbcd KR |
245 | symbolS *symbolP; |
246 | int i, count; | |
247 | fixS *p; | |
248 | ||
249 | for (count = 0, p = fixP; p; p = p->fx_next) | |
250 | if (p->fx_addsy) | |
251 | count++; | |
252 | if (!count) | |
253 | return; | |
254 | ||
6d5460ab | 255 | #ifdef BFD_HEADERS |
355afbcd | 256 | ri_table = (struct internal_reloc *) calloc (sizeof (*ri_table), count); |
6d5460ab | 257 | #else |
355afbcd | 258 | ri_table = (RELOC *) calloc (sizeof (*ri_table), count); |
6d5460ab | 259 | #endif |
355afbcd KR |
260 | if (!ri_table) |
261 | as_fatal ("obj_emit_relocations: Could not malloc relocation table"); | |
262 | ||
6d5460ab | 263 | #ifdef TC_I960 |
355afbcd KR |
264 | callj_table = (char *) malloc (sizeof (char) * count); |
265 | if (!callj_table) | |
266 | as_fatal ("obj_emit_relocations: Could not malloc callj table"); | |
6d5460ab | 267 | #endif |
355afbcd KR |
268 | |
269 | for (i = 0; fixP; fixP = fixP->fx_next) | |
270 | { | |
271 | if (symbolP = fixP->fx_addsy) | |
272 | { | |
85051959 | 273 | int rtype_ok = 0; |
fecd2382 | 274 | #if defined(TC_M68K) |
355afbcd KR |
275 | ri_table[i].r_type = (fixP->fx_pcrel ? |
276 | (fixP->fx_size == 1 ? R_PCRBYTE : | |
277 | fixP->fx_size == 2 ? R_PCRWORD : | |
278 | R_PCRLONG) : | |
279 | (fixP->fx_size == 1 ? R_RELBYTE : | |
280 | fixP->fx_size == 2 ? R_RELWORD : | |
281 | R_RELLONG)); | |
85051959 ILT |
282 | rtype_ok = 1; |
283 | #endif | |
284 | #if defined(TC_I386) | |
355afbcd | 285 | /* FIXME-SOON R_OFF8 & R_DIR16 are a vague guess, completly |
6d5460ab | 286 | untested. */ |
355afbcd KR |
287 | ri_table[i].r_type = (fixP->fx_pcrel ? |
288 | (fixP->fx_size == 1 ? R_PCRBYTE : | |
289 | fixP->fx_size == 2 ? R_PCRWORD : | |
290 | R_PCRLONG) : | |
291 | (fixP->fx_size == 1 ? R_OFF8 : | |
292 | fixP->fx_size == 2 ? R_DIR16 : | |
293 | R_DIR32)); | |
85051959 ILT |
294 | rtype_ok = 1; |
295 | #endif | |
296 | #if defined(TC_I960) | |
355afbcd KR |
297 | ri_table[i].r_type = (fixP->fx_pcrel |
298 | ? R_IPRMED | |
299 | : R_RELLONG); | |
300 | callj_table[i] = fixP->fx_callj ? 1 : 0; | |
85051959 ILT |
301 | rtype_ok = 1; |
302 | #endif | |
303 | #if defined(TC_A29K) | |
355afbcd | 304 | ri_table[i].r_type = tc_coff_fix2rtype (fixP); |
85051959 ILT |
305 | rtype_ok = 1; |
306 | #endif | |
307 | if (!rtype_ok) | |
308 | abort (); | |
355afbcd KR |
309 | ri_table[i].r_vaddr = (fixP->fx_frag->fr_address |
310 | + fixP->fx_where); | |
311 | /* If symbol associated to relocation entry is a bss symbol | |
85051959 ILT |
312 | or undefined symbol just remember the index of the symbol. |
313 | Otherwise store the index of the symbol describing the | |
314 | section the symbol belong to. This heuristic speeds up ld. | |
315 | */ | |
355afbcd | 316 | /* Local symbols can generate relocation information. In case |
85051959 ILT |
317 | of structure return for instance. But they have no symbol |
318 | number because they won't be emitted in the final object. | |
319 | In the case where they are in the BSS section, this leads | |
320 | to an incorrect r_symndx. | |
321 | Under bsd the loader do not care if the symbol reference | |
322 | is incorrect. But the SYS V ld complains about this. To | |
323 | avoid this we associate the symbol to the associated | |
324 | section, *even* if it is the BSS section. */ | |
355afbcd | 325 | /* If someone can tell me why the other symbols of the bss |
85051959 ILT |
326 | section are not associated with the .bss section entry, |
327 | I'd be gratefull. I guess that it has to do with the special | |
328 | nature of the .bss section. Or maybe this is because the | |
329 | bss symbols are declared in the common section and can | |
330 | be resized later. Can it break code some where ? */ | |
355afbcd KR |
331 | ri_table[i].r_symndx = (S_GET_SEGMENT (symbolP) == SEG_TEXT |
332 | ? dot_text_symbol->sy_number | |
333 | : (S_GET_SEGMENT (symbolP) == SEG_DATA | |
334 | ? dot_data_symbol->sy_number | |
335 | : ((SF_GET_LOCAL (symbolP) | |
336 | ? dot_bss_symbol->sy_number | |
337 | : symbolP->sy_number)))); /* bss or undefined */ | |
338 | ||
339 | /* md_ri_to_chars((char *) &ri, ri); *//* Last step : write md f */ | |
340 | ||
341 | i++; | |
342 | } /* if there's a symbol */ | |
343 | } /* for each fixP */ | |
344 | ||
85051959 ILT |
345 | /* AIX ld prefer to have the reloc table with r_vaddr sorted. |
346 | But sorting it should not hurt any other ld. */ | |
355afbcd KR |
347 | qsort (ri_table, count, sizeof (*ri_table), reloc_compare); |
348 | ||
349 | for (i = 0; i < count; i++) | |
350 | { | |
57574979 | 351 | #ifdef BFD_HEADERS |
355afbcd | 352 | *where += bfd_coff_swap_reloc_out (stdoutput, &ri_table[i], *where); |
6d5460ab | 353 | # ifdef TC_A29K |
355afbcd | 354 | /* The 29k has a special kludge for the high 16 bit reloc. |
85051959 ILT |
355 | Two relocations are emmited, R_IHIHALF, and R_IHCONST. |
356 | The second one doesn't contain a symbol, but uses the | |
357 | value for offset */ | |
355afbcd KR |
358 | if (ri_table[i].r_type == R_IHIHALF) |
359 | { | |
360 | /* now emit the second bit */ | |
361 | ri_table[i].r_type = R_IHCONST; | |
362 | ri_table[i].r_symndx = fixP->fx_addnumber; | |
363 | *where += bfd_coff_swap_reloc_out (stdoutput, &ri_table[i], | |
364 | *where); | |
365 | } | |
366 | # endif /* TC_A29K */ | |
367 | ||
6d5460ab | 368 | #else /* not BFD_HEADERS */ |
355afbcd | 369 | append (where, (char *) &ri_table[i], RELSZ); |
6d5460ab | 370 | #endif /* not BFD_HEADERS */ |
355afbcd | 371 | |
fecd2382 | 372 | #ifdef TC_I960 |
355afbcd KR |
373 | if (callj_table[i]) |
374 | { | |
375 | ri_table[i].r_type = R_OPTCALL; | |
6d5460ab | 376 | # ifdef BFD_HEADERS |
355afbcd KR |
377 | *where += bfd_coff_swap_reloc_out (stdoutput, &ri_table[i], |
378 | *where); | |
6d5460ab | 379 | # else |
355afbcd KR |
380 | append (where, (char *) &ri_table[i], (unsigned long) RELSZ); |
381 | # endif /* BFD_HEADERS */ | |
382 | } /* if it's a callj, do it again for the opcode */ | |
fecd2382 | 383 | #endif /* TC_I960 */ |
355afbcd KR |
384 | } |
385 | ||
386 | free (ri_table); | |
6d5460ab | 387 | #ifdef TC_I960 |
355afbcd | 388 | free (callj_table); |
6d5460ab | 389 | #endif |
355afbcd KR |
390 | |
391 | return; | |
392 | } /* obj_emit_relocations() */ | |
fecd2382 RP |
393 | |
394 | /* Coff file generation & utilities */ | |
395 | ||
57574979 | 396 | #ifdef BFD_HEADERS |
355afbcd KR |
397 | void |
398 | obj_header_append (where, headers) | |
399 | char **where; | |
400 | object_headers *headers; | |
57574979 | 401 | { |
355afbcd KR |
402 | tc_headers_hook (headers); |
403 | *where += bfd_coff_swap_filehdr_out (stdoutput, &(headers->filehdr), *where); | |
57574979 | 404 | #ifndef OBJ_COFF_OMIT_OPTIONAL_HEADER |
355afbcd | 405 | *where += bfd_coff_swap_aouthdr_out (stdoutput, &(headers->aouthdr), *where); |
57574979 | 406 | #endif |
355afbcd KR |
407 | obj_coff_section_header_append (where, &text_section_header); |
408 | obj_coff_section_header_append (where, &data_section_header); | |
409 | obj_coff_section_header_append (where, &bss_section_header); | |
57574979 SC |
410 | } |
411 | ||
85051959 | 412 | #else /* ! BFD_HEADERS */ |
57574979 | 413 | |
355afbcd KR |
414 | void |
415 | obj_header_append (where, headers) | |
416 | char **where; | |
417 | object_headers *headers; | |
fecd2382 | 418 | { |
355afbcd KR |
419 | tc_headers_hook (headers); |
420 | ||
d1a9e594 | 421 | #ifdef CROSS_COMPILE |
355afbcd KR |
422 | /* Eventually swap bytes for cross compilation for file header */ |
423 | md_number_to_chars (*where, headers->filehdr.f_magic, sizeof (headers->filehdr.f_magic)); | |
424 | *where += sizeof (headers->filehdr.f_magic); | |
425 | md_number_to_chars (*where, headers->filehdr.f_nscns, sizeof (headers->filehdr.f_nscns)); | |
426 | *where += sizeof (headers->filehdr.f_nscns); | |
427 | md_number_to_chars (*where, headers->filehdr.f_timdat, sizeof (headers->filehdr.f_timdat)); | |
428 | *where += sizeof (headers->filehdr.f_timdat); | |
429 | md_number_to_chars (*where, headers->filehdr.f_symptr, sizeof (headers->filehdr.f_symptr)); | |
430 | *where += sizeof (headers->filehdr.f_symptr); | |
431 | md_number_to_chars (*where, headers->filehdr.f_nsyms, sizeof (headers->filehdr.f_nsyms)); | |
432 | *where += sizeof (headers->filehdr.f_nsyms); | |
433 | md_number_to_chars (*where, headers->filehdr.f_opthdr, sizeof (headers->filehdr.f_opthdr)); | |
434 | *where += sizeof (headers->filehdr.f_opthdr); | |
435 | md_number_to_chars (*where, headers->filehdr.f_flags, sizeof (headers->filehdr.f_flags)); | |
436 | *where += sizeof (headers->filehdr.f_flags); | |
437 | ||
fecd2382 | 438 | #ifndef OBJ_COFF_OMIT_OPTIONAL_HEADER |
355afbcd KR |
439 | /* Eventually swap bytes for cross compilation for a.out header */ |
440 | md_number_to_chars (*where, headers->aouthdr.magic, sizeof (headers->aouthdr.magic)); | |
441 | *where += sizeof (headers->aouthdr.magic); | |
442 | md_number_to_chars (*where, headers->aouthdr.vstamp, sizeof (headers->aouthdr.vstamp)); | |
443 | *where += sizeof (headers->aouthdr.vstamp); | |
444 | md_number_to_chars (*where, headers->aouthdr.tsize, sizeof (headers->aouthdr.tsize)); | |
445 | *where += sizeof (headers->aouthdr.tsize); | |
446 | md_number_to_chars (*where, headers->aouthdr.dsize, sizeof (headers->aouthdr.dsize)); | |
447 | *where += sizeof (headers->aouthdr.dsize); | |
448 | md_number_to_chars (*where, headers->aouthdr.bsize, sizeof (headers->aouthdr.bsize)); | |
449 | *where += sizeof (headers->aouthdr.bsize); | |
450 | md_number_to_chars (*where, headers->aouthdr.entry, sizeof (headers->aouthdr.entry)); | |
451 | *where += sizeof (headers->aouthdr.entry); | |
452 | md_number_to_chars (*where, headers->aouthdr.text_start, sizeof (headers->aouthdr.text_start)); | |
453 | *where += sizeof (headers->aouthdr.text_start); | |
454 | md_number_to_chars (*where, headers->aouthdr.data_start, sizeof (headers->aouthdr.data_start)); | |
455 | *where += sizeof (headers->aouthdr.data_start); | |
456 | md_number_to_chars (*where, headers->aouthdr.tagentries, sizeof (headers->aouthdr.tagentries)); | |
457 | *where += sizeof (headers->aouthdr.tagentries); | |
fecd2382 | 458 | #endif /* OBJ_COFF_OMIT_OPTIONAL_HEADER */ |
355afbcd | 459 | |
d1a9e594 | 460 | #else /* CROSS_COMPILE */ |
355afbcd KR |
461 | |
462 | append (where, (char *) &headers->filehdr, sizeof (headers->filehdr)); | |
fecd2382 | 463 | #ifndef OBJ_COFF_OMIT_OPTIONAL_HEADER |
355afbcd | 464 | append (where, (char *) &headers->aouthdr, sizeof (headers->aouthdr)); |
fecd2382 | 465 | #endif /* OBJ_COFF_OMIT_OPTIONAL_HEADER */ |
355afbcd | 466 | |
d1a9e594 | 467 | #endif /* CROSS_COMPILE */ |
355afbcd KR |
468 | |
469 | /* Output the section headers */ | |
470 | obj_coff_section_header_append (where, &text_section_header); | |
471 | obj_coff_section_header_append (where, &data_section_header); | |
472 | obj_coff_section_header_append (where, &bss_section_header); | |
473 | ||
474 | return; | |
475 | } /* obj_header_append() */ | |
476 | ||
85051959 ILT |
477 | #endif /* ! BFD_HEADERS */ |
478 | ||
355afbcd KR |
479 | void |
480 | obj_symbol_to_chars (where, symbolP) | |
481 | char **where; | |
482 | symbolS *symbolP; | |
fecd2382 | 483 | { |
85051959 ILT |
484 | /* Move the value into the COFF symbol itself. */ |
485 | symbolP->sy_symbol.ost_entry.n_value = S_GET_VALUE (symbolP); | |
486 | ||
57574979 | 487 | #ifdef BFD_HEADERS |
355afbcd KR |
488 | unsigned int numaux = symbolP->sy_symbol.ost_entry.n_numaux; |
489 | unsigned int i; | |
490 | ||
491 | if (S_GET_SEGMENT (symbolP) == SEG_REGISTER) | |
492 | { | |
493 | S_SET_SEGMENT (symbolP, SEG_ABSOLUTE); | |
494 | } | |
495 | *where += bfd_coff_swap_sym_out (stdoutput, &symbolP->sy_symbol.ost_entry, | |
496 | *where); | |
497 | ||
498 | for (i = 0; i < numaux; i++) | |
499 | { | |
500 | *where += bfd_coff_swap_aux_out (stdoutput, | |
501 | &symbolP->sy_symbol.ost_auxent[i], | |
502 | S_GET_DATA_TYPE (symbolP), | |
503 | S_GET_STORAGE_CLASS (symbolP), | |
504 | *where); | |
505 | } | |
506 | ||
a39116f1 | 507 | #else /* BFD_HEADERS */ |
355afbcd KR |
508 | SYMENT *syment = &symbolP->sy_symbol.ost_entry; |
509 | int i; | |
510 | char numaux = syment->n_numaux; | |
511 | unsigned short type = S_GET_DATA_TYPE (symbolP); | |
512 | ||
d1a9e594 | 513 | #ifdef CROSS_COMPILE |
355afbcd KR |
514 | md_number_to_chars (*where, syment->n_value, sizeof (syment->n_value)); |
515 | *where += sizeof (syment->n_value); | |
516 | md_number_to_chars (*where, syment->n_scnum, sizeof (syment->n_scnum)); | |
517 | *where += sizeof (syment->n_scnum); | |
518 | md_number_to_chars (*where, 0, sizeof (short)); /* pad n_flags */ | |
519 | *where += sizeof (short); | |
520 | md_number_to_chars (*where, syment->n_type, sizeof (syment->n_type)); | |
521 | *where += sizeof (syment->n_type); | |
522 | md_number_to_chars (*where, syment->n_sclass, sizeof (syment->n_sclass)); | |
523 | *where += sizeof (syment->n_sclass); | |
524 | md_number_to_chars (*where, syment->n_numaux, sizeof (syment->n_numaux)); | |
525 | *where += sizeof (syment->n_numaux); | |
d1a9e594 | 526 | #else /* CROSS_COMPILE */ |
355afbcd | 527 | append (where, (char *) syment, sizeof (*syment)); |
d1a9e594 | 528 | #endif /* CROSS_COMPILE */ |
355afbcd | 529 | |
85051959 ILT |
530 | /* Should do the following: |
531 | if (.file entry) MD(..)... else if (static entry) MD(..) */ | |
355afbcd KR |
532 | if (numaux > OBJ_COFF_MAX_AUXENTRIES) |
533 | { | |
534 | as_bad ("Internal error? too many auxents for symbol"); | |
535 | } /* too many auxents */ | |
536 | ||
537 | for (i = 0; i < numaux; ++i) | |
538 | { | |
d1a9e594 | 539 | #ifdef CROSS_COMPILE |
355afbcd KR |
540 | #if 0 /* This code has never been tested */ |
541 | /* The most common case, x_sym entry. */ | |
542 | if ((SF_GET (symbolP) & (SF_FILE | SF_STATICS)) == 0) | |
543 | { | |
544 | md_number_to_chars (*where, auxP->x_sym.x_tagndx, sizeof (auxP->x_sym.x_tagndx)); | |
545 | *where += sizeof (auxP->x_sym.x_tagndx); | |
546 | if (ISFCN (type)) | |
547 | { | |
548 | md_number_to_chars (*where, auxP->x_sym.x_misc.x_fsize, sizeof (auxP->x_sym.x_misc.x_fsize)); | |
549 | *where += sizeof (auxP->x_sym.x_misc.x_fsize); | |
550 | } | |
551 | else | |
552 | { | |
553 | md_number_to_chars (*where, auxP->x_sym.x_misc.x_lnno, sizeof (auxP->x_sym.x_misc.x_lnno)); | |
554 | *where += sizeof (auxP->x_sym.x_misc.x_lnno); | |
555 | md_number_to_chars (*where, auxP->x_sym.x_misc.x_size, sizeof (auxP->x_sym.x_misc.x_size)); | |
556 | *where += sizeof (auxP->x_sym.x_misc.x_size); | |
557 | } | |
558 | if (ISARY (type)) | |
559 | { | |
560 | register int index; | |
561 | for (index = 0; index < DIMNUM; index++) | |
562 | 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])); | |
563 | *where += sizeof (auxP->x_sym.x_fcnary.x_ary.x_dimen[index]); | |
564 | } | |
565 | else | |
566 | { | |
567 | md_number_to_chars (*where, auxP->x_sym.x_fcnary.x_fcn.x_lnnoptr, sizeof (auxP->x_sym.x_fcnary.x_fcn.x_lnnoptr)); | |
568 | *where += sizeof (auxP->x_sym.x_fcnary.x_fcn.x_lnnoptr); | |
569 | md_number_to_chars (*where, auxP->x_sym.x_fcnary.x_fcn.x_endndx, sizeof (auxP->x_sym.x_fcnary.x_fcn.x_endndx)); | |
570 | *where += sizeof (auxP->x_sym.x_fcnary.x_fcn.x_endndx); | |
571 | } | |
572 | md_number_to_chars (*where, auxP->x_sym.x_tvndx, sizeof (auxP->x_sym.x_tvndx)); | |
573 | *where += sizeof (auxP->x_sym.x_tvndx); | |
574 | } | |
575 | else if (SF_GET_FILE (symbolP)) | |
576 | { /* .file */ | |
577 | ; | |
578 | } | |
579 | else if (SF_GET_STATICS (symbolP)) | |
580 | { /* .text, .data, .bss symbols */ | |
581 | md_number_to_chars (*where, auxP->x_scn.x_scnlen, sizeof (auxP->x_scn.x_scnlen)); | |
582 | *where += sizeof (auxP->x_scn.x_scnlen); | |
583 | md_number_to_chars (*where, auxP->x_scn.x_nreloc, sizeof (auxP->x_scn.x_nreloc)); | |
584 | *where += sizeof (auxP->x_scn.x_nreloc); | |
585 | md_number_to_chars (*where, auxP->x_scn.x_nlinno, sizeof (auxP->x_scn.x_nlinno)); | |
586 | *where += sizeof (auxP->x_scn.x_nlinno); | |
587 | } | |
fecd2382 | 588 | #endif /* 0 */ |
d1a9e594 | 589 | #else /* CROSS_COMPILE */ |
355afbcd | 590 | append (where, (char *) &symbolP->sy_symbol.ost_auxent[i], sizeof (symbolP->sy_symbol.ost_auxent[i])); |
d1a9e594 | 591 | #endif /* CROSS_COMPILE */ |
355afbcd KR |
592 | |
593 | }; /* for each aux in use */ | |
594 | #endif /* BFD_HEADERS */ | |
595 | return; | |
596 | } /* obj_symbol_to_chars() */ | |
fecd2382 | 597 | |
57574979 | 598 | #ifdef BFD_HEADERS |
355afbcd KR |
599 | static void |
600 | obj_coff_section_header_append (where, header) | |
601 | char **where; | |
602 | struct internal_scnhdr *header; | |
57574979 | 603 | { |
355afbcd | 604 | *where += bfd_coff_swap_scnhdr_out (stdoutput, header, *where); |
57574979 | 605 | } |
355afbcd | 606 | |
57574979 | 607 | #else |
355afbcd KR |
608 | static void |
609 | obj_coff_section_header_append (where, header) | |
610 | char **where; | |
611 | SCNHDR *header; | |
fecd2382 | 612 | { |
d1a9e594 | 613 | #ifdef CROSS_COMPILE |
355afbcd KR |
614 | memcpy (*where, header->s_name, sizeof (header->s_name)); |
615 | *where += sizeof (header->s_name); | |
616 | ||
617 | md_number_to_chars (*where, header->s_paddr, sizeof (header->s_paddr)); | |
618 | *where += sizeof (header->s_paddr); | |
619 | ||
620 | md_number_to_chars (*where, header->s_vaddr, sizeof (header->s_vaddr)); | |
621 | *where += sizeof (header->s_vaddr); | |
622 | ||
623 | md_number_to_chars (*where, header->s_size, sizeof (header->s_size)); | |
624 | *where += sizeof (header->s_size); | |
625 | ||
626 | md_number_to_chars (*where, header->s_scnptr, sizeof (header->s_scnptr)); | |
627 | *where += sizeof (header->s_scnptr); | |
628 | ||
629 | md_number_to_chars (*where, header->s_relptr, sizeof (header->s_relptr)); | |
630 | *where += sizeof (header->s_relptr); | |
631 | ||
632 | md_number_to_chars (*where, header->s_lnnoptr, sizeof (header->s_lnnoptr)); | |
633 | *where += sizeof (header->s_lnnoptr); | |
634 | ||
635 | md_number_to_chars (*where, header->s_nreloc, sizeof (header->s_nreloc)); | |
636 | *where += sizeof (header->s_nreloc); | |
637 | ||
638 | md_number_to_chars (*where, header->s_nlnno, sizeof (header->s_nlnno)); | |
639 | *where += sizeof (header->s_nlnno); | |
640 | ||
641 | md_number_to_chars (*where, header->s_flags, sizeof (header->s_flags)); | |
642 | *where += sizeof (header->s_flags); | |
643 | ||
57574979 | 644 | #ifdef TC_I960 |
355afbcd KR |
645 | md_number_to_chars (*where, header->s_align, sizeof (header->s_align)); |
646 | *where += sizeof (header->s_align); | |
57574979 | 647 | #endif /* TC_I960 */ |
355afbcd | 648 | |
d1a9e594 | 649 | #else /* CROSS_COMPILE */ |
355afbcd KR |
650 | |
651 | append (where, (char *) header, sizeof (*header)); | |
652 | ||
d1a9e594 | 653 | #endif /* CROSS_COMPILE */ |
355afbcd KR |
654 | |
655 | return; | |
656 | } /* obj_coff_section_header_append() */ | |
fecd2382 | 657 | |
57574979 | 658 | #endif |
355afbcd KR |
659 | void |
660 | obj_emit_symbols (where, symbol_rootP) | |
661 | char **where; | |
662 | symbolS *symbol_rootP; | |
fecd2382 | 663 | { |
355afbcd KR |
664 | symbolS *symbolP; |
665 | /* | |
a39116f1 RP |
666 | * Emit all symbols left in the symbol chain. |
667 | */ | |
355afbcd KR |
668 | for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP)) |
669 | { | |
670 | /* Used to save the offset of the name. It is used to point | |
a39116f1 | 671 | to the string in memory but must be a file offset. */ |
355afbcd KR |
672 | register char *temp; |
673 | ||
674 | tc_coff_symbol_emit_hook (symbolP); | |
675 | ||
676 | temp = S_GET_NAME (symbolP); | |
677 | if (SF_GET_STRING (symbolP)) | |
678 | { | |
679 | S_SET_OFFSET (symbolP, symbolP->sy_name_offset); | |
680 | S_SET_ZEROES (symbolP, 0); | |
681 | } | |
682 | else | |
683 | { | |
684 | memset (symbolP->sy_symbol.ost_entry.n_name, '\0', SYMNMLEN); | |
685 | strncpy (symbolP->sy_symbol.ost_entry.n_name, temp, SYMNMLEN); | |
a39116f1 | 686 | } |
355afbcd KR |
687 | obj_symbol_to_chars (where, symbolP); |
688 | S_SET_NAME (symbolP, temp); | |
689 | } | |
690 | } /* obj_emit_symbols() */ | |
fecd2382 | 691 | |
85051959 ILT |
692 | #endif /* ! BFD_ASSEMBLER */ |
693 | ||
fecd2382 RP |
694 | /* Merge a debug symbol containing debug information into a normal symbol. */ |
695 | ||
355afbcd KR |
696 | void |
697 | c_symbol_merge (debug, normal) | |
698 | symbolS *debug; | |
699 | symbolS *normal; | |
fecd2382 | 700 | { |
355afbcd KR |
701 | S_SET_DATA_TYPE (normal, S_GET_DATA_TYPE (debug)); |
702 | S_SET_STORAGE_CLASS (normal, S_GET_STORAGE_CLASS (debug)); | |
703 | ||
704 | if (S_GET_NUMBER_AUXILIARY (debug) > S_GET_NUMBER_AUXILIARY (normal)) | |
85051959 ILT |
705 | /* take the most we have */ |
706 | S_SET_NUMBER_AUXILIARY (normal, S_GET_NUMBER_AUXILIARY (debug)); | |
355afbcd KR |
707 | |
708 | if (S_GET_NUMBER_AUXILIARY (debug) > 0) | |
709 | { | |
85051959 ILT |
710 | /* Move all the auxiliary information. */ |
711 | #ifdef BFD_ASSEMBLER | |
712 | /* @@ How many fields do we want to preserve? Would it make more | |
713 | sense to pick and choose those we want to copy? Should look | |
714 | into this further.... [raeburn:19920512.2209EST] */ | |
715 | alent *linenos; | |
716 | linenos = coffsymbol (normal->bsym)->lineno; | |
717 | memcpy ((char *) &coffsymbol (normal->bsym)->native, | |
718 | (char *) &coffsymbol (debug->bsym)->native, | |
719 | S_GET_NUMBER_AUXILIARY(debug) * AUXESZ); | |
720 | coffsymbol (normal->bsym)->lineno = linenos; | |
721 | #else | |
722 | memcpy ((char *) &normal->sy_symbol.ost_auxent[0], | |
723 | (char *) &debug->sy_symbol.ost_auxent[0], | |
724 | S_GET_NUMBER_AUXILIARY (debug) * AUXESZ); | |
725 | #endif | |
726 | } | |
355afbcd KR |
727 | |
728 | /* Move the debug flags. */ | |
729 | SF_SET_DEBUG_FIELD (normal, SF_GET_DEBUG_FIELD (debug)); | |
730 | } /* c_symbol_merge() */ | |
fecd2382 | 731 | |
85051959 | 732 | static symbolS *previous_file_symbol; |
355afbcd KR |
733 | void |
734 | c_dot_file_symbol (filename) | |
735 | char *filename; | |
fecd2382 | 736 | { |
355afbcd KR |
737 | symbolS *symbolP; |
738 | ||
85051959 ILT |
739 | #ifdef BFD_ASSEMBLER |
740 | symbolP = symbol_new (filename, &bfd_abs_section, 0, | |
741 | &zero_address_frag); | |
742 | #else | |
355afbcd KR |
743 | symbolP = symbol_new (".file", |
744 | SEG_DEBUG, | |
745 | 0, | |
746 | &zero_address_frag); | |
85051959 | 747 | #endif |
355afbcd KR |
748 | |
749 | S_SET_STORAGE_CLASS (symbolP, C_FILE); | |
750 | S_SET_NUMBER_AUXILIARY (symbolP, 1); | |
85051959 ILT |
751 | |
752 | #ifdef BFD_ASSEMBLER | |
753 | symbolP->bsym->flags = BSF_DEBUGGING; | |
754 | #else | |
755 | if (strlen(filename) > 14) | |
756 | { | |
757 | /* This won't fit into a 14 char space, it will go into the string | |
758 | table. */ | |
759 | symbolP->sy_symbol.ost_auxent->x_file.x_n.x_zeroes = 0; | |
760 | (&(symbolP->sy_symbol.ost_auxent->x_file.x_n.x_offset))[0] = string_byte_count; | |
761 | (&(symbolP->sy_symbol.ost_auxent->x_file.x_n.x_offset))[1] = (int)filename; | |
762 | } | |
763 | else | |
764 | { | |
765 | SA_SET_FILE_FNAME (symbolP, filename); | |
766 | } | |
767 | SF_SET_DEBUG (symbolP); | |
768 | #endif | |
355afbcd KR |
769 | |
770 | #ifndef NO_LISTING | |
771 | { | |
772 | extern int listing; | |
773 | if (listing) | |
774 | { | |
775 | listing_source_file (filename); | |
776 | } | |
777 | } | |
778 | #endif | |
779 | ||
355afbcd KR |
780 | S_SET_VALUE (symbolP, (long) previous_file_symbol); |
781 | ||
782 | previous_file_symbol = symbolP; | |
783 | ||
784 | /* Make sure that the symbol is first on the symbol chain */ | |
785 | if (symbol_rootP != symbolP) | |
786 | { | |
787 | if (symbolP == symbol_lastP) | |
788 | { | |
789 | symbol_lastP = symbol_lastP->sy_previous; | |
790 | } /* if it was the last thing on the list */ | |
791 | ||
792 | symbol_remove (symbolP, &symbol_rootP, &symbol_lastP); | |
793 | symbol_insert (symbolP, symbol_rootP, &symbol_rootP, &symbol_lastP); | |
794 | symbol_rootP = symbolP; | |
795 | } /* if not first on the list */ | |
85051959 | 796 | } |
355afbcd | 797 | |
fecd2382 RP |
798 | /* |
799 | * Build a 'section static' symbol. | |
800 | */ | |
801 | ||
355afbcd KR |
802 | char * |
803 | c_section_symbol (name, value, length, nreloc, nlnno) | |
804 | char *name; | |
805 | long value; | |
806 | long length; | |
807 | unsigned short nreloc; | |
808 | unsigned short nlnno; | |
fecd2382 | 809 | { |
355afbcd KR |
810 | symbolS *symbolP; |
811 | ||
812 | symbolP = symbol_new (name, | |
813 | (name[1] == 't' | |
85051959 ILT |
814 | ? text_section |
815 | : name[1] == 'd' | |
816 | ? data_section | |
817 | : bss_section), | |
355afbcd KR |
818 | value, |
819 | &zero_address_frag); | |
820 | ||
821 | S_SET_STORAGE_CLASS (symbolP, C_STAT); | |
822 | S_SET_NUMBER_AUXILIARY (symbolP, 1); | |
823 | ||
824 | SA_SET_SCN_SCNLEN (symbolP, length); | |
825 | SA_SET_SCN_NRELOC (symbolP, nreloc); | |
826 | SA_SET_SCN_NLINNO (symbolP, nlnno); | |
827 | ||
828 | SF_SET_STATICS (symbolP); | |
829 | ||
830 | return (char *) symbolP; | |
831 | } /* c_section_symbol() */ | |
832 | ||
833 | void | |
834 | c_section_header (header, | |
835 | name, | |
836 | core_address, | |
837 | size, | |
838 | data_ptr, | |
839 | reloc_ptr, | |
840 | lineno_ptr, | |
841 | reloc_number, | |
842 | lineno_number, | |
843 | alignment) | |
57574979 | 844 | #ifdef BFD_HEADERS |
355afbcd | 845 | struct internal_scnhdr *header; |
57574979 | 846 | #else |
355afbcd | 847 | SCNHDR *header; |
57574979 | 848 | #endif |
355afbcd KR |
849 | char *name; |
850 | long core_address; | |
851 | long size; | |
852 | long data_ptr; | |
853 | long reloc_ptr; | |
854 | long lineno_ptr; | |
855 | long reloc_number; | |
856 | long lineno_number; | |
857 | long alignment; | |
fecd2382 | 858 | { |
355afbcd KR |
859 | strncpy (header->s_name, name, 8); |
860 | header->s_paddr = header->s_vaddr = core_address; | |
861 | header->s_scnptr = ((header->s_size = size) != 0) ? data_ptr : 0; | |
862 | header->s_relptr = reloc_ptr; | |
863 | header->s_lnnoptr = lineno_ptr; | |
864 | header->s_nreloc = reloc_number; | |
865 | header->s_nlnno = lineno_number; | |
866 | ||
fecd2382 RP |
867 | #ifdef OBJ_COFF_SECTION_HEADER_HAS_ALIGNMENT |
868 | #ifdef OBJ_COFF_BROKEN_ALIGNMENT | |
355afbcd | 869 | header->s_align = ((name[1] == 'b' || (size > 0)) ? 16 : 0); |
fecd2382 | 870 | #else |
355afbcd KR |
871 | header->s_align = ((alignment == 0) |
872 | ? 0 | |
873 | : (1 << alignment)); | |
fecd2382 RP |
874 | #endif /* OBJ_COFF_BROKEN_ALIGNMENT */ |
875 | #endif /* OBJ_COFF_SECTION_HEADER_HAS_ALIGNMENT */ | |
355afbcd KR |
876 | |
877 | header->s_flags = STYP_REG | (name[1] == 't' | |
878 | ? STYP_TEXT | |
85051959 ILT |
879 | : name[1] == 'd' |
880 | ? STYP_DATA | |
881 | : name[1] == 'b' | |
882 | ? STYP_BSS | |
883 | : STYP_INFO); | |
884 | } | |
fecd2382 RP |
885 | |
886 | /* Line number handling */ | |
887 | ||
85051959 ILT |
888 | #ifdef BFD_ASSEMBLER |
889 | ||
890 | /* Symbol of last function, which we should hang line#s off of. */ | |
891 | symbolS *function_lineoff; | |
892 | ||
893 | #else | |
894 | ||
895 | /* Offset in line#s where the last function started (the odd entry for | |
896 | line #0). */ | |
897 | int function_lineoff = -1; | |
898 | ||
899 | int text_lineno_number; | |
900 | ||
901 | /* We use this to build pointers from .bf's into the linetable. It | |
902 | should match exactly the values that are later assigned in | |
903 | text_lineno_number by write.c. */ | |
904 | int our_lineno_number; | |
fecd2382 | 905 | |
85051959 ILT |
906 | lineno *lineno_lastP; |
907 | #endif | |
908 | ||
909 | #ifndef BFD_ASSEMBLER | |
fecd2382 | 910 | int |
355afbcd KR |
911 | c_line_new (paddr, line_number, frag) |
912 | long paddr; | |
913 | unsigned short line_number; | |
914 | fragS *frag; | |
fecd2382 | 915 | { |
355afbcd KR |
916 | lineno *new_line = (lineno *) xmalloc (sizeof (lineno)); |
917 | ||
918 | new_line->line.l_addr.l_paddr = paddr; | |
919 | new_line->line.l_lnno = line_number; | |
920 | new_line->frag = (char *) frag; | |
921 | new_line->next = (lineno *) 0; | |
922 | ||
923 | if (lineno_rootP == (lineno *) 0) | |
924 | lineno_rootP = new_line; | |
925 | else | |
926 | lineno_lastP->next = new_line; | |
927 | lineno_lastP = new_line; | |
928 | return LINESZ * our_lineno_number++; | |
fecd2382 | 929 | } |
85051959 | 930 | #endif |
fecd2382 | 931 | |
355afbcd KR |
932 | void |
933 | obj_emit_lineno (where, line, file_start) | |
934 | char **where; | |
85051959 | 935 | #ifndef BFD_ASSEMBLER /* sigh */ |
355afbcd | 936 | lineno *line; |
85051959 | 937 | #endif |
355afbcd | 938 | char *file_start; |
fecd2382 | 939 | { |
85051959 | 940 | #ifndef BFD_ASSEMBLER |
57574979 | 941 | #ifdef BFD_HEADERS |
355afbcd | 942 | struct bfd_internal_lineno *line_entry; |
57574979 | 943 | #else |
355afbcd | 944 | LINENO *line_entry; |
57574979 | 945 | #endif |
355afbcd KR |
946 | for (; line; line = line->next) |
947 | { | |
948 | line_entry = &line->line; | |
949 | ||
85051959 ILT |
950 | /* FIXME-SOMEDAY Resolving the sy_number of function linno's used to be |
951 | done in write_object_file() but their symbols need a fileptr to the | |
952 | lnno, so I moved this resolution check here. xoxorich. */ | |
355afbcd KR |
953 | |
954 | if (line_entry->l_lnno == 0) | |
955 | { | |
956 | /* There is a good chance that the symbol pointed to | |
85051959 ILT |
957 | is not the one that will be emitted and that the |
958 | sy_number is not accurate. */ | |
355afbcd KR |
959 | symbolS *symbolP; |
960 | ||
961 | symbolP = (symbolS *) line_entry->l_addr.l_symndx; | |
962 | ||
963 | line_entry->l_addr.l_symndx = symbolP->sy_number; | |
964 | symbolP->sy_symbol.ost_auxent[0].x_sym.x_fcnary.x_fcn.x_lnnoptr = *where - file_start; | |
965 | ||
966 | } /* if this is a function linno */ | |
57574979 | 967 | #ifdef BFD_HEADERS |
355afbcd | 968 | *where += bfd_coff_swap_lineno_out (stdoutput, line_entry, *where); |
57574979 | 969 | #else |
355afbcd | 970 | /* No matter which member of the union we process, they are |
85051959 | 971 | both long. */ |
d1a9e594 | 972 | #ifdef CROSS_COMPILE |
355afbcd KR |
973 | md_number_to_chars (*where, line_entry->l_addr.l_paddr, sizeof (line_entry->l_addr.l_paddr)); |
974 | *where += sizeof (line_entry->l_addr.l_paddr); | |
975 | ||
976 | md_number_to_chars (*where, line_entry->l_lnno, sizeof (line_entry->l_lnno)); | |
977 | *where += sizeof (line_entry->l_lnno); | |
978 | ||
a39116f1 | 979 | #ifdef TC_I960 |
355afbcd KR |
980 | **where = '0'; |
981 | ++*where; | |
982 | **where = '0'; | |
983 | ++*where; | |
a39116f1 | 984 | #endif /* TC_I960 */ |
355afbcd | 985 | |
d1a9e594 | 986 | #else /* CROSS_COMPILE */ |
355afbcd | 987 | append (where, (char *) line_entry, LINESZ); |
d1a9e594 | 988 | #endif /* CROSS_COMPILE */ |
a39116f1 | 989 | #endif /* BFD_HEADERS */ |
355afbcd | 990 | } /* for each line number */ |
85051959 ILT |
991 | #else /* BFD_ASSEMBLER */ |
992 | abort (); | |
993 | #endif /* BFD_ASSEMBLER */ | |
994 | } | |
fecd2382 | 995 | |
355afbcd KR |
996 | void |
997 | obj_symbol_new_hook (symbolP) | |
998 | symbolS *symbolP; | |
fecd2382 | 999 | { |
355afbcd KR |
1000 | char underscore = 0; /* Symbol has leading _ */ |
1001 | ||
85051959 ILT |
1002 | #ifdef BFD_ASSEMBLER |
1003 | { | |
1004 | long sz = (OBJ_COFF_MAX_AUXENTRIES + 1) * sizeof (combined_entry_type); | |
1005 | char *s = (char *) bfd_alloc_by_size_t (stdoutput, sz); | |
1006 | memset (s, 0, sz); | |
1007 | coffsymbol (symbolP->bsym)->native = (combined_entry_type *) s; | |
1008 | } | |
1009 | #else | |
355afbcd KR |
1010 | /* Effective symbol */ |
1011 | /* Store the pointer in the offset. */ | |
1012 | S_SET_ZEROES (symbolP, 0L); | |
355afbcd KR |
1013 | /* Additional information */ |
1014 | symbolP->sy_symbol.ost_flags = 0; | |
1015 | /* Auxiliary entries */ | |
1016 | memset ((char *) &symbolP->sy_symbol.ost_auxent[0], '\0', AUXESZ); | |
85051959 ILT |
1017 | #endif |
1018 | S_SET_DATA_TYPE (symbolP, T_NULL); | |
1019 | S_SET_STORAGE_CLASS (symbolP, 0); | |
1020 | S_SET_NUMBER_AUXILIARY (symbolP, 0); | |
355afbcd | 1021 | |
a39116f1 | 1022 | #ifdef STRIP_UNDERSCORE |
355afbcd | 1023 | /* Remove leading underscore at the beginning of the symbol. |
85051959 | 1024 | This is to be compatible with the standard librairies. */ |
355afbcd KR |
1025 | if (*S_GET_NAME (symbolP) == '_') |
1026 | { | |
1027 | underscore = 1; | |
1028 | S_SET_NAME (symbolP, S_GET_NAME (symbolP) + 1); | |
85051959 | 1029 | } |
fecd2382 | 1030 | #endif /* STRIP_UNDERSCORE */ |
355afbcd KR |
1031 | |
1032 | if (S_IS_STRING (symbolP)) | |
1033 | SF_SET_STRING (symbolP); | |
1034 | if (!underscore && S_IS_LOCAL (symbolP)) | |
1035 | SF_SET_LOCAL (symbolP); | |
85051959 | 1036 | } |
fecd2382 | 1037 | |
a39116f1 | 1038 | /* stack stuff */ |
355afbcd KR |
1039 | stack * |
1040 | stack_init (chunk_size, element_size) | |
1041 | unsigned long chunk_size; | |
1042 | unsigned long element_size; | |
fecd2382 | 1043 | { |
355afbcd KR |
1044 | stack *st; |
1045 | ||
85051959 ILT |
1046 | st = (stack *) malloc (sizeof (stack)); |
1047 | if (!st) | |
1048 | return 0; | |
1049 | st->data = malloc (chunk_size); | |
1050 | if (!st->data) | |
355afbcd KR |
1051 | { |
1052 | free (st); | |
85051959 | 1053 | return 0; |
355afbcd KR |
1054 | } |
1055 | st->pointer = 0; | |
1056 | st->size = chunk_size; | |
1057 | st->chunk_size = chunk_size; | |
1058 | st->element_size = element_size; | |
1059 | return st; | |
85051959 | 1060 | } |
355afbcd KR |
1061 | |
1062 | void | |
1063 | stack_delete (st) | |
1064 | stack *st; | |
fecd2382 | 1065 | { |
355afbcd KR |
1066 | free (st->data); |
1067 | free (st); | |
fecd2382 RP |
1068 | } |
1069 | ||
355afbcd KR |
1070 | char * |
1071 | stack_push (st, element) | |
1072 | stack *st; | |
1073 | char *element; | |
fecd2382 | 1074 | { |
355afbcd KR |
1075 | if (st->pointer + st->element_size >= st->size) |
1076 | { | |
1077 | st->size += st->chunk_size; | |
1078 | if ((st->data = xrealloc (st->data, st->size)) == (char *) 0) | |
1079 | return (char *) 0; | |
1080 | } | |
1081 | memcpy (st->data + st->pointer, element, st->element_size); | |
1082 | st->pointer += st->element_size; | |
1083 | return st->data + st->pointer; | |
1084 | } /* stack_push() */ | |
1085 | ||
1086 | char * | |
1087 | stack_pop (st) | |
1088 | stack *st; | |
fecd2382 | 1089 | { |
355afbcd KR |
1090 | if ((st->pointer -= st->element_size) < 0) |
1091 | { | |
1092 | st->pointer = 0; | |
1093 | return (char *) 0; | |
1094 | } | |
1095 | return st->data + st->pointer; | |
fecd2382 RP |
1096 | } |
1097 | ||
355afbcd KR |
1098 | char * |
1099 | stack_top (st) | |
1100 | stack *st; | |
fecd2382 | 1101 | { |
355afbcd | 1102 | return st->data + st->pointer - st->element_size; |
fecd2382 RP |
1103 | } |
1104 | ||
1105 | ||
1106 | /* | |
1107 | * Handle .ln directives. | |
1108 | */ | |
1109 | ||
85051959 ILT |
1110 | #ifdef BFD_ASSEMBLER |
1111 | static symbolS *current_lineno_sym; | |
1112 | static struct line_no *line_nos; | |
1113 | ||
1114 | static void | |
1115 | add_lineno (frag, offset, num) | |
1116 | fragS *frag; | |
1117 | int offset; | |
1118 | int num; | |
1119 | { | |
1120 | struct line_no *new_line = (struct line_no *) bfd_alloc_by_size_t (stdoutput, | |
1121 | sizeof (struct line_no)); | |
1122 | if (!current_lineno_sym) | |
1123 | { | |
1124 | abort (); | |
1125 | } | |
1126 | new_line->next = line_nos; | |
1127 | new_line->frag = frag; | |
1128 | new_line->l.line_number = num; | |
1129 | new_line->l.u.offset = offset; | |
1130 | line_nos = new_line; | |
1131 | } | |
1132 | ||
1133 | static void | |
1134 | add_linesym (sym) | |
1135 | symbolS *sym; | |
1136 | { | |
1137 | if (line_nos) | |
1138 | { | |
1139 | add_lineno (0, 0, 0); | |
1140 | coffsymbol (current_lineno_sym->bsym)->lineno = (alent *) line_nos; | |
1141 | line_nos = 0; | |
1142 | } | |
1143 | current_lineno_sym = sym; | |
1144 | } | |
1145 | #endif | |
1146 | ||
355afbcd | 1147 | static void |
85051959 ILT |
1148 | obj_coff_ln (appline) |
1149 | int appline; | |
355afbcd KR |
1150 | { |
1151 | int l; | |
85051959 ILT |
1152 | |
1153 | if (! appline && def_symbol_in_progress != NULL) | |
355afbcd KR |
1154 | { |
1155 | as_warn (".ln pseudo-op inside .def/.endef: ignored."); | |
1156 | demand_empty_rest_of_line (); | |
1157 | return; | |
85051959 | 1158 | } |
355afbcd | 1159 | |
85051959 ILT |
1160 | l = get_absolute_expression (); |
1161 | #ifdef BFD_ASSEMBLER | |
1162 | add_lineno (frag_now, frag_now_fix (), l); | |
1163 | #else | |
1164 | c_line_new (frag_now_fix (), l, frag_now); | |
1165 | #endif | |
355afbcd KR |
1166 | |
1167 | #ifndef NO_LISTING | |
1168 | { | |
1169 | extern int listing; | |
1170 | ||
1171 | if (listing) | |
1172 | { | |
85051959 ILT |
1173 | if (! appline) |
1174 | l += line_base - 1; | |
1175 | listing_source_line (l); | |
355afbcd KR |
1176 | } |
1177 | } | |
1178 | #endif | |
1179 | ||
1180 | demand_empty_rest_of_line (); | |
355afbcd | 1181 | } /* obj_coff_ln() */ |
fecd2382 RP |
1182 | |
1183 | /* | |
1184 | * def() | |
1185 | * | |
1186 | * Handle .def directives. | |
1187 | * | |
1188 | * One might ask : why can't we symbol_new if the symbol does not | |
1189 | * already exist and fill it with debug information. Because of | |
1190 | * the C_EFCN special symbol. It would clobber the value of the | |
1191 | * function symbol before we have a chance to notice that it is | |
1192 | * a C_EFCN. And a second reason is that the code is more clear this | |
1193 | * way. (at least I think it is :-). | |
1194 | * | |
1195 | */ | |
1196 | ||
1197 | #define SKIP_SEMI_COLON() while (*input_line_pointer++ != ';') | |
1198 | #define SKIP_WHITESPACES() while (*input_line_pointer == ' ' || \ | |
a39116f1 RP |
1199 | *input_line_pointer == '\t') \ |
1200 | input_line_pointer++; | |
fecd2382 | 1201 | |
355afbcd KR |
1202 | static void |
1203 | obj_coff_def (what) | |
1204 | int what; | |
fecd2382 | 1205 | { |
355afbcd KR |
1206 | char name_end; /* Char after the end of name */ |
1207 | char *symbol_name; /* Name of the debug symbol */ | |
1208 | char *symbol_name_copy; /* Temporary copy of the name */ | |
1209 | unsigned int symbol_name_length; | |
355afbcd KR |
1210 | |
1211 | if (def_symbol_in_progress != NULL) | |
1212 | { | |
1213 | as_warn (".def pseudo-op used inside of .def/.endef: ignored."); | |
1214 | demand_empty_rest_of_line (); | |
1215 | return; | |
1216 | } /* if not inside .def/.endef */ | |
1217 | ||
1218 | SKIP_WHITESPACES (); | |
1219 | ||
355afbcd | 1220 | symbol_name = input_line_pointer; |
85051959 ILT |
1221 | #ifdef STRIP_UNDERSCORE |
1222 | if (symbol_name[0] == '_' && symbol_name[1] != 0) | |
1223 | symbol_name++; | |
1224 | #endif /* STRIP_UNDERSCORE */ | |
1225 | ||
355afbcd KR |
1226 | name_end = get_symbol_end (); |
1227 | symbol_name_length = strlen (symbol_name); | |
1228 | symbol_name_copy = xmalloc (symbol_name_length + 1); | |
1229 | strcpy (symbol_name_copy, symbol_name); | |
1230 | ||
1231 | /* Initialize the new symbol */ | |
85051959 ILT |
1232 | #ifdef BFD_ASSEMBLER |
1233 | def_symbol_in_progress = symbol_make (symbol_name_copy); | |
1234 | #else | |
1235 | def_symbol_in_progress = (symbolS *) obstack_alloc (¬es, sizeof (*def_symbol_in_progress)); | |
1236 | memset (def_symbol_in_progress, '\0', sizeof (*def_symbol_in_progress)); | |
1237 | ||
355afbcd | 1238 | S_SET_NAME (def_symbol_in_progress, symbol_name_copy); |
355afbcd KR |
1239 | def_symbol_in_progress->sy_name_offset = ~0; |
1240 | def_symbol_in_progress->sy_number = ~0; | |
85051959 ILT |
1241 | #endif |
1242 | ||
355afbcd KR |
1243 | def_symbol_in_progress->sy_frag = &zero_address_frag; |
1244 | ||
1245 | if (S_IS_STRING (def_symbol_in_progress)) | |
85051959 | 1246 | SF_SET_STRING (def_symbol_in_progress); |
355afbcd KR |
1247 | |
1248 | *input_line_pointer = name_end; | |
1249 | ||
1250 | demand_empty_rest_of_line (); | |
85051959 | 1251 | } |
fecd2382 RP |
1252 | |
1253 | unsigned int dim_index; | |
355afbcd KR |
1254 | static void |
1255 | obj_coff_endef () | |
1256 | { | |
1257 | symbolS *symbolP; | |
1258 | /* DIM BUG FIX sac@cygnus.com */ | |
1259 | dim_index = 0; | |
1260 | if (def_symbol_in_progress == NULL) | |
1261 | { | |
1262 | as_warn (".endef pseudo-op used outside of .def/.endef: ignored."); | |
1263 | demand_empty_rest_of_line (); | |
1264 | return; | |
1265 | } /* if not inside .def/.endef */ | |
1266 | ||
1267 | /* Set the section number according to storage class. */ | |
1268 | switch (S_GET_STORAGE_CLASS (def_symbol_in_progress)) | |
1269 | { | |
1270 | case C_STRTAG: | |
1271 | case C_ENTAG: | |
1272 | case C_UNTAG: | |
1273 | SF_SET_TAG (def_symbol_in_progress); | |
1274 | /* intentional fallthrough */ | |
1275 | case C_FILE: | |
1276 | case C_TPDEF: | |
1277 | SF_SET_DEBUG (def_symbol_in_progress); | |
85051959 ILT |
1278 | #ifdef BFD_ASSEMBLER |
1279 | S_SET_SEGMENT (def_symbol_in_progress, fetch_coff_debug_section ()); | |
1280 | #else | |
355afbcd | 1281 | S_SET_SEGMENT (def_symbol_in_progress, SEG_DEBUG); |
85051959 | 1282 | #endif |
355afbcd KR |
1283 | break; |
1284 | ||
1285 | case C_EFCN: | |
1286 | SF_SET_LOCAL (def_symbol_in_progress); /* Do not emit this symbol. */ | |
1287 | /* intentional fallthrough */ | |
1288 | case C_BLOCK: | |
1289 | SF_SET_PROCESS (def_symbol_in_progress); /* Will need processing before writing */ | |
1290 | /* intentional fallthrough */ | |
1291 | case C_FCN: | |
85051959 ILT |
1292 | { |
1293 | CONST char *name; | |
1294 | S_SET_SEGMENT (def_symbol_in_progress, text_section); | |
355afbcd | 1295 | |
85051959 ILT |
1296 | #ifdef BFD_ASSEMBLER |
1297 | name = bfd_asymbol_name (def_symbol_in_progress->bsym); | |
1298 | #else | |
1299 | name = def_symbol_in_progress->sy_symbol.ost_entry._n._n_nptr[1]; | |
1300 | #endif | |
1301 | if (name[1] == 'b' && name[2] == 'f') | |
1302 | { | |
1303 | if (function_lineoff < 0) | |
1304 | as_warn ("`%s' symbol without preceding function", name); | |
1305 | #ifdef BFD_ASSEMBLER | |
1306 | abort (); | |
1307 | #else | |
1308 | SA_GET_SYM_LNNOPTR (def_symbol_in_progress) = function_lineoff; | |
1309 | #endif | |
1310 | /* Will need relocating */ | |
1311 | SF_SET_PROCESS (def_symbol_in_progress); | |
1312 | #ifdef BFD_ASSEMBLER | |
1313 | function_lineoff = 0; | |
1314 | #else | |
1315 | function_lineoff = -1; | |
1316 | #endif | |
1317 | } | |
1318 | } | |
355afbcd KR |
1319 | break; |
1320 | ||
fecd2382 | 1321 | #ifdef C_AUTOARG |
355afbcd | 1322 | case C_AUTOARG: |
fecd2382 | 1323 | #endif /* C_AUTOARG */ |
355afbcd KR |
1324 | case C_AUTO: |
1325 | case C_REG: | |
1326 | case C_MOS: | |
1327 | case C_MOE: | |
1328 | case C_MOU: | |
1329 | case C_ARG: | |
1330 | case C_REGPARM: | |
1331 | case C_FIELD: | |
1332 | case C_EOS: | |
1333 | SF_SET_DEBUG (def_symbol_in_progress); | |
85051959 | 1334 | S_SET_SEGMENT (def_symbol_in_progress, absolute_section); |
355afbcd KR |
1335 | break; |
1336 | ||
1337 | case C_EXT: | |
1338 | case C_STAT: | |
1339 | case C_LABEL: | |
1340 | /* Valid but set somewhere else (s_comm, s_lcomm, colon) */ | |
1341 | break; | |
1342 | ||
1343 | case C_USTATIC: | |
1344 | case C_EXTDEF: | |
1345 | case C_ULABEL: | |
85051959 ILT |
1346 | as_warn ("unexpected storage class %d", |
1347 | S_GET_STORAGE_CLASS (def_symbol_in_progress)); | |
355afbcd KR |
1348 | break; |
1349 | } /* switch on storage class */ | |
1350 | ||
85051959 ILT |
1351 | /* Now that we have built a debug symbol, try to find if we should |
1352 | merge with an existing symbol or not. If a symbol is C_EFCN or | |
1353 | SEG_ABSOLUTE or untagged SEG_DEBUG it never merges. */ | |
1354 | ||
1355 | /* Two cases for functions. Either debug followed by definition or | |
1356 | definition followed by debug. For definition first, we will | |
1357 | merge the debug symbol into the definition. For debug first, the | |
1358 | lineno entry MUST point to the definition function or else it | |
1359 | will point off into space when obj_crawl_symbol_chain() merges | |
1360 | the debug symbol into the real symbol. Therefor, let's presume | |
1361 | the debug symbol is a real function reference. */ | |
1362 | ||
1363 | /* FIXME-SOON If for some reason the definition label/symbol is | |
1364 | never seen, this will probably leave an undefined symbol at link | |
1365 | time. */ | |
355afbcd KR |
1366 | |
1367 | if (S_GET_STORAGE_CLASS (def_symbol_in_progress) == C_EFCN | |
85051959 ILT |
1368 | #ifdef BFD_ASSEMBLER |
1369 | || (!strcmp (bfd_get_section_name (stdoutput, | |
1370 | S_GET_SEGMENT (def_symbol_in_progress)), | |
1371 | "*DEBUG*") | |
1372 | && !SF_GET_TAG (def_symbol_in_progress)) | |
1373 | #else | |
355afbcd KR |
1374 | || (S_GET_SEGMENT (def_symbol_in_progress) == SEG_DEBUG |
1375 | && !SF_GET_TAG (def_symbol_in_progress)) | |
85051959 ILT |
1376 | #endif |
1377 | || S_GET_SEGMENT (def_symbol_in_progress) == absolute_section | |
355afbcd KR |
1378 | || (symbolP = symbol_find_base (S_GET_NAME (def_symbol_in_progress), DO_NOT_STRIP)) == NULL) |
1379 | { | |
85051959 ILT |
1380 | #ifdef BFD_ASSEMBLER |
1381 | if (def_symbol_in_progress != symbol_lastP) | |
1382 | symbol_append (def_symbol_in_progress, symbol_lastP, &symbol_rootP, | |
1383 | &symbol_lastP); | |
1384 | #else | |
1385 | symbol_append (def_symbol_in_progress, symbol_lastP, &symbol_rootP, | |
1386 | &symbol_lastP); | |
1387 | #endif | |
355afbcd KR |
1388 | } |
1389 | else | |
1390 | { | |
85051959 ILT |
1391 | /* This symbol already exists, merge the newly created symbol |
1392 | into the old one. This is not mandatory. The linker can | |
1393 | handle duplicate symbols correctly. But I guess that it save | |
1394 | a *lot* of space if the assembly file defines a lot of | |
1395 | symbols. [loic] */ | |
355afbcd | 1396 | |
85051959 ILT |
1397 | /* The debug entry (def_symbol_in_progress) is merged into the |
1398 | previous definition. */ | |
355afbcd KR |
1399 | |
1400 | c_symbol_merge (def_symbol_in_progress, symbolP); | |
1401 | /* FIXME-SOON Should *def_symbol_in_progress be free'd? xoxorich. */ | |
1402 | def_symbol_in_progress = symbolP; | |
1403 | ||
1404 | if (SF_GET_FUNCTION (def_symbol_in_progress) | |
1405 | || SF_GET_TAG (def_symbol_in_progress)) | |
1406 | { | |
85051959 ILT |
1407 | /* For functions, and tags, the symbol *must* be where the |
1408 | debug symbol appears. Move the existing symbol to the | |
1409 | current place. */ | |
355afbcd KR |
1410 | /* If it already is at the end of the symbol list, do nothing */ |
1411 | if (def_symbol_in_progress != symbol_lastP) | |
1412 | { | |
1413 | symbol_remove (def_symbol_in_progress, &symbol_rootP, &symbol_lastP); | |
1414 | symbol_append (def_symbol_in_progress, symbol_lastP, &symbol_rootP, &symbol_lastP); | |
85051959 ILT |
1415 | } |
1416 | } | |
1417 | } | |
355afbcd KR |
1418 | |
1419 | if (SF_GET_TAG (def_symbol_in_progress) | |
1420 | && symbol_find_base (S_GET_NAME (def_symbol_in_progress), DO_NOT_STRIP) == NULL) | |
1421 | { | |
1422 | tag_insert (S_GET_NAME (def_symbol_in_progress), def_symbol_in_progress); | |
85051959 | 1423 | } |
355afbcd KR |
1424 | |
1425 | if (SF_GET_FUNCTION (def_symbol_in_progress)) | |
1426 | { | |
1427 | know (sizeof (def_symbol_in_progress) <= sizeof (long)); | |
85051959 ILT |
1428 | #ifdef BFD_ASSEMBLER |
1429 | function_lineoff = def_symbol_in_progress; | |
1430 | add_linesym (def_symbol_in_progress); | |
1431 | #else | |
1432 | function_lineoff = c_line_new ((long) def_symbol_in_progress, 0, | |
1433 | &zero_address_frag); | |
1434 | #endif | |
355afbcd KR |
1435 | SF_SET_PROCESS (def_symbol_in_progress); |
1436 | ||
1437 | if (symbolP == NULL) | |
1438 | { | |
85051959 ILT |
1439 | /* That is, if this is the first time we've seen the |
1440 | function... */ | |
355afbcd KR |
1441 | symbol_table_insert (def_symbol_in_progress); |
1442 | } /* definition follows debug */ | |
1443 | } /* Create the line number entry pointing to the function being defined */ | |
1444 | ||
1445 | def_symbol_in_progress = NULL; | |
1446 | demand_empty_rest_of_line (); | |
1447 | return; | |
85051959 | 1448 | } |
355afbcd KR |
1449 | |
1450 | static void | |
1451 | obj_coff_dim () | |
1452 | { | |
1453 | register int dim_index; | |
1454 | ||
1455 | if (def_symbol_in_progress == NULL) | |
1456 | { | |
1457 | as_warn (".dim pseudo-op used outside of .def/.endef: ignored."); | |
1458 | demand_empty_rest_of_line (); | |
1459 | return; | |
1460 | } /* if not inside .def/.endef */ | |
1461 | ||
1462 | S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1); | |
1463 | ||
1464 | for (dim_index = 0; dim_index < DIMNUM; dim_index++) | |
1465 | { | |
1466 | SKIP_WHITESPACES (); | |
1467 | SA_SET_SYM_DIMEN (def_symbol_in_progress, dim_index, get_absolute_expression ()); | |
1468 | ||
1469 | switch (*input_line_pointer) | |
1470 | { | |
1471 | ||
1472 | case ',': | |
1473 | input_line_pointer++; | |
1474 | break; | |
1475 | ||
1476 | default: | |
1477 | as_warn ("badly formed .dim directive ignored"); | |
1478 | /* intentional fallthrough */ | |
1479 | case '\n': | |
1480 | case ';': | |
1481 | dim_index = DIMNUM; | |
1482 | break; | |
1483 | } /* switch on following character */ | |
1484 | } /* for each dimension */ | |
1485 | ||
1486 | demand_empty_rest_of_line (); | |
1487 | return; | |
1488 | } /* obj_coff_dim() */ | |
1489 | ||
1490 | static void | |
1491 | obj_coff_line () | |
1492 | { | |
1493 | int this_base; | |
1494 | ||
1495 | if (def_symbol_in_progress == NULL) | |
1496 | { | |
85051959 | 1497 | obj_coff_ln (0); |
355afbcd KR |
1498 | return; |
1499 | } /* if it looks like a stabs style line */ | |
1500 | ||
1501 | this_base = get_absolute_expression (); | |
1502 | if (this_base > line_base) | |
1503 | { | |
1504 | line_base = this_base; | |
1505 | } | |
1506 | ||
1507 | ||
1508 | S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1); | |
1509 | SA_SET_SYM_LNNO (def_symbol_in_progress, line_base); | |
1510 | ||
1511 | demand_empty_rest_of_line (); | |
1512 | return; | |
1513 | } /* obj_coff_line() */ | |
1514 | ||
1515 | static void | |
1516 | obj_coff_size () | |
1517 | { | |
1518 | if (def_symbol_in_progress == NULL) | |
1519 | { | |
1520 | as_warn (".size pseudo-op used outside of .def/.endef ignored."); | |
1521 | demand_empty_rest_of_line (); | |
1522 | return; | |
1523 | } /* if not inside .def/.endef */ | |
1524 | ||
1525 | S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1); | |
1526 | SA_SET_SYM_SIZE (def_symbol_in_progress, get_absolute_expression ()); | |
1527 | demand_empty_rest_of_line (); | |
1528 | return; | |
1529 | } /* obj_coff_size() */ | |
1530 | ||
1531 | static void | |
1532 | obj_coff_scl () | |
1533 | { | |
1534 | if (def_symbol_in_progress == NULL) | |
1535 | { | |
1536 | as_warn (".scl pseudo-op used outside of .def/.endef ignored."); | |
1537 | demand_empty_rest_of_line (); | |
1538 | return; | |
1539 | } /* if not inside .def/.endef */ | |
1540 | ||
1541 | S_SET_STORAGE_CLASS (def_symbol_in_progress, get_absolute_expression ()); | |
1542 | demand_empty_rest_of_line (); | |
1543 | return; | |
1544 | } /* obj_coff_scl() */ | |
1545 | ||
1546 | static void | |
1547 | obj_coff_tag () | |
a39116f1 | 1548 | { |
355afbcd KR |
1549 | char *symbol_name; |
1550 | char name_end; | |
1551 | ||
1552 | if (def_symbol_in_progress == NULL) | |
1553 | { | |
1554 | as_warn (".tag pseudo-op used outside of .def/.endef ignored."); | |
1555 | demand_empty_rest_of_line (); | |
1556 | return; | |
1557 | } /* if not inside .def/.endef */ | |
1558 | ||
1559 | S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1); | |
1560 | symbol_name = input_line_pointer; | |
1561 | name_end = get_symbol_end (); | |
1562 | ||
1563 | /* Assume that the symbol referred to by .tag is always defined. */ | |
1564 | /* This was a bad assumption. I've added find_or_make. xoxorich. */ | |
85051959 ILT |
1565 | SA_SET_SYM_TAGNDX (def_symbol_in_progress, |
1566 | (long) tag_find_or_make (symbol_name)); | |
355afbcd KR |
1567 | if (SA_GET_SYM_TAGNDX (def_symbol_in_progress) == 0L) |
1568 | { | |
1569 | as_warn ("tag not found for .tag %s", symbol_name); | |
1570 | } /* not defined */ | |
1571 | ||
1572 | SF_SET_TAGGED (def_symbol_in_progress); | |
1573 | *input_line_pointer = name_end; | |
1574 | ||
1575 | demand_empty_rest_of_line (); | |
355afbcd KR |
1576 | } /* obj_coff_tag() */ |
1577 | ||
1578 | static void | |
1579 | obj_coff_type () | |
1580 | { | |
1581 | if (def_symbol_in_progress == NULL) | |
1582 | { | |
1583 | as_warn (".type pseudo-op used outside of .def/.endef ignored."); | |
1584 | demand_empty_rest_of_line (); | |
1585 | return; | |
1586 | } /* if not inside .def/.endef */ | |
1587 | ||
1588 | S_SET_DATA_TYPE (def_symbol_in_progress, get_absolute_expression ()); | |
1589 | ||
1590 | if (ISFCN (S_GET_DATA_TYPE (def_symbol_in_progress)) && | |
1591 | S_GET_STORAGE_CLASS (def_symbol_in_progress) != C_TPDEF) | |
1592 | { | |
1593 | SF_SET_FUNCTION (def_symbol_in_progress); | |
1594 | } /* is a function */ | |
1595 | ||
1596 | demand_empty_rest_of_line (); | |
1597 | return; | |
1598 | } /* obj_coff_type() */ | |
1599 | ||
1600 | static void | |
1601 | obj_coff_val () | |
1602 | { | |
1603 | if (def_symbol_in_progress == NULL) | |
1604 | { | |
1605 | as_warn (".val pseudo-op used outside of .def/.endef ignored."); | |
1606 | demand_empty_rest_of_line (); | |
1607 | return; | |
1608 | } /* if not inside .def/.endef */ | |
1609 | ||
1610 | if (is_name_beginner (*input_line_pointer)) | |
1611 | { | |
1612 | char *symbol_name = input_line_pointer; | |
1613 | char name_end = get_symbol_end (); | |
1614 | ||
1615 | if (!strcmp (symbol_name, ".")) | |
1616 | { | |
1617 | def_symbol_in_progress->sy_frag = frag_now; | |
1618 | S_SET_VALUE (def_symbol_in_progress, obstack_next_free (&frags) - frag_now->fr_literal); | |
1619 | /* If the .val is != from the .def (e.g. statics) */ | |
1620 | } | |
1621 | else if (strcmp (S_GET_NAME (def_symbol_in_progress), symbol_name)) | |
1622 | { | |
5868b1fe ILT |
1623 | def_symbol_in_progress->sy_value.X_add_symbol = |
1624 | symbol_find_or_make (symbol_name); | |
1625 | def_symbol_in_progress->sy_value.X_subtract_symbol = NULL; | |
1626 | def_symbol_in_progress->sy_value.X_add_number = 0; | |
1627 | def_symbol_in_progress->sy_value.X_seg = undefined_section; | |
1628 | ||
1629 | /* If the segment is undefined when the forward reference is | |
1630 | resolved, then copy the segment id from the forward | |
1631 | symbol. */ | |
355afbcd KR |
1632 | SF_SET_GET_SEGMENT (def_symbol_in_progress); |
1633 | } | |
1634 | /* Otherwise, it is the name of a non debug symbol and its value will be calculated later. */ | |
1635 | *input_line_pointer = name_end; | |
1636 | } | |
1637 | else | |
1638 | { | |
1639 | S_SET_VALUE (def_symbol_in_progress, get_absolute_expression ()); | |
1640 | } /* if symbol based */ | |
1641 | ||
1642 | demand_empty_rest_of_line (); | |
1643 | return; | |
1644 | } /* obj_coff_val() */ | |
fecd2382 RP |
1645 | |
1646 | /* | |
1647 | * Maintain a list of the tagnames of the structres. | |
1648 | */ | |
1649 | ||
355afbcd KR |
1650 | static void |
1651 | tag_init () | |
fecd2382 | 1652 | { |
355afbcd KR |
1653 | tag_hash = hash_new (); |
1654 | return; | |
1655 | } /* tag_init() */ | |
1656 | ||
1657 | static void | |
1658 | tag_insert (name, symbolP) | |
85051959 | 1659 | CONST char *name; |
355afbcd | 1660 | symbolS *symbolP; |
fecd2382 | 1661 | { |
355afbcd KR |
1662 | register char *error_string; |
1663 | ||
1664 | if (*(error_string = hash_jam (tag_hash, name, (char *) symbolP))) | |
1665 | { | |
1666 | as_fatal ("Inserting \"%s\" into structure table failed: %s", | |
1667 | name, error_string); | |
1668 | } | |
1669 | return; | |
1670 | } /* tag_insert() */ | |
1671 | ||
1672 | static symbolS * | |
1673 | tag_find_or_make (name) | |
1674 | char *name; | |
1675 | { | |
1676 | symbolS *symbolP; | |
1677 | ||
1678 | if ((symbolP = tag_find (name)) == NULL) | |
1679 | { | |
85051959 ILT |
1680 | symbolP = symbol_new (name, undefined_section, |
1681 | 0, &zero_address_frag); | |
355afbcd KR |
1682 | |
1683 | tag_insert (S_GET_NAME (symbolP), symbolP); | |
1684 | symbol_table_insert (symbolP); | |
1685 | } /* not found */ | |
1686 | ||
1687 | return (symbolP); | |
1688 | } /* tag_find_or_make() */ | |
1689 | ||
1690 | static symbolS * | |
1691 | tag_find (name) | |
1692 | char *name; | |
fecd2382 | 1693 | { |
a39116f1 | 1694 | #ifdef STRIP_UNDERSCORE |
355afbcd KR |
1695 | if (*name == '_') |
1696 | name++; | |
fecd2382 | 1697 | #endif /* STRIP_UNDERSCORE */ |
355afbcd KR |
1698 | return ((symbolS *) hash_find (tag_hash, name)); |
1699 | } /* tag_find() */ | |
fecd2382 | 1700 | |
355afbcd KR |
1701 | void |
1702 | obj_read_begin_hook () | |
1703 | { | |
1704 | /* These had better be the same. Usually 18 bytes. */ | |
57574979 | 1705 | #ifndef BFD_HEADERS |
355afbcd KR |
1706 | know (sizeof (SYMENT) == sizeof (AUXENT)); |
1707 | know (SYMESZ == AUXESZ); | |
57574979 | 1708 | #endif |
355afbcd | 1709 | tag_init (); |
85051959 | 1710 | } |
fecd2382 | 1711 | |
355afbcd KR |
1712 | void |
1713 | obj_crawl_symbol_chain (headers) | |
1714 | object_headers *headers; | |
fecd2382 | 1715 | { |
355afbcd KR |
1716 | int symbol_number = 0; |
1717 | lineno *lineP; | |
1718 | symbolS *last_functionP = NULL; | |
1719 | symbolS *last_tagP; | |
1720 | symbolS *symbolP; | |
1721 | symbolS *symbol_externP = NULL; | |
1722 | symbolS *symbol_extern_lastP = NULL; | |
1723 | ||
1724 | /* Initialize the stack used to keep track of the matching .bb .be */ | |
1725 | stack *block_stack = stack_init (512, sizeof (symbolS *)); | |
1726 | ||
355afbcd KR |
1727 | tc_crawl_symbol_chain (headers); |
1728 | ||
1729 | /* The symbol list should be ordered according to the following sequence | |
1730 | * order : | |
1731 | * . .file symbol | |
1732 | * . debug entries for functions | |
1733 | * . fake symbols for .text .data and .bss | |
1734 | * . defined symbols | |
1735 | * . undefined symbols | |
1736 | * But this is not mandatory. The only important point is to put the | |
1737 | * undefined symbols at the end of the list. | |
1738 | */ | |
1739 | ||
1740 | if (symbol_rootP == NULL | |
1741 | || S_GET_STORAGE_CLASS (symbol_rootP) != C_FILE) | |
1742 | { | |
1743 | know (!previous_file_symbol); | |
1744 | c_dot_file_symbol ("fake"); | |
1745 | } /* Is there a .file symbol ? If not insert one at the beginning. */ | |
1746 | ||
1747 | /* | |
1748 | * Build up static symbols for .text, .data and .bss | |
1749 | */ | |
1750 | dot_text_symbol = (symbolS *) | |
1751 | c_section_symbol (".text", | |
1752 | 0, | |
1753 | H_GET_TEXT_SIZE (headers), | |
1754 | 0 /*text_relocation_number */ , | |
1755 | 0 /*text_lineno_number */ ); | |
1756 | #ifdef TE_I386AIX | |
1757 | symbol_remove (dot_text_symbol, &symbol_rootP, &symbol_lastP); | |
1758 | symbol_append (dot_text_symbol, previous_file_symbol, | |
1759 | &symbol_rootP, &symbol_lastP); | |
1760 | #endif /* TE_I386AIX */ | |
1761 | ||
1762 | dot_data_symbol = (symbolS *) | |
1763 | c_section_symbol (".data", | |
1764 | H_GET_TEXT_SIZE (headers), | |
1765 | H_GET_DATA_SIZE (headers), | |
1766 | 0 /*data_relocation_number */ , | |
1767 | 0); /* There are no data lineno entries */ | |
1768 | #ifdef TE_I386AIX | |
1769 | symbol_remove (dot_data_symbol, &symbol_rootP, &symbol_lastP); | |
1770 | symbol_append (dot_data_symbol, dot_text_symbol, | |
1771 | &symbol_rootP, &symbol_lastP); | |
1772 | #endif /* TE_I386AIX */ | |
1773 | ||
1774 | dot_bss_symbol = (symbolS *) | |
1775 | c_section_symbol (".bss", | |
1776 | H_GET_TEXT_SIZE (headers) + H_GET_DATA_SIZE (headers), | |
1777 | H_GET_BSS_SIZE (headers), | |
1778 | 0, /* No relocation for a bss section. */ | |
1779 | 0); /* There are no bss lineno entries */ | |
1780 | #ifdef TE_I386AIX | |
1781 | symbol_remove (dot_bss_symbol, &symbol_rootP, &symbol_lastP); | |
1782 | symbol_append (dot_bss_symbol, dot_data_symbol, | |
1783 | &symbol_rootP, &symbol_lastP); | |
1784 | #endif /* TE_I386AIX */ | |
1785 | ||
fecd2382 | 1786 | #if defined(DEBUG) |
355afbcd | 1787 | verify_symbol_chain (symbol_rootP, symbol_lastP); |
fecd2382 | 1788 | #endif /* DEBUG */ |
355afbcd KR |
1789 | |
1790 | /* Three traversals of symbol chains here. The | |
1791 | first traversal yanks externals into a temporary | |
1792 | chain, removing the externals from the global | |
1793 | chain, numbers symbols, and does some other guck. | |
1794 | The second traversal is on the temporary chain of | |
1795 | externals and just appends them to the global | |
1796 | chain again, numbering them as we go. The third | |
1797 | traversal patches pointers to symbols (using sym | |
1798 | indexes). The last traversal was once done as | |
1799 | part of the first pass, but that fails when a | |
1800 | reference preceeds a definition as the definition | |
1801 | has no number at the time we process the | |
1802 | reference. */ | |
1803 | ||
1804 | /* Note that symbolP will be NULL at the end of a loop | |
1805 | if an external was at the beginning of the list (it | |
1806 | gets moved off the list). Hence the weird check in | |
1807 | the loop control. | |
1808 | */ | |
1809 | for (symbolP = symbol_rootP; | |
1810 | symbolP; | |
1811 | symbolP = symbolP ? symbol_next (symbolP) : symbol_rootP) | |
1812 | { | |
1813 | if (!SF_GET_DEBUG (symbolP)) | |
1814 | { | |
1815 | /* Debug symbols do not need all this rubbish */ | |
1816 | symbolS *real_symbolP; | |
1817 | ||
1818 | /* L* and C_EFCN symbols never merge. */ | |
1819 | if (!SF_GET_LOCAL (symbolP) | |
1820 | && (real_symbolP = symbol_find_base (S_GET_NAME (symbolP), DO_NOT_STRIP)) | |
1821 | && real_symbolP != symbolP) | |
1822 | { | |
1823 | /* FIXME-SOON: where do dups come from? Maybe tag references before definitions? xoxorich. */ | |
1824 | /* Move the debug data from the debug symbol to the | |
1825 | real symbol. Do NOT do the oposite (i.e. move from | |
1826 | real symbol to debug symbol and remove real symbol from the | |
1827 | list.) Because some pointers refer to the real symbol | |
1828 | whereas no pointers refer to the debug symbol. */ | |
1829 | c_symbol_merge (symbolP, real_symbolP); | |
1830 | /* Replace the current symbol by the real one */ | |
1831 | /* The symbols will never be the last or the first | |
1832 | because : 1st symbol is .file and 3 last symbols are | |
1833 | .text, .data, .bss */ | |
1834 | symbol_remove (real_symbolP, &symbol_rootP, &symbol_lastP); | |
1835 | symbol_insert (real_symbolP, symbolP, &symbol_rootP, &symbol_lastP); | |
1836 | symbol_remove (symbolP, &symbol_rootP, &symbol_lastP); | |
1837 | symbolP = real_symbolP; | |
1838 | } /* if not local but dup'd */ | |
1839 | ||
1840 | if (flagseen['R'] && (S_GET_SEGMENT (symbolP) == SEG_DATA)) | |
1841 | { | |
1842 | S_SET_SEGMENT (symbolP, SEG_TEXT); | |
1843 | } /* push data into text */ | |
1844 | ||
5868b1fe | 1845 | resolve_symbol_value (symbolP); |
355afbcd KR |
1846 | |
1847 | if (!S_IS_DEFINED (symbolP) && !SF_GET_LOCAL (symbolP)) | |
1848 | { | |
1849 | S_SET_EXTERNAL (symbolP); | |
1850 | } | |
1851 | else if (S_GET_STORAGE_CLASS (symbolP) == C_NULL) | |
1852 | { | |
1853 | if (S_GET_SEGMENT (symbolP) == SEG_TEXT) | |
1854 | { | |
1855 | S_SET_STORAGE_CLASS (symbolP, C_LABEL); | |
1856 | } | |
1857 | else | |
1858 | { | |
1859 | S_SET_STORAGE_CLASS (symbolP, C_STAT); | |
1860 | } | |
1861 | } /* no storage class yet */ | |
1862 | ||
1863 | /* Mainly to speed up if not -g */ | |
1864 | if (SF_GET_PROCESS (symbolP)) | |
1865 | { | |
1866 | /* Handle the nested blocks auxiliary info. */ | |
1867 | if (S_GET_STORAGE_CLASS (symbolP) == C_BLOCK) | |
1868 | { | |
1869 | if (!strcmp (S_GET_NAME (symbolP), ".bb")) | |
1870 | stack_push (block_stack, (char *) &symbolP); | |
1871 | else | |
1872 | { /* .eb */ | |
1873 | register symbolS *begin_symbolP; | |
1874 | begin_symbolP = *(symbolS **) stack_pop (block_stack); | |
1875 | if (begin_symbolP == (symbolS *) 0) | |
1876 | as_warn ("mismatched .eb"); | |
1877 | else | |
1878 | SA_SET_SYM_ENDNDX (begin_symbolP, symbol_number + 2); | |
1879 | } | |
1880 | } | |
1881 | /* If we are able to identify the type of a function, and we | |
1882 | are out of a function (last_functionP == 0) then, the | |
1883 | function symbol will be associated with an auxiliary | |
1884 | entry. */ | |
1885 | if (last_functionP == (symbolS *) 0 && | |
1886 | SF_GET_FUNCTION (symbolP)) | |
1887 | { | |
1888 | last_functionP = symbolP; | |
1889 | ||
1890 | if (S_GET_NUMBER_AUXILIARY (symbolP) < 1) | |
1891 | { | |
1892 | S_SET_NUMBER_AUXILIARY (symbolP, 1); | |
1893 | } /* make it at least 1 */ | |
1894 | ||
1895 | /* Clobber possible stale .dim information. */ | |
1896 | memset (symbolP->sy_symbol.ost_auxent[0].x_sym.x_fcnary.x_ary.x_dimen, | |
1897 | '\0', sizeof (symbolP->sy_symbol.ost_auxent[0].x_sym.x_fcnary.x_ary.x_dimen)); | |
1898 | } | |
1899 | /* The C_FCN doesn't need any additional information. | |
1900 | I don't even know if this is needed for sdb. But the | |
1901 | standard assembler generates it, so... | |
fecd2382 | 1902 | */ |
355afbcd KR |
1903 | if (S_GET_STORAGE_CLASS (symbolP) == C_EFCN) |
1904 | { | |
1905 | if (last_functionP == (symbolS *) 0) | |
1906 | as_fatal ("C_EFCN symbol out of scope"); | |
1907 | SA_SET_SYM_FSIZE (last_functionP, | |
1908 | (long) (S_GET_VALUE (symbolP) - | |
1909 | S_GET_VALUE (last_functionP))); | |
1910 | SA_SET_SYM_ENDNDX (last_functionP, symbol_number); | |
1911 | last_functionP = (symbolS *) 0; | |
fecd2382 | 1912 | } |
355afbcd KR |
1913 | } |
1914 | } | |
1915 | else if (SF_GET_TAG (symbolP)) | |
1916 | { | |
1917 | /* First descriptor of a structure must point to | |
1918 | the first slot after the structure description. */ | |
1919 | last_tagP = symbolP; | |
1920 | ||
1921 | } | |
1922 | else if (S_GET_STORAGE_CLASS (symbolP) == C_EOS) | |
1923 | { | |
1924 | /* +2 take in account the current symbol */ | |
1925 | SA_SET_SYM_ENDNDX (last_tagP, symbol_number + 2); | |
1926 | } | |
1927 | else if (S_GET_STORAGE_CLASS (symbolP) == C_FILE) | |
1928 | { | |
85051959 ILT |
1929 | if (symbolP->sy_symbol.ost_auxent->x_file.x_n.x_zeroes == 0) |
1930 | { | |
1931 | symbolP->sy_symbol.ost_auxent->x_file.x_n.x_offset = string_byte_count; | |
1932 | string_byte_count += | |
1933 | strlen(GET_FILENAME_STRING(symbolP)) + 1; | |
1934 | ||
1935 | ||
1936 | } | |
1937 | ||
355afbcd KR |
1938 | if (S_GET_VALUE (symbolP)) |
1939 | { | |
1940 | S_SET_VALUE ((symbolS *) S_GET_VALUE (symbolP), symbol_number); | |
1941 | S_SET_VALUE (symbolP, 0); | |
1942 | } /* no one points at the first .file symbol */ | |
1943 | } /* if debug or tag or eos or file */ | |
1944 | ||
1945 | /* We must put the external symbols apart. The loader | |
85051959 ILT |
1946 | does not bomb if we do not. But the references in |
1947 | the endndx field for a .bb symbol are not corrected | |
1948 | if an external symbol is removed between .bb and .be. | |
1949 | I.e in the following case : | |
1950 | [20] .bb endndx = 22 | |
1951 | [21] foo external | |
1952 | [22] .be | |
1953 | ld will move the symbol 21 to the end of the list but | |
1954 | endndx will still be 22 instead of 21. */ | |
355afbcd KR |
1955 | |
1956 | if (SF_GET_LOCAL (symbolP)) | |
1957 | { | |
1958 | /* remove C_EFCN and LOCAL (L...) symbols */ | |
1959 | /* next pointer remains valid */ | |
1960 | symbol_remove (symbolP, &symbol_rootP, &symbol_lastP); | |
1961 | ||
1962 | } | |
1963 | else if ( | |
1964 | #ifdef TE_I386AIX | |
85051959 ILT |
1965 | S_GET_STORAGE_CLASS (symbolP) == C_EXT |
1966 | && !SF_GET_FUNCTION (symbolP) | |
355afbcd | 1967 | #else /* not TE_I386AIX */ |
85051959 ILT |
1968 | !S_IS_DEFINED (symbolP) |
1969 | && !S_IS_DEBUG (symbolP) | |
1970 | && !SF_GET_STATICS (symbolP) | |
355afbcd | 1971 | #endif /* not TE_I386AIX */ |
85051959 | 1972 | ) |
355afbcd KR |
1973 | { |
1974 | /* if external, Remove from the list */ | |
1975 | symbolS *hold = symbol_previous (symbolP); | |
1976 | ||
1977 | symbol_remove (symbolP, &symbol_rootP, &symbol_lastP); | |
1978 | symbol_clear_list_pointers (symbolP); | |
1979 | symbol_append (symbolP, symbol_extern_lastP, &symbol_externP, &symbol_extern_lastP); | |
1980 | symbolP = hold; | |
1981 | } | |
1982 | else | |
1983 | { | |
1984 | if (SF_GET_STRING (symbolP)) | |
1985 | { | |
1986 | symbolP->sy_name_offset = string_byte_count; | |
1987 | string_byte_count += strlen (S_GET_NAME (symbolP)) + 1; | |
1988 | } | |
1989 | else | |
1990 | { | |
1991 | symbolP->sy_name_offset = 0; | |
1992 | } /* fix "long" names */ | |
1993 | ||
1994 | symbolP->sy_number = symbol_number; | |
1995 | symbol_number += 1 + S_GET_NUMBER_AUXILIARY (symbolP); | |
1996 | } /* if local symbol */ | |
1997 | } /* traverse the symbol list */ | |
1998 | ||
1999 | for (symbolP = symbol_externP; symbol_externP;) | |
2000 | { | |
2001 | symbolS *tmp = symbol_externP; | |
2002 | ||
2003 | /* append */ | |
2004 | symbol_remove (tmp, &symbol_externP, &symbol_extern_lastP); | |
2005 | symbol_append (tmp, symbol_lastP, &symbol_rootP, &symbol_lastP); | |
2006 | ||
2007 | /* and process */ | |
2008 | if (SF_GET_STRING (tmp)) | |
2009 | { | |
2010 | tmp->sy_name_offset = string_byte_count; | |
2011 | string_byte_count += strlen (S_GET_NAME (tmp)) + 1; | |
2012 | } | |
2013 | else | |
2014 | { | |
2015 | tmp->sy_name_offset = 0; | |
2016 | } /* fix "long" names */ | |
2017 | ||
2018 | tmp->sy_number = symbol_number; | |
2019 | symbol_number += 1 + S_GET_NUMBER_AUXILIARY (tmp); | |
2020 | } /* append the entire extern chain */ | |
2021 | ||
85051959 ILT |
2022 | /* When a tag reference preceeds the tag definition, the definition |
2023 | will not have a number at the time we process the reference | |
2024 | during the first traversal. Thus, a second traversal. */ | |
355afbcd KR |
2025 | |
2026 | for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP)) | |
2027 | { | |
2028 | if (SF_GET_TAGGED (symbolP)) | |
2029 | { | |
2030 | SA_SET_SYM_TAGNDX (symbolP, ((symbolS *) SA_GET_SYM_TAGNDX (symbolP))->sy_number); | |
85051959 ILT |
2031 | } |
2032 | } | |
355afbcd KR |
2033 | |
2034 | know (symbol_externP == NULL); | |
2035 | know (symbol_extern_lastP == NULL); | |
2036 | ||
85051959 ILT |
2037 | /* FIXME-SOMEDAY I'm counting line no's here so we know what to put |
2038 | in the section headers, and I'm resolving the addresses since I'm | |
2039 | not sure how to do it later. I am NOT resolving the linno's | |
2040 | representing functions. Their symbols need a fileptr pointing to | |
2041 | this linno when emitted. Thus, I resolve them on emit. | |
2042 | xoxorich. */ | |
355afbcd KR |
2043 | |
2044 | for (lineP = lineno_rootP; lineP; lineP = lineP->next) | |
2045 | { | |
2046 | if (lineP->line.l_lnno > 0) | |
2047 | { | |
2048 | lineP->line.l_addr.l_paddr += ((fragS *) lineP->frag)->fr_address; | |
2049 | } | |
2050 | else | |
2051 | { | |
2052 | ; | |
2053 | } | |
2054 | text_lineno_number++; | |
2055 | } /* for each line number */ | |
2056 | ||
2057 | H_SET_SYMBOL_TABLE_SIZE (headers, symbol_number); | |
2058 | ||
2059 | return; | |
85051959 | 2060 | } |
fecd2382 RP |
2061 | |
2062 | /* | |
2063 | * Find strings by crawling along symbol table chain. | |
2064 | */ | |
2065 | ||
355afbcd KR |
2066 | void |
2067 | obj_emit_strings (where) | |
2068 | char **where; | |
fecd2382 | 2069 | { |
355afbcd KR |
2070 | symbolS *symbolP; |
2071 | ||
d1a9e594 | 2072 | #ifdef CROSS_COMPILE |
355afbcd KR |
2073 | /* Gotta do md_ byte-ordering stuff for string_byte_count first - KWK */ |
2074 | md_number_to_chars (*where, string_byte_count, sizeof (string_byte_count)); | |
2075 | *where += sizeof (string_byte_count); | |
d1a9e594 | 2076 | #else /* CROSS_COMPILE */ |
355afbcd | 2077 | append (where, (char *) &string_byte_count, (unsigned long) sizeof (string_byte_count)); |
d1a9e594 | 2078 | #endif /* CROSS_COMPILE */ |
355afbcd KR |
2079 | |
2080 | for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP)) | |
2081 | { | |
85051959 ILT |
2082 | if (S_GET_STORAGE_CLASS(symbolP) == C_FILE) |
2083 | { | |
2084 | /* May need special treatment for this auxent */ | |
2085 | if (symbolP->sy_symbol.ost_auxent->x_file.x_n.x_zeroes == 0) | |
2086 | { | |
2087 | char *p = GET_FILENAME_STRING(symbolP); | |
2088 | append | |
2089 | (where,p, strlen(p)+1); | |
2090 | } | |
2091 | } | |
355afbcd KR |
2092 | if (SF_GET_STRING (symbolP)) |
2093 | { | |
85051959 ILT |
2094 | append (where, S_GET_NAME (symbolP), |
2095 | (unsigned long) (strlen (S_GET_NAME (symbolP)) + 1)); | |
355afbcd KR |
2096 | } /* if it has a string */ |
2097 | } /* walk the symbol chain */ | |
85051959 | 2098 | } |
355afbcd KR |
2099 | |
2100 | void | |
2101 | obj_pre_write_hook (headers) | |
2102 | object_headers *headers; | |
fecd2382 | 2103 | { |
355afbcd KR |
2104 | register int text_relocation_number = 0; |
2105 | register int data_relocation_number = 0; | |
2106 | register fixS *fixP; | |
2107 | ||
85051959 ILT |
2108 | /* FIXME-SOMEDAY this should be done at fixup_segment time but I'm |
2109 | going to wait until I do multiple segments. xoxorich. */ | |
355afbcd KR |
2110 | /* Count the number of relocation entries for text and data */ |
2111 | for (fixP = text_fix_root; fixP; fixP = fixP->fx_next) | |
2112 | { | |
2113 | if (fixP->fx_addsy) | |
2114 | { | |
2115 | ++text_relocation_number; | |
fecd2382 | 2116 | #ifdef TC_I960 |
355afbcd KR |
2117 | /* two relocs per callj under coff. */ |
2118 | if (fixP->fx_callj) | |
2119 | { | |
2120 | ++text_relocation_number; | |
2121 | } /* if callj and not already fixed. */ | |
fecd2382 | 2122 | #endif /* TC_I960 */ |
57574979 | 2123 | #ifdef TC_A29K |
355afbcd KR |
2124 | /* Count 2 for a constH */ |
2125 | if (fixP->fx_r_type == RELOC_CONSTH) | |
2126 | { | |
2127 | ++text_relocation_number; | |
2128 | } | |
57574979 | 2129 | #endif |
355afbcd KR |
2130 | |
2131 | } /* if not yet fixed */ | |
2132 | } /* for each fix */ | |
2133 | ||
2134 | SA_SET_SCN_NRELOC (dot_text_symbol, text_relocation_number); | |
2135 | /* Assign the number of line number entries for the text section */ | |
2136 | SA_SET_SCN_NLINNO (dot_text_symbol, text_lineno_number); | |
2137 | /* Assign the size of the section */ | |
2138 | SA_SET_SCN_SCNLEN (dot_text_symbol, H_GET_TEXT_SIZE (headers)); | |
2139 | ||
2140 | for (fixP = data_fix_root; fixP; fixP = fixP->fx_next) | |
2141 | { | |
2142 | if (fixP->fx_addsy) | |
2143 | { | |
2144 | ++data_relocation_number; | |
2145 | } /* if still relocatable */ | |
57574979 | 2146 | #ifdef TC_A29K |
355afbcd KR |
2147 | /* Count 2 for a constH */ |
2148 | if (fixP->fx_r_type == RELOC_CONSTH) | |
2149 | { | |
2150 | ++data_relocation_number; | |
2151 | } | |
57574979 | 2152 | #endif |
355afbcd KR |
2153 | |
2154 | } /* for each fix */ | |
2155 | ||
2156 | ||
2157 | SA_SET_SCN_NRELOC (dot_data_symbol, data_relocation_number); | |
2158 | /* Assign the size of the section */ | |
2159 | SA_SET_SCN_SCNLEN (dot_data_symbol, H_GET_DATA_SIZE (headers)); | |
2160 | ||
2161 | /* Assign the size of the section */ | |
2162 | SA_SET_SCN_SCNLEN (dot_bss_symbol, H_GET_BSS_SIZE (headers)); | |
2163 | ||
2164 | /* pre write hook can add relocs (for 960 and 29k coff) so */ | |
2165 | headers->relocation_size = text_relocation_number * RELSZ + | |
2166 | data_relocation_number * RELSZ; | |
2167 | ||
2168 | ||
2169 | ||
2170 | /* Fill in extra coff fields */ | |
2171 | ||
2172 | /* Initialize general line number information. */ | |
2173 | H_SET_LINENO_SIZE (headers, text_lineno_number * LINESZ); | |
2174 | ||
2175 | /* filehdr */ | |
2176 | H_SET_FILE_MAGIC_NUMBER (headers, FILE_HEADER_MAGIC); | |
2177 | H_SET_NUMBER_OF_SECTIONS (headers, 3); /* text+data+bss */ | |
57574979 | 2178 | #ifndef OBJ_COFF_OMIT_TIMESTAMP |
355afbcd | 2179 | H_SET_TIME_STAMP (headers, (long) time ((long *) 0)); |
57574979 | 2180 | #else /* OBJ_COFF_OMIT_TIMESTAMP */ |
355afbcd | 2181 | H_SET_TIME_STAMP (headers, 0); |
57574979 | 2182 | #endif /* OBJ_COFF_OMIT_TIMESTAMP */ |
355afbcd | 2183 | H_SET_SYMBOL_TABLE_POINTER (headers, H_GET_SYMBOL_TABLE_FILE_OFFSET (headers)); |
57574979 | 2184 | #if 0 |
355afbcd KR |
2185 | printf ("FILHSZ %x\n", FILHSZ); |
2186 | printf ("OBJ_COFF_AOUTHDRSZ %x\n", OBJ_COFF_AOUTHDRSZ); | |
2187 | printf ("section headers %x\n", H_GET_NUMBER_OF_SECTIONS (headers) * SCNHSZ); | |
2188 | printf ("get text size %x\n", H_GET_TEXT_SIZE (headers)); | |
2189 | printf ("get data size %x\n", H_GET_DATA_SIZE (headers)); | |
2190 | printf ("get relocation size %x\n", H_GET_RELOCATION_SIZE (headers)); | |
2191 | printf ("get lineno size %x\n", H_GET_LINENO_SIZE (headers)); | |
57574979 | 2192 | #endif |
355afbcd KR |
2193 | /* symbol table size allready set */ |
2194 | H_SET_SIZEOF_OPTIONAL_HEADER (headers, OBJ_COFF_AOUTHDRSZ); | |
2195 | ||
2196 | /* do not added the F_RELFLG for the standard COFF. | |
6d5460ab RP |
2197 | * The AIX linker complain on file with relocation info striped flag. |
2198 | */ | |
2199 | #ifdef KEEP_RELOC_INFO | |
355afbcd KR |
2200 | H_SET_FLAGS (headers, (text_lineno_number == 0 ? F_LNNO : 0) |
2201 | | BYTE_ORDERING); | |
6d5460ab | 2202 | #else |
355afbcd KR |
2203 | H_SET_FLAGS (headers, (text_lineno_number == 0 ? F_LNNO : 0) |
2204 | | ((text_relocation_number + data_relocation_number) ? 0 : F_RELFLG) | |
2205 | | BYTE_ORDERING); | |
2206 | #endif | |
2207 | /* aouthdr */ | |
2208 | /* magic number allready set */ | |
2209 | H_SET_VERSION_STAMP (headers, 0); | |
2210 | /* Text, data, bss size; entry point; text_start and data_start are already set */ | |
2211 | ||
2212 | /* Build section headers */ | |
2213 | ||
2214 | c_section_header (&text_section_header, | |
2215 | ".text", | |
2216 | 0, | |
2217 | H_GET_TEXT_SIZE (headers), | |
2218 | H_GET_TEXT_FILE_OFFSET (headers), | |
2219 | (SA_GET_SCN_NRELOC (dot_text_symbol) | |
2220 | ? H_GET_RELOCATION_FILE_OFFSET (headers) | |
2221 | : 0), | |
2222 | (text_lineno_number | |
2223 | ? H_GET_LINENO_FILE_OFFSET (headers) | |
2224 | : 0), | |
2225 | SA_GET_SCN_NRELOC (dot_text_symbol), | |
2226 | text_lineno_number, | |
2227 | section_alignment[(int) SEG_TEXT]); | |
2228 | ||
2229 | c_section_header (&data_section_header, | |
2230 | ".data", | |
2231 | H_GET_TEXT_SIZE (headers), | |
2232 | H_GET_DATA_SIZE (headers), | |
2233 | (H_GET_DATA_SIZE (headers) | |
2234 | ? H_GET_DATA_FILE_OFFSET (headers) | |
2235 | : 0), | |
2236 | (SA_GET_SCN_NRELOC (dot_data_symbol) | |
2237 | ? (H_GET_RELOCATION_FILE_OFFSET (headers) | |
2238 | + text_section_header.s_nreloc * RELSZ) | |
2239 | : 0), | |
2240 | 0, /* No line number information */ | |
2241 | SA_GET_SCN_NRELOC (dot_data_symbol), | |
2242 | 0, /* No line number information */ | |
2243 | section_alignment[(int) SEG_DATA]); | |
2244 | ||
2245 | c_section_header (&bss_section_header, | |
2246 | ".bss", | |
2247 | H_GET_TEXT_SIZE (headers) + H_GET_DATA_SIZE (headers), | |
2248 | H_GET_BSS_SIZE (headers), | |
2249 | 0, /* No file offset */ | |
2250 | 0, /* No relocation information */ | |
2251 | 0, /* No line number information */ | |
2252 | 0, /* No relocation information */ | |
2253 | 0, /* No line number information */ | |
2254 | section_alignment[(int) SEG_BSS]); | |
85051959 | 2255 | } |
fecd2382 RP |
2256 | |
2257 | /* This is a copy from aout. All I do is neglect to actually build the symbol. */ | |
2258 | ||
355afbcd KR |
2259 | static void |
2260 | obj_coff_stab (what) | |
2261 | int what; | |
fecd2382 | 2262 | { |
355afbcd KR |
2263 | char *string; |
2264 | expressionS e; | |
2265 | int goof = 0; /* TRUE if we have aborted. */ | |
2266 | int length; | |
2267 | int saved_type = 0; | |
2268 | long longint; | |
2269 | symbolS *symbolP = 0; | |
2270 | ||
2271 | if (what == 's') | |
2272 | { | |
2273 | string = demand_copy_C_string (&length); | |
2274 | SKIP_WHITESPACE (); | |
2275 | ||
2276 | if (*input_line_pointer == ',') | |
2277 | { | |
2278 | input_line_pointer++; | |
2279 | } | |
2280 | else | |
2281 | { | |
2282 | as_bad ("I need a comma after symbol's name"); | |
2283 | goof = 1; | |
2284 | } /* better be a comma */ | |
2285 | } /* skip the string */ | |
2286 | ||
2287 | /* | |
fecd2382 RP |
2288 | * Input_line_pointer->after ','. String->symbol name. |
2289 | */ | |
355afbcd KR |
2290 | if (!goof) |
2291 | { | |
2292 | if (get_absolute_expression_and_terminator (&longint) != ',') | |
2293 | { | |
2294 | as_bad ("I want a comma after the n_type expression"); | |
2295 | goof = 1; | |
2296 | input_line_pointer--; /* Backup over a non-',' char. */ | |
2297 | } /* on error */ | |
2298 | } /* no error */ | |
2299 | ||
2300 | if (!goof) | |
2301 | { | |
2302 | if (get_absolute_expression_and_terminator (&longint) != ',') | |
2303 | { | |
2304 | as_bad ("I want a comma after the n_other expression"); | |
2305 | goof = 1; | |
2306 | input_line_pointer--; /* Backup over a non-',' char. */ | |
2307 | } /* on error */ | |
2308 | } /* no error */ | |
2309 | ||
2310 | if (!goof) | |
2311 | { | |
2312 | get_absolute_expression (); | |
2313 | ||
2314 | if (what == 's' || what == 'n') | |
2315 | { | |
2316 | if (*input_line_pointer != ',') | |
2317 | { | |
2318 | as_bad ("I want a comma after the n_desc expression"); | |
2319 | goof = 1; | |
2320 | } | |
2321 | else | |
2322 | { | |
2323 | input_line_pointer++; | |
2324 | } /* on goof */ | |
2325 | } /* not stabd */ | |
2326 | } /* no error */ | |
2327 | ||
2328 | expression (&e); | |
2329 | ||
2330 | if (goof) | |
2331 | { | |
2332 | ignore_rest_of_line (); | |
2333 | } | |
2334 | else | |
2335 | { | |
2336 | demand_empty_rest_of_line (); | |
2337 | } /* on error */ | |
2338 | } /* obj_coff_stab() */ | |
fecd2382 | 2339 | |
85051959 ILT |
2340 | #ifdef BFD_ASSEMBLER |
2341 | static | |
2342 | unsigned long | |
2343 | align (val, exp) | |
2344 | { | |
2345 | int n = (1 << exp) - 1; | |
2346 | printf ("align (%x, %x)\n", val, exp); | |
2347 | val = (val + n) & ~n; | |
2348 | return val; | |
2349 | } | |
2350 | ||
2351 | void | |
2352 | coff_check_file_symbols (symp, punt) | |
2353 | symbolS *symp; | |
2354 | int *punt; | |
2355 | { | |
2356 | static symbolS *last_functionP, *last_tagP; | |
2357 | static stack *block_stack; | |
2358 | ||
2359 | if (!block_stack) | |
2360 | block_stack = stack_init (512, sizeof (symbolS*)); | |
2361 | ||
2362 | #if 1 | |
2363 | if (!S_IS_DEFINED (symp) && S_GET_STORAGE_CLASS (symp) != C_STAT) | |
2364 | S_SET_STORAGE_CLASS (symp, C_EXT); | |
2365 | #endif | |
2366 | ||
2367 | if (!SF_GET_DEBUG (symp)) | |
2368 | { | |
2369 | symbolS *real; | |
2370 | if (!SF_GET_LOCAL (symp) | |
2371 | && (real = symbol_find_base (S_GET_NAME (symp), DO_NOT_STRIP)) | |
2372 | && real != symp) | |
2373 | { | |
2374 | c_symbol_merge (symp, real); | |
2375 | *punt = 1; | |
2376 | } | |
2377 | if (!S_IS_DEFINED (symp) && !SF_GET_LOCAL (symp)) | |
2378 | { | |
2379 | assert (S_GET_VALUE (symp) == 0); | |
2380 | S_SET_EXTERNAL (symp); | |
2381 | } | |
2382 | else if (S_GET_STORAGE_CLASS (symp) == C_NULL) | |
2383 | { | |
2384 | if (S_GET_SEGMENT (symp) == text_section) | |
2385 | S_SET_STORAGE_CLASS (symp, C_LABEL); | |
2386 | else | |
2387 | S_SET_STORAGE_CLASS (symp, C_STAT); | |
2388 | } | |
2389 | if (SF_GET_PROCESS (symp)) | |
2390 | { | |
2391 | if (S_GET_STORAGE_CLASS (symp) == C_BLOCK) | |
2392 | { | |
2393 | if (!strcmp (S_GET_NAME (symp), ".bb")) | |
2394 | stack_push (block_stack, (char *) &symp); | |
2395 | else | |
2396 | { | |
2397 | symbolS *begin; | |
2398 | begin = *(symbolS **) stack_pop (block_stack); | |
2399 | if (begin == 0) | |
2400 | as_warn ("mismatched .eb"); | |
2401 | else | |
2402 | SA_SET_SYM_ENDNDX (begin, begin); | |
2403 | } | |
2404 | } | |
2405 | if (last_functionP == 0 && SF_GET_FUNCTION (symp)) | |
2406 | { | |
2407 | union internal_auxent *auxp; | |
2408 | last_functionP = symp; | |
2409 | if (S_GET_NUMBER_AUXILIARY (symp) < 1) | |
2410 | S_SET_NUMBER_AUXILIARY (symp, 1); | |
2411 | auxp = &coffsymbol (symp->bsym)->native[1].u.auxent; | |
2412 | memset (auxp->x_sym.x_fcnary.x_ary.x_dimen, 0, | |
2413 | sizeof (auxp->x_sym.x_fcnary.x_ary.x_dimen)); | |
2414 | } | |
2415 | if (S_GET_STORAGE_CLASS (symp) == C_EFCN) | |
2416 | { | |
2417 | if (last_functionP == 0) | |
2418 | as_fatal ("C_EFCN symbol out of scope"); | |
2419 | SA_SET_SYM_FSIZE (last_functionP, | |
2420 | (long) (S_GET_VALUE (symp) | |
2421 | - S_GET_VALUE (last_functionP))); | |
2422 | SA_SET_SYM_ENDNDX (last_functionP, symp); | |
2423 | last_functionP = 0; | |
2424 | } | |
2425 | } | |
2426 | else if (SF_GET_TAG (symp)) | |
2427 | last_tagP = symp; | |
2428 | else if (S_GET_STORAGE_CLASS (symp) == C_EOS) | |
2429 | SA_SET_SYM_ENDNDX (last_tagP, symp); | |
2430 | else if (S_GET_STORAGE_CLASS (symp) == C_FILE) | |
2431 | { | |
2432 | if (S_GET_VALUE (symp)) | |
2433 | { | |
2434 | S_SET_VALUE ((symbolS *) S_GET_VALUE (symp), 0xdeadbeef); | |
2435 | S_SET_VALUE (symp, 0); | |
2436 | } | |
2437 | } | |
2438 | if (SF_GET_LOCAL (symp)) | |
2439 | *punt = 1; | |
2440 | /* more ... */ | |
2441 | } | |
2442 | if (coffsymbol (symp->bsym)->lineno) | |
2443 | { | |
2444 | int i, n; | |
2445 | struct line_no *lptr; | |
2446 | alent *l; | |
2447 | ||
2448 | lptr = (struct line_no *) coffsymbol (symp->bsym)->lineno; | |
2449 | for (i = 0; lptr; lptr = lptr->next) | |
2450 | i++; | |
2451 | n = i + 1; | |
2452 | lptr = (struct line_no *) coffsymbol (symp->bsym)->lineno; | |
2453 | l = (alent *) bfd_alloc_by_size_t (stdoutput, n * sizeof (alent)); | |
2454 | coffsymbol (symp->bsym)->lineno = l; | |
2455 | for (i = n - 1; i > 0; i--) | |
2456 | { | |
2457 | if (lptr->frag) | |
2458 | lptr->l.u.offset += lptr->frag->fr_address; | |
2459 | l[i] = lptr->l; | |
2460 | lptr = lptr->next; | |
2461 | } | |
2462 | } | |
2463 | } | |
2464 | ||
2465 | void | |
2466 | DEFUN_VOID(obj_coff_section) | |
2467 | { | |
2468 | /* Strip out the section name */ | |
2469 | char *section_name ; | |
2470 | char *section_name_end; | |
2471 | char c; | |
2472 | ||
2473 | unsigned int len; | |
2474 | unsigned int exp; | |
2475 | ||
2476 | section_name = input_line_pointer; | |
2477 | c = get_symbol_end(); | |
2478 | section_name_end = input_line_pointer; | |
2479 | ||
2480 | len = section_name_end - section_name ; | |
2481 | input_line_pointer++; | |
2482 | SKIP_WHITESPACE(); | |
2483 | if (c == ',') | |
2484 | exp = get_absolute_expression(); | |
2485 | else if (*input_line_pointer == ',') | |
2486 | { | |
2487 | input_line_pointer++; | |
2488 | exp = get_absolute_expression(); | |
2489 | } | |
2490 | else | |
2491 | { | |
2492 | exp = 0; | |
2493 | } | |
2494 | ||
2495 | printf ("change_to_section(`%s',%d,%x)\n", section_name, len,exp); | |
2496 | *section_name_end = c; | |
2497 | } | |
2498 | ||
2499 | void | |
2500 | coff_frob_file () | |
2501 | { | |
2502 | if (symbol_rootP == NULL | |
2503 | || S_GET_STORAGE_CLASS (symbol_rootP) != C_FILE) | |
2504 | { | |
2505 | assert (previous_file_symbol == 0); | |
2506 | c_dot_file_symbol ("fake"); | |
2507 | } | |
2508 | if (current_lineno_sym) | |
2509 | add_linesym ((symbolS *) 0); | |
2510 | } | |
2511 | #endif /* BFD_ASSEMBLER */ | |
2512 | ||
fecd2382 | 2513 | #ifdef DEBUG |
a39116f1 | 2514 | /* for debugging */ |
85051959 | 2515 | CONST char * |
355afbcd KR |
2516 | s_get_name (s) |
2517 | symbolS *s; | |
fecd2382 | 2518 | { |
355afbcd KR |
2519 | return ((s == NULL) ? "(NULL)" : S_GET_NAME (s)); |
2520 | } /* s_get_name() */ | |
2521 | ||
2522 | void | |
2523 | symbol_dump () | |
2524 | { | |
2525 | symbolS *symbolP; | |
2526 | ||
2527 | for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP)) | |
2528 | { | |
85051959 ILT |
2529 | #ifdef BFD_ASSEMBLER |
2530 | printf("0x%lx: \"%s\" type = %ld, class = %d, segment = %d\n", | |
2531 | (unsigned long) symbolP, | |
2532 | S_GET_NAME(symbolP), | |
2533 | (long) S_GET_DATA_TYPE(symbolP), | |
2534 | S_GET_STORAGE_CLASS(symbolP), | |
2535 | (int) S_GET_SEGMENT(symbolP)); | |
2536 | #else | |
355afbcd KR |
2537 | printf ("%3ld: 0x%lx \"%s\" type = %ld, class = %d, segment = %d\n", |
2538 | symbolP->sy_number, | |
2539 | (unsigned long) symbolP, | |
2540 | S_GET_NAME (symbolP), | |
2541 | (long) S_GET_DATA_TYPE (symbolP), | |
2542 | S_GET_STORAGE_CLASS (symbolP), | |
2543 | (int) S_GET_SEGMENT (symbolP)); | |
85051959 ILT |
2544 | #endif |
2545 | } | |
2546 | } | |
355afbcd | 2547 | |
fecd2382 RP |
2548 | #endif /* DEBUG */ |
2549 | ||
fecd2382 | 2550 | /* end of obj-coff.c */ |