1 /* Generic COFF swapping routines, for BFD.
2    Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1999, 2000,
3    2001, 2002, 2005
4    Free Software Foundation, Inc.
5    Written by Cygnus Support.
6 
7    This file is part of BFD, the Binary File Descriptor library.
8 
9    This program is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 2 of the License, or
12    (at your option) any later version.
13 
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18 
19    You should have received a copy of the GNU General Public License
20    along with this program; if not, write to the Free Software
21    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
22 
23 /* This file contains routines used to swap COFF data.  It is a header
24    file because the details of swapping depend on the details of the
25    structures used by each COFF implementation.  This is included by
26    coffcode.h, as well as by the ECOFF backend.
27 
28    Any file which uses this must first include "coff/internal.h" and
29    "coff/CPU.h".  The functions will then be correct for that CPU.  */
30 
31 #ifndef GET_FCN_LNNOPTR
32 #define GET_FCN_LNNOPTR(abfd, ext) \
33   H_GET_32 (abfd, ext->x_sym.x_fcnary.x_fcn.x_lnnoptr)
34 #endif
35 
36 #ifndef GET_FCN_ENDNDX
37 #define GET_FCN_ENDNDX(abfd, ext) \
38   H_GET_32 (abfd, ext->x_sym.x_fcnary.x_fcn.x_endndx)
39 #endif
40 
41 #ifndef PUT_FCN_LNNOPTR
42 #define PUT_FCN_LNNOPTR(abfd, in, ext) \
43   H_PUT_32 (abfd,  in, ext->x_sym.x_fcnary.x_fcn.x_lnnoptr)
44 #endif
45 #ifndef PUT_FCN_ENDNDX
46 #define PUT_FCN_ENDNDX(abfd, in, ext) \
47   H_PUT_32 (abfd, in, ext->x_sym.x_fcnary.x_fcn.x_endndx)
48 #endif
49 #ifndef GET_LNSZ_LNNO
50 #define GET_LNSZ_LNNO(abfd, ext) \
51   H_GET_16 (abfd, ext->x_sym.x_misc.x_lnsz.x_lnno)
52 #endif
53 #ifndef GET_LNSZ_SIZE
54 #define GET_LNSZ_SIZE(abfd, ext) \
55   H_GET_16 (abfd, ext->x_sym.x_misc.x_lnsz.x_size)
56 #endif
57 #ifndef PUT_LNSZ_LNNO
58 #define PUT_LNSZ_LNNO(abfd, in, ext) \
59   H_PUT_16 (abfd, in, ext->x_sym.x_misc.x_lnsz.x_lnno)
60 #endif
61 #ifndef PUT_LNSZ_SIZE
62 #define PUT_LNSZ_SIZE(abfd, in, ext) \
63   H_PUT_16 (abfd, in, ext->x_sym.x_misc.x_lnsz.x_size)
64 #endif
65 #ifndef GET_SCN_SCNLEN
66 #define GET_SCN_SCNLEN(abfd, ext) \
67   H_GET_32 (abfd, ext->x_scn.x_scnlen)
68 #endif
69 #ifndef GET_SCN_NRELOC
70 #define GET_SCN_NRELOC(abfd, ext) \
71   H_GET_16 (abfd, ext->x_scn.x_nreloc)
72 #endif
73 #ifndef GET_SCN_NLINNO
74 #define GET_SCN_NLINNO(abfd, ext) \
75   H_GET_16 (abfd, ext->x_scn.x_nlinno)
76 #endif
77 #ifndef PUT_SCN_SCNLEN
78 #define PUT_SCN_SCNLEN(abfd, in, ext) \
79   H_PUT_32 (abfd, in, ext->x_scn.x_scnlen)
80 #endif
81 #ifndef PUT_SCN_NRELOC
82 #define PUT_SCN_NRELOC(abfd, in, ext) \
83   H_PUT_16 (abfd, in, ext->x_scn.x_nreloc)
84 #endif
85 #ifndef PUT_SCN_NLINNO
86 #define PUT_SCN_NLINNO(abfd, in, ext) \
87   H_PUT_16 (abfd, in, ext->x_scn.x_nlinno)
88 #endif
89 #ifndef GET_LINENO_LNNO
90 #define GET_LINENO_LNNO(abfd, ext) \
91   H_GET_16 (abfd, ext->l_lnno);
92 #endif
93 #ifndef PUT_LINENO_LNNO
94 #define PUT_LINENO_LNNO(abfd, val, ext) \
95   H_PUT_16 (abfd, val, ext->l_lnno);
96 #endif
97 
98 /* The f_symptr field in the filehdr is sometimes 64 bits.  */
99 #ifndef GET_FILEHDR_SYMPTR
100 #define GET_FILEHDR_SYMPTR H_GET_32
101 #endif
102 #ifndef PUT_FILEHDR_SYMPTR
103 #define PUT_FILEHDR_SYMPTR H_PUT_32
104 #endif
105 
106 /* Some fields in the aouthdr are sometimes 64 bits.  */
107 #ifndef GET_AOUTHDR_TSIZE
108 #define GET_AOUTHDR_TSIZE H_GET_32
109 #endif
110 #ifndef PUT_AOUTHDR_TSIZE
111 #define PUT_AOUTHDR_TSIZE H_PUT_32
112 #endif
113 #ifndef GET_AOUTHDR_DSIZE
114 #define GET_AOUTHDR_DSIZE H_GET_32
115 #endif
116 #ifndef PUT_AOUTHDR_DSIZE
117 #define PUT_AOUTHDR_DSIZE H_PUT_32
118 #endif
119 #ifndef GET_AOUTHDR_BSIZE
120 #define GET_AOUTHDR_BSIZE H_GET_32
121 #endif
122 #ifndef PUT_AOUTHDR_BSIZE
123 #define PUT_AOUTHDR_BSIZE H_PUT_32
124 #endif
125 #ifndef GET_AOUTHDR_ENTRY
126 #define GET_AOUTHDR_ENTRY H_GET_32
127 #endif
128 #ifndef PUT_AOUTHDR_ENTRY
129 #define PUT_AOUTHDR_ENTRY H_PUT_32
130 #endif
131 #ifndef GET_AOUTHDR_TEXT_START
132 #define GET_AOUTHDR_TEXT_START H_GET_32
133 #endif
134 #ifndef PUT_AOUTHDR_TEXT_START
135 #define PUT_AOUTHDR_TEXT_START H_PUT_32
136 #endif
137 #ifndef GET_AOUTHDR_DATA_START
138 #define GET_AOUTHDR_DATA_START H_GET_32
139 #endif
140 #ifndef PUT_AOUTHDR_DATA_START
141 #define PUT_AOUTHDR_DATA_START H_PUT_32
142 #endif
143 
144 /* Some fields in the scnhdr are sometimes 64 bits.  */
145 #ifndef GET_SCNHDR_PADDR
146 #define GET_SCNHDR_PADDR H_GET_32
147 #endif
148 #ifndef PUT_SCNHDR_PADDR
149 #define PUT_SCNHDR_PADDR H_PUT_32
150 #endif
151 #ifndef GET_SCNHDR_VADDR
152 #define GET_SCNHDR_VADDR H_GET_32
153 #endif
154 #ifndef PUT_SCNHDR_VADDR
155 #define PUT_SCNHDR_VADDR H_PUT_32
156 #endif
157 #ifndef GET_SCNHDR_SIZE
158 #define GET_SCNHDR_SIZE H_GET_32
159 #endif
160 #ifndef PUT_SCNHDR_SIZE
161 #define PUT_SCNHDR_SIZE H_PUT_32
162 #endif
163 #ifndef GET_SCNHDR_SCNPTR
164 #define GET_SCNHDR_SCNPTR H_GET_32
165 #endif
166 #ifndef PUT_SCNHDR_SCNPTR
167 #define PUT_SCNHDR_SCNPTR H_PUT_32
168 #endif
169 #ifndef GET_SCNHDR_RELPTR
170 #define GET_SCNHDR_RELPTR H_GET_32
171 #endif
172 #ifndef PUT_SCNHDR_RELPTR
173 #define PUT_SCNHDR_RELPTR H_PUT_32
174 #endif
175 #ifndef GET_SCNHDR_LNNOPTR
176 #define GET_SCNHDR_LNNOPTR H_GET_32
177 #endif
178 #ifndef PUT_SCNHDR_LNNOPTR
179 #define PUT_SCNHDR_LNNOPTR H_PUT_32
180 #endif
181 #ifndef GET_SCNHDR_NRELOC
182 #define GET_SCNHDR_NRELOC H_GET_16
183 #endif
184 #ifndef MAX_SCNHDR_NRELOC
185 #define MAX_SCNHDR_NRELOC 0xffff
186 #endif
187 #ifndef PUT_SCNHDR_NRELOC
188 #define PUT_SCNHDR_NRELOC H_PUT_16
189 #endif
190 #ifndef GET_SCNHDR_NLNNO
191 #define GET_SCNHDR_NLNNO H_GET_16
192 #endif
193 #ifndef MAX_SCNHDR_NLNNO
194 #define MAX_SCNHDR_NLNNO 0xffff
195 #endif
196 #ifndef PUT_SCNHDR_NLNNO
197 #define PUT_SCNHDR_NLNNO H_PUT_16
198 #endif
199 #ifndef GET_SCNHDR_FLAGS
200 #define GET_SCNHDR_FLAGS H_GET_32
201 #endif
202 #ifndef PUT_SCNHDR_FLAGS
203 #define PUT_SCNHDR_FLAGS H_PUT_32
204 #endif
205 
206 #ifndef GET_RELOC_VADDR
207 #define GET_RELOC_VADDR H_GET_32
208 #endif
209 #ifndef PUT_RELOC_VADDR
210 #define PUT_RELOC_VADDR H_PUT_32
211 #endif
212 
213 #ifndef NO_COFF_RELOCS
214 
215 static void
216 coff_swap_reloc_in (bfd * abfd, void * src, void * dst)
217 {
218   RELOC *reloc_src = (RELOC *) src;
219   struct internal_reloc *reloc_dst = (struct internal_reloc *) dst;
220 
221   reloc_dst->r_vaddr  = GET_RELOC_VADDR (abfd, reloc_src->r_vaddr);
222   reloc_dst->r_symndx = H_GET_S32 (abfd, reloc_src->r_symndx);
223   reloc_dst->r_type   = H_GET_16 (abfd, reloc_src->r_type);
224 
225 #ifdef SWAP_IN_RELOC_OFFSET
226   reloc_dst->r_offset = SWAP_IN_RELOC_OFFSET (abfd, reloc_src->r_offset);
227 #endif
228 }
229 
230 static unsigned int
231 coff_swap_reloc_out (bfd * abfd, void * src, void * dst)
232 {
233   struct internal_reloc *reloc_src = (struct internal_reloc *) src;
234   struct external_reloc *reloc_dst = (struct external_reloc *) dst;
235 
236   PUT_RELOC_VADDR (abfd, reloc_src->r_vaddr, reloc_dst->r_vaddr);
237   H_PUT_32 (abfd, reloc_src->r_symndx, reloc_dst->r_symndx);
238   H_PUT_16 (abfd, reloc_src->r_type, reloc_dst->r_type);
239 
240 #ifdef SWAP_OUT_RELOC_OFFSET
241   SWAP_OUT_RELOC_OFFSET (abfd, reloc_src->r_offset, reloc_dst->r_offset);
242 #endif
243 #ifdef SWAP_OUT_RELOC_EXTRA
244   SWAP_OUT_RELOC_EXTRA (abfd, reloc_src, reloc_dst);
245 #endif
246 
247   return bfd_coff_relsz (abfd);
248 }
249 
250 #endif /* NO_COFF_RELOCS */
251 
252 static void
253 coff_swap_filehdr_in (bfd * abfd, void * src, void * dst)
254 {
255   FILHDR *filehdr_src = (FILHDR *) src;
256   struct internal_filehdr *filehdr_dst = (struct internal_filehdr *) dst;
257 
258 #ifdef COFF_ADJUST_FILEHDR_IN_PRE
259   COFF_ADJUST_FILEHDR_IN_PRE (abfd, src, dst);
260 #endif
261   filehdr_dst->f_magic  = H_GET_16 (abfd, filehdr_src->f_magic);
262   filehdr_dst->f_nscns  = H_GET_16 (abfd, filehdr_src->f_nscns);
263   filehdr_dst->f_timdat = H_GET_32 (abfd, filehdr_src->f_timdat);
264   filehdr_dst->f_symptr = GET_FILEHDR_SYMPTR (abfd, filehdr_src->f_symptr);
265   filehdr_dst->f_nsyms  = H_GET_32 (abfd, filehdr_src->f_nsyms);
266   filehdr_dst->f_opthdr = H_GET_16 (abfd, filehdr_src->f_opthdr);
267   filehdr_dst->f_flags  = H_GET_16 (abfd, filehdr_src->f_flags);
268 #ifdef TIC80_TARGET_ID
269   filehdr_dst->f_target_id = H_GET_16 (abfd, filehdr_src->f_target_id);
270 #endif
271 
272 #ifdef COFF_ADJUST_FILEHDR_IN_POST
273   COFF_ADJUST_FILEHDR_IN_POST (abfd, src, dst);
274 #endif
275 }
276 
277 static  unsigned int
278 coff_swap_filehdr_out (bfd *abfd, void * in, void * out)
279 {
280   struct internal_filehdr *filehdr_in = (struct internal_filehdr *) in;
281   FILHDR *filehdr_out = (FILHDR *) out;
282 
283 #ifdef COFF_ADJUST_FILEHDR_OUT_PRE
284   COFF_ADJUST_FILEHDR_OUT_PRE (abfd, in, out);
285 #endif
286   H_PUT_16 (abfd, filehdr_in->f_magic, filehdr_out->f_magic);
287   H_PUT_16 (abfd, filehdr_in->f_nscns, filehdr_out->f_nscns);
288   H_PUT_32 (abfd, filehdr_in->f_timdat, filehdr_out->f_timdat);
289   PUT_FILEHDR_SYMPTR (abfd, filehdr_in->f_symptr, filehdr_out->f_symptr);
290   H_PUT_32 (abfd, filehdr_in->f_nsyms, filehdr_out->f_nsyms);
291   H_PUT_16 (abfd, filehdr_in->f_opthdr, filehdr_out->f_opthdr);
292   H_PUT_16 (abfd, filehdr_in->f_flags, filehdr_out->f_flags);
293 #ifdef TIC80_TARGET_ID
294   H_PUT_16 (abfd, filehdr_in->f_target_id, filehdr_out->f_target_id);
295 #endif
296 
297 #ifdef COFF_ADJUST_FILEHDR_OUT_POST
298   COFF_ADJUST_FILEHDR_OUT_POST (abfd, in, out);
299 #endif
300   return bfd_coff_filhsz (abfd);
301 }
302 
303 #ifndef NO_COFF_SYMBOLS
304 
305 static void
306 coff_swap_sym_in (bfd * abfd, void * ext1, void * in1)
307 {
308   SYMENT *ext = (SYMENT *) ext1;
309   struct internal_syment *in = (struct internal_syment *) in1;
310 
311   if (ext->e.e_name[0] == 0)
312     {
313       in->_n._n_n._n_zeroes = 0;
314       in->_n._n_n._n_offset = H_GET_32 (abfd, ext->e.e.e_offset);
315     }
316   else
317     {
318 #if SYMNMLEN != E_SYMNMLEN
319 #error we need to cope with truncating or extending SYMNMLEN
320 #else
321       memcpy (in->_n._n_name, ext->e.e_name, SYMNMLEN);
322 #endif
323     }
324 
325   in->n_value = H_GET_32 (abfd, ext->e_value);
326   in->n_scnum = H_GET_16 (abfd, ext->e_scnum);
327   if (sizeof (ext->e_type) == 2)
328     in->n_type = H_GET_16 (abfd, ext->e_type);
329   else
330     in->n_type = H_GET_32 (abfd, ext->e_type);
331   in->n_sclass = H_GET_8 (abfd, ext->e_sclass);
332   in->n_numaux = H_GET_8 (abfd, ext->e_numaux);
333 #ifdef COFF_ADJUST_SYM_IN_POST
334   COFF_ADJUST_SYM_IN_POST (abfd, ext1, in1);
335 #endif
336 }
337 
338 static unsigned int
339 coff_swap_sym_out (bfd * abfd, void * inp, void * extp)
340 {
341   struct internal_syment *in = (struct internal_syment *) inp;
342   SYMENT *ext =(SYMENT *) extp;
343 
344 #ifdef COFF_ADJUST_SYM_OUT_PRE
345   COFF_ADJUST_SYM_OUT_PRE (abfd, inp, extp);
346 #endif
347 
348   if (in->_n._n_name[0] == 0)
349     {
350       H_PUT_32 (abfd, 0, ext->e.e.e_zeroes);
351       H_PUT_32 (abfd, in->_n._n_n._n_offset, ext->e.e.e_offset);
352     }
353   else
354     {
355 #if SYMNMLEN != E_SYMNMLEN
356 #error we need to cope with truncating or extending SYMNMLEN
357 #else
358       memcpy (ext->e.e_name, in->_n._n_name, SYMNMLEN);
359 #endif
360     }
361 
362   H_PUT_32 (abfd, in->n_value, ext->e_value);
363   H_PUT_16 (abfd, in->n_scnum, ext->e_scnum);
364 
365   if (sizeof (ext->e_type) == 2)
366     H_PUT_16 (abfd, in->n_type, ext->e_type);
367   else
368     H_PUT_32 (abfd, in->n_type, ext->e_type);
369 
370   H_PUT_8 (abfd, in->n_sclass, ext->e_sclass);
371   H_PUT_8 (abfd, in->n_numaux, ext->e_numaux);
372 
373 #ifdef COFF_ADJUST_SYM_OUT_POST
374   COFF_ADJUST_SYM_OUT_POST (abfd, inp, extp);
375 #endif
376 
377   return SYMESZ;
378 }
379 
380 static void
381 coff_swap_aux_in (bfd *abfd,
382 		  void * ext1,
383 		  int type,
384 		  int class,
385 		  int indx,
386 		  int numaux,
387 		  void * in1)
388 {
389   AUXENT *ext = (AUXENT *) ext1;
390   union internal_auxent *in = (union internal_auxent *) in1;
391 
392 #ifdef COFF_ADJUST_AUX_IN_PRE
393   COFF_ADJUST_AUX_IN_PRE (abfd, ext1, type, class, indx, numaux, in1);
394 #endif
395 
396   switch (class)
397     {
398     case C_FILE:
399       if (ext->x_file.x_fname[0] == 0)
400 	{
401 	  in->x_file.x_n.x_zeroes = 0;
402 	  in->x_file.x_n.x_offset = H_GET_32 (abfd, ext->x_file.x_n.x_offset);
403 	}
404       else
405 	{
406 #if FILNMLEN != E_FILNMLEN
407 #error we need to cope with truncating or extending FILNMLEN
408 #else
409 	  if (numaux > 1)
410 	    {
411 	      if (indx == 0)
412 		memcpy (in->x_file.x_fname, ext->x_file.x_fname,
413 			numaux * sizeof (AUXENT));
414 	    }
415 	  else
416 	    memcpy (in->x_file.x_fname, ext->x_file.x_fname, FILNMLEN);
417 #endif
418 	}
419       goto end;
420 
421     case C_STAT:
422 #ifdef C_LEAFSTAT
423     case C_LEAFSTAT:
424 #endif
425     case C_HIDDEN:
426       if (type == T_NULL)
427 	{
428 	  in->x_scn.x_scnlen = GET_SCN_SCNLEN (abfd, ext);
429 	  in->x_scn.x_nreloc = GET_SCN_NRELOC (abfd, ext);
430 	  in->x_scn.x_nlinno = GET_SCN_NLINNO (abfd, ext);
431 
432 	  /* PE defines some extra fields; we zero them out for
433              safety.  */
434 	  in->x_scn.x_checksum = 0;
435 	  in->x_scn.x_associated = 0;
436 	  in->x_scn.x_comdat = 0;
437 
438 	  goto end;
439 	}
440       break;
441     }
442 
443   in->x_sym.x_tagndx.l = H_GET_32 (abfd, ext->x_sym.x_tagndx);
444 #ifndef NO_TVNDX
445   in->x_sym.x_tvndx = H_GET_16 (abfd, ext->x_sym.x_tvndx);
446 #endif
447 
448   if (class == C_BLOCK || class == C_FCN || ISFCN (type) || ISTAG (class))
449     {
450       in->x_sym.x_fcnary.x_fcn.x_lnnoptr = GET_FCN_LNNOPTR (abfd, ext);
451       in->x_sym.x_fcnary.x_fcn.x_endndx.l = GET_FCN_ENDNDX (abfd, ext);
452     }
453   else
454     {
455 #if DIMNUM != E_DIMNUM
456 #error we need to cope with truncating or extending DIMNUM
457 #endif
458       in->x_sym.x_fcnary.x_ary.x_dimen[0] =
459 	H_GET_16 (abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[0]);
460       in->x_sym.x_fcnary.x_ary.x_dimen[1] =
461 	H_GET_16 (abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[1]);
462       in->x_sym.x_fcnary.x_ary.x_dimen[2] =
463 	H_GET_16 (abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[2]);
464       in->x_sym.x_fcnary.x_ary.x_dimen[3] =
465 	H_GET_16 (abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[3]);
466     }
467 
468   if (ISFCN (type))
469     in->x_sym.x_misc.x_fsize = H_GET_32 (abfd, ext->x_sym.x_misc.x_fsize);
470   else
471     {
472       in->x_sym.x_misc.x_lnsz.x_lnno = GET_LNSZ_LNNO (abfd, ext);
473       in->x_sym.x_misc.x_lnsz.x_size = GET_LNSZ_SIZE (abfd, ext);
474     }
475 
476  end: ;
477 
478 #ifdef COFF_ADJUST_AUX_IN_POST
479   COFF_ADJUST_AUX_IN_POST (abfd, ext1, type, class, indx, numaux, in1);
480 #endif
481 }
482 
483 static unsigned int
484 coff_swap_aux_out (bfd * abfd,
485 		   void * inp,
486 		   int type,
487 		   int class,
488 		   int indx ATTRIBUTE_UNUSED,
489 		   int numaux ATTRIBUTE_UNUSED,
490 		   void * extp)
491 {
492   union internal_auxent * in = (union internal_auxent *) inp;
493   AUXENT *ext = (AUXENT *) extp;
494 
495 #ifdef COFF_ADJUST_AUX_OUT_PRE
496   COFF_ADJUST_AUX_OUT_PRE (abfd, inp, type, class, indx, numaux, extp);
497 #endif
498 
499   memset (ext, 0, AUXESZ);
500 
501   switch (class)
502     {
503     case C_FILE:
504       if (in->x_file.x_fname[0] == 0)
505 	{
506 	  H_PUT_32 (abfd, 0, ext->x_file.x_n.x_zeroes);
507 	  H_PUT_32 (abfd, in->x_file.x_n.x_offset, ext->x_file.x_n.x_offset);
508 	}
509       else
510 	{
511 #if FILNMLEN != E_FILNMLEN
512 #error we need to cope with truncating or extending FILNMLEN
513 #else
514 	  memcpy (ext->x_file.x_fname, in->x_file.x_fname, FILNMLEN);
515 #endif
516 	}
517       goto end;
518 
519     case C_STAT:
520 #ifdef C_LEAFSTAT
521     case C_LEAFSTAT:
522 #endif
523     case C_HIDDEN:
524       if (type == T_NULL)
525 	{
526 	  PUT_SCN_SCNLEN (abfd, in->x_scn.x_scnlen, ext);
527 	  PUT_SCN_NRELOC (abfd, in->x_scn.x_nreloc, ext);
528 	  PUT_SCN_NLINNO (abfd, in->x_scn.x_nlinno, ext);
529 	  goto end;
530 	}
531       break;
532     }
533 
534   H_PUT_32 (abfd, in->x_sym.x_tagndx.l, ext->x_sym.x_tagndx);
535 #ifndef NO_TVNDX
536   H_PUT_16 (abfd, in->x_sym.x_tvndx, ext->x_sym.x_tvndx);
537 #endif
538 
539   if (class == C_BLOCK || class == C_FCN || ISFCN (type) || ISTAG (class))
540     {
541       PUT_FCN_LNNOPTR (abfd, in->x_sym.x_fcnary.x_fcn.x_lnnoptr, ext);
542       PUT_FCN_ENDNDX (abfd, in->x_sym.x_fcnary.x_fcn.x_endndx.l, ext);
543     }
544   else
545     {
546 #if DIMNUM != E_DIMNUM
547 #error we need to cope with truncating or extending DIMNUM
548 #endif
549       H_PUT_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[0],
550 	       ext->x_sym.x_fcnary.x_ary.x_dimen[0]);
551       H_PUT_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[1],
552 	       ext->x_sym.x_fcnary.x_ary.x_dimen[1]);
553       H_PUT_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[2],
554 	       ext->x_sym.x_fcnary.x_ary.x_dimen[2]);
555       H_PUT_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[3],
556 	       ext->x_sym.x_fcnary.x_ary.x_dimen[3]);
557     }
558 
559   if (ISFCN (type))
560     H_PUT_32 (abfd, in->x_sym.x_misc.x_fsize, ext->x_sym.x_misc.x_fsize);
561   else
562     {
563       PUT_LNSZ_LNNO (abfd, in->x_sym.x_misc.x_lnsz.x_lnno, ext);
564       PUT_LNSZ_SIZE (abfd, in->x_sym.x_misc.x_lnsz.x_size, ext);
565     }
566 
567  end:
568 #ifdef COFF_ADJUST_AUX_OUT_POST
569   COFF_ADJUST_AUX_OUT_POST (abfd, inp, type, class, indx, numaux, extp);
570 #endif
571   return AUXESZ;
572 }
573 
574 #endif /* NO_COFF_SYMBOLS */
575 
576 #ifndef NO_COFF_LINENOS
577 
578 static void
579 coff_swap_lineno_in (bfd * abfd, void * ext1, void * in1)
580 {
581   LINENO *ext = (LINENO *) ext1;
582   struct internal_lineno *in = (struct internal_lineno *) in1;
583 
584   in->l_addr.l_symndx = H_GET_32 (abfd, ext->l_addr.l_symndx);
585   in->l_lnno = GET_LINENO_LNNO (abfd, ext);
586 }
587 
588 static unsigned int
589 coff_swap_lineno_out (bfd * abfd, void * inp, void * outp)
590 {
591   struct internal_lineno *in = (struct internal_lineno *) inp;
592   struct external_lineno *ext = (struct external_lineno *) outp;
593   H_PUT_32 (abfd, in->l_addr.l_symndx, ext->l_addr.l_symndx);
594 
595   PUT_LINENO_LNNO (abfd, in->l_lnno, ext);
596   return LINESZ;
597 }
598 
599 #endif /* NO_COFF_LINENOS */
600 
601 static void
602 coff_swap_aouthdr_in (bfd * abfd, void * aouthdr_ext1, void * aouthdr_int1)
603 {
604   AOUTHDR *aouthdr_ext;
605   struct internal_aouthdr *aouthdr_int;
606 
607   aouthdr_ext = (AOUTHDR *) aouthdr_ext1;
608   aouthdr_int = (struct internal_aouthdr *) aouthdr_int1;
609   aouthdr_int->magic = H_GET_16 (abfd, aouthdr_ext->magic);
610   aouthdr_int->vstamp = H_GET_16 (abfd, aouthdr_ext->vstamp);
611   aouthdr_int->tsize = GET_AOUTHDR_TSIZE (abfd, aouthdr_ext->tsize);
612   aouthdr_int->dsize = GET_AOUTHDR_DSIZE (abfd, aouthdr_ext->dsize);
613   aouthdr_int->bsize = GET_AOUTHDR_BSIZE (abfd, aouthdr_ext->bsize);
614   aouthdr_int->entry = GET_AOUTHDR_ENTRY (abfd, aouthdr_ext->entry);
615   aouthdr_int->text_start =
616     GET_AOUTHDR_TEXT_START (abfd, aouthdr_ext->text_start);
617   aouthdr_int->data_start =
618     GET_AOUTHDR_DATA_START (abfd, aouthdr_ext->data_start);
619 
620 #ifdef I960
621   aouthdr_int->tagentries = H_GET_32 (abfd, aouthdr_ext->tagentries);
622 #endif
623 
624 #ifdef APOLLO_M68
625   H_PUT_32 (abfd, aouthdr_int->o_inlib, aouthdr_ext->o_inlib);
626   H_PUT_32 (abfd, aouthdr_int->o_sri, aouthdr_ext->o_sri);
627   H_PUT_32 (abfd, aouthdr_int->vid[0], aouthdr_ext->vid);
628   H_PUT_32 (abfd, aouthdr_int->vid[1], aouthdr_ext->vid + 4);
629 #endif
630 
631 #ifdef RS6000COFF_C
632 #ifdef XCOFF64
633   aouthdr_int->o_toc = H_GET_64 (abfd, aouthdr_ext->o_toc);
634 #else
635   aouthdr_int->o_toc = H_GET_32 (abfd, aouthdr_ext->o_toc);
636 #endif
637   aouthdr_int->o_snentry  = H_GET_16 (abfd, aouthdr_ext->o_snentry);
638   aouthdr_int->o_sntext   = H_GET_16 (abfd, aouthdr_ext->o_sntext);
639   aouthdr_int->o_sndata   = H_GET_16 (abfd, aouthdr_ext->o_sndata);
640   aouthdr_int->o_sntoc    = H_GET_16 (abfd, aouthdr_ext->o_sntoc);
641   aouthdr_int->o_snloader = H_GET_16 (abfd, aouthdr_ext->o_snloader);
642   aouthdr_int->o_snbss    = H_GET_16 (abfd, aouthdr_ext->o_snbss);
643   aouthdr_int->o_algntext = H_GET_16 (abfd, aouthdr_ext->o_algntext);
644   aouthdr_int->o_algndata = H_GET_16 (abfd, aouthdr_ext->o_algndata);
645   aouthdr_int->o_modtype  = H_GET_16 (abfd, aouthdr_ext->o_modtype);
646   aouthdr_int->o_cputype  = H_GET_16 (abfd, aouthdr_ext->o_cputype);
647 #ifdef XCOFF64
648   aouthdr_int->o_maxstack = H_GET_64 (abfd, aouthdr_ext->o_maxstack);
649   aouthdr_int->o_maxdata  = H_GET_64 (abfd, aouthdr_ext->o_maxdata);
650 #else
651   aouthdr_int->o_maxstack = H_GET_32 (abfd, aouthdr_ext->o_maxstack);
652   aouthdr_int->o_maxdata  = H_GET_32 (abfd, aouthdr_ext->o_maxdata);
653 #endif
654 #endif
655 
656 #ifdef MIPSECOFF
657   aouthdr_int->bss_start  = H_GET_32 (abfd, aouthdr_ext->bss_start);
658   aouthdr_int->gp_value   = H_GET_32 (abfd, aouthdr_ext->gp_value);
659   aouthdr_int->gprmask    = H_GET_32 (abfd, aouthdr_ext->gprmask);
660   aouthdr_int->cprmask[0] = H_GET_32 (abfd, aouthdr_ext->cprmask[0]);
661   aouthdr_int->cprmask[1] = H_GET_32 (abfd, aouthdr_ext->cprmask[1]);
662   aouthdr_int->cprmask[2] = H_GET_32 (abfd, aouthdr_ext->cprmask[2]);
663   aouthdr_int->cprmask[3] = H_GET_32 (abfd, aouthdr_ext->cprmask[3]);
664 #endif
665 
666 #ifdef ALPHAECOFF
667   aouthdr_int->bss_start = H_GET_64 (abfd, aouthdr_ext->bss_start);
668   aouthdr_int->gp_value  = H_GET_64 (abfd, aouthdr_ext->gp_value);
669   aouthdr_int->gprmask   = H_GET_32 (abfd, aouthdr_ext->gprmask);
670   aouthdr_int->fprmask   = H_GET_32 (abfd, aouthdr_ext->fprmask);
671 #endif
672 }
673 
674 static unsigned int
675 coff_swap_aouthdr_out (bfd * abfd, void * in, void * out)
676 {
677   struct internal_aouthdr *aouthdr_in = (struct internal_aouthdr *) in;
678   AOUTHDR *aouthdr_out = (AOUTHDR *) out;
679 
680   H_PUT_16 (abfd, aouthdr_in->magic, aouthdr_out->magic);
681   H_PUT_16 (abfd, aouthdr_in->vstamp, aouthdr_out->vstamp);
682   PUT_AOUTHDR_TSIZE (abfd, aouthdr_in->tsize, aouthdr_out->tsize);
683   PUT_AOUTHDR_DSIZE (abfd, aouthdr_in->dsize, aouthdr_out->dsize);
684   PUT_AOUTHDR_BSIZE (abfd, aouthdr_in->bsize, aouthdr_out->bsize);
685   PUT_AOUTHDR_ENTRY (abfd, aouthdr_in->entry, aouthdr_out->entry);
686   PUT_AOUTHDR_TEXT_START (abfd, aouthdr_in->text_start,
687 			  aouthdr_out->text_start);
688   PUT_AOUTHDR_DATA_START (abfd, aouthdr_in->data_start,
689 			  aouthdr_out->data_start);
690 
691 #ifdef I960
692   H_PUT_32 (abfd, aouthdr_in->tagentries, aouthdr_out->tagentries);
693 #endif
694 
695 #ifdef RS6000COFF_C
696 #ifdef XCOFF64
697   H_PUT_64 (abfd, aouthdr_in->o_toc, aouthdr_out->o_toc);
698 #else
699   H_PUT_32 (abfd, aouthdr_in->o_toc, aouthdr_out->o_toc);
700 #endif
701   H_PUT_16 (abfd, aouthdr_in->o_snentry, aouthdr_out->o_snentry);
702   H_PUT_16 (abfd, aouthdr_in->o_sntext, aouthdr_out->o_sntext);
703   H_PUT_16 (abfd, aouthdr_in->o_sndata, aouthdr_out->o_sndata);
704   H_PUT_16 (abfd, aouthdr_in->o_sntoc, aouthdr_out->o_sntoc);
705   H_PUT_16 (abfd, aouthdr_in->o_snloader, aouthdr_out->o_snloader);
706   H_PUT_16 (abfd, aouthdr_in->o_snbss, aouthdr_out->o_snbss);
707   H_PUT_16 (abfd, aouthdr_in->o_algntext, aouthdr_out->o_algntext);
708   H_PUT_16 (abfd, aouthdr_in->o_algndata, aouthdr_out->o_algndata);
709   H_PUT_16 (abfd, aouthdr_in->o_modtype, aouthdr_out->o_modtype);
710   H_PUT_16 (abfd, aouthdr_in->o_cputype, aouthdr_out->o_cputype);
711 #ifdef XCOFF64
712   H_PUT_64 (abfd, aouthdr_in->o_maxstack, aouthdr_out->o_maxstack);
713   H_PUT_64 (abfd, aouthdr_in->o_maxdata, aouthdr_out->o_maxdata);
714 #else
715   H_PUT_32 (abfd, aouthdr_in->o_maxstack, aouthdr_out->o_maxstack);
716   H_PUT_32 (abfd, aouthdr_in->o_maxdata, aouthdr_out->o_maxdata);
717 #endif
718   memset (aouthdr_out->o_resv2, 0, sizeof aouthdr_out->o_resv2);
719 #ifdef XCOFF64
720   memset (aouthdr_out->o_debugger, 0, sizeof aouthdr_out->o_debugger);
721   memset (aouthdr_out->o_resv3, 0, sizeof aouthdr_out->o_resv3);
722 #endif
723 #endif
724 
725 #ifdef MIPSECOFF
726   H_PUT_32 (abfd, aouthdr_in->bss_start, aouthdr_out->bss_start);
727   H_PUT_32 (abfd, aouthdr_in->gp_value, aouthdr_out->gp_value);
728   H_PUT_32 (abfd, aouthdr_in->gprmask, aouthdr_out->gprmask);
729   H_PUT_32 (abfd, aouthdr_in->cprmask[0], aouthdr_out->cprmask[0]);
730   H_PUT_32 (abfd, aouthdr_in->cprmask[1], aouthdr_out->cprmask[1]);
731   H_PUT_32 (abfd, aouthdr_in->cprmask[2], aouthdr_out->cprmask[2]);
732   H_PUT_32 (abfd, aouthdr_in->cprmask[3], aouthdr_out->cprmask[3]);
733 #endif
734 
735 #ifdef ALPHAECOFF
736   /* FIXME: What does bldrev mean?  */
737   H_PUT_16 (abfd, 2, aouthdr_out->bldrev);
738   H_PUT_16 (abfd, 0, aouthdr_out->padding);
739   H_PUT_64 (abfd, aouthdr_in->bss_start, aouthdr_out->bss_start);
740   H_PUT_64 (abfd, aouthdr_in->gp_value, aouthdr_out->gp_value);
741   H_PUT_32 (abfd, aouthdr_in->gprmask, aouthdr_out->gprmask);
742   H_PUT_32 (abfd, aouthdr_in->fprmask, aouthdr_out->fprmask);
743 #endif
744 
745   return AOUTSZ;
746 }
747 
748 static void
749 coff_swap_scnhdr_in (bfd * abfd, void * ext, void * in)
750 {
751   SCNHDR *scnhdr_ext = (SCNHDR *) ext;
752   struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *) in;
753 
754 #ifdef COFF_ADJUST_SCNHDR_IN_PRE
755   COFF_ADJUST_SCNHDR_IN_PRE (abfd, ext, in);
756 #endif
757   memcpy (scnhdr_int->s_name, scnhdr_ext->s_name, sizeof (scnhdr_int->s_name));
758 
759   scnhdr_int->s_vaddr = GET_SCNHDR_VADDR (abfd, scnhdr_ext->s_vaddr);
760   scnhdr_int->s_paddr = GET_SCNHDR_PADDR (abfd, scnhdr_ext->s_paddr);
761   scnhdr_int->s_size = GET_SCNHDR_SIZE (abfd, scnhdr_ext->s_size);
762 
763   scnhdr_int->s_scnptr = GET_SCNHDR_SCNPTR (abfd, scnhdr_ext->s_scnptr);
764   scnhdr_int->s_relptr = GET_SCNHDR_RELPTR (abfd, scnhdr_ext->s_relptr);
765   scnhdr_int->s_lnnoptr = GET_SCNHDR_LNNOPTR (abfd, scnhdr_ext->s_lnnoptr);
766   scnhdr_int->s_flags = GET_SCNHDR_FLAGS (abfd, scnhdr_ext->s_flags);
767   scnhdr_int->s_nreloc = GET_SCNHDR_NRELOC (abfd, scnhdr_ext->s_nreloc);
768   scnhdr_int->s_nlnno = GET_SCNHDR_NLNNO (abfd, scnhdr_ext->s_nlnno);
769 #ifdef I960
770   scnhdr_int->s_align = GET_SCNHDR_ALIGN (abfd, scnhdr_ext->s_align);
771 #endif
772 #ifdef COFF_ADJUST_SCNHDR_IN_POST
773   COFF_ADJUST_SCNHDR_IN_POST (abfd, ext, in);
774 #endif
775 }
776 
777 static unsigned int
778 coff_swap_scnhdr_out (bfd * abfd, void * in, void * out)
779 {
780   struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *) in;
781   SCNHDR *scnhdr_ext = (SCNHDR *) out;
782   unsigned int ret = bfd_coff_scnhsz (abfd);
783 
784 #ifdef COFF_ADJUST_SCNHDR_OUT_PRE
785   COFF_ADJUST_SCNHDR_OUT_PRE (abfd, in, out);
786 #endif
787   memcpy (scnhdr_ext->s_name, scnhdr_int->s_name, sizeof (scnhdr_int->s_name));
788 
789   PUT_SCNHDR_VADDR (abfd, scnhdr_int->s_vaddr, scnhdr_ext->s_vaddr);
790   PUT_SCNHDR_PADDR (abfd, scnhdr_int->s_paddr, scnhdr_ext->s_paddr);
791   PUT_SCNHDR_SIZE (abfd, scnhdr_int->s_size, scnhdr_ext->s_size);
792   PUT_SCNHDR_SCNPTR (abfd, scnhdr_int->s_scnptr, scnhdr_ext->s_scnptr);
793   PUT_SCNHDR_RELPTR (abfd, scnhdr_int->s_relptr, scnhdr_ext->s_relptr);
794   PUT_SCNHDR_LNNOPTR (abfd, scnhdr_int->s_lnnoptr, scnhdr_ext->s_lnnoptr);
795   PUT_SCNHDR_FLAGS (abfd, scnhdr_int->s_flags, scnhdr_ext->s_flags);
796 #if defined(M88)
797   H_PUT_32 (abfd, scnhdr_int->s_nlnno, scnhdr_ext->s_nlnno);
798   H_PUT_32 (abfd, scnhdr_int->s_nreloc, scnhdr_ext->s_nreloc);
799 #else
800   if (scnhdr_int->s_nlnno <= MAX_SCNHDR_NLNNO)
801     PUT_SCNHDR_NLNNO (abfd, scnhdr_int->s_nlnno, scnhdr_ext->s_nlnno);
802   else
803     {
804       char buf[sizeof (scnhdr_int->s_name) + 1];
805 
806       memcpy (buf, scnhdr_int->s_name, sizeof (scnhdr_int->s_name));
807       buf[sizeof (scnhdr_int->s_name)] = '\0';
808       (*_bfd_error_handler)
809 	(_("%s: warning: %s: line number overflow: 0x%lx > 0xffff"),
810 	 bfd_get_filename (abfd),
811 	 buf, scnhdr_int->s_nlnno);
812       PUT_SCNHDR_NLNNO (abfd, 0xffff, scnhdr_ext->s_nlnno);
813     }
814 
815   if (scnhdr_int->s_nreloc <= MAX_SCNHDR_NRELOC)
816     PUT_SCNHDR_NRELOC (abfd, scnhdr_int->s_nreloc, scnhdr_ext->s_nreloc);
817   else
818     {
819       char buf[sizeof (scnhdr_int->s_name) + 1];
820 
821       memcpy (buf, scnhdr_int->s_name, sizeof (scnhdr_int->s_name));
822       buf[sizeof (scnhdr_int->s_name)] = '\0';
823       (*_bfd_error_handler) (_("%s: %s: reloc overflow: 0x%lx > 0xffff"),
824 			     bfd_get_filename (abfd),
825 			     buf, scnhdr_int->s_nreloc);
826       bfd_set_error (bfd_error_file_truncated);
827       PUT_SCNHDR_NRELOC (abfd, 0xffff, scnhdr_ext->s_nreloc);
828       ret = 0;
829     }
830 #endif
831 
832 #ifdef I960
833   PUT_SCNHDR_ALIGN (abfd, scnhdr_int->s_align, scnhdr_ext->s_align);
834 #endif
835 #ifdef COFF_ADJUST_SCNHDR_OUT_POST
836   COFF_ADJUST_SCNHDR_OUT_POST (abfd, in, out);
837 #endif
838   return ret;
839 }
840