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