1 /* Generic COFF swapping routines, for BFD.
2 Copyright (C) 1990-2016 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 #endif /* NO_COFF_RELOCS */
250
251 static void
coff_swap_filehdr_in(bfd * abfd,void * src,void * dst)252 coff_swap_filehdr_in (bfd * abfd, void * src, void * dst)
253 {
254 FILHDR *filehdr_src = (FILHDR *) src;
255 struct internal_filehdr *filehdr_dst = (struct internal_filehdr *) dst;
256
257 #ifdef COFF_ADJUST_FILEHDR_IN_PRE
258 COFF_ADJUST_FILEHDR_IN_PRE (abfd, src, dst);
259 #endif
260 filehdr_dst->f_magic = H_GET_16 (abfd, filehdr_src->f_magic);
261 filehdr_dst->f_nscns = H_GET_16 (abfd, filehdr_src->f_nscns);
262 filehdr_dst->f_timdat = H_GET_32 (abfd, filehdr_src->f_timdat);
263 filehdr_dst->f_symptr = GET_FILEHDR_SYMPTR (abfd, filehdr_src->f_symptr);
264 filehdr_dst->f_nsyms = H_GET_32 (abfd, filehdr_src->f_nsyms);
265 filehdr_dst->f_opthdr = H_GET_16 (abfd, filehdr_src->f_opthdr);
266 filehdr_dst->f_flags = H_GET_16 (abfd, filehdr_src->f_flags);
267 #ifdef TIC80_TARGET_ID
268 filehdr_dst->f_target_id = H_GET_16 (abfd, filehdr_src->f_target_id);
269 #endif
270
271 #ifdef COFF_ADJUST_FILEHDR_IN_POST
272 COFF_ADJUST_FILEHDR_IN_POST (abfd, src, dst);
273 #endif
274 }
275
276 static unsigned int
coff_swap_filehdr_out(bfd * abfd,void * in,void * out)277 coff_swap_filehdr_out (bfd *abfd, void * in, void * out)
278 {
279 struct internal_filehdr *filehdr_in = (struct internal_filehdr *) in;
280 FILHDR *filehdr_out = (FILHDR *) out;
281
282 #ifdef COFF_ADJUST_FILEHDR_OUT_PRE
283 COFF_ADJUST_FILEHDR_OUT_PRE (abfd, in, out);
284 #endif
285 H_PUT_16 (abfd, filehdr_in->f_magic, filehdr_out->f_magic);
286 H_PUT_16 (abfd, filehdr_in->f_nscns, filehdr_out->f_nscns);
287 H_PUT_32 (abfd, filehdr_in->f_timdat, filehdr_out->f_timdat);
288 PUT_FILEHDR_SYMPTR (abfd, filehdr_in->f_symptr, filehdr_out->f_symptr);
289 H_PUT_32 (abfd, filehdr_in->f_nsyms, filehdr_out->f_nsyms);
290 H_PUT_16 (abfd, filehdr_in->f_opthdr, filehdr_out->f_opthdr);
291 H_PUT_16 (abfd, filehdr_in->f_flags, filehdr_out->f_flags);
292 #ifdef TIC80_TARGET_ID
293 H_PUT_16 (abfd, filehdr_in->f_target_id, filehdr_out->f_target_id);
294 #endif
295
296 #ifdef COFF_ADJUST_FILEHDR_OUT_POST
297 COFF_ADJUST_FILEHDR_OUT_POST (abfd, in, out);
298 #endif
299 return bfd_coff_filhsz (abfd);
300 }
301
302 #ifndef NO_COFF_SYMBOLS
303
304 static void
coff_swap_sym_in(bfd * abfd,void * ext1,void * in1)305 coff_swap_sym_in (bfd * abfd, void * ext1, void * in1)
306 {
307 SYMENT *ext = (SYMENT *) ext1;
308 struct internal_syment *in = (struct internal_syment *) in1;
309
310 if (ext->e.e_name[0] == 0)
311 {
312 in->_n._n_n._n_zeroes = 0;
313 in->_n._n_n._n_offset = H_GET_32 (abfd, ext->e.e.e_offset);
314 }
315 else
316 {
317 #if SYMNMLEN != E_SYMNMLEN
318 #error we need to cope with truncating or extending SYMNMLEN
319 #else
320 memcpy (in->_n._n_name, ext->e.e_name, SYMNMLEN);
321 #endif
322 }
323
324 in->n_value = H_GET_32 (abfd, ext->e_value);
325 in->n_scnum = (short) H_GET_16 (abfd, ext->e_scnum);
326 if (sizeof (ext->e_type) == 2)
327 in->n_type = H_GET_16 (abfd, ext->e_type);
328 else
329 in->n_type = H_GET_32 (abfd, ext->e_type);
330 in->n_sclass = H_GET_8 (abfd, ext->e_sclass);
331 in->n_numaux = H_GET_8 (abfd, ext->e_numaux);
332 #ifdef COFF_ADJUST_SYM_IN_POST
333 COFF_ADJUST_SYM_IN_POST (abfd, ext1, in1);
334 #endif
335 }
336
337 static unsigned int
coff_swap_sym_out(bfd * abfd,void * inp,void * extp)338 coff_swap_sym_out (bfd * abfd, void * inp, void * extp)
339 {
340 struct internal_syment *in = (struct internal_syment *) inp;
341 SYMENT *ext =(SYMENT *) extp;
342
343 #ifdef COFF_ADJUST_SYM_OUT_PRE
344 COFF_ADJUST_SYM_OUT_PRE (abfd, inp, extp);
345 #endif
346
347 if (in->_n._n_name[0] == 0)
348 {
349 H_PUT_32 (abfd, 0, ext->e.e.e_zeroes);
350 H_PUT_32 (abfd, in->_n._n_n._n_offset, ext->e.e.e_offset);
351 }
352 else
353 {
354 #if SYMNMLEN != E_SYMNMLEN
355 #error we need to cope with truncating or extending SYMNMLEN
356 #else
357 memcpy (ext->e.e_name, in->_n._n_name, SYMNMLEN);
358 #endif
359 }
360
361 H_PUT_32 (abfd, in->n_value, ext->e_value);
362 H_PUT_16 (abfd, in->n_scnum, ext->e_scnum);
363
364 if (sizeof (ext->e_type) == 2)
365 H_PUT_16 (abfd, in->n_type, ext->e_type);
366 else
367 H_PUT_32 (abfd, in->n_type, ext->e_type);
368
369 H_PUT_8 (abfd, in->n_sclass, ext->e_sclass);
370 H_PUT_8 (abfd, in->n_numaux, ext->e_numaux);
371
372 #ifdef COFF_ADJUST_SYM_OUT_POST
373 COFF_ADJUST_SYM_OUT_POST (abfd, inp, extp);
374 #endif
375
376 return SYMESZ;
377 }
378
379 static void
coff_swap_aux_in(bfd * abfd,void * ext1,int type,int in_class,int indx,int numaux,void * in1)380 coff_swap_aux_in (bfd *abfd,
381 void * ext1,
382 int type,
383 int in_class,
384 int indx,
385 int numaux,
386 void * in1)
387 {
388 AUXENT *ext = (AUXENT *) ext1;
389 union internal_auxent *in = (union internal_auxent *) in1;
390
391 #ifdef COFF_ADJUST_AUX_IN_PRE
392 COFF_ADJUST_AUX_IN_PRE (abfd, ext1, type, in_class, indx, numaux, in1);
393 #endif
394
395 switch (in_class)
396 {
397 case C_FILE:
398 if (ext->x_file.x_fname[0] == 0)
399 {
400 in->x_file.x_n.x_zeroes = 0;
401 in->x_file.x_n.x_offset = H_GET_32 (abfd, ext->x_file.x_n.x_offset);
402 }
403 else
404 {
405 #if FILNMLEN != E_FILNMLEN
406 #error we need to cope with truncating or extending FILNMLEN
407 #else
408 if (numaux > 1)
409 {
410 if (indx == 0)
411 memcpy (in->x_file.x_fname, ext->x_file.x_fname,
412 numaux * sizeof (AUXENT));
413 }
414 else
415 memcpy (in->x_file.x_fname, ext->x_file.x_fname, FILNMLEN);
416 #endif
417 }
418 goto end;
419
420 case C_STAT:
421 #ifdef C_LEAFSTAT
422 case C_LEAFSTAT:
423 #endif
424 case C_HIDDEN:
425 if (type == T_NULL)
426 {
427 in->x_scn.x_scnlen = GET_SCN_SCNLEN (abfd, ext);
428 in->x_scn.x_nreloc = GET_SCN_NRELOC (abfd, ext);
429 in->x_scn.x_nlinno = GET_SCN_NLINNO (abfd, ext);
430
431 /* PE defines some extra fields; we zero them out for
432 safety. */
433 in->x_scn.x_checksum = 0;
434 in->x_scn.x_associated = 0;
435 in->x_scn.x_comdat = 0;
436
437 goto end;
438 }
439 break;
440 }
441
442 in->x_sym.x_tagndx.l = H_GET_32 (abfd, ext->x_sym.x_tagndx);
443 #ifndef NO_TVNDX
444 in->x_sym.x_tvndx = H_GET_16 (abfd, ext->x_sym.x_tvndx);
445 #endif
446
447 if (in_class == C_BLOCK || in_class == C_FCN || ISFCN (type)
448 || ISTAG (in_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, in_class, indx, numaux, in1);
480 #endif
481 }
482
483 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)484 coff_swap_aux_out (bfd * abfd,
485 void * inp,
486 int type,
487 int in_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, in_class, indx, numaux, extp);
497 #endif
498
499 memset (ext, 0, AUXESZ);
500
501 switch (in_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 (in_class == C_BLOCK || in_class == C_FCN || ISFCN (type)
540 || ISTAG (in_class))
541 {
542 PUT_FCN_LNNOPTR (abfd, in->x_sym.x_fcnary.x_fcn.x_lnnoptr, ext);
543 PUT_FCN_ENDNDX (abfd, in->x_sym.x_fcnary.x_fcn.x_endndx.l, ext);
544 }
545 else
546 {
547 #if DIMNUM != E_DIMNUM
548 #error we need to cope with truncating or extending DIMNUM
549 #endif
550 H_PUT_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[0],
551 ext->x_sym.x_fcnary.x_ary.x_dimen[0]);
552 H_PUT_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[1],
553 ext->x_sym.x_fcnary.x_ary.x_dimen[1]);
554 H_PUT_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[2],
555 ext->x_sym.x_fcnary.x_ary.x_dimen[2]);
556 H_PUT_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[3],
557 ext->x_sym.x_fcnary.x_ary.x_dimen[3]);
558 }
559
560 if (ISFCN (type))
561 H_PUT_32 (abfd, in->x_sym.x_misc.x_fsize, ext->x_sym.x_misc.x_fsize);
562 else
563 {
564 PUT_LNSZ_LNNO (abfd, in->x_sym.x_misc.x_lnsz.x_lnno, ext);
565 PUT_LNSZ_SIZE (abfd, in->x_sym.x_misc.x_lnsz.x_size, ext);
566 }
567
568 end:
569 #ifdef COFF_ADJUST_AUX_OUT_POST
570 COFF_ADJUST_AUX_OUT_POST (abfd, inp, type, in_class, indx, numaux, extp);
571 #endif
572 return AUXESZ;
573 }
574
575 #endif /* NO_COFF_SYMBOLS */
576
577 #ifndef NO_COFF_LINENOS
578
579 static void
coff_swap_lineno_in(bfd * abfd,void * ext1,void * in1)580 coff_swap_lineno_in (bfd * abfd, void * ext1, void * in1)
581 {
582 LINENO *ext = (LINENO *) ext1;
583 struct internal_lineno *in = (struct internal_lineno *) in1;
584
585 in->l_addr.l_symndx = H_GET_32 (abfd, ext->l_addr.l_symndx);
586 in->l_lnno = GET_LINENO_LNNO (abfd, ext);
587 }
588
589 static unsigned int
coff_swap_lineno_out(bfd * abfd,void * inp,void * outp)590 coff_swap_lineno_out (bfd * abfd, void * inp, void * outp)
591 {
592 struct internal_lineno *in = (struct internal_lineno *) inp;
593 struct external_lineno *ext = (struct external_lineno *) outp;
594 H_PUT_32 (abfd, in->l_addr.l_symndx, ext->l_addr.l_symndx);
595
596 PUT_LINENO_LNNO (abfd, in->l_lnno, ext);
597 return LINESZ;
598 }
599
600 #endif /* NO_COFF_LINENOS */
601
602 static void
coff_swap_aouthdr_in(bfd * abfd,void * aouthdr_ext1,void * aouthdr_int1)603 coff_swap_aouthdr_in (bfd * abfd, void * aouthdr_ext1, void * aouthdr_int1)
604 {
605 AOUTHDR *aouthdr_ext;
606 struct internal_aouthdr *aouthdr_int;
607
608 aouthdr_ext = (AOUTHDR *) aouthdr_ext1;
609 aouthdr_int = (struct internal_aouthdr *) aouthdr_int1;
610 aouthdr_int->magic = H_GET_16 (abfd, aouthdr_ext->magic);
611 aouthdr_int->vstamp = H_GET_16 (abfd, aouthdr_ext->vstamp);
612 aouthdr_int->tsize = GET_AOUTHDR_TSIZE (abfd, aouthdr_ext->tsize);
613 aouthdr_int->dsize = GET_AOUTHDR_DSIZE (abfd, aouthdr_ext->dsize);
614 aouthdr_int->bsize = GET_AOUTHDR_BSIZE (abfd, aouthdr_ext->bsize);
615 aouthdr_int->entry = GET_AOUTHDR_ENTRY (abfd, aouthdr_ext->entry);
616 aouthdr_int->text_start =
617 GET_AOUTHDR_TEXT_START (abfd, aouthdr_ext->text_start);
618 aouthdr_int->data_start =
619 GET_AOUTHDR_DATA_START (abfd, aouthdr_ext->data_start);
620
621 #ifdef I960
622 aouthdr_int->tagentries = H_GET_32 (abfd, aouthdr_ext->tagentries);
623 #endif
624
625 #ifdef APOLLO_M68
626 H_PUT_32 (abfd, aouthdr_int->o_inlib, aouthdr_ext->o_inlib);
627 H_PUT_32 (abfd, aouthdr_int->o_sri, aouthdr_ext->o_sri);
628 H_PUT_32 (abfd, aouthdr_int->vid[0], aouthdr_ext->vid);
629 H_PUT_32 (abfd, aouthdr_int->vid[1], aouthdr_ext->vid + 4);
630 #endif
631
632 #ifdef RS6000COFF_C
633 #ifdef XCOFF64
634 aouthdr_int->o_toc = H_GET_64 (abfd, aouthdr_ext->o_toc);
635 #else
636 aouthdr_int->o_toc = H_GET_32 (abfd, aouthdr_ext->o_toc);
637 #endif
638 aouthdr_int->o_snentry = H_GET_16 (abfd, aouthdr_ext->o_snentry);
639 aouthdr_int->o_sntext = H_GET_16 (abfd, aouthdr_ext->o_sntext);
640 aouthdr_int->o_sndata = H_GET_16 (abfd, aouthdr_ext->o_sndata);
641 aouthdr_int->o_sntoc = H_GET_16 (abfd, aouthdr_ext->o_sntoc);
642 aouthdr_int->o_snloader = H_GET_16 (abfd, aouthdr_ext->o_snloader);
643 aouthdr_int->o_snbss = H_GET_16 (abfd, aouthdr_ext->o_snbss);
644 aouthdr_int->o_algntext = H_GET_16 (abfd, aouthdr_ext->o_algntext);
645 aouthdr_int->o_algndata = H_GET_16 (abfd, aouthdr_ext->o_algndata);
646 aouthdr_int->o_modtype = H_GET_16 (abfd, aouthdr_ext->o_modtype);
647 aouthdr_int->o_cputype = H_GET_16 (abfd, aouthdr_ext->o_cputype);
648 #ifdef XCOFF64
649 aouthdr_int->o_maxstack = H_GET_64 (abfd, aouthdr_ext->o_maxstack);
650 aouthdr_int->o_maxdata = H_GET_64 (abfd, aouthdr_ext->o_maxdata);
651 #else
652 aouthdr_int->o_maxstack = H_GET_32 (abfd, aouthdr_ext->o_maxstack);
653 aouthdr_int->o_maxdata = H_GET_32 (abfd, aouthdr_ext->o_maxdata);
654 #endif
655 #endif
656
657 #ifdef MIPSECOFF
658 aouthdr_int->bss_start = H_GET_32 (abfd, aouthdr_ext->bss_start);
659 aouthdr_int->gp_value = H_GET_32 (abfd, aouthdr_ext->gp_value);
660 aouthdr_int->gprmask = H_GET_32 (abfd, aouthdr_ext->gprmask);
661 aouthdr_int->cprmask[0] = H_GET_32 (abfd, aouthdr_ext->cprmask[0]);
662 aouthdr_int->cprmask[1] = H_GET_32 (abfd, aouthdr_ext->cprmask[1]);
663 aouthdr_int->cprmask[2] = H_GET_32 (abfd, aouthdr_ext->cprmask[2]);
664 aouthdr_int->cprmask[3] = H_GET_32 (abfd, aouthdr_ext->cprmask[3]);
665 #endif
666
667 #ifdef ALPHAECOFF
668 aouthdr_int->bss_start = H_GET_64 (abfd, aouthdr_ext->bss_start);
669 aouthdr_int->gp_value = H_GET_64 (abfd, aouthdr_ext->gp_value);
670 aouthdr_int->gprmask = H_GET_32 (abfd, aouthdr_ext->gprmask);
671 aouthdr_int->fprmask = H_GET_32 (abfd, aouthdr_ext->fprmask);
672 #endif
673 }
674
675 static unsigned int
coff_swap_aouthdr_out(bfd * abfd,void * in,void * out)676 coff_swap_aouthdr_out (bfd * abfd, void * in, void * out)
677 {
678 struct internal_aouthdr *aouthdr_in = (struct internal_aouthdr *) in;
679 AOUTHDR *aouthdr_out = (AOUTHDR *) out;
680
681 H_PUT_16 (abfd, aouthdr_in->magic, aouthdr_out->magic);
682 H_PUT_16 (abfd, aouthdr_in->vstamp, aouthdr_out->vstamp);
683 PUT_AOUTHDR_TSIZE (abfd, aouthdr_in->tsize, aouthdr_out->tsize);
684 PUT_AOUTHDR_DSIZE (abfd, aouthdr_in->dsize, aouthdr_out->dsize);
685 PUT_AOUTHDR_BSIZE (abfd, aouthdr_in->bsize, aouthdr_out->bsize);
686 PUT_AOUTHDR_ENTRY (abfd, aouthdr_in->entry, aouthdr_out->entry);
687 PUT_AOUTHDR_TEXT_START (abfd, aouthdr_in->text_start,
688 aouthdr_out->text_start);
689 PUT_AOUTHDR_DATA_START (abfd, aouthdr_in->data_start,
690 aouthdr_out->data_start);
691
692 #ifdef I960
693 H_PUT_32 (abfd, aouthdr_in->tagentries, aouthdr_out->tagentries);
694 #endif
695
696 #ifdef RS6000COFF_C
697 #ifdef XCOFF64
698 H_PUT_64 (abfd, aouthdr_in->o_toc, aouthdr_out->o_toc);
699 #else
700 H_PUT_32 (abfd, aouthdr_in->o_toc, aouthdr_out->o_toc);
701 #endif
702 H_PUT_16 (abfd, aouthdr_in->o_snentry, aouthdr_out->o_snentry);
703 H_PUT_16 (abfd, aouthdr_in->o_sntext, aouthdr_out->o_sntext);
704 H_PUT_16 (abfd, aouthdr_in->o_sndata, aouthdr_out->o_sndata);
705 H_PUT_16 (abfd, aouthdr_in->o_sntoc, aouthdr_out->o_sntoc);
706 H_PUT_16 (abfd, aouthdr_in->o_snloader, aouthdr_out->o_snloader);
707 H_PUT_16 (abfd, aouthdr_in->o_snbss, aouthdr_out->o_snbss);
708 H_PUT_16 (abfd, aouthdr_in->o_algntext, aouthdr_out->o_algntext);
709 H_PUT_16 (abfd, aouthdr_in->o_algndata, aouthdr_out->o_algndata);
710 H_PUT_16 (abfd, aouthdr_in->o_modtype, aouthdr_out->o_modtype);
711 H_PUT_16 (abfd, aouthdr_in->o_cputype, aouthdr_out->o_cputype);
712 #ifdef XCOFF64
713 H_PUT_64 (abfd, aouthdr_in->o_maxstack, aouthdr_out->o_maxstack);
714 H_PUT_64 (abfd, aouthdr_in->o_maxdata, aouthdr_out->o_maxdata);
715 #else
716 H_PUT_32 (abfd, aouthdr_in->o_maxstack, aouthdr_out->o_maxstack);
717 H_PUT_32 (abfd, aouthdr_in->o_maxdata, aouthdr_out->o_maxdata);
718 #endif
719 memset (aouthdr_out->o_resv2, 0, sizeof aouthdr_out->o_resv2);
720 #ifdef XCOFF64
721 memset (aouthdr_out->o_debugger, 0, sizeof aouthdr_out->o_debugger);
722 memset (aouthdr_out->o_resv3, 0, sizeof aouthdr_out->o_resv3);
723 #endif
724 #endif
725
726 #ifdef MIPSECOFF
727 H_PUT_32 (abfd, aouthdr_in->bss_start, aouthdr_out->bss_start);
728 H_PUT_32 (abfd, aouthdr_in->gp_value, aouthdr_out->gp_value);
729 H_PUT_32 (abfd, aouthdr_in->gprmask, aouthdr_out->gprmask);
730 H_PUT_32 (abfd, aouthdr_in->cprmask[0], aouthdr_out->cprmask[0]);
731 H_PUT_32 (abfd, aouthdr_in->cprmask[1], aouthdr_out->cprmask[1]);
732 H_PUT_32 (abfd, aouthdr_in->cprmask[2], aouthdr_out->cprmask[2]);
733 H_PUT_32 (abfd, aouthdr_in->cprmask[3], aouthdr_out->cprmask[3]);
734 #endif
735
736 #ifdef ALPHAECOFF
737 /* FIXME: What does bldrev mean? */
738 H_PUT_16 (abfd, 2, aouthdr_out->bldrev);
739 H_PUT_16 (abfd, 0, aouthdr_out->padding);
740 H_PUT_64 (abfd, aouthdr_in->bss_start, aouthdr_out->bss_start);
741 H_PUT_64 (abfd, aouthdr_in->gp_value, aouthdr_out->gp_value);
742 H_PUT_32 (abfd, aouthdr_in->gprmask, aouthdr_out->gprmask);
743 H_PUT_32 (abfd, aouthdr_in->fprmask, aouthdr_out->fprmask);
744 #endif
745
746 return AOUTSZ;
747 }
748
749 static void
coff_swap_scnhdr_in(bfd * abfd,void * ext,void * in)750 coff_swap_scnhdr_in (bfd * abfd, void * ext, void * in)
751 {
752 SCNHDR *scnhdr_ext = (SCNHDR *) ext;
753 struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *) in;
754
755 #ifdef COFF_ADJUST_SCNHDR_IN_PRE
756 COFF_ADJUST_SCNHDR_IN_PRE (abfd, ext, in);
757 #endif
758 memcpy (scnhdr_int->s_name, scnhdr_ext->s_name, sizeof (scnhdr_int->s_name));
759
760 scnhdr_int->s_vaddr = GET_SCNHDR_VADDR (abfd, scnhdr_ext->s_vaddr);
761 scnhdr_int->s_paddr = GET_SCNHDR_PADDR (abfd, scnhdr_ext->s_paddr);
762 scnhdr_int->s_size = GET_SCNHDR_SIZE (abfd, scnhdr_ext->s_size);
763
764 scnhdr_int->s_scnptr = GET_SCNHDR_SCNPTR (abfd, scnhdr_ext->s_scnptr);
765 scnhdr_int->s_relptr = GET_SCNHDR_RELPTR (abfd, scnhdr_ext->s_relptr);
766 scnhdr_int->s_lnnoptr = GET_SCNHDR_LNNOPTR (abfd, scnhdr_ext->s_lnnoptr);
767 scnhdr_int->s_flags = GET_SCNHDR_FLAGS (abfd, scnhdr_ext->s_flags);
768 scnhdr_int->s_nreloc = GET_SCNHDR_NRELOC (abfd, scnhdr_ext->s_nreloc);
769 scnhdr_int->s_nlnno = GET_SCNHDR_NLNNO (abfd, scnhdr_ext->s_nlnno);
770 #ifdef I960
771 scnhdr_int->s_align = GET_SCNHDR_ALIGN (abfd, scnhdr_ext->s_align);
772 #endif
773 #ifdef COFF_ADJUST_SCNHDR_IN_POST
774 COFF_ADJUST_SCNHDR_IN_POST (abfd, ext, in);
775 #endif
776 }
777
778 static unsigned int
coff_swap_scnhdr_out(bfd * abfd,void * in,void * out)779 coff_swap_scnhdr_out (bfd * abfd, void * in, void * out)
780 {
781 struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *) in;
782 SCNHDR *scnhdr_ext = (SCNHDR *) out;
783 unsigned int ret = bfd_coff_scnhsz (abfd);
784
785 #ifdef COFF_ADJUST_SCNHDR_OUT_PRE
786 COFF_ADJUST_SCNHDR_OUT_PRE (abfd, in, out);
787 #endif
788 memcpy (scnhdr_ext->s_name, scnhdr_int->s_name, sizeof (scnhdr_int->s_name));
789
790 PUT_SCNHDR_VADDR (abfd, scnhdr_int->s_vaddr, scnhdr_ext->s_vaddr);
791 PUT_SCNHDR_PADDR (abfd, scnhdr_int->s_paddr, scnhdr_ext->s_paddr);
792 PUT_SCNHDR_SIZE (abfd, scnhdr_int->s_size, scnhdr_ext->s_size);
793 PUT_SCNHDR_SCNPTR (abfd, scnhdr_int->s_scnptr, scnhdr_ext->s_scnptr);
794 PUT_SCNHDR_RELPTR (abfd, scnhdr_int->s_relptr, scnhdr_ext->s_relptr);
795 PUT_SCNHDR_LNNOPTR (abfd, scnhdr_int->s_lnnoptr, scnhdr_ext->s_lnnoptr);
796 PUT_SCNHDR_FLAGS (abfd, scnhdr_int->s_flags, scnhdr_ext->s_flags);
797 #if defined(M88)
798 H_PUT_32 (abfd, scnhdr_int->s_nlnno, scnhdr_ext->s_nlnno);
799 H_PUT_32 (abfd, scnhdr_int->s_nreloc, scnhdr_ext->s_nreloc);
800 #else
801 if (scnhdr_int->s_nlnno <= MAX_SCNHDR_NLNNO)
802 PUT_SCNHDR_NLNNO (abfd, scnhdr_int->s_nlnno, scnhdr_ext->s_nlnno);
803 else
804 {
805 char buf[sizeof (scnhdr_int->s_name) + 1];
806
807 memcpy (buf, scnhdr_int->s_name, sizeof (scnhdr_int->s_name));
808 buf[sizeof (scnhdr_int->s_name)] = '\0';
809 (*_bfd_error_handler)
810 (_("%s: warning: %s: line number overflow: 0x%lx > 0xffff"),
811 bfd_get_filename (abfd),
812 buf, scnhdr_int->s_nlnno);
813 PUT_SCNHDR_NLNNO (abfd, 0xffff, scnhdr_ext->s_nlnno);
814 }
815
816 if (scnhdr_int->s_nreloc <= MAX_SCNHDR_NRELOC)
817 PUT_SCNHDR_NRELOC (abfd, scnhdr_int->s_nreloc, scnhdr_ext->s_nreloc);
818 else
819 {
820 char buf[sizeof (scnhdr_int->s_name) + 1];
821
822 memcpy (buf, scnhdr_int->s_name, sizeof (scnhdr_int->s_name));
823 buf[sizeof (scnhdr_int->s_name)] = '\0';
824 (*_bfd_error_handler) (_("%s: %s: reloc overflow: 0x%lx > 0xffff"),
825 bfd_get_filename (abfd),
826 buf, scnhdr_int->s_nreloc);
827 bfd_set_error (bfd_error_file_truncated);
828 PUT_SCNHDR_NRELOC (abfd, 0xffff, scnhdr_ext->s_nreloc);
829 ret = 0;
830 }
831 #endif
832
833 #ifdef I960
834 PUT_SCNHDR_ALIGN (abfd, scnhdr_int->s_align, scnhdr_ext->s_align);
835 #endif
836 #ifdef COFF_ADJUST_SCNHDR_OUT_POST
837 COFF_ADJUST_SCNHDR_OUT_POST (abfd, in, out);
838 #endif
839 return ret;
840 }
841