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