Initial revision
[deliverable/binutils-gdb.git] / bfd / coffcode.h
CommitLineData
0f268757
SC
1/* Support for Intel 960 COFF and Motorola 88k BCS COFF (and maybe others) */
2
3/* Copyright (C) 1990, 1991 Free Software Foundation, Inc.
4
5This file is part of BFD, the Binary File Diddler.
6
7BFD is free software; you can redistribute it and/or modify it under the
8 terms of the GNU General Public License as published by the Free Software
9 Foundation; either version 1, or (at your option) any later version.
10
11BFD is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14 details.
15
16You should have received a copy of the GNU General Public License along with
17 BFD; see the file COPYING. If not, write to the Free Software Foundation,
18 675 Mass Ave, Cambridge, MA 02139, USA.
19*/
20
21/* $Id$ */
22/* Most of this hacked by Steve Chamberlain, steve@cygnus.com */
23
24#include "archures.h" /* Machine architectures and types */
25
26/* SUPPRESS 558 */
27/* SUPPRESS 590 */
28/* SUPPRESS 529 */
29/* SUPPRESS 530 */
30
31/* Align an address upward to a boundary, expressed as a number of bytes.
32 E.g. align to an 8-byte boundary with argument of 8. */
33#define ALIGN(this, boundary) \
34 ((( (this) + ((boundary) -1)) & (~((boundary)-1))))
35
36/* Align an address upward to a power of two. Argument is the power
37 of two, e.g. 8-byte alignment uses argument of 3 (8 == 2^3). */
38#define i960_align(addr, align) \
39 ( ((addr) + ((1<<(align))-1)) & (-1 << (align)))
40
41#define sp(x) bfd_h_put_x(abfd, x, &x)
42
43#define PUTWORD bfd_h_put_32
44#define PUTHALF bfd_h_put_16
45#ifndef I960
46#define GDB_EXPORT static
47#else
48#define GDB_EXPORT /* nothing */
49#endif
50
51PROTO(static void,force_indices_file_symbol_relative,(bfd *abfd,
52 struct internal_syment *symtab));
53
54\f
55/* void warning(); */
56extern asection abs_section;
57
58static int
59DEFUN(get_index,(symbol),
60 asymbol *symbol)
61{
62 return (int) symbol->value;
63}
64
65static void
66DEFUN(set_index,(symbol, idx),
67 asymbol *symbol AND
68 unsigned int idx)
69{
70 symbol->value = idx;
71}
72
73
74
75
76
77/* All the swapping routines:
78*/
79
80
81GDB_EXPORT
82void
83DEFUN(bfd_swap_reloc_in,(abfd, reloc_src, reloc_dst),
84 bfd *abfd AND
85 RELOC *reloc_src AND
86 struct internal_reloc *reloc_dst)
87{
88 reloc_dst->r_vaddr = bfd_h_get_32(abfd, reloc_src->r_vaddr);
89 reloc_dst->r_symndx = bfd_h_get_32(abfd, reloc_src->r_symndx);
90 reloc_dst->r_type = bfd_h_get_16(abfd, reloc_src->r_type);
91#if M88
92 reloc_dst->r_offset = bfd_h_get_16(abfd, reloc_src->r_offset);
93#endif
94}
95
96GDB_EXPORT
97 void
98DEFUN(bfd_swap_reloc_out,(abfd, reloc_src, reloc_dst),
99 bfd *abfd AND
100 struct internal_reloc *reloc_src AND
101 struct external_reloc *reloc_dst)
102{
103 bfd_h_put_32(abfd, reloc_src->r_vaddr, reloc_dst->r_vaddr);
104 bfd_h_put_32(abfd, reloc_src->r_symndx, reloc_dst->r_symndx);
105 bfd_h_put_16(abfd, reloc_src->r_type, reloc_dst->r_type);
106#if M88
107 bfd_h_put_16(abfd, reloc_src->r_offset, reloc_dst->r_offset);
108#endif
109
110}
111
112GDB_EXPORT void
113DEFUN(bfd_swap_filehdr_in,(abfd, filehdr_src, filehdr_dst),
114 bfd *abfd AND
115 FILHDR *filehdr_src AND
116 struct internal_filehdr *filehdr_dst)
117{
118 filehdr_dst->f_magic = bfd_h_get_16(abfd, filehdr_src->f_magic);
119 filehdr_dst->f_nscns = bfd_h_get_16(abfd,filehdr_src-> f_nscns);
120 filehdr_dst->f_timdat = bfd_h_get_32(abfd,filehdr_src-> f_timdat);
121 filehdr_dst->f_symptr = bfd_h_get_32(abfd,filehdr_src-> f_symptr);
122 filehdr_dst->f_nsyms = bfd_h_get_32(abfd,filehdr_src-> f_nsyms);
123 filehdr_dst->f_opthdr = bfd_h_get_16(abfd,filehdr_src-> f_opthdr);
124 filehdr_dst->f_flags = bfd_h_get_16(abfd,filehdr_src-> f_flags);
125}
126
127GDB_EXPORT void
128DEFUN(bfd_swap_filehdr_out,(abfd, filehdr_in, filehdr_out),
129 bfd *abfd AND
130 struct internal_filehdr *filehdr_in AND
131 FILHDR *filehdr_out)
132{
133 bfd_h_put_16(abfd, filehdr_in->f_magic, filehdr_out->f_magic);
134 bfd_h_put_16(abfd, filehdr_in->f_nscns, filehdr_out->f_nscns);
135 bfd_h_put_32(abfd, filehdr_in->f_timdat, filehdr_out->f_timdat);
136 bfd_h_put_32(abfd, filehdr_in->f_symptr, filehdr_out->f_symptr);
137 bfd_h_put_32(abfd, filehdr_in->f_nsyms, filehdr_out->f_nsyms);
138 bfd_h_put_16(abfd, filehdr_in->f_opthdr, filehdr_out->f_opthdr);
139 bfd_h_put_16(abfd, filehdr_in->f_flags, filehdr_out->f_flags);
140}
141
142
143GDB_EXPORT
144void
145DEFUN(bfd_coff_swap_sym_in,(abfd, ext, in),
146 bfd *abfd AND
147 SYMENT *ext AND
148 struct internal_syment *in)
149{
150 if( ext->e.e_name[0] == 0) {
151 in->_n._n_n._n_zeroes = 0;
152 in->_n._n_n._n_offset = bfd_h_get_32(abfd, ext->e.e.e_offset);
153 }
154 else {
155 memcpy(in->_n._n_name, ext->e.e_name, SYMNMLEN);
156 }
157 in->n_value = bfd_h_get_32(abfd, ext->e_value);
158 in->n_scnum = bfd_h_get_16(abfd, ext->e_scnum);
159 if (sizeof(ext->e_type) == 2){
160 in->n_type = bfd_h_get_16(abfd, ext->e_type);
161 }
162 else {
163 in->n_type = bfd_h_get_32(abfd, ext->e_type);
164 }
165 in->n_sclass = bfd_h_get_8(abfd, ext->e_sclass);
166 in->n_numaux = bfd_h_get_8(abfd, ext->e_numaux);
167}
168
169GDB_EXPORT void
170DEFUN(bfd_coff_swap_sym_out,(abfd,in, ext),
171 bfd *abfd AND
172 struct internal_syment *in AND
173 SYMENT *ext)
174{
175 if(in->_n._n_name[0] == 0) {
176 bfd_h_put_32(abfd, 0, ext->e.e.e_zeroes);
177 bfd_h_put_32(abfd, in->_n._n_n._n_offset, ext->e.e.e_offset);
178 }
179 else {
180 memcpy(ext->e.e_name, in->_n._n_name, SYMNMLEN);
181 }
182 bfd_h_put_32(abfd, in->n_value , ext->e_value);
183 bfd_h_put_16(abfd, in->n_scnum , ext->e_scnum);
184 if (sizeof(ext->e_type) == 2)
185 {
186 bfd_h_put_16(abfd, in->n_type , ext->e_type);
187 }
188 else
189 {
190 bfd_h_put_32(abfd, in->n_type , ext->e_type);
191 }
192 bfd_h_put_8(abfd, in->n_sclass , ext->e_sclass);
193 bfd_h_put_8(abfd, in->n_numaux , ext->e_numaux);
194}
195
196GDB_EXPORT void
197DEFUN(bfd_coff_swap_aux_in,(abfd, ext, type, class, in),
198 bfd *abfd AND
199 AUXENT *ext AND
200 int type AND
201 int class AND
202 union internal_auxent *in)
203{
204 switch (class) {
205 case C_FILE:
206 if (ext->x_file.x_fname[0] == 0) {
207 in->x_file.x_n.x_zeroes = 0;
208 in->x_file.x_n.x_offset = bfd_h_get_32(abfd, ext->x_file.x_n.x_offset);
209 }
210
211 break;
212 case C_STAT:
213#ifdef C_LEAFSTAT
214 case C_LEAFSTAT:
215#endif
216 case C_HIDDEN:
217 if (type == T_NULL) {
218 in->x_scn.x_scnlen = bfd_h_get_32(abfd, ext->x_scn.x_scnlen);
219 in->x_scn.x_nreloc = bfd_h_get_16(abfd, ext->x_scn.x_nreloc);
220 in->x_scn.x_nlinno = bfd_h_get_16(abfd, ext->x_scn.x_nlinno);
221 break;
222 }
223 default:
224 in->x_sym.x_tagndx = bfd_h_get_32(abfd, ext->x_sym.x_tagndx);
225 in->x_sym.x_tvndx = bfd_h_get_16(abfd, ext->x_sym.x_tvndx);
226
227 if (ISARY(type) || class == C_BLOCK) {
228 in->x_sym.x_fcnary.x_ary.x_dimen[0] = bfd_h_get_16(abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[0]);
229 in->x_sym.x_fcnary.x_ary.x_dimen[1] = bfd_h_get_16(abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[1]);
230 in->x_sym.x_fcnary.x_ary.x_dimen[2] = bfd_h_get_16(abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[2]);
231 in->x_sym.x_fcnary.x_ary.x_dimen[3] = bfd_h_get_16(abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[3]);
232 }
233 else {
234 in->x_sym.x_fcnary.x_fcn.x_lnnoptr = bfd_h_get_32(abfd, ext->x_sym.x_fcnary.x_fcn.x_lnnoptr);
235 in->x_sym.x_fcnary.x_fcn.x_endndx = bfd_h_get_32(abfd, ext->x_sym.x_fcnary.x_fcn.x_endndx);
236 }
237 if (ISFCN(type)) {
238 in->x_sym.x_misc.x_fsize = bfd_h_get_32(abfd, ext->x_sym.x_misc.x_fsize);
239 }
240 else {
241 in->x_sym.x_misc.x_lnsz.x_lnno = bfd_h_get_16(abfd, ext->x_sym.x_misc.x_lnsz.x_lnno);
242 in->x_sym.x_misc.x_lnsz.x_size = bfd_h_get_16(abfd, ext->x_sym.x_misc.x_lnsz.x_size);
243 }
244 }
245}
246
247GDB_EXPORT void
248DEFUN(bfd_coff_swap_aux_out,(abfd, in, type, class, ext),
249 bfd *abfd AND
250 union internal_auxent *in AND
251 int type AND
252 int class AND
253 AUXENT *ext)
254{
255 switch (class) {
256 case C_FILE:
257 if (in->x_file.x_fname[0] == 0) {
258 PUTWORD(abfd, 0, ext->x_file.x_n.x_zeroes );
259 PUTWORD(abfd, in->x_file.x_n.x_offset, ext->x_file.x_n.x_offset);
260 }
261
262 break;
263 case C_STAT:
264#ifdef C_LEAFSTAT
265 case C_LEAFSTAT:
266#endif
267 case C_HIDDEN:
268 if (type == T_NULL) {
269 PUTWORD(abfd, in->x_scn.x_scnlen, ext->x_scn.x_scnlen);
270 PUTWORD(abfd, in->x_scn.x_nreloc, ext->x_scn.x_nreloc);
271 PUTWORD(abfd, in->x_scn.x_nlinno, ext->x_scn.x_nlinno);
272 break;
273 }
274 default:
275 PUTWORD(abfd, in->x_sym.x_tagndx, ext->x_sym.x_tagndx);
276 PUTWORD(abfd, in->x_sym.x_tvndx , ext->x_sym.x_tvndx);
277
278 if (ISARY(type) || class == C_BLOCK) {
279 bfd_h_put_16(abfd, in->x_sym.x_fcnary.x_ary.x_dimen[0],ext->x_sym.x_fcnary.x_ary.x_dimen[0]);
280 bfd_h_put_16(abfd, in->x_sym.x_fcnary.x_ary.x_dimen[1],ext->x_sym.x_fcnary.x_ary.x_dimen[1]);
281 bfd_h_put_16(abfd, in->x_sym.x_fcnary.x_ary.x_dimen[2],ext->x_sym.x_fcnary.x_ary.x_dimen[2]);
282 bfd_h_put_16(abfd, in->x_sym.x_fcnary.x_ary.x_dimen[3],ext->x_sym.x_fcnary.x_ary.x_dimen[3]);
283 }
284 else {
285 PUTWORD(abfd, in->x_sym.x_fcnary.x_fcn.x_lnnoptr, ext->x_sym.x_fcnary.x_fcn.x_lnnoptr);
286 PUTWORD(abfd, in->x_sym.x_fcnary.x_fcn.x_endndx, ext->x_sym.x_fcnary.x_fcn.x_endndx);
287 }
288 if (ISFCN(type)) {
289 PUTWORD(abfd, in->x_sym.x_misc.x_fsize, ext->x_sym.x_misc.x_fsize);
290 }
291 else {
292 bfd_h_put_16(abfd, in->x_sym.x_misc.x_lnsz.x_lnno, ext->x_sym.x_misc.x_lnsz.x_lnno);
293 bfd_h_put_16(abfd, in->x_sym.x_misc.x_lnsz.x_size, ext->x_sym.x_misc.x_lnsz.x_size);
294 }
295 }
296}
297
298GDB_EXPORT void
299DEFUN(bfd_coff_swap_lineno_in,(abfd, ext, in),
300 bfd *abfd AND
301 LINENO *ext AND
302 struct internal_lineno *in)
303{
304 in->l_addr.l_symndx = bfd_h_get_32(abfd, ext->l_addr.l_symndx);
305 in->l_lnno = bfd_h_get_16(abfd, ext->l_lnno);
306}
307
308GDB_EXPORT void
309DEFUN(bfd_coff_swap_lineno_out,(abfd, in, ext),
310 bfd *abfd AND
311 struct internal_lineno *in AND
312 struct external_lineno *ext)
313{
314 PUTWORD(abfd, in->l_addr.l_symndx, ext->l_addr.l_symndx);
315 PUTHALF(abfd, in->l_lnno, ext->l_lnno);
316}
317
318
319
320
321GDB_EXPORT void
322DEFUN(bfd_swap_aouthdr_in,(abfd, aouthdr_ext, aouthdr_int),
323 bfd *abfd AND
324 AOUTHDR *aouthdr_ext AND
325 struct internal_aouthdr *aouthdr_int)
326{
327 aouthdr_int->magic = bfd_h_get_16(abfd, aouthdr_ext->magic);
328 aouthdr_int->vstamp = bfd_h_get_16(abfd, aouthdr_ext->vstamp);
329 aouthdr_int->tsize = bfd_h_get_32(abfd, aouthdr_ext->tsize);
330 aouthdr_int->dsize = bfd_h_get_32(abfd, aouthdr_ext->dsize);
331 aouthdr_int->bsize = bfd_h_get_32(abfd, aouthdr_ext->bsize);
332 aouthdr_int->entry = bfd_h_get_32(abfd, aouthdr_ext->entry);
333 aouthdr_int->text_start = bfd_h_get_32(abfd, aouthdr_ext->text_start);
334 aouthdr_int->data_start = bfd_h_get_32(abfd, aouthdr_ext->data_start);
335#ifdef I960
336 aouthdr_int->tagentries = bfd_h_get_32(abfd, aouthdr_ext->tagentries);
337#endif
338}
339
340GDB_EXPORT void
341DEFUN(bfd_swap_aouthdr_out,(abfd, aouthdr_in, aouthdr_out),
342 bfd *abfd AND
343 struct internal_aouthdr *aouthdr_in AND
344 AOUTHDR *aouthdr_out)
345{
346 bfd_h_put_16(abfd, aouthdr_in->magic, aouthdr_out->magic);
347 bfd_h_put_16(abfd, aouthdr_in->vstamp, aouthdr_out->vstamp);
348 bfd_h_put_32(abfd, aouthdr_in->tsize, aouthdr_out->tsize);
349 bfd_h_put_32(abfd, aouthdr_in->dsize, aouthdr_out->dsize);
350 bfd_h_put_32(abfd, aouthdr_in->bsize, aouthdr_out->bsize);
351 bfd_h_put_32(abfd, aouthdr_in->entry, aouthdr_out->entry);
352 bfd_h_put_32(abfd, aouthdr_in->text_start, aouthdr_out->text_start);
353 bfd_h_put_32(abfd, aouthdr_in->data_start, aouthdr_out->data_start);
354#ifdef I960
355 bfd_h_put_32(abfd, aouthdr_in->tagentries, aouthdr_out->tagentries);
356#endif
357}
358
359GDB_EXPORT void
360DEFUN(bfd_coff_swap_scnhdr_in,(abfd, scnhdr_ext, scnhdr_int),
361 bfd *abfd AND
362 SCNHDR *scnhdr_ext AND
363 struct internal_scnhdr *scnhdr_int)
364{
365 memcpy(scnhdr_int->s_name, scnhdr_ext->s_name, sizeof(scnhdr_int->s_name));
366 scnhdr_int->s_vaddr = bfd_h_get_32(abfd, scnhdr_ext->s_vaddr);
367 scnhdr_int->s_paddr = bfd_h_get_32(abfd, scnhdr_ext->s_paddr);
368 scnhdr_int->s_size = bfd_h_get_32(abfd, scnhdr_ext->s_size);
369 scnhdr_int->s_scnptr = bfd_h_get_32(abfd, scnhdr_ext->s_scnptr);
370 scnhdr_int->s_relptr = bfd_h_get_32(abfd, scnhdr_ext->s_relptr);
371 scnhdr_int->s_lnnoptr = bfd_h_get_32(abfd, scnhdr_ext->s_lnnoptr);
372 scnhdr_int->s_nreloc = bfd_h_get_16(abfd, scnhdr_ext->s_nreloc);
373 scnhdr_int->s_nlnno = bfd_h_get_16(abfd, scnhdr_ext->s_nlnno);
374 scnhdr_int->s_flags = bfd_h_get_32(abfd, scnhdr_ext->s_flags);
375#ifdef I960
376 scnhdr_int->s_align = bfd_h_get_32(abfd, scnhdr_ext->s_align);
377#endif
378}
379
380static void
381DEFUN(swap_scnhdr_out,(abfd, scnhdr_int, scnhdr_ext),
382 bfd *abfd AND
383 struct internal_scnhdr *scnhdr_int AND
384 SCNHDR *scnhdr_ext)
385{
386 memcpy(scnhdr_ext->s_name, scnhdr_int->s_name, sizeof(scnhdr_int->s_name));
387 PUTWORD(abfd, scnhdr_int->s_vaddr, scnhdr_ext->s_vaddr);
388 PUTWORD(abfd, scnhdr_int->s_paddr, scnhdr_ext->s_paddr);
389 PUTWORD(abfd, scnhdr_int->s_size, scnhdr_ext->s_size);
390 PUTWORD(abfd, scnhdr_int->s_scnptr, scnhdr_ext->s_scnptr);
391 PUTWORD(abfd, scnhdr_int->s_relptr, scnhdr_ext->s_relptr);
392 PUTWORD(abfd, scnhdr_int->s_lnnoptr, scnhdr_ext->s_lnnoptr);
393 PUTWORD(abfd, scnhdr_int->s_nreloc, scnhdr_ext->s_nreloc);
394 PUTHALF(abfd, scnhdr_int->s_nlnno, scnhdr_ext->s_nlnno);
395 PUTHALF(abfd, scnhdr_int->s_flags, scnhdr_ext->s_flags);
396#ifdef I960
397 PUTWORD(abfd, scnhdr_int->s_align, scnhdr_ext->s_align);
398#endif
399}
400
401/*
402 initialize a section structure with information peculiar to this
403 particular implementation of coff
404*/
405
406static boolean
407DEFUN(coff_new_section_hook,(abfd_ignore, section_ignore),
408 bfd *abfd_ignore AND
409 asection *section_ignore)
410{
411#ifdef MC88MAGIC
412 /* FIXME, shouldn't this ifdef be on something that says we are
413 actually COMPILING FOR an 88K coff file, rather than simply
414 knowing its magic number? */
415 /* Align to at least 16 bytes */
416 section_ignore->alignment_power = 4;
417#endif
418#if M68
419 section_ignore->alignment_power = 3;
420#endif
421 return true;
422}
423
424/* Take a section header read from a coff file (in HOST byte order),
425 and make a BFD "section" out of it. */
426static boolean
427DEFUN(make_a_section_from_file,(abfd, hdr),
428 bfd *abfd AND
429 struct internal_scnhdr *hdr)
430{
431 asection *return_section;
432
433 {
434 /* Assorted wastage to null-terminate the name, thanks AT&T! */
435 char *name = bfd_alloc(abfd, sizeof (hdr->s_name)+1);
436 if (name == NULL) {
437 bfd_error = no_memory;
438 return false;
439 }
440 strncpy(name, (char *) &hdr->s_name[0], sizeof (hdr->s_name));
441 name[sizeof (hdr->s_name)] = 0;
442
443 return_section = bfd_make_section(abfd, name);
444 }
445
446 /* s_paddr is presumed to be = to s_vaddr */
447#define assign(to, from) return_section->to = hdr->from
448 assign(vma, s_vaddr);
449 /* assign (vma, s_vaddr); */
450 assign(size, s_size);
451 assign(filepos, s_scnptr);
452 assign(rel_filepos, s_relptr);
453 assign(reloc_count, s_nreloc);
454#ifdef I960
455 {
456 /* FIXME, use a temp var rather than alignment_power */
457 assign(alignment_power, s_align);
458 {
459 unsigned int i;
460 for (i = 0; i < 32; i++) {
461 if ((1 << i) >= (int) (return_section->alignment_power)) {
462 return_section->alignment_power = i;
463 break;
464 }
465 }
466 }
467 }
468#endif
469 assign(line_filepos, s_lnnoptr);
470 /*
471 return_section->linesize = hdr->s_nlnno * sizeof (struct lineno);
472 */
473
474#undef assign
475 return_section->lineno_count = hdr->s_nlnno;
476 return_section->userdata = NULL;
477 return_section->next = (asection *) NULL;
478 return_section->flags = 0;
479 if ((hdr->s_flags & STYP_TEXT) || (hdr->s_flags & STYP_DATA))
480 return_section->flags = (SEC_LOAD | SEC_ALLOC);
481 else if (hdr->s_flags & STYP_BSS)
482 return_section->flags = SEC_ALLOC;
483
484 if (hdr->s_nreloc != 0)
485 return_section->flags |= SEC_RELOC;
486 if (hdr->s_scnptr != 0)
487 return_section->flags |= SEC_HAS_CONTENTS;
488 return true;
489}
490static boolean
491DEFUN(coff_mkobject,(abfd),
492 bfd *abfd)
493{
494 set_tdata (abfd, bfd_zalloc (abfd,sizeof(coff_data_type)));
495 if (coff_data(abfd) == 0) {
496 bfd_error = no_memory;
497 return false;
498 }
499 coff_data(abfd)->relocbase = 0;
500 return true;
501}
502
503static
504bfd_target *
505DEFUN(coff_real_object_p,(abfd, nscns, internal_f, internal_a),
506 bfd *abfd AND
507 unsigned nscns AND
508 struct internal_filehdr *internal_f AND
509 struct internal_aouthdr *internal_a)
510{
511 coff_data_type *coff;
512
513 size_t readsize; /* length of file_info */
514 SCNHDR *external_sections;
515
516 /* Build a play area */
517 if (coff_mkobject(abfd) != true)
518 return 0;
519 coff = coff_data(abfd);
520
521
522 external_sections = (SCNHDR *)bfd_alloc(abfd, readsize = (nscns * SCNHSZ));
523 if (bfd_read((PTR)external_sections, 1, readsize, abfd) != readsize) {
524 goto fail;
525 }
526
527
528
529 /* Now copy data as required; construct all asections etc */
530 coff->symbol_index_slew = 0;
531 coff->relocbase =0;
532 coff->raw_syment_count = 0;
533 coff->raw_linenos = 0;
534 coff->raw_syments = 0;
535 coff->sym_filepos =0;
536 coff->flags = internal_f->f_flags;
537 if (nscns != 0) {
538 unsigned int i;
539 for (i = 0; i < nscns; i++) {
540 struct internal_scnhdr tmp;
541 bfd_coff_swap_scnhdr_in(abfd, external_sections + i, &tmp);
542 make_a_section_from_file(abfd,&tmp);
543 }
544 }
545 /* Determine the machine architecture and type. */
546 abfd->obj_machine = 0;
547 switch (internal_f->f_magic) {
548#ifdef MIPS
549case MIPS_MAGIC_1:
550case MIPS_MAGIC_2:
551case MIPS_MAGIC_3:
552 abfd->obj_arch = bfd_arch_mips;
553 abfd->obj_machine = 0;
554 break;
555#endif
556
557#ifdef MC68MAGIC
558 case MC68MAGIC:
559 case M68MAGIC:
560 abfd->obj_arch = bfd_arch_m68k;
561 abfd->obj_machine = 68020;
562 break;
563#endif
564#ifdef MC88MAGIC
565 case MC88MAGIC:
566 case MC88DMAGIC:
567 case MC88OMAGIC:
568 abfd->obj_arch = bfd_arch_m88k;
569 abfd->obj_machine = 88100;
570 break;
571#endif
572#ifdef I960
573#ifdef I960ROMAGIC
574 case I960ROMAGIC:
575 case I960RWMAGIC:
576 abfd->obj_arch = bfd_arch_i960;
577 switch (F_I960TYPE & internal_f->f_flags)
578 {
579 default:
580 case F_I960CORE:
581 abfd->obj_machine = bfd_mach_i960_core;
582 break;
583 case F_I960KB:
584 abfd->obj_machine = bfd_mach_i960_kb_sb;
585 break;
586 case F_I960MC:
587 abfd->obj_machine = bfd_mach_i960_mc;
588 break;
589 case F_I960XA:
590 abfd->obj_machine = bfd_mach_i960_xa;
591 break;
592 case F_I960CA:
593 abfd->obj_machine = bfd_mach_i960_ca;
594 break;
595 case F_I960KA:
596 abfd->obj_machine = bfd_mach_i960_ka_sa;
597 break;
598
599 }
600 break;
601#endif
602#endif
603
604 default: /* Unreadable input file type */
605 abfd->obj_arch = bfd_arch_obscure;
606 break;
607 }
608
609 if (!(internal_f->f_flags & F_RELFLG))
610 abfd->flags |= HAS_RELOC;
611 if ((internal_f->f_flags & F_EXEC))
612 abfd->flags |= EXEC_P;
613 if (!(internal_f->f_flags & F_LNNO))
614 abfd->flags |= HAS_LINENO;
615 if (!(internal_f->f_flags & F_LSYMS))
616 abfd->flags |= HAS_LOCALS;
617
618
619 bfd_get_symcount(abfd) = internal_f->f_nsyms;
620 if (internal_f->f_nsyms)
621 abfd->flags |= HAS_SYMS;
622
623 coff->sym_filepos = internal_f->f_symptr;
624
625
626
627 coff->symbols = (coff_symbol_type *) NULL;
628 bfd_get_start_address(abfd) = internal_f->f_opthdr ? internal_a->entry : 0;
629
630 return abfd->xvec;
631 fail:
632 bfd_release(abfd, coff);
633 return (bfd_target *)NULL;
634}
635
636static bfd_target *
637DEFUN(coff_object_p,(abfd),
638 bfd *abfd)
639 {
640 int nscns;
641 FILHDR filehdr;
642 AOUTHDR opthdr;
643 struct internal_filehdr internal_f;
644 struct internal_aouthdr internal_a;
645
646 bfd_error = system_call_error;
647
648 /* figure out how much to read */
649 if (bfd_read((PTR) &filehdr, 1, FILHSZ, abfd) != FILHSZ)
650 return 0;
651
652 bfd_swap_filehdr_in(abfd, &filehdr, &internal_f);
653
654 if (BADMAG(internal_f)) {
655 bfd_error = wrong_format;
656 return 0;
657 }
658 nscns =internal_f.f_nscns;
659
660 if (internal_f.f_opthdr) {
661 if (bfd_read((PTR) &opthdr, 1,AOUTSZ, abfd) != AOUTSZ) {
662 return 0;
663 }
664 bfd_swap_aouthdr_in(abfd, &opthdr, &internal_a);
665 }
666
667 /* Seek past the opt hdr stuff */
668 bfd_seek(abfd, internal_f.f_opthdr + FILHSZ, SEEK_SET);
669
670 /* if the optional header is NULL or not the correct size then
671 quit; the only difference I can see between m88k dgux headers (MC88DMAGIC)
672 and Intel 960 readwrite headers (I960WRMAGIC) is that the
673 optional header is of a different size.
674
675 But the mips keeps extra stuff in it's opthdr, so dont check
676 when doing that
677 */
678
679#ifndef MIPS
680 if (internal_f.f_opthdr != 0 && AOUTSZ != internal_f.f_opthdr)
681 return (bfd_target *)NULL;
682#endif
683
684 return coff_real_object_p(abfd, nscns, &internal_f, &internal_a);
685 }
686
687
688
689
690/*
691Takes a bfd and a symbol, returns a pointer to the coff specific area
692of the symbol if there is one.
693*/
694static coff_symbol_type *
695DEFUN(coff_symbol_from,(abfd, symbol),
696 bfd *abfd AND
697 asymbol *symbol)
698{
699 if (symbol->the_bfd->xvec->flavour != bfd_target_coff_flavour_enum)
700 return (coff_symbol_type *)NULL;
701
702 if (symbol->the_bfd->tdata == (PTR)NULL)
703 return (coff_symbol_type *)NULL;
704
705 return (coff_symbol_type *) symbol;
706}
707
708
709
710
711
712
713
714static void
715DEFUN(coff_count_linenumbers,(abfd),
716 bfd *abfd)
717{
718 unsigned int limit = bfd_get_symcount(abfd);
719 unsigned int i;
720 asymbol **p;
721 {
722 asection *s = abfd->sections->output_section;
723 while (s) {
724 BFD_ASSERT(s->lineno_count == 0);
725 s = s->next;
726 }
727 }
728
729
730 for (p = abfd->outsymbols, i = 0; i < limit; i++, p++) {
731 asymbol *q_maybe = *p;
732 if (q_maybe->the_bfd->xvec->flavour == bfd_target_coff_flavour_enum) {
733 coff_symbol_type *q = coffsymbol(q_maybe);
734 if (q->lineno) {
735 /*
736 This symbol has a linenumber, increment the owning
737 section's linenumber count
738 */
739 alent *l = q->lineno;
740 q->symbol.section->output_section->lineno_count++;
741 l++;
742 while (l->line_number) {
743 q->symbol.section->output_section->lineno_count++;
744 l++;
745 }
746 }
747 }
748 }
749}
750
751/*
752 This function returns true if the supplied SYMENT has an AUXENT with
753 a tagndx field which should be relocated.
754
755 The coff book says that all auxents have this and should be moved,
756 but all the actual implementations I've looked at do this ..
757 (sac@cygnus.com)
758
759*/
760static boolean
761DEFUN(uses_x_sym_x_tagndx_p,(abfd, native),
762 bfd *abfd AND
763 struct internal_syment *native)
764{
765 if (BTYPE(native->n_type) == T_STRUCT) return true;
766 if (BTYPE(native->n_type) == T_UNION) return true;
767 if (BTYPE(native->n_type) == T_ENUM) return true;
768 return false;
769}
770
771
772/*
773This procedure runs through the native entries in a coff symbol table
774and links up all the elements which should point to one another, in
775particular these are:
776
777strtag, entag and untags have an auxent endindex which points to the
778first syment after the .eos. This is simple to do, we just keep a
779pointer to the symbol with the most recent pending strtag and patch it
780when we see the eos. This works since coff structs are never nested.
781
782ISFCN type entries have an endindex which points to the next static or
783extern in the table, thereby skipping the function contents.
784The coff book says that an ISFCN's tagindex
785points to the first .bf for the function, so far I havn't seen it
786used. We do this using the same mechanism as strtags.
787
788Each file entry has a value which points to the next file entry,
789the last file entry points to the first extern symbol in the table
790which is not an ISFCN.
791
792Each .bb entry points to the matching .eb entry, but these are nested
793so we keep a stack of them.
794
795The tagndx of .eos items points to the strtag attached to them, this
796is simply the last_tagndx again.
797
798The tagndx of items with type strtag point to the defining struct.
799This bit is complicated; We know that a struct ref and def must be
800within the same file, so all the natives will be in the same vector.
801This means that we can subtracts two pointers and get the index
802differences between to items, used to work out the true index of the
803target.
804
805We store in the name field of each syment the actual native index
806applied so we can dig it out through a pointer. */
807
808static void
809DEFUN(coff_mangle_symbols,(bfd_ptr),
810 bfd *bfd_ptr)
811{
812 unsigned int symbol_count = bfd_get_symcount(bfd_ptr);
813 asymbol **symbol_ptr_ptr = bfd_ptr->outsymbols;
814 struct internal_syment *last_tagndx = (struct internal_syment *)NULL;
815 struct internal_syment *last_file = (struct internal_syment *)NULL;
816 struct internal_syment *last_fcn = (struct internal_syment *)NULL;
817 struct internal_syment *block_stack[50];
818 struct internal_syment **last_block = &block_stack[0];
819 boolean first_time = true;
820 unsigned int symbol_index;
821 unsigned int native_index = 0;
822
823 for (symbol_index = 0; symbol_index < symbol_count; symbol_index++) {
824 coff_symbol_type *coff_symbol_ptr =
825 coff_symbol_from(bfd_ptr, symbol_ptr_ptr[symbol_index]);
826 if (coff_symbol_ptr == (coff_symbol_type *)NULL) {
827 /*
828 This symbol has no coff information in it, it will take up
829 only one slot in the output symbol table
830 */
831 native_index++;
832 }
833 else {
834 struct internal_syment *syment = coff_symbol_ptr->native;
835 if (syment == (struct internal_syment *)NULL) {
836 native_index++;
837 }
838 else {
839 /* Normalize the symbol flags */
840 if (coff_symbol_ptr->symbol.flags & BSF_FORT_COMM) {
841 /* a common symbol is undefined with a value */
842 syment->n_scnum = N_UNDEF;
843 syment->n_value = coff_symbol_ptr->symbol.value;
844 }
845 else if (coff_symbol_ptr->symbol.flags & BSF_DEBUGGING) {
846 syment->n_value = coff_symbol_ptr->symbol.value;
847 }
848 else if (coff_symbol_ptr->symbol.flags & BSF_UNDEFINED) {
849 syment->n_scnum = N_UNDEF;
850 syment->n_value = 0;
851 }
852 else if (coff_symbol_ptr->symbol.flags & BSF_ABSOLUTE) {
853 syment->n_scnum = N_ABS;
854 syment->n_value = coff_symbol_ptr->symbol.value;
855 }
856 else {
857 syment->n_scnum =
858 coff_symbol_ptr->symbol.section->output_section->index+1;
859
860 syment->n_value =
861 coff_symbol_ptr->symbol.value +
862 coff_symbol_ptr->symbol.section->output_offset +
863 coff_symbol_ptr->symbol.section->output_section->vma;
864 }
865
866
867 /* If this symbol ties up something then do it */
868
869 if (syment->n_sclass == C_FILE && last_file != (struct internal_syment *)NULL)
870 {
871 last_file->n_value = native_index;
872 }
873 else if ((syment->n_sclass == C_EXT
874 || syment->n_sclass == C_STAT
875#ifdef C_LEAFEXT
876 || syment->n_sclass == C_LEAFEXT
877 || syment->n_sclass == C_LEAFSTAT
878#endif
879 )
880 && last_fcn != (struct internal_syment *)NULL)
881 {
882 union internal_auxent *auxent = (union internal_auxent *)(last_fcn+1);
883 auxent->x_sym.x_fcnary.x_fcn.x_endndx = native_index;
884 last_fcn = (struct internal_syment *)NULL;
885
886 }
887 else if (syment->n_sclass == C_EOS && last_tagndx != (struct internal_syment*)NULL)
888 {
889 union internal_auxent *auxent = (union internal_auxent *)(last_tagndx+1);
890 /* Remember that we keep the native index in the offset
891 so patch the beginning of the struct to point to this
892 */
893 auxent->x_sym.x_tagndx = last_tagndx->_n._n_n._n_offset;
894 auxent->x_sym.x_fcnary.x_fcn.x_endndx = syment->n_numaux + 1 + native_index;
895 /* Now point the eos to the structure */
896 auxent = (union internal_auxent *)(syment+1);
897 auxent->x_sym.x_tagndx = last_tagndx->_n._n_n._n_offset;
898 }
899 else if (syment->n_sclass == C_BLOCK
900 && coff_symbol_ptr->symbol.name[1] == 'e')
901 {
902 union internal_auxent *auxent = (union internal_auxent *)((*(--last_block))+1);
903 auxent->x_sym.x_fcnary.x_fcn.x_endndx = native_index + syment->n_numaux + 1;
904 }
905 if (syment->n_sclass == C_EXT
906 && !ISFCN(syment->n_type)
907 && first_time == true
908 && last_file != (struct internal_syment *)NULL) {
909 /* This is the first external symbol seen which isn't a
910 function place it in the last .file entry */
911 last_file->n_value = native_index;
912 first_time = false;
913 }
914#ifdef C_LEAFPROC
915 if (syment->n_sclass == C_LEAFPROC &&
916 syment->n_numaux == 2) {
917 union internal_auxent *auxent = (union internal_auxent *)(syment+2);
918 /* This is the definition of a leaf proc, we'll relocate the
919 address */
920 auxent->x_bal.x_balntry =
921 coff_symbol_ptr->symbol.section->output_offset +
922 coff_symbol_ptr->symbol.section->output_section->vma +
923 auxent->x_bal.x_balntry ;
924 }
925#endif
926 /* If this symbol needs to be tied up then remember some facts */
927 if (syment->n_sclass == C_FILE)
928 {
929 last_file = syment;
930 }
931 if (syment->n_numaux != 0) {
932 /*
933 If this symbol would like to point to something in the
934 future then remember where it is
935 */
936 if (uses_x_sym_x_tagndx_p(bfd_ptr, syment)) {
937 /*
938 If this is a ref to a structure then we'll tie it up
939 now - there are never any forward refs for one
940 */
941 if (syment->n_sclass == C_STRTAG ||
942 syment->n_sclass == C_ENTAG ||
943 syment->n_sclass == C_UNTAG) {
944 last_tagndx = syment;
945 }
946 else {
947 /*
948 This is a ref to a structure - the structure must
949 have been defined within the same file, and previous
950 to this point, so we can deduce the new tagndx
951 directly.
952 */
953 union internal_auxent *auxent = (union internal_auxent *)(syment+1);
954 bfd *bfd_ptr = coff_symbol_ptr->symbol.the_bfd;
955 struct internal_syment *base = obj_raw_syments(bfd_ptr);
956 auxent->x_sym.x_tagndx = base[auxent->x_sym.x_tagndx]._n._n_n._n_offset;
957
958
959 }
960 }
961 if (ISFCN(syment->n_type)) {
962 last_fcn = syment;
963 }
964 if (syment->n_sclass == C_BLOCK
965 && coff_symbol_ptr->symbol.name[1] == 'b')
966 {
967 *last_block++ = syment;
968 }
969 }
970 syment->_n._n_n._n_offset = native_index;
971 native_index = native_index + 1 + syment->n_numaux;
972 }
973 }
974 }
975}
976
977
978static void
979DEFUN(coff_write_symbols,(abfd),
980bfd *abfd)
981{
982 unsigned int i;
983 unsigned int limit = bfd_get_symcount(abfd);
984 unsigned int written = 0;
985 struct internal_syment dummy;
986 asymbol **p;
987 unsigned int string_size = 0;
988
989
990 /* Seek to the right place */
991 bfd_seek(abfd, obj_sym_filepos(abfd), SEEK_SET);
992
993 /* Output all the symbols we have */
994
995 written = 0;
996 for (p = abfd->outsymbols, i = 0; i < limit; i++, p++) {
997 asymbol *symbol = *p;
998 coff_symbol_type *c_symbol = coff_symbol_from(abfd, symbol);
999
1000 unsigned int j;
1001 struct internal_syment *native;
1002 if (c_symbol == (coff_symbol_type *) NULL ||
1003 c_symbol->native == (struct internal_syment *) NULL) {
1004 /*
1005 This symbol has been created by the loader, or come from a non
1006 coff format. It has no native element to inherit, make our
1007 own
1008 */
1009
1010 native = &dummy;
1011 native->n_type = T_NULL;
1012#ifdef I960
1013 native->n_flags = 0;
1014#endif
1015 if (symbol->flags & BSF_ABSOLUTE) {
1016 native->n_scnum = N_ABS;
1017 native->n_value = symbol->value;
1018 }
1019 else if (symbol->flags & (BSF_UNDEFINED | BSF_FORT_COMM)) {
1020 native->n_scnum = N_UNDEF;
1021 native->n_value = symbol->value;
1022 }
1023 else if (symbol->flags & BSF_DEBUGGING) {
1024 /*
1025 remove name so it doesn't take up any space
1026 */
1027 symbol->name = "";
1028 continue;
1029 }
1030 else {
1031 native->n_scnum = symbol->section->output_section->index +
1032 1;
1033 native->n_value = symbol->value +
1034 symbol->section->output_section->vma +
1035 symbol->section->output_offset;
1036#ifdef I960
1037 /* Copy the any flags from the the file hdr into the symbol */
1038 {
1039 coff_symbol_type *c = coff_symbol_from(abfd, symbol);
1040 if (c != (coff_symbol_type *)NULL) {
1041 native->n_flags = c->symbol.the_bfd->flags;
1042 }
1043 }
1044#endif
1045 }
1046
1047#ifdef HASPAD1
1048 native->pad1[0] = 0;
1049 native->pad1[0] = 0;
1050#endif
1051
1052 native->n_type = 0;
1053 if (symbol->flags & BSF_LOCAL)
1054 native->n_sclass = C_STAT;
1055 else
1056 native->n_sclass = C_EXT;
1057 native->n_numaux = 0;
1058 }
1059 else
1060 /*
1061 Does this symbol have an ascociated line number - if so then
1062 make it remember this symbol index. Also tag the auxent of
1063 this symbol to point to the right place in the lineno table
1064 */
1065 {
1066 alent *lineno = c_symbol->lineno;
1067 native = c_symbol->native;
1068 if (lineno) {
1069 unsigned int count = 0;
1070 lineno[count].u.offset = written;
1071 if (native->n_numaux) {
1072 union internal_auxent *a = (union internal_auxent *) (native + 1);
1073
1074 a->x_sym.x_fcnary.x_fcn.x_lnnoptr =
1075 c_symbol->symbol.section->output_section->moving_line_filepos;
1076 }
1077 /*
1078 And count and relocate all other linenumbers
1079 */
1080 count++;
1081 while (lineno[count].line_number) {
1082 lineno[count].u.offset +=
1083 c_symbol->symbol.section->output_section->vma +
1084 c_symbol->symbol.section->output_offset;
1085 count++;
1086 }
1087 c_symbol->symbol.section->output_section->moving_line_filepos +=
1088 count * LINESZ;
1089
1090 }
1091 } /* if symbol new to coff */
1092
1093 /* Fix the symbol names */
1094 {
1095 unsigned int name_length;
1096 if (symbol->name == (char *) NULL) {
1097 /*
1098 coff symbols always have names, so we'll make one up
1099 */
1100 symbol->name = "strange";
1101 }
1102 name_length = strlen(symbol->name);
1103 if (name_length <= SYMNMLEN) {
1104 /* This name will fit into the symbol neatly */
1105 strncpy(native->_n._n_name, symbol->name, SYMNMLEN);
1106 }
1107 else {
1108 native->_n._n_n._n_offset = string_size + 4;
1109 native->_n._n_n._n_zeroes = 0;
1110 string_size += name_length + 1;
1111 }
1112 {
1113 unsigned int numaux = native->n_numaux;
1114 int type = native->n_type;
1115 int class = native->n_sclass;
1116 SYMENT buf;
1117 bfd_coff_swap_sym_out(abfd, native, &buf);
1118 bfd_write((PTR)& buf, 1, SYMESZ, abfd);
1119 for (j = 0; j != native->n_numaux;
1120 j++) {
1121 AUXENT buf1;
1122 bfd_coff_swap_aux_out(abfd,
1123 (union internal_auxent *)(native + j + 1), type, class, &buf1);
1124 bfd_write((PTR) (native + j + 1), 1, AUXESZ, abfd);
1125 }
1126 /*
1127 Reuse somewhere in the symbol to keep the index
1128 */
1129 set_index(symbol, written);
1130 written += 1 + numaux;
1131 }
1132 }
1133 } /* for each out symbol */
1134
1135 bfd_get_symcount(abfd) = written;
1136 /* Now write out strings */
1137
1138 if (string_size) {
1139 unsigned int size = string_size + 4;
1140 size = size;
1141 bfd_write((PTR) &size, 1, sizeof(size), abfd);
1142 for (p = abfd->outsymbols, i = 0; i < limit; i++, p++) {
1143 asymbol *q = *p;
1144 size_t name_length = strlen(q->name);
1145 if (name_length > SYMNMLEN) {
1146 bfd_write((PTR) (q->name), 1, name_length + 1, abfd);
1147 }
1148 }
1149 }
1150 else {
1151 /* We would normally not write anything here, but we'll write
1152 out 4 so that any stupid coff reader which tries to read
1153 the string table even when there isn't one won't croak.
1154 */
1155
1156 uint32e_type size = 4;
1157 size = size;
1158 bfd_write((PTR)&size, 1, sizeof(size), abfd);
1159
1160 }
1161
1162}
1163
1164static void
1165coff_write_relocs(abfd)
1166bfd *abfd;
1167 {
1168 asection *s;
1169 for (s = abfd->sections; s != (asection *) NULL; s = s->next) {
1170 unsigned int i;
1171 struct external_reloc dst;
1172
1173 arelent **p = s->orelocation;
1174 bfd_seek(abfd, s->rel_filepos, SEEK_SET);
1175 for (i = 0; i < s->reloc_count; i++) {
1176 struct internal_reloc n;
1177 arelent *q = p[i];
1178 memset((PTR)&n, 0, sizeof(n));
1179 n.r_vaddr = q->address + s->vma;
1180 if (q->sym_ptr_ptr) {
1181 n.r_symndx = get_index((*(q->sym_ptr_ptr)));
1182 }
1183#ifdef SELECT_RELOC
1184 /* Work out reloc type from what is required */
1185 SELECT_RELOC(n.r_type, q->howto);
1186#else
1187 n.r_type = q->howto->type;
1188#endif
1189 bfd_swap_reloc_out(abfd, &n, &dst);
1190 bfd_write((PTR) &n, 1, RELSZ, abfd);
1191 }
1192 }
1193 }
1194
1195static void
1196DEFUN(coff_write_linenumbers,(abfd),
1197 bfd *abfd)
1198 {
1199 asection *s;
1200 for (s = abfd->sections; s != (asection *) NULL; s = s->next) {
1201 if (s->lineno_count) {
1202 asymbol **q = abfd->outsymbols;
1203 bfd_seek(abfd, s->line_filepos, SEEK_SET);
1204 /* Find all the linenumbers in this section */
1205 while (*q) {
1206 asymbol *p = *q;
1207 alent *l = BFD_SEND(p->the_bfd, _get_lineno, (p->the_bfd, p));
1208 if (l) {
1209 /* Found a linenumber entry, output */
1210 struct internal_lineno out;
1211 LINENO buff;
1212 bzero( (PTR)&out, sizeof(out));
1213 out.l_lnno = 0;
1214 out.l_addr.l_symndx = l->u.offset;
1215 bfd_coff_swap_lineno_out(abfd, &out, &buff);
1216 bfd_write((PTR) &buff, 1, LINESZ, abfd);
1217 l++;
1218 while (l->line_number) {
1219 out.l_lnno = l->line_number;
1220 out.l_addr.l_symndx = l->u.offset;
1221 bfd_coff_swap_lineno_out(abfd, &out, &buff);
1222 bfd_write((PTR) &buff, 1, LINESZ, abfd);
1223 l++;
1224 }
1225 }
1226 q++;
1227 }
1228 }
1229 }
1230 }
1231
1232
1233static asymbol *
1234coff_make_empty_symbol(abfd)
1235bfd *abfd;
1236 {
1237 coff_symbol_type *new = (coff_symbol_type *) bfd_alloc(abfd, sizeof(coff_symbol_type));
1238 if (new == NULL) {
1239 bfd_error = no_memory;
1240 return (NULL);
1241 } /* on error */
1242 new->native = 0;
1243 new->lineno = (alent *) NULL;
1244 new->symbol.the_bfd = abfd;
1245 return &new->symbol;
1246 }
1247
1248static void
1249coff_print_symbol(ignore_abfd, file, symbol, how)
1250bfd *ignore_abfd;
1251FILE *file;
1252asymbol *symbol;
1253bfd_print_symbol_enum_type how;
1254 {
1255 switch (how) {
1256 case bfd_print_symbol_name_enum:
1257 fprintf(file, "%s", symbol->name);
1258 break;
1259 case bfd_print_symbol_type_enum:
1260 fprintf(file, "coff %lx %lx", (unsigned long) coffsymbol(symbol)->native,
1261 (unsigned long) coffsymbol(symbol)->lineno);
1262 break;
1263 case bfd_print_symbol_all_enum:
1264 {
1265 CONST char *section_name = symbol->section == (asection *) NULL ?
1266 "*abs" : symbol->section->name;
1267 bfd_print_symbol_vandf((PTR) file, symbol);
1268
1269 fprintf(file, " %-5s %s %s %s",
1270 section_name,
1271 coffsymbol(symbol)->native ? "n" : "g",
1272 coffsymbol(symbol)->lineno ? "l" : " ",
1273 symbol->name);
1274 }
1275
1276
1277 break;
1278 }
1279 }
1280
1281static alent *
1282coff_get_lineno(ignore_abfd, symbol)
1283bfd *ignore_abfd;
1284asymbol *symbol;
1285 {
1286 return coffsymbol(symbol)->lineno;
1287 }
1288
1289/*
1290Set flags and magic number of a coff file from architecture and machine
1291type. Result is true if we can represent the arch&type, false if not.
1292*/
1293static boolean
1294coff_set_flags(abfd, magicp, flagsp)
1295bfd *abfd;
1296unsigned *magicp,
1297*flagsp;
1298 {
1299
1300 switch (abfd->obj_arch) {
1301
1302#ifdef I960ROMAGIC
1303
1304 case bfd_arch_i960:
1305
1306 {
1307 unsigned flags;
1308 *magicp = I960ROMAGIC;
1309 /*
1310 ((bfd_get_file_flags(abfd) & WP_TEXT) ? I960ROMAGIC :
1311 I960RWMAGIC); FIXME???
1312 */
1313 switch (abfd->obj_machine) {
1314 case bfd_mach_i960_core:
1315 flags = F_I960CORE;
1316 break;
1317 case bfd_mach_i960_kb_sb:
1318 flags = F_I960KB;
1319 break;
1320 case bfd_mach_i960_mc:
1321 flags = F_I960MC;
1322 break;
1323 case bfd_mach_i960_xa:
1324 flags = F_I960XA;
1325 break;
1326 case bfd_mach_i960_ca:
1327 flags = F_I960CA;
1328 break;
1329 case bfd_mach_i960_ka_sa:
1330 flags = F_I960KA;
1331 break;
1332 default:
1333 return false;
1334 }
1335 *flagsp = flags;
1336 return true;
1337 }
1338 break;
1339#endif
1340#ifdef MIPS
1341 case bfd_arch_mips:
1342 *magicp = MIPS_MAGIC_2;
1343 return true;
1344 break;
1345#endif
1346#ifdef MC68MAGIC
1347 case bfd_arch_m68k:
1348 *magicp = MC68MAGIC;
1349 return true;
1350#endif
1351
1352#ifdef MC88MAGIC
1353 case bfd_arch_m88k:
1354 *magicp = MC88OMAGIC;
1355 return true;
1356 break;
1357#endif
1358
1359 default: /* Unknown architecture */
1360 return false;
1361 }
1362
1363 return false;
1364 }
1365
1366
1367static boolean
1368coff_set_arch_mach(abfd, arch, machine)
1369bfd *abfd;
1370enum bfd_architecture arch;
1371unsigned long machine;
1372 {
1373 unsigned dummy1,
1374 dummy2;
1375 abfd->obj_arch = arch;
1376 abfd->obj_machine = machine;
1377 if (arch != bfd_arch_unknown &&
1378 coff_set_flags(abfd, &dummy1, &dummy2) != true)
1379 return false; /* We can't represent this type */
1380 return true; /* We're easy ... */
1381 }
1382
1383
1384/* Calculate the file position for each section. */
1385
1386static void
1387coff_compute_section_file_positions(abfd)
1388bfd *abfd;
1389 {
1390 asection *current;
1391 file_ptr sofar = FILHSZ;
1392 if (bfd_get_start_address(abfd)) {
1393 /*
1394 A start address may have been added to the original file. In this
1395 case it will need an optional header to record it.
1396 */
1397 abfd->flags |= EXEC_P;
1398 }
1399 if (abfd->flags & EXEC_P)
1400 sofar += AOUTSZ;
1401
1402
1403 sofar += abfd->section_count * SCNHSZ;
1404
1405 for (current = abfd->sections; current != NULL; current =
1406 current->next) {
1407 /* Only deal with sections which have contents */
1408 if (!(current->flags & SEC_HAS_CONTENTS))
1409 continue;
1410
1411 /* Align the sections in the file to the same boundary on
1412 which they are aligned in virtual memory. I960 doesn't
1413 do this (FIXME) so we can stay in sync with Intel. 960
1414 doesn't yet page from files... */
1415#ifndef I960
1416 sofar = ALIGN(sofar, 1 << current->alignment_power);
1417#endif
1418 /* FIXME, in demand paged files, the low order bits of the file
1419 offset must match the low order bits of the virtual address.
1420 "Low order" is apparently implementation defined. Add code
1421 here to round sofar up to match the virtual address. */
1422
1423 current->filepos = sofar;
1424 sofar += current->size;
1425 }
1426 obj_relocbase(abfd) = sofar;
1427 }
1428
1429
1430
1431
1432/* SUPPRESS 558 */
1433/* SUPPRESS 529 */
1434static boolean
1435DEFUN(coff_write_object_contents,(abfd),
1436bfd *abfd)
1437{
1438 asection *current;
1439 boolean hasrelocs = false;
1440 boolean haslinno = false;
1441 file_ptr reloc_base;
1442 file_ptr lineno_base;
1443 file_ptr sym_base;
1444 file_ptr scn_base;
1445 file_ptr data_base;
1446 unsigned long reloc_size = 0;
1447 unsigned long lnno_size = 0;
1448 asection *text_sec = NULL;
1449 asection *data_sec = NULL;
1450 asection *bss_sec = NULL;
1451
1452 struct internal_filehdr internal_f;
1453 struct internal_aouthdr internal_a;
1454
1455 struct icofdata *coff = obj_icof(abfd);
1456
1457
1458 bfd_error = system_call_error;
1459
1460
1461 if(abfd->output_has_begun == false) {
1462 coff_compute_section_file_positions(abfd);
1463 }
1464
1465 if (abfd->sections != (asection *)NULL) {
1466 scn_base = abfd->sections->filepos;
1467 }
1468 else {
1469 scn_base = 0;
1470 }
1471 if (bfd_seek(abfd, scn_base, SEEK_SET) != 0)
1472 return false;
1473 reloc_base = obj_relocbase(abfd);
1474
1475 /* Make a pass through the symbol table to count line number entries and
1476 put them into the correct asections */
1477
1478 coff_count_linenumbers(abfd);
1479 data_base = scn_base;
1480
1481 /* Work out the size of the reloc and linno areas */
1482
1483 for (current = abfd->sections; current != NULL; current = current->next) {
1484 reloc_size += current->reloc_count * RELSZ;
1485 lnno_size += current->lineno_count * LINESZ;
1486 data_base += SCNHSZ;
1487 }
1488
1489 lineno_base = reloc_base + reloc_size;
1490 sym_base = lineno_base + lnno_size;
1491
1492 /* Indicate in each section->line_filepos its actual file address */
1493 for (current = abfd->sections; current != NULL; current = current->next) {
1494 if (current->lineno_count) {
1495 current->line_filepos = lineno_base;
1496 current->moving_line_filepos = lineno_base;
1497 lineno_base += current->lineno_count * LINESZ;
1498 }
1499 else {
1500 current->line_filepos = 0;
1501 }
1502 if (current->reloc_count) {
1503 current->rel_filepos = reloc_base;
1504 reloc_base += current->reloc_count * sizeof(struct internal_reloc);
1505 }
1506 else {
1507 current->rel_filepos = 0;
1508 }
1509 }
1510
1511 /* Write section headers to the file. */
1512
1513 bfd_seek(abfd,
1514 (file_ptr) ((abfd->flags & EXEC_P) ?
1515 (FILHSZ + AOUTSZ) : FILHSZ),
1516 SEEK_SET);
1517
1518 {
1519#if 0
1520 unsigned int pad = abfd->flags & D_PAGED ? data_base : 0;
1521#endif
1522 unsigned int pad = 0;
1523
1524 for (current = abfd->sections; current != NULL; current = current->next) {
1525 struct internal_scnhdr section;
1526 strncpy(&(section.s_name[0]), current->name, 8);
1527 section.s_vaddr = current->vma + pad;
1528 section.s_paddr = current->vma + pad;
1529 section.s_size = current->size - pad;
1530 /*
1531 If this section has no size or is unloadable then the scnptr
1532 will be 0 too
1533 */
1534 if (current->size - pad == 0 ||
1535 (current->flags & SEC_LOAD) == 0) {
1536 section.s_scnptr = 0;
1537
1538 }
1539 else {
1540 section.s_scnptr = current->filepos;
1541 }
1542 section.s_relptr = current->rel_filepos;
1543 section.s_lnnoptr = current->line_filepos;
1544 section.s_nreloc = current->reloc_count;
1545 section.s_nlnno = current->lineno_count;
1546 if (current->reloc_count != 0)
1547 hasrelocs = true;
1548 if (current->lineno_count != 0)
1549 haslinno = true;
1550
1551 if (!strcmp(current->name, _TEXT)) {
1552 text_sec = current;
1553 section.s_flags = STYP_TEXT; /* kinda stupid */
1554 }
1555 else if (!strcmp(current->name, _DATA)) {
1556 data_sec = current;
1557 section.s_flags = STYP_DATA; /* kinda stupid */
1558 }
1559 else if (!strcmp(current->name, _BSS)) {
1560 bss_sec = current;
1561 section.s_flags = STYP_BSS; /* kinda stupid */
1562 }
1563
1564
1565#ifdef I960
1566 section.s_align = (current->alignment_power
1567 ? 1 << current->alignment_power
1568 : 0);
1569
1570#endif
1571 {
1572 SCNHDR buff;
1573
1574 swap_scnhdr_out(abfd, &section, &buff);
1575 bfd_write((PTR) (&buff), 1, SCNHSZ, abfd);
1576
1577 }
1578 pad = 0;
1579 }
1580 }
1581
1582 /* OK, now set up the filehdr... */
1583 internal_f.f_nscns = abfd->section_count;
1584 /*
1585 We will NOT put a fucking timestamp in the header here. Every time you
1586 put it back, I will come in and take it out again. I'm sorry. This
1587 field does not belong here. We fill it with a 0 so it compares the
1588 same but is not a reasonable time. -- gnu@cygnus.com
1589 */
1590 /*
1591 Well, I like it, so I'm conditionally compiling it in.
1592 steve@cygnus.com
1593 */
1594#ifdef COFF_TIMESTAMP
1595 internal_f.f_timdat = time(0);
1596#else
1597 internal_f.f_timdat = 0;
1598#endif
1599
1600 if (bfd_get_symcount(abfd) != 0)
1601 internal_f.f_symptr = sym_base;
1602 else
1603 internal_f.f_symptr = 0;
1604
1605 internal_f.f_flags = 0;
1606
1607 if (abfd->flags & EXEC_P)
1608 internal_f.f_opthdr = AOUTSZ;
1609 else
1610 internal_f.f_opthdr = 0;
1611
1612 if (!hasrelocs)
1613 internal_f.f_flags |= F_RELFLG;
1614 if (!haslinno)
1615 internal_f.f_flags |= F_LNNO;
1616 if (0 == bfd_get_symcount(abfd))
1617 internal_f.f_flags |= F_LSYMS;
1618 if (abfd->flags & EXEC_P)
1619 internal_f.f_flags |= F_EXEC;
1620#if M88
1621 internal_f.f_flags |= F_AR32W;
1622#else
1623 if (!abfd->xvec->byteorder_big_p)
1624 internal_f.f_flags |= F_AR32WR;
1625#endif
1626 /*
1627 FIXME, should do something about the other byte orders and
1628 architectures.
1629 */
1630
1631 /* Set up architecture-dependent stuff */
1632
1633 { int magic = 0;
1634 int flags = 0;
1635 coff_set_flags(abfd, &magic, &flags);
1636 internal_f.f_magic = magic;
1637 internal_f.f_flags = flags;
1638
1639 /* ...and the "opt"hdr... */
1640
1641#ifdef I960
1642 internal_a.magic = (magic == I960ROMAGIC ? NMAGIC : OMAGIC);
1643#endif
1644#if M88
1645 internal_a.magic = PAGEMAGICBCS;
1646#endif
1647 }
1648 /* Now should write relocs, strings, syms */
1649 obj_sym_filepos(abfd) = sym_base;
1650
1651 if (bfd_get_symcount(abfd) != 0) {
1652 coff_mangle_symbols(abfd);
1653 coff_write_symbols(abfd);
1654 coff_write_linenumbers(abfd);
1655 coff_write_relocs(abfd);
1656 }
1657 if (text_sec) {
1658 internal_a.tsize = text_sec->size;
1659 internal_a.text_start =text_sec->size ? text_sec->vma : 0;
1660 }
1661 if (data_sec) {
1662 internal_a.dsize = data_sec->size;
1663 internal_a.data_start = data_sec->size ? data_sec->vma : 0;
1664 }
1665 if (bss_sec) {
1666 internal_a.bsize = bss_sec->size;
1667 }
1668
1669 internal_a.entry = bfd_get_start_address(abfd);
1670 internal_f.f_nsyms = bfd_get_symcount(abfd);
1671
1672 /* now write them */
1673 if (bfd_seek(abfd, 0L, SEEK_SET) != 0)
1674 return false;
1675 {
1676 FILHDR buff;
1677 bfd_swap_filehdr_out(abfd, &internal_f, &buff);
1678 bfd_write((PTR) &buff, 1, FILHSZ, abfd);
1679 }
1680 if (abfd->flags & EXEC_P) {
1681 AOUTHDR buff;
1682 bfd_swap_aouthdr_out(abfd, &internal_a, &buff);
1683 bfd_write((PTR) &buff, 1, AOUTSZ, abfd);
1684 }
1685 return true;
1686}
1687
1688static boolean
1689coff_set_section_contents(abfd, section, location, offset, count)
1690 bfd *abfd;
1691 sec_ptr section;
1692 PTR location;
1693 file_ptr offset;
1694 size_t count;
1695{
1696 if (abfd->output_has_begun == false) /* set by bfd.c handler */
1697 coff_compute_section_file_positions(abfd);
1698
1699 bfd_seek(abfd, (file_ptr) (section->filepos + offset), SEEK_SET);
1700
1701 if (count != 0) {
1702 return (bfd_write(location, 1, count, abfd) == count) ? true : false;
1703 }
1704 return true;
1705}
1706#if 0
1707static boolean
1708coff_close_and_cleanup(abfd)
1709 bfd *abfd;
1710{
1711 if (!bfd_read_p(abfd))
1712 switch (abfd->format) {
1713 case bfd_archive:
1714 if (!_bfd_write_archive_contents(abfd))
1715 return false;
1716 break;
1717 case bfd_object:
1718 if (!coff_write_object_contents(abfd))
1719 return false;
1720 break;
1721 default:
1722 bfd_error = invalid_operation;
1723 return false;
1724 }
1725
1726 /* We depend on bfd_close to free all the memory on the obstack. */
1727 /* FIXME if bfd_release is not using obstacks! */
1728 return true;
1729}
1730
1731#endif
1732static PTR
1733buy_and_read(abfd, where, seek_direction, size)
1734 bfd *abfd;
1735 file_ptr where;
1736 int seek_direction;
1737 size_t size;
1738{
1739 PTR area = (PTR) bfd_alloc(abfd, size);
1740 if (!area) {
1741 bfd_error = no_memory;
1742 return (NULL);
1743 }
1744 bfd_seek(abfd, where, seek_direction);
1745 if (bfd_read(area, 1, size, abfd) != size) {
1746 bfd_error = system_call_error;
1747 return (NULL);
1748 } /* on error */
1749 return (area);
1750} /* buy_and_read() */
1751
1752static void
1753DEFUN(offset_symbol_indices,(abfd, symtab, count, offset),
1754 bfd *abfd AND
1755 struct internal_syment *symtab AND
1756 unsigned long count AND
1757 long offset)
1758{
1759 struct internal_syment *end = symtab + count;
1760 for (; symtab < end; ++symtab) {
1761 if (symtab->n_sclass == C_FILE) {
1762 symtab->n_value = 0;
1763 }
1764 else if (symtab->n_sclass == C_ALIAS) {
1765 /*
1766 These guys have indices in their values.
1767 */
1768 symtab->n_value = symtab->n_value + offset;
1769 }
1770 else if (symtab->n_numaux) {
1771 /*
1772 anybody else without an aux, has no indices.
1773 */
1774
1775 if (symtab->n_sclass == C_EOS
1776 || (BTYPE(symtab->n_type) == T_STRUCT
1777 && symtab->n_sclass != C_STRTAG)
1778 || BTYPE(symtab->n_type) == T_UNION
1779 || BTYPE(symtab->n_type) == T_ENUM) {
1780 /* If the tagndx is 0 then the struct hasn't really been
1781 defined, so leave it alone */
1782
1783 if(((union internal_auxent *) (symtab + 1))->x_sym.x_tagndx != 0) {
1784 ((union internal_auxent *) (symtab + 1))->x_sym.x_tagndx += offset;
1785 }
1786
1787 } /* These guys have a tagndx */
1788 if (symtab->n_sclass == C_STRTAG
1789 || symtab->n_sclass == C_UNTAG
1790 || symtab->n_sclass == C_ENTAG
1791 || symtab->n_sclass == C_BLOCK
1792 || symtab->n_sclass == C_FCN
1793 || ISFCN(symtab->n_type)) {
1794
1795 ((union internal_auxent *) (symtab +
1796 1))->x_sym.x_fcnary.x_fcn.x_endndx
1797 += offset;
1798
1799 } /* These guys have an endndx */
1800#ifndef I960
1801 if (ISFCN(symtab->n_type)) {
1802 ((union internal_auxent *) (symtab + 1))->x_sym.x_tvndx += offset;
1803 } /* These guys have a tvndx. I think...
1804 (FIXME) */
1805#endif /* Not I960 */
1806
1807 } /* if value, else if aux */
1808 symtab += symtab->n_numaux;
1809 } /* walk the symtab */
1810
1811 return;
1812} /* offset_symbol_indices() */
1813
1814#if 0
1815/* swap the entire symbol table - we c*/
1816static void
1817swap_raw_symtab(abfd, raw_symtab)
1818bfd *abfd;
1819SYMENT *raw_symtab;
1820 {
1821 long i;
1822 SYMENT *end = raw_symtab + bfd_get_symcount(abfd);
1823 for (; raw_symtab < end; ++raw_symtab) {
1824 bfd_coff_swap_sym(abfd, raw_symtab);
1825
1826 for (i = raw_symtab->n_numaux; i; --i, ++raw_symtab) {
1827 bfd_coff_swap_aux(abfd,
1828 (AUXENT *)(raw_symtab + 1),
1829 raw_symtab->n_type,
1830 raw_symtab->n_sclass);
1831 } /* swap all the aux entries */
1832 } /* walk the symbol table */
1833
1834 return;
1835 } /* swap_raw_symtab() */
1836#endif
1837/*
1838read a symbol table into freshly mallocated memory, swap it, and knit the
1839symbol names into a normalized form. By normalized here I mean that all
1840symbols have an n_offset pointer that points to a NULL terminated string.
1841Oh, and the first symbol MUST be a C_FILE. If there wasn't one there
1842before, put one there.
1843*/
1844
1845static struct internal_syment *
1846DEFUN(get_normalized_symtab,(abfd),
1847bfd *abfd)
1848{
1849
1850 struct internal_syment *internal;
1851 struct internal_syment *internal_ptr;
1852 struct internal_syment *internal_end;
1853 SYMENT *raw;
1854 SYMENT *raw_src;
1855 SYMENT *raw_end;
1856 char *string_table = NULL;
1857 unsigned long size;
1858 char string_table_size_buffer[4];
1859 unsigned long string_table_size = 0;
1860 unsigned int raw_size;
1861 if (obj_raw_syments(abfd) != (struct internal_syment *)NULL) {
1862 return obj_raw_syments(abfd);
1863 }
1864 if ((size = bfd_get_symcount(abfd) * sizeof(struct internal_syment)) == 0) {
1865 bfd_error = no_symbols;
1866 return (NULL);
1867 }
1868
1869 internal = (struct internal_syment *)bfd_alloc(abfd, size);
1870 internal_end = internal + bfd_get_symcount(abfd);
1871
1872 raw_size = bfd_get_symcount(abfd) * SYMESZ;
1873 raw = (SYMENT *)bfd_alloc(abfd,raw_size);
1874
1875 if (bfd_seek(abfd, obj_sym_filepos(abfd), SEEK_SET) == -1
1876 || bfd_read((PTR)raw, raw_size, 1, abfd) != raw_size) {
1877 bfd_error = system_call_error;
1878 return (NULL);
1879 }
1880 /* mark the end of the symbols */
1881 raw_end = raw + bfd_get_symcount(abfd);
1882 /*
1883 FIXME SOMEDAY. A string table size of zero is very weird, but
1884 probably possible. If one shows up, it will probably kill us.
1885 */
1886
1887 /* Swap all the raw entries */
1888 for (raw_src = raw, internal_ptr = internal; raw_src < raw_end; raw_src++, internal_ptr++) {
1889 unsigned int i;
1890 bfd_coff_swap_sym_in(abfd, raw_src,internal_ptr);
1891 for (i = internal_ptr->n_numaux; i; --i, raw_src++, internal_ptr++) {
1892 bfd_coff_swap_aux_in(abfd, (AUXENT *)(raw_src +1), internal_ptr->n_type,
1893 internal_ptr->n_sclass, (union
1894 internal_auxent *)(internal_ptr +1));
1895 }
1896 }
1897
1898 /* Free all the raw stuff */
1899 bfd_release(abfd, raw_src);
1900
1901 for (internal_ptr = internal; internal_ptr < internal_end; internal_ptr ++) {
1902
1903 if (internal_ptr->_n._n_n._n_zeroes != 0) {
1904 /*
1905 This is a "short" name. Make it long.
1906 */
1907 unsigned long i = 0;
1908 char *newstring = NULL;
1909 /*
1910 find the length of this string without walking into memory
1911 that isn't ours.
1912 */
1913
1914 for (i = 0; i < 8; ++i) {
1915 if (internal_ptr->_n._n_name[i] == '\0') {
1916 break;
1917 } /* if end of string */
1918 } /* possible lengths of this string. */
1919
1920 if ((newstring = (PTR) bfd_alloc(abfd, ++i)) == NULL) {
1921 bfd_error = no_memory;
1922 return (NULL);
1923 } /* on error */
1924 bzero(newstring, i);
1925 strncpy(newstring, internal_ptr->_n._n_name, i-1);
1926 internal_ptr->_n._n_n._n_offset = (int) newstring;
1927 internal_ptr->_n._n_n._n_zeroes = 0;
1928
1929 }
1930 else {
1931 if (string_table == NULL) {
1932 /*
1933 NOTE: we don't read the string table until now because we
1934 don't necessarily know that we have one until now.
1935 */
1936 /*
1937 At this point we should be "seek"'d to the end of the
1938 symbols === the symbol table size.
1939 */
1940
1941 if (bfd_read((char *) string_table_size_buffer,
1942 sizeof(string_table_size_buffer),
1943 1, abfd) != sizeof(string_table_size)) {
1944 bfd_error = system_call_error;
1945 return (NULL);
1946 } /* on error */
1947
1948 string_table_size = bfd_h_get_32(abfd, string_table_size_buffer);
1949
1950 if ((string_table = (PTR) bfd_alloc(abfd, string_table_size -= 4)) == NULL) {
1951 bfd_error = no_memory;
1952 return (NULL);
1953 } /* on mallocation error */
1954 if (bfd_read(string_table, string_table_size, 1, abfd) != string_table_size) {
1955 bfd_error = system_call_error;
1956 return (NULL);
1957 } /* on error */
1958 } /* have not yet read the string table. */
1959 /*
1960 This is a long name already. Just point it at the string in
1961 memory.
1962 */
1963 internal_ptr->_n._n_n._n_offset = (int) (string_table - 4 + internal_ptr->_n._n_n._n_offset);
1964
1965 } /* switch on type of symbol name */
1966
1967 internal_ptr += internal_ptr->n_numaux;
1968 } /* for each symbol */
1969#if 0
1970#ifndef GNU960
1971 /* I'm not sure of the repercussions of this, so the Intel
1972 folks will always do the force
1973 */
1974 if (obj_symbol_slew(abfd) > 0)
1975 force_indices_file_symbol_relative(abfd, internal);
1976#else
1977 force_indices_file_symbol_relative(abfd, internal);
1978#endif
1979#endif
1980 obj_raw_syments(abfd) = internal;
1981 obj_string_table(abfd) = string_table;
1982
1983 return (internal);
1984} /* get_normalized_symtab() */
1985
1986static
1987struct sec *
1988DEFUN(section_from_bfd_index,(abfd, index),
1989 bfd *abfd AND
1990 int index)
1991{
1992 if (index > 0) {
1993 struct sec *answer = abfd->sections;
1994 while (--index) {
1995 answer = answer->next;
1996 }
1997 return answer;
1998 }
1999 return 0;
2000}
2001
2002
2003
2004
2005static boolean
2006coff_slurp_line_table(abfd, asect)
2007bfd *abfd;
2008asection *asect;
2009 {
2010 LINENO *native_lineno;
2011 alent *lineno_cache;
2012
2013 BFD_ASSERT(asect->lineno == (alent *) NULL);
2014
2015 native_lineno = (LINENO *) buy_and_read(abfd,
2016 asect->line_filepos,
2017 SEEK_SET,
2018 (size_t) (LINESZ *
2019 asect->lineno_count));
2020 lineno_cache =
2021 (alent *) bfd_alloc(abfd, (size_t) ((asect->lineno_count + 1) * sizeof(alent)));
2022 if (lineno_cache == NULL) {
2023 bfd_error = no_memory;
2024 return false;
2025 } else {
2026 unsigned int counter = 0;
2027 alent *cache_ptr = lineno_cache;
2028 LINENO *src = native_lineno;
2029
2030 while (counter < asect->lineno_count) {
2031 struct internal_lineno dst;
2032 bfd_coff_swap_lineno_in(abfd, src, &dst);
2033 cache_ptr->line_number = dst.l_lnno;
2034
2035 if (cache_ptr->line_number == 0) {
2036 coff_symbol_type *sym =
2037 (coff_symbol_type *) (dst.l_addr.l_symndx
2038 + obj_symbol_slew(abfd)
2039 + obj_raw_syments(abfd))->_n._n_n._n_zeroes;
2040 cache_ptr->u.sym = (asymbol *) sym;
2041 sym->lineno = cache_ptr;
2042 }
2043 else {
2044 cache_ptr->u.offset = dst.l_addr.l_paddr
2045 - bfd_section_vma(abfd, asect);
2046 } /* If no linenumber expect a symbol index */
2047
2048 cache_ptr++;
2049 src++;
2050 counter++;
2051 }
2052 cache_ptr->line_number = 0;
2053
2054 }
2055 asect->lineno = lineno_cache;
2056 /* FIXME, free native_lineno here, or use alloca or something. */
2057 return true;
2058 } /* coff_slurp_line_table() */
2059
2060#if 0
2061static struct internal_syment *
2062DEFUN(find_next_file_symbol,(abfd, current, end),
2063 bfd *abfd AND
2064 struct internal_syment *current AND
2065 struct internal_syment *end)
2066{
2067 current += current->n_numaux + 1;
2068
2069 while (current < end) {
2070 if (current->n_sclass== C_FILE) {
2071 return (current);
2072 }
2073 current += current->n_numaux + 1;
2074 }
2075 return end;
2076}
2077#endif
2078
2079/*
2080Note that C_FILE symbols can, and some do, have more than 1 aux entry.
2081*/
2082#if 0
2083static void
2084DEFUN(force_indices_file_symbol_relative,(abfd, symtab),
2085 bfd *abfd AND
2086 struct internal_syment *symtab)
2087{
2088 struct internal_syment *end = symtab + bfd_get_symcount(abfd);
2089 struct internal_syment *current;
2090 struct internal_syment *next;
2091 /* the first symbol had damn well better be a C_FILE. */
2092 BFD_ASSERT(symtab->n_sclass == C_FILE);
2093
2094 for (current = find_next_file_symbol(abfd, symtab, end);
2095 current < end;
2096 current = next) {
2097 offset_symbol_indices(abfd, current,
2098 ((next =
2099 find_next_file_symbol(abfd, current,
2100 end)) - current),
2101 symtab - current);
2102 }
2103 return;
2104}
2105#endif
2106static boolean
2107DEFUN(coff_slurp_symbol_table,(abfd),
2108 bfd *abfd)
2109 {
2110 struct internal_syment *native_symbols;
2111 coff_symbol_type *cached_area;
2112 unsigned int *table_ptr;
2113
2114 unsigned int number_of_symbols = 0;
2115 if (obj_symbols(abfd))
2116 return true;
2117 bfd_seek(abfd, obj_sym_filepos(abfd), SEEK_SET);
2118
2119 /* Read in the symbol table */
2120 if ((native_symbols = get_normalized_symtab(abfd)) == NULL) {
2121 return (false);
2122 } /* on error */
2123
2124
2125 /* Allocate enough room for all the symbols in cached form */
2126 cached_area =
2127 (coff_symbol_type *)
2128 bfd_alloc(abfd, (size_t) (bfd_get_symcount(abfd) * sizeof(coff_symbol_type)));
2129
2130 if (cached_area == NULL) {
2131 bfd_error = no_memory;
2132 return false;
2133 } /* on error */
2134 table_ptr =
2135 (unsigned int *)
2136 bfd_alloc(abfd, (size_t) (bfd_get_symcount(abfd) * sizeof(unsigned int)));
2137
2138 if (table_ptr == NULL) {
2139 bfd_error = no_memory;
2140 return false;
2141 } else {
2142 coff_symbol_type *dst = cached_area;
2143 unsigned int last_native_index = bfd_get_symcount(abfd);
2144 unsigned int this_index = 0;
2145 while (this_index < last_native_index) {
2146 struct internal_syment *src = native_symbols + this_index;
2147 table_ptr[this_index] = number_of_symbols;
2148 dst->symbol.the_bfd = abfd;
2149
2150 dst->symbol.name = (char *)(src->_n._n_n._n_offset);
2151 /*
2152 We use the native name field to point to the cached field
2153 */
2154 src->_n._n_n._n_zeroes = (int) dst;
2155 dst->symbol.section = section_from_bfd_index(abfd,
2156 src->n_scnum);
2157 switch (src->n_sclass) {
2158#ifdef I960
2159 case C_LEAFEXT:
2160#if 0
2161 dst->symbol.value = src->n_value - dst->symbol.section->vma;
2162 dst->symbol.flags = BSF_EXPORT | BSF_GLOBAL;
2163 dst->symbol.flags |= BSF_NOT_AT_END;
2164#endif
2165 /* Fall through to next case */
2166
2167#endif
2168
2169 case C_EXT:
2170 if ((src->n_scnum) == 0) {
2171 if ((src->n_value) == 0) {
2172 dst->symbol.flags = BSF_UNDEFINED;
2173 dst->symbol.value= 0;
2174 }
2175 else {
2176 dst->symbol.flags = BSF_FORT_COMM;
2177 dst->symbol.value = (src->n_value);
2178 }
2179 }
2180 else {
2181 /*
2182 Base the value as an index from the base of the
2183 section
2184 */
2185 if (dst->symbol.section == (asection *) NULL) {
2186 dst->symbol.flags = BSF_EXPORT | BSF_GLOBAL | BSF_ABSOLUTE;
2187 dst->symbol.value = src->n_value;
2188 }
2189 else {
2190 dst->symbol.flags = BSF_EXPORT | BSF_GLOBAL;
2191 dst->symbol.value = src->n_value - dst->symbol.section->vma;
2192 }
2193 if (ISFCN((src->n_type))) {
2194 /*
2195 A function ext does not go at the end of a file
2196 */
2197 dst->symbol.flags |= BSF_NOT_AT_END;
2198 }
2199 }
2200
2201 break;
2202 case C_STAT: /* static */
2203#ifdef I960
2204 case C_LEAFSTAT: /* static leaf procedure */
2205#endif
2206 case C_LABEL: /* label */
2207 dst->symbol.flags = BSF_LOCAL;
2208 /*
2209 Base the value as an index from the base of the section
2210 */
2211 dst->symbol.value = (src->n_value) - dst->symbol.section->vma;
2212 break;
2213
2214 case C_MOS: /* member of structure */
2215 case C_EOS: /* end of structure */
2216 case C_REGPARM: /* register parameter */
2217 case C_REG: /* register variable */
2218#ifdef C_AUTOARG
2219 case C_AUTOARG: /* 960-specific storage class */
2220#endif
2221 case C_TPDEF: /* type definition */
2222
2223 case C_ARG:
2224 case C_AUTO: /* automatic variable */
2225 case C_FIELD: /* bit field */
2226 case C_ENTAG: /* enumeration tag */
2227 case C_MOE: /* member of enumeration */
2228 case C_MOU: /* member of union */
2229 case C_UNTAG: /* union tag */
2230
2231 dst->symbol.flags = BSF_DEBUGGING;
2232 dst->symbol.value = (src->n_value);
2233 break;
2234
2235 case C_FILE: /* file name */
2236 case C_STRTAG: /* structure tag */
2237 dst->symbol.flags = BSF_DEBUGGING;
2238 dst->symbol.value = (src->n_value);
2239
2240 break;
2241 case C_BLOCK: /* ".bb" or ".eb" */
2242 case C_FCN: /* ".bf" or ".ef" */
2243 dst->symbol.flags = BSF_LOCAL;
2244 /*
2245 Base the value as an index from the base of the section
2246 */
2247 dst->symbol.value = (src->n_value) - dst->symbol.section->vma;
2248
2249 break;
2250 case C_EFCN: /* physical end of function */
2251 case C_NULL:
2252 case C_EXTDEF: /* external definition */
2253 case C_ULABEL: /* undefined label */
2254 case C_USTATIC: /* undefined static */
2255 case C_LINE: /* line # reformatted as symbol table entry */
2256 case C_ALIAS: /* duplicate tag */
2257 case C_HIDDEN: /* ext symbol in dmert public lib */
2258
2259 default:
2260
2261 abort();
2262 dst->symbol.flags = BSF_DEBUGGING;
2263 dst->symbol.value = (src->n_value);
2264
2265 break;
2266 }
2267
2268 BFD_ASSERT(dst->symbol.flags != 0);
2269
2270 dst->native = src;
2271
2272 dst->symbol.udata = 0;
2273 dst->lineno = (alent *) NULL;
2274 this_index += (src->n_numaux) + 1;
2275 dst++;
2276 number_of_symbols++;
2277 } /* walk the native symtab */
2278 } /* bfdize the native symtab */
2279
2280 obj_symbols(abfd) = cached_area;
2281 obj_raw_syments(abfd) = native_symbols;
2282
2283 bfd_get_symcount(abfd) = number_of_symbols;
2284 obj_convert(abfd) = table_ptr;
2285 /* Slurp the line tables for each section too */
2286 {
2287 asection *p;
2288 p = abfd->sections;
2289 while (p) {
2290 coff_slurp_line_table(abfd, p);
2291 p = p->next;
2292 }
2293 }
2294 return true;
2295 } /* coff_slurp_symbol_table() */
2296
2297static unsigned int
2298coff_get_symtab_upper_bound(abfd)
2299bfd *abfd;
2300 {
2301 if (!coff_slurp_symbol_table(abfd))
2302 return 0;
2303
2304 return (bfd_get_symcount(abfd) + 1) * (sizeof(coff_symbol_type *));
2305 }
2306
2307
2308static unsigned int
2309coff_get_symtab(abfd, alocation)
2310bfd *abfd;
2311asymbol **alocation;
2312 {
2313 unsigned int counter = 0;
2314 coff_symbol_type *symbase;
2315 coff_symbol_type **location = (coff_symbol_type **) (alocation);
2316 if (!coff_slurp_symbol_table(abfd))
2317 return 0;
2318
2319 for (symbase = obj_symbols(abfd); counter++ < bfd_get_symcount(abfd);)
2320 *(location++) = symbase++;
2321 *location++ = 0;
2322 return bfd_get_symcount(abfd);
2323 }
2324
2325static unsigned int
2326coff_get_reloc_upper_bound(abfd, asect)
2327bfd *abfd;
2328sec_ptr asect;
2329 {
2330 if (bfd_get_format(abfd) != bfd_object) {
2331 bfd_error = invalid_operation;
2332 return 0;
2333 }
2334 return (asect->reloc_count + 1) * sizeof(arelent *);
2335 }
2336
2337static boolean
2338DEFUN(coff_slurp_reloc_table,(abfd, asect, symbols),
2339 bfd *abfd AND
2340 sec_ptr asect AND
2341 asymbol **symbols)
2342 {
2343 RELOC *native_relocs;
2344 arelent *reloc_cache;
2345 if (asect->relocation)
2346 return true;
2347 if (asect->reloc_count == 0)
2348 return true;
2349 if (!coff_slurp_symbol_table(abfd))
2350 return false;
2351 native_relocs =
2352 (RELOC *) buy_and_read(abfd,
2353 asect->rel_filepos,
2354 SEEK_SET,
2355 (size_t) (RELSZ *
2356 asect->reloc_count));
2357 reloc_cache = (arelent *)
2358 bfd_alloc(abfd, (size_t) (asect->reloc_count * sizeof(arelent)));
2359
2360 if (reloc_cache == NULL) {
2361 bfd_error = no_memory;
2362 return false;
2363 } { /* on error */
2364 arelent *cache_ptr;
2365 RELOC *src;
2366 for (cache_ptr = reloc_cache,
2367 src = native_relocs;
2368 cache_ptr < reloc_cache + asect->reloc_count;
2369 cache_ptr++,
2370 src++) {
2371 struct internal_reloc dst;
2372 asymbol *ptr;
2373 bfd_swap_reloc_in(abfd, src, &dst);
2374 dst.r_symndx += obj_symbol_slew(abfd);
2375 cache_ptr->sym_ptr_ptr = symbols + obj_convert(abfd)[dst.r_symndx];
2376
2377 ptr = *(cache_ptr->sym_ptr_ptr);
2378 cache_ptr->address = dst.r_vaddr;
2379 /*
2380 The symbols definitions that we have read in have been
2381 relocated as if their sections started at 0. But the offsets
2382 refering to the symbols in the raw data have not been
2383 modified, so we have to have a negative addend to compensate.
2384
2385 Note that symbols which used to be common must be left alone
2386 */
2387
2388 if (ptr->the_bfd == abfd
2389 && ptr->section != (asection *) NULL
2390 && ((ptr->flags & BSF_OLD_COMMON)== 0))
2391 {
2392 cache_ptr->addend = -(ptr->section->vma + ptr->value);
2393 }
2394 else {
2395 cache_ptr->addend = 0;
2396 }
2397
2398 cache_ptr->address -= asect->vma;
2399
2400 cache_ptr->section = (asection *) NULL;
2401
2402#if I960
2403 cache_ptr->howto = howto_table + dst.r_type;
2404#endif
2405#if M68
2406 cache_ptr->howto = howto_table + dst.r_type - R_RELBYTE;
2407#endif
2408#if M88
2409 if (dst.r_type >= R_PCR16L && dst.r_type <= R_VRT32) {
2410 cache_ptr->howto = howto_table + dst.r_type - R_PCR16L;
2411 cache_ptr->addend += dst.r_offset << 16;
2412 }
2413 else {
2414 BFD_ASSERT(0);
2415 }
2416#endif
2417
2418 }
2419
2420 }
2421
2422 asect->relocation = reloc_cache;
2423 return true;
2424 }
2425
2426
2427/* This is stupid. This function should be a boolean predicate */
2428static unsigned int
2429coff_canonicalize_reloc(abfd, section, relptr, symbols)
2430bfd *abfd;
2431sec_ptr section;
2432arelent **relptr;
2433asymbol **symbols;
2434 {
2435 arelent *tblptr = section->relocation;
2436 unsigned int count = 0;
2437 if (!(tblptr || coff_slurp_reloc_table(abfd, section, symbols)))
2438 return 0;
2439 tblptr = section->relocation;
2440 if (!tblptr)
2441 return 0;
2442
2443 for (; count++ < section->reloc_count;)
2444 *relptr++ = tblptr++;
2445
2446 *relptr = 0;
2447
2448 return section->reloc_count;
2449 }
2450
2451
2452/*
2453provided a bfd, a section and an offset into the section, calculate and
2454return the name of the source file and the line nearest to the wanted
2455location.
2456*/
2457
2458static boolean
2459DEFUN(coff_find_nearest_line,(abfd,
2460 section,
2461 symbols,
2462 offset,
2463 filename_ptr,
2464 functionname_ptr,
2465 line_ptr),
2466 bfd *abfd AND
2467 asection *section AND
2468 asymbol **symbols AND
2469 bfd_vma offset AND
2470 CONST char **filename_ptr AND
2471 CONST char **functionname_ptr AND
2472 unsigned int *line_ptr)
2473{
2474 static bfd *cache_abfd;
2475 static asection *cache_section;
2476 static bfd_vma cache_offset;
2477 static unsigned int cache_i;
2478 static alent *cache_l;
2479
2480 unsigned int i = 0;
2481 struct icofdata *cof = obj_icof(abfd);
2482 /* Run through the raw syments if available */
2483 struct internal_syment *p;
2484 alent *l;
2485 unsigned int line_base = 0;
2486
2487
2488 *filename_ptr = 0;
2489 *functionname_ptr = 0;
2490 *line_ptr = 0;
2491
2492 /* Don't try and find line numbers in a non coff file */
2493 if (abfd->xvec->flavour != bfd_target_coff_flavour_enum)
2494 return false;
2495
2496 if (cof == (struct icofdata *)NULL)
2497 return false;
2498
2499 p = cof->raw_syments;
2500 /*
2501 I don't know for sure what's right, but this isn't it. First off, an
2502 object file may not have any C_FILE's in it. After
2503 get_normalized_symtab(), it should have at least 1, the one I put
2504 there, but otherwise, all bets are off. Point #2, the first C_FILE
2505 isn't necessarily the right C_FILE because any given object may have
2506 many. I think you'll have to track sections as they coelesce in order
2507 to find the C_STAT symbol for this section. Then you'll have to work
2508 backwards to find the previous C_FILE, or choke if you get to a C_STAT
2509 for the same kind of section. That will mean that the original object
2510 file didn't have a C_FILE. xoxorich.
2511 */
2512
2513#ifdef WEREBEINGPEDANTIC
2514 return false;
2515#endif
2516
2517 for (i = 0; i < cof->raw_syment_count; i++) {
2518 if (p->n_sclass == C_FILE) {
2519 /* File name is embeded in auxent */
2520 /*
2521 This isn't right. The fname should probably be normalized
2522 during get_normalized_symtab(). In any case, what was here
2523 wasn't right because a SYMENT.n_name isn't an
2524 AUXENT.x_file.x_fname. xoxorich.
2525 */
2526
2527 *filename_ptr = ((AUXENT *) (p + 1))->x_file.x_fname;
2528 break;
2529 }
2530 p += 1 + p->n_numaux;
2531 }
2532 /* Now wander though the raw linenumbers of the section */
2533 /*
2534 If this is the same bfd as we were previously called with and this is
2535 the same section, and the offset we want is further down then we can
2536 prime the lookup loop
2537 */
2538 if (abfd == cache_abfd &&
2539 section == cache_section &&
2540 offset >= cache_offset) {
2541 i = cache_i;
2542 l = cache_l;
2543 }
2544 else {
2545 i = 0;
2546 l = section->lineno;
2547 }
2548
2549 for (; i < section->lineno_count; i++) {
2550 if (l->line_number == 0) {
2551 /* Get the symbol this line number points at */
2552 coff_symbol_type *coff = (coff_symbol_type *) (l->u.sym);
2553 *functionname_ptr = coff->symbol.name;
2554 if (coff->native) {
2555 struct internal_syment *s = coff->native;
2556 s = s + 1 + s->n_numaux;
2557 /*
2558 S should now point to the .bf of the function
2559 */
2560 if (s->n_numaux) {
2561 /*
2562 The linenumber is stored in the auxent
2563 */
2564 union internal_auxent *a = (union internal_auxent *) (s + 1);
2565 line_base = a->x_sym.x_misc.x_lnsz.x_lnno;
2566 }
2567 }
2568 }
2569 else {
2570 if (l->u.offset > offset)
2571 break;
2572 *line_ptr = l->line_number + line_base + 1;
2573 }
2574 l++;
2575 }
2576
2577 cache_abfd = abfd;
2578 cache_section = section;
2579 cache_offset = offset;
2580 cache_i = i;
2581 cache_l = l;
2582 return true;
2583}
2584
2585#ifdef GNU960
2586file_ptr
2587coff_sym_filepos(abfd)
2588bfd *abfd;
2589 {
2590 return obj_sym_filepos(abfd);
2591 }
2592#endif
2593
2594
2595static int
2596DEFUN(coff_sizeof_headers,(abfd, reloc),
2597 bfd *abfd AND
2598 boolean reloc)
2599 {
2600 size_t size;
2601
2602 if (reloc == false) {
2603 size = FILHSZ + AOUTSZ;
2604 }
2605 else {
2606 size = FILHSZ;
2607 }
2608
2609 size += abfd->section_count * SCNHSZ;
2610 return size;
2611 }
2612
2613
2614#define coff_core_file_failing_command _bfd_dummy_core_file_failing_command
2615#define coff_core_file_failing_signal _bfd_dummy_core_file_failing_signal
2616#define coff_core_file_matches_executable_p _bfd_dummy_core_file_matches_executable_p
2617#define coff_slurp_armap bfd_slurp_coff_armap
2618#define coff_slurp_extended_name_table _bfd_slurp_extended_name_table
2619#define coff_truncate_arname bfd_dont_truncate_arname
2620#define coff_openr_next_archived_file bfd_generic_openr_next_archived_file
2621#define coff_generic_stat_arch_elt bfd_generic_stat_arch_elt
2622#define coff_get_section_contents bfd_generic_get_section_contents
2623#define coff_close_and_cleanup bfd_generic_close_and_cleanup
This page took 0.122767 seconds and 4 git commands to generate.