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