1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22/*
23 * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
24 * Use is subject to license terms.
25 */
26
27#pragma ident	"%Z%%M%	%I%	%E% SMI"
28
29#include "syn.h"
30#include <memory.h>
31#include <libelf.h>
32#include <link.h>
33#include <sys/elf_SPARC.h>
34#include <sys/elf_amd64.h>
35#include <decl.h>
36#include <msg.h>
37#include <sgs.h>
38
39
40/*
41 * fmsize:  Array used to determine what size the the structures
42 *	    are (for memory image & file image).
43 *
44 * x64:  Translation routines - to file & to memory.
45 *
46 * What must be done when adding a new type for conversion:
47 *
48 * The first question is whether you need a new ELF_T_* type
49 * to be created.  If you've introduced a new structure - then
50 * it will need to be described - this is done by:
51 *
52 * o adding a new type ELF_T_* to usr/src/head/libelf.h
53 * o Create a new macro to define the bytes contained in the structure. Take a
54 *   look at the 'Syminfo_1' macro defined below.  The declarations describe
55 *   the structure based off of the field size of each element of the structure.
56 * o Add a entry to the fmsize table for the new ELF_T_* type.
57 * o Create a <newtype>_11_tof macro.  Take a look at 'syminfo_11_tof'.
58 * o Create a <newtype>_11_tom macro.  Take a look at 'syminfo_11_tom'.
59 * o The <newtype>_11_tof & <newtype>_11_tom results in conversion routines
60 *   <newtype>_2L11_tof, <newtype>_2L11_tom, <newtype>_2M11_tof,
61 *   <newtype>_2M11_tom being created in xlate.c.  These routines
62 *   need to be added to the 'x64[]' array.
63 * o Add entries to getdata.c::align32[] and getdata.c::align64[].  These
64 *   tables define what the alignment requirements for a data type are.
65 *
66 * In order to tie a section header type (SHT_*) to a data
67 * structure you need to update elf64_mtype() so that it can
68 * make the association.  If you are introducing a new section built
69 * on a basic datatype (SHT_INIT_ARRAY) then this is all the updating
70 * that needs to be done.
71 *
72 *
73 * ELF translation routines
74 *
75 *	These routines make a subtle implicit assumption.
76 *	The file representations of all structures are "packed,"
77 *	meaning no implicit padding bytes occur.  This might not
78 *	be the case for the memory representations.  Consequently,
79 *	the memory representations ALWAYS contain at least as many
80 *	bytes as the file representations.  Otherwise, the memory
81 *	structures would lose information, meaning they're not
82 *	implemented properly.
83 *
84 *	The words above apply to structures with the same members.
85 *	If a future version changes the number of members, the
86 *	relative structure sizes for different version must be
87 *	tested with the compiler.
88 */
89
90#define	HI32	0x80000000UL
91#define	LO31	0x7fffffffUL
92
93#define	HI64	0x8000000000000000ULL
94#define	LO63	0x7fffffffffffffffULL
95
96/*
97 *	These macros create indexes for accessing the bytes of
98 *	words and halfwords for ELFCLASS64 data representations
99 *	(currently ELFDATA2LSB and ELFDATA2MSB).  In all cases,
100 *
101 *	x = ((((((((((((X_7 << 8) + X_6) << 8) + X_5) << 8) + X_4) << 8
102 *		+ X_3) << 8) + X_2) << 8) + X_1) << 8) + X_0
103 *	w = (((((X_3 << 8) + X_2) << 8) + X_1) << 8) + X_0
104 *	h = (X_1 << 8) + X_0
105 *
106 *	These assume the file representations for Addr, Off,
107 *	Sword, and Word use 4 bytes, but the memory def's for
108 *	the types may differ.
109 *
110 *	Naming convention:
111 *		..._L	ELFDATA2LSB
112 *		..._M	ELFDATA2MSB
113 *
114 *	enuma_*(n)	define enum names for addr n
115 *	enumb_*(n)	define enum names for byte n
116 *	enumh_*(n)	define enum names for half n
117 *	enumo_*(n)	define enum names for off n
118 *	enumw_*(n)	define enum names for word n
119 *	enumx_*(n)	define enum names for xword n
120 *	enuml_*(n)	define enum names for Lword n
121 *	tofa(d,s,n)	xlate addr n from mem s to file d
122 *	tofb(d,s,n)	xlate byte n from mem s to file d
123 *	tofh(d,s,n)	xlate half n from mem s to file d
124 *	tofo(d,s,n)	xlate off n from mem s to file d
125 *	tofw(d,s,n)	xlate word n from mem s to file d
126 *	tofx(d,s,n)	xlate xword n from mem s to file d
127 *	tofl(d,s,n)	xlate Lword n from mem s to file d
128 *	toma(s,n)	xlate addr n from file s to expression value
129 *	tomb(s,n)	xlate byte n from file s to expression value
130 *	tomh(s,n)	xlate half n from file s to expression value
131 *	tomo(s,n)	xlate off n from file s to expression value
132 *	tomw(s,n)	xlate word n from file s to expression value
133 *	tomx(s,n)	xlate xword n from file s to expression value
134 *	toml(s,n)	xlate Lword n from file s to expression value
135 *
136 *	tof*() macros must move a multi-byte value into a temporary
137 *	because ``in place'' conversions are allowed.  If a temp is not
138 *	used for multi-byte objects, storing an initial destination byte
139 *	may clobber a source byte not yet examined.
140 *
141 *	tom*() macros compute an expression value from the source
142 *	without touching the destination; so they're safe.
143 */
144
145define(enuma_L, `$1_L0, $1_L1, $1_L2, $1_L3, $1_L4, $1_L5, $1_L6, $1_L7')dnl
146define(enuma_M, `$1_M7, $1_M6, $1_M5, $1_M4, $1_M3, $1_M2, $1_M1, $1_M0')dnl
147define(enumb_L, `$1_L')dnl
148define(enumb_M, `$1_M')dnl
149define(enumh_L, `$1_L0, $1_L1')dnl
150define(enumh_M, `$1_M1, $1_M0')dnl
151define(enumo_L, `$1_L0, $1_L1, $1_L2, $1_L3, $1_L4, $1_L5, $1_L6, $1_L7')dnl
152define(enumo_M, `$1_M7, $1_M6, $1_M5, $1_M4, $1_M3, $1_M2, $1_M1, $1_M0')dnl
153define(enumw_L, `$1_L0, $1_L1, $1_L2, $1_L3')dnl
154define(enumw_M, `$1_M3, $1_M2, $1_M1, $1_M0')dnl
155define(enumx_L, `$1_L0, $1_L1, $1_L2, $1_L3, $1_L4, $1_L5, $1_L6, $1_L7')dnl
156define(enumx_M, `$1_M7, $1_M6, $1_M5, $1_M4, $1_M3, $1_M2, $1_M1, $1_M0')dnl
157define(enuml_L, `$1_L0, $1_L1, $1_L2, $1_L3, $1_L4, $1_L5, $1_L6, $1_L7')dnl
158define(enuml_M, `$1_M7, $1_M6, $1_M5, $1_M4, $1_M3, $1_M2, $1_M1, $1_M0')dnl
159
160define(tofa, `{	Elf64_Addr _t_ = $2;
161		($1)[$3`'0] = (Byte)_t_,
162		($1)[$3`'1] = (Byte)(_t_>>8),
163		($1)[$3`'2] = (Byte)(_t_>>16),
164		($1)[$3`'3] = (Byte)(_t_>>24),
165		($1)[$3`'4] = (Byte)(_t_>>32),
166		($1)[$3`'5] = (Byte)(_t_>>40),
167		($1)[$3`'6] = (Byte)(_t_>>48),
168		($1)[$3`'7] = (Byte)(_t_>>56); }')dnl
169define(tofb, `($1)[$3] = (Byte)($2)')dnl
170define(tofh, `{ Elf64_Half _t_ = $2;
171		($1)[$3`'0] = (Byte)_t_,
172		($1)[$3`'1] = (Byte)(_t_>>8); }')dnl
173define(tofo, `{ Elf64_Off _t_ = $2;
174		($1)[$3`'0] = (Byte)_t_,
175		($1)[$3`'1] = (Byte)(_t_>>8),
176		($1)[$3`'2] = (Byte)(_t_>>16),
177		($1)[$3`'3] = (Byte)(_t_>>24),
178		($1)[$3`'4] = (Byte)(_t_>>32),
179		($1)[$3`'5] = (Byte)(_t_>>40),
180		($1)[$3`'6] = (Byte)(_t_>>48),
181		($1)[$3`'7] = (Byte)(_t_>>56); }')dnl
182define(tofw, `{ Elf64_Word _t_ = $2;
183		($1)[$3`'0] = (Byte)_t_,
184		($1)[$3`'1] = (Byte)(_t_>>8),
185		($1)[$3`'2] = (Byte)(_t_>>16),
186		($1)[$3`'3] = (Byte)(_t_>>24); }')dnl
187define(tofx, `{ Elf64_Xword _t_ = $2;
188		($1)[$3`'0] = (Byte)_t_,
189		($1)[$3`'1] = (Byte)(_t_>>8),
190		($1)[$3`'2] = (Byte)(_t_>>16),
191		($1)[$3`'3] = (Byte)(_t_>>24),
192		($1)[$3`'4] = (Byte)(_t_>>32),
193		($1)[$3`'5] = (Byte)(_t_>>40),
194		($1)[$3`'6] = (Byte)(_t_>>48),
195		($1)[$3`'7] = (Byte)(_t_>>56); }')dnl
196define(tofl, `{ Elf64_Lword _t_ = $2;
197		($1)[$3`'0] = (Byte)_t_,
198		($1)[$3`'1] = (Byte)(_t_>>8),
199		($1)[$3`'2] = (Byte)(_t_>>16),
200		($1)[$3`'3] = (Byte)(_t_>>24),
201		($1)[$3`'4] = (Byte)(_t_>>32),
202		($1)[$3`'5] = (Byte)(_t_>>40),
203		($1)[$3`'6] = (Byte)(_t_>>48),
204		($1)[$3`'7] = (Byte)(_t_>>56); }')dnl
205
206define(toma, `(((((((((((Elf64_Addr)($1)[$2`'7]<<8)
207		+($1)[$2`'6]<<8)
208		+($1)[$2`'5]<<8)
209		+($1)[$2`'4]<<8)
210		+($1)[$2`'3]<<8)
211		+($1)[$2`'2])<<8)
212		+($1)[$2`'1])<<8)
213		+($1)[$2`'0])')dnl
214define(tomb, `((Byte)($1)[$2])')dnl
215define(tomh, `(((Elf64_Half)($1)[$2`'1]<<8)+($1)[$2`'0])')dnl
216define(tomo, `(((((((((((Elf64_Off)($1)[$2`'7]<<8)
217		+($1)[$2`'6]<<8)
218		+($1)[$2`'5]<<8)
219		+($1)[$2`'4]<<8)
220		+($1)[$2`'3]<<8)
221		+($1)[$2`'2])<<8)
222		+($1)[$2`'1])<<8)
223		+($1)[$2`'0])')dnl
224define(tomw, `(((((((Elf64_Word)($1)[$2`'3]<<8)
225		+($1)[$2`'2])<<8)
226		+($1)[$2`'1])<<8)
227		+($1)[$2`'0])')dnl
228define(tomx, `(((((((((((Elf64_Xword)($1)[$2`'7]<<8)
229		+($1)[$2`'6]<<8)
230		+($1)[$2`'5]<<8)
231		+($1)[$2`'4]<<8)
232		+($1)[$2`'3]<<8)
233		+($1)[$2`'2])<<8)
234		+($1)[$2`'1])<<8)
235		+($1)[$2`'0])')dnl
236define(toml, `(((((((((((Elf64_Lword)($1)[$2`'7]<<8)
237		+($1)[$2`'6]<<8)
238		+($1)[$2`'5]<<8)
239		+($1)[$2`'4]<<8)
240		+($1)[$2`'3]<<8)
241		+($1)[$2`'2])<<8)
242		+($1)[$2`'1])<<8)
243		+($1)[$2`'0])')dnl
244
245
246/*
247 * ELF data object indexes
248 *	The enums are broken apart to get around deficiencies
249 *	in some compilers.
250 */
251
252define(Addr, `
253enum
254{
255	enuma_$1(A)`'ifelse(`$2', `', `', `,
256	A_sizeof')
257};')
258
259Addr(L)
260Addr(M,1)
261
262
263define(Half, `
264enum
265{
266	enumh_$1(H)`'ifelse(`$2', `', `', `,
267	H_sizeof')
268};')
269
270Half(L)
271Half(M,1)
272
273define(Lword, `
274enum
275{
276	enuml_$1(L)`'ifelse(`$2', `', `', `,
277	L_sizeof')
278};')
279
280Lword(L)
281Lword(M,1)
282
283define(Move_1, `
284enum
285{
286	enuml_$1(M1_value),
287	enumx_$1(M1_info),
288	enumx_$1(M1_poffset),
289	enumh_$1(M1_repeat),
290	enumh_$1(M1_stride)`'ifelse(`$2', `', `', `,
291	M1_sizeof')
292};')
293
294Move_1(L)
295Move_1(M,1)
296
297
298define(MoveP_1, `
299enum
300{
301	enuml_$1(MP1_value),
302	enumx_$1(MP1_info),
303	enumx_$1(MP1_poffset),
304	enumh_$1(MP1_repeat),
305	enumh_$1(MP1_stride),
306	enumw_$1(MP1_padding)`'ifelse(`$2', `', `', `,
307	MP1_sizeof')
308};')
309
310MoveP_1(L)
311MoveP_1(M,1)
312
313
314define(Off, `
315enum
316{
317	enumo_$1(O)`'ifelse(`$2', `', `', `,
318	O_sizeof')
319};')
320
321Off(L)
322Off(M,1)
323
324
325define(Word, `
326enum
327{
328	enumw_$1(W)`'ifelse(`$2', `', `', `,
329	W_sizeof')
330};')
331
332Word(L)
333Word(M,1)
334
335
336define(Xword, `
337enum
338{
339	enumx_$1(X)`'ifelse(`$2',`', `', `,
340	X_sizeof')
341};')
342
343Xword(L)
344Xword(M,1)
345
346
347define(Dyn_1, `
348enum
349{
350	enumx_$1(D1_tag),
351	enumx_$1(D1_val)`'ifelse(`$2', `', `', `,
352	D1_sizeof')
353};')
354
355Dyn_1(L)
356Dyn_1(M,1)
357
358
359#define	E1_Nident	16
360
361define(Ehdr_1, `
362enum {
363	ifelse(`$2', `', `E1_ident, ')E1_ident_$1_Z = E1_Nident - 1,
364	enumh_$1(E1_type),
365	enumh_$1(E1_machine),
366	enumw_$1(E1_version),
367	enuma_$1(E1_entry),
368	enumo_$1(E1_phoff),
369	enumo_$1(E1_shoff),
370	enumw_$1(E1_flags),
371	enumh_$1(E1_ehsize),
372	enumh_$1(E1_phentsize),
373	enumh_$1(E1_phnum),
374	enumh_$1(E1_shentsize),
375	enumh_$1(E1_shnum),
376	enumh_$1(E1_shstrndx)`'ifelse(`$2', `', `', `,
377	E1_sizeof')
378};')
379
380Ehdr_1(L)
381Ehdr_1(M,1)
382
383define(Nhdr_1, `
384enum
385{
386	enumw_$1(N1_namesz),
387	enumw_$1(N1_descsz),
388	enumw_$1(N1_type)`'ifelse(`$2', `', `', `,
389	N1_sizeof')
390};')
391
392Nhdr_1(L)
393Nhdr_1(M,1)
394
395define(Phdr_1, `
396enum
397{
398	enumw_$1(P1_type),
399	enumw_$1(P1_flags),
400	enumo_$1(P1_offset),
401	enuma_$1(P1_vaddr),
402	enuma_$1(P1_paddr),
403	enumx_$1(P1_filesz),
404	enumx_$1(P1_memsz),
405	enumx_$1(P1_align)`'ifelse(`$2', `', `', `,
406	P1_sizeof')
407};')
408
409Phdr_1(L)
410Phdr_1(M,1)
411
412
413define(Rel_1, `
414enum
415{
416	enuma_$1(R1_offset),
417	enumx_$1(R1_info)`'ifelse(`$2', `', `', `,
418	R1_sizeof')
419};')
420
421Rel_1(L)
422Rel_1(M,1)
423
424
425define(Rela_1, `
426enum
427{
428	enuma_$1(RA1_offset),
429	enumx_$1(RA1_info),
430	enumx_$1(RA1_addend)`'ifelse(`$2', `', `', `,
431	RA1_sizeof')
432};')
433
434Rela_1(L)
435Rela_1(M,1)
436
437
438define(Shdr_1, `
439enum
440{
441	enumw_$1(SH1_name),
442	enumw_$1(SH1_type),
443	enumx_$1(SH1_flags),
444	enuma_$1(SH1_addr),
445	enumo_$1(SH1_offset),
446	enumx_$1(SH1_size),
447	enumw_$1(SH1_link),
448	enumw_$1(SH1_info),
449	enumx_$1(SH1_addralign),
450	enumx_$1(SH1_entsize)`'ifelse(`$2', `', `', `,
451	SH1_sizeof')
452};')
453
454Shdr_1(L)
455Shdr_1(M,1)
456
457
458define(Sym_1, `
459enum
460{
461	enumw_$1(ST1_name),
462	enumb_$1(ST1_info),
463	enumb_$1(ST1_other),
464	enumh_$1(ST1_shndx),
465	enuma_$1(ST1_value),
466	enumx_$1(ST1_size)`'ifelse(`$2', `', `', `,
467	ST1_sizeof')
468};')
469
470Sym_1(L)
471Sym_1(M,1)
472
473
474define(Syminfo_1, `
475enum
476{
477	enumh_$1(SI1_boundto),
478	enumh_$1(SI1_flags)`'ifelse(`$2', `', `', `,
479	SI1_sizeof')
480};')
481
482Syminfo_1(L)
483Syminfo_1(M,1)
484
485
486define(Cap_1, `
487enum
488{
489	enumx_$1(C1_tag),
490	enumx_$1(C1_val)`'ifelse(`$2', `', `', `,
491	C1_sizeof')
492};')
493
494Cap_1(L)
495Cap_1(M,1)
496
497
498define(Verdef_1, `
499enum
500{
501	enumh_$1(VD1_version),
502	enumh_$1(VD1_flags),
503	enumh_$1(VD1_ndx),
504	enumh_$1(VD1_cnt),
505	enumw_$1(VD1_hash),
506	enumw_$1(VD1_aux),
507	enumw_$1(VD1_next)`'ifelse(`$2', `', `', `,
508	VD1_sizeof')
509};')
510
511Verdef_1(L)
512Verdef_1(M,1)
513
514
515define(Verdaux_1, `
516enum
517{
518	enumw_$1(VDA1_name),
519	enumw_$1(VDA1_next)`'ifelse(`$2', `', `', `,
520	VDA1_sizeof')
521};')
522
523Verdaux_1(L)
524Verdaux_1(M,1)
525
526
527define(Verneed_1, `
528enum
529{
530	enumh_$1(VN1_version),
531	enumh_$1(VN1_cnt),
532	enumw_$1(VN1_file),
533	enumw_$1(VN1_aux),
534	enumw_$1(VN1_next)`'ifelse(`$2', `', `', `,
535	VN1_sizeof')
536};')
537
538Verneed_1(L)
539Verneed_1(M,1)
540
541
542define(Vernaux_1, `
543enum
544{
545	enumw_$1(VNA1_hash),
546	enumh_$1(VNA1_flags),
547	enumh_$1(VNA1_other),
548	enumw_$1(VNA1_name),
549	enumw_$1(VNA1_next)`'ifelse(`$2', `', `', `,
550	VNA1_sizeof')
551};')
552
553Vernaux_1(L)
554Vernaux_1(M,1)
555
556
557/*
558 *	Translation function declarations.
559 *
560 *		<object>_<data><dver><sver>_tof
561 *		<object>_<data><dver><sver>_tom
562 *	where
563 *		<data>	2L	ELFDATA2LSB
564 *			2M	ELFDATA2MSB
565 */
566
567static void	addr_2L_tof(), addr_2L_tom(),
568		addr_2M_tof(), addr_2M_tom(),
569		byte_to(),
570		dyn_2L11_tof(), dyn_2L11_tom(),
571		dyn_2M11_tof(), dyn_2M11_tom(),
572		ehdr_2L11_tof(), ehdr_2L11_tom(),
573		ehdr_2M11_tof(), ehdr_2M11_tom(),
574		half_2L_tof(), half_2L_tom(),
575		half_2M_tof(), half_2M_tom(),
576		move_2L11_tof(), move_2L11_tom(),
577		move_2M11_tof(), move_2M11_tom(),
578		movep_2L11_tof(), movep_2L11_tom(),
579		movep_2M11_tof(), movep_2M11_tom(),
580		off_2L_tof(), off_2L_tom(),
581		off_2M_tof(), off_2M_tom(),
582		note_2L11_tof(), note_2L11_tom(),
583		note_2M11_tof(), note_2M11_tom(),
584		phdr_2L11_tof(), phdr_2L11_tom(),
585		phdr_2M11_tof(), phdr_2M11_tom(),
586		rel_2L11_tof(), rel_2L11_tom(),
587		rel_2M11_tof(), rel_2M11_tom(),
588		rela_2L11_tof(), rela_2L11_tom(),
589		rela_2M11_tof(), rela_2M11_tom(),
590		shdr_2L11_tof(), shdr_2L11_tom(),
591		shdr_2M11_tof(), shdr_2M11_tom(),
592		sword_2L_tof(), sword_2L_tom(),
593		sword_2M_tof(), sword_2M_tom(),
594		sym_2L11_tof(), sym_2L11_tom(),
595		sym_2M11_tof(), sym_2M11_tom(),
596		syminfo_2L11_tof(), syminfo_2L11_tom(),
597		syminfo_2M11_tof(), syminfo_2M11_tom(),
598		word_2L_tof(), word_2L_tom(),
599		word_2M_tof(), word_2M_tom(),
600		verdef_2L11_tof(), verdef_2L11_tom(),
601		verdef_2M11_tof(), verdef_2M11_tom(),
602		verneed_2L11_tof(), verneed_2L11_tom(),
603		verneed_2M11_tof(), verneed_2M11_tom(),
604		sxword_2L_tof(), sxword_2L_tom(),
605		sxword_2M_tof(), sxword_2M_tom(),
606		xword_2L_tof(), xword_2L_tom(),
607		xword_2M_tof(), xword_2M_tom(),
608		cap_2L11_tof(), cap_2L11_tom(),
609		cap_2M11_tof(), cap_2M11_tom();
610
611
612/*
613 *	x64 [dst_version - 1] [src_version - 1] [encode - 1] [type]
614 */
615
616static struct {
617	void	(*x_tof)(),
618		(*x_tom)();
619} x64 [EV_CURRENT] [EV_CURRENT] [ELFDATANUM - 1] [ELF_T_NUM] = {
620	{
621		{
622			{			/* [1-1][1-1][2LSB-1][.] */
623/* BYTE */			{ byte_to, byte_to },
624/* ADDR */			{ addr_2L_tof, addr_2L_tom },
625/* DYN */			{ dyn_2L11_tof, dyn_2L11_tom },
626/* EHDR */			{ ehdr_2L11_tof, ehdr_2L11_tom },
627/* HALF */			{ half_2L_tof, half_2L_tom },
628/* OFF */			{ off_2L_tof, off_2L_tom },
629/* PHDR */			{ phdr_2L11_tof, phdr_2L11_tom },
630/* RELA */			{ rela_2L11_tof, rela_2L11_tom },
631/* REL */			{ rel_2L11_tof, rel_2L11_tom },
632/* SHDR */			{ shdr_2L11_tof, shdr_2L11_tom },
633/* SWORD */			{ sword_2L_tof, sword_2L_tom },
634/* SYM */			{ sym_2L11_tof, sym_2L11_tom },
635/* WORD */			{ word_2L_tof, word_2L_tom },
636/* VERDEF */			{ verdef_2L11_tof, verdef_2L11_tom},
637/* VERNEED */			{ verneed_2L11_tof, verneed_2L11_tom},
638/* SXWORD */			{ sxword_2L_tof, sxword_2L_tom },
639/* XWORD */			{ xword_2L_tof, xword_2L_tom },
640/* SYMINFO */			{ syminfo_2L11_tof, syminfo_2L11_tom },
641/* NOTE */			{ note_2L11_tof, note_2L11_tom },
642/* MOVE */			{ move_2L11_tof, move_2L11_tom },
643/* MOVEP */			{ movep_2L11_tof, movep_2L11_tom },
644/* CAP */			{ cap_2L11_tof, cap_2L11_tom },
645			},
646			{			/* [1-1][1-1][2MSB-1][.] */
647/* BYTE */			{ byte_to, byte_to },
648/* ADDR */			{ addr_2M_tof, addr_2M_tom },
649/* DYN */			{ dyn_2M11_tof, dyn_2M11_tom },
650/* EHDR */			{ ehdr_2M11_tof, ehdr_2M11_tom },
651/* HALF */			{ half_2M_tof, half_2M_tom },
652/* OFF */			{ off_2M_tof, off_2M_tom },
653/* PHDR */			{ phdr_2M11_tof, phdr_2M11_tom },
654/* RELA */			{ rela_2M11_tof, rela_2M11_tom },
655/* REL */			{ rel_2M11_tof, rel_2M11_tom },
656/* SHDR */			{ shdr_2M11_tof, shdr_2M11_tom },
657/* SWORD */			{ sword_2M_tof, sword_2M_tom },
658/* SYM */			{ sym_2M11_tof, sym_2M11_tom },
659/* WORD */			{ word_2M_tof, word_2M_tom },
660/* VERDEF */			{ verdef_2M11_tof, verdef_2M11_tom},
661/* VERNEED */			{ verneed_2M11_tof, verneed_2M11_tom},
662/* SXWORD */			{ sxword_2M_tof, sxword_2M_tom },
663/* XWORD */			{ xword_2M_tof, xword_2M_tom },
664/* SYMINFO */			{ syminfo_2M11_tof, syminfo_2M11_tom },
665/* NOTE */			{ note_2M11_tof, note_2M11_tom },
666/* MOVE */			{ move_2M11_tof, move_2M11_tom },
667/* MOVEP */			{ movep_2M11_tof, movep_2M11_tom },
668/* CAP */			{ cap_2M11_tof, cap_2M11_tom },
669			},
670		},
671	},
672};
673
674
675/*
676 *	size [version - 1] [type]
677 */
678
679static const struct {
680	size_t	s_filesz,
681		s_memsz;
682} fmsize [EV_CURRENT] [ELF_T_NUM] =
683{
684	{					/* [1-1][.] */
685/* BYTE */	{ 1, 1 },
686/* ADDR */	{ A_sizeof, sizeof (Elf64_Addr) },
687/* DYN */	{ D1_sizeof, sizeof (Elf64_Dyn) },
688/* EHDR */	{ E1_sizeof, sizeof (Elf64_Ehdr) },
689/* HALF */	{ H_sizeof, sizeof (Elf64_Half) },
690/* OFF */	{ O_sizeof, sizeof (Elf64_Off) },
691/* PHDR */	{ P1_sizeof, sizeof (Elf64_Phdr) },
692/* RELA */	{ RA1_sizeof, sizeof (Elf64_Rela) },
693/* REL */	{ R1_sizeof, sizeof (Elf64_Rel) },
694/* SHDR */	{ SH1_sizeof, sizeof (Elf64_Shdr) },
695/* SWORD */	{ W_sizeof, sizeof (Elf64_Sword) },
696/* SYM */	{ ST1_sizeof, sizeof (Elf64_Sym) },
697/* WORD */	{ W_sizeof, sizeof (Elf64_Word) },
698/* VERDEF */	{ 1, 1 },	/* both VERDEF & VERNEED have varying size */
699/* VERNEED */	{ 1, 1 },	/* structures so we set their sizes to 1 */
700/* SXWORD */	{ X_sizeof, sizeof (Elf64_Sxword) },
701/* XWORD */	{ X_sizeof, sizeof (Elf64_Xword) },
702/* SYMINFO */	{ SI1_sizeof, sizeof (Elf64_Syminfo) },
703/* NOTE */	{ 1, 1},	/* NOTE has varying sized data we can't */
704				/*  use the usual table magic. */
705/* MOVE */	{ M1_sizeof, sizeof (Elf64_Move) },
706/* MOVEP */	{ MP1_sizeof, sizeof (Elf64_Move) },
707/* CAP */	{ C1_sizeof, sizeof (Elf64_Cap) },
708	},
709};
710
711
712/*
713 *	memory type [version - 1] [section type]
714 */
715
716static const Elf_Type	mtype[EV_CURRENT][SHT_NUM] =
717{
718	{			/* [1-1][.] */
719/* NULL */		ELF_T_BYTE,
720/* PROGBITS */		ELF_T_BYTE,
721/* SYMTAB */		ELF_T_SYM,
722/* STRTAB */		ELF_T_BYTE,
723/* RELA */		ELF_T_RELA,
724/* HASH */		ELF_T_WORD,
725/* DYNAMIC */		ELF_T_DYN,
726/* NOTE */		ELF_T_NOTE,
727/* NOBITS */		ELF_T_BYTE,
728/* REL */		ELF_T_REL,
729/* SHLIB */		ELF_T_BYTE,
730/* DYNSYM */		ELF_T_SYM,
731/* UNKNOWN12 */		ELF_T_BYTE,
732/* UNKNOWN13 */		ELF_T_BYTE,
733/* INIT_ARRAY */	ELF_T_ADDR,
734/* FINI_ARRAY */	ELF_T_ADDR,
735/* PREINIT_ARRAY */	ELF_T_ADDR,
736/* GROUP */		ELF_T_WORD,
737/* SYMTAB_SHNDX */	ELF_T_WORD
738	},
739};
740
741
742size_t
743elf64_fsize(Elf_Type type, size_t count, unsigned ver)
744{
745	if (--ver >= EV_CURRENT) {
746		_elf_seterr(EREQ_VER, 0);
747		return (0);
748	}
749	if ((unsigned)type >= ELF_T_NUM) {
750		_elf_seterr(EREQ_TYPE, 0);
751		return (0);
752	}
753	return (fmsize[ver][type].s_filesz * count);
754}
755
756
757size_t
758_elf64_msize(Elf_Type type, unsigned ver)
759{
760	return (fmsize[ver - 1][type].s_memsz);
761}
762
763
764Elf_Type
765/* ARGSUSED */
766_elf64_mtype(Elf * elf, Elf64_Word shtype, unsigned ver)
767{
768	Elf64_Ehdr *	ehdr = (Elf64_Ehdr *)elf->ed_ehdr;
769
770	if (shtype < SHT_NUM)
771		return (mtype[ver - 1][shtype]);
772
773	switch (shtype) {
774	case SHT_SUNW_symsort:
775	case SHT_SUNW_tlssort:
776		return (ELF_T_WORD);
777	case SHT_SUNW_LDYNSYM:
778		return (ELF_T_SYM);
779	case SHT_SUNW_dof:
780		return (ELF_T_BYTE);
781	case SHT_SUNW_cap:
782		return (ELF_T_CAP);
783	case SHT_SUNW_SIGNATURE:
784		return (ELF_T_BYTE);
785	case SHT_SUNW_ANNOTATE:
786		return (ELF_T_BYTE);
787	case SHT_SUNW_DEBUGSTR:
788		return (ELF_T_BYTE);
789	case SHT_SUNW_DEBUG:
790		return (ELF_T_BYTE);
791	case SHT_SUNW_move:
792		/*
793		 * Right now - the only 64bit binaries I know
794		 * about with a move is SPARC - and SPARC
795		 * binaries pad the size of the move.
796		 */
797		return (ELF_T_MOVEP);
798	case SHT_SUNW_COMDAT:
799		return (ELF_T_BYTE);
800	case SHT_SUNW_syminfo:
801		return (ELF_T_SYMINFO);
802	case SHT_SUNW_verdef:
803		return (ELF_T_VDEF);
804	case SHT_SUNW_verneed:
805		return (ELF_T_VNEED);
806	case SHT_SUNW_versym:
807		return (ELF_T_HALF);
808	};
809
810	/*
811	 * Check for the sparc specific section types
812	 * below.
813	 */
814	if (((ehdr->e_machine == EM_SPARC) ||
815	    (ehdr->e_machine == EM_SPARC32PLUS) ||
816	    (ehdr->e_machine == EM_SPARCV9)) &&
817	    (shtype == SHT_SPARC_GOTDATA))
818		return (ELF_T_BYTE);
819
820	/*
821	 * Check for the amd64 specific section types
822	 * below.
823	 */
824	if ((ehdr->e_machine == EM_AMD64) &&
825	    (shtype == SHT_AMD64_UNWIND))
826		return (ELF_T_BYTE);
827
828	/*
829	 * And the default is ELF_T_BYTE - but we should
830	 * certainly have caught any sections we know about
831	 * above.  This is for unknown sections to libelf.
832	 */
833	return (ELF_T_BYTE);
834}
835
836
837size_t
838_elf64_entsz(Elf *elf, Elf64_Word shtype, unsigned ver)
839{
840	Elf_Type	ttype;
841
842	ttype = _elf64_mtype(elf, shtype, ver);
843	return ((ttype == ELF_T_BYTE) ? 0 : fmsize[ver - 1][ttype].s_filesz);
844}
845
846
847static Elf_Data *
848xlate(Elf_Data *dst, const Elf_Data *src, unsigned encode, int tof)
849						/* !0 -> xlatetof */
850{
851	size_t		cnt, dsz, ssz;
852	unsigned	type;
853	unsigned	dver, sver;
854	void		(*f)();
855	unsigned	_encode;
856
857	if (dst == 0 || src == 0)
858		return (0);
859	if (--encode >= (ELFDATANUM - 1)) {
860		_elf_seterr(EREQ_ENCODE, 0);
861		return (0);
862	}
863	if ((dver = dst->d_version - 1) >= EV_CURRENT ||
864	    (sver = src->d_version - 1) >= EV_CURRENT) {
865		_elf_seterr(EREQ_VER, 0);
866		return (0);
867	}
868	if ((type = src->d_type) >= ELF_T_NUM) {
869		_elf_seterr(EREQ_TYPE, 0);
870		return (0);
871	}
872
873	if (tof) {
874		dsz = fmsize[dver][type].s_filesz;
875		ssz = fmsize[sver][type].s_memsz;
876		f = x64[dver][sver][encode][type].x_tof;
877	} else {
878		dsz = fmsize[dver][type].s_memsz;
879		ssz = fmsize[sver][type].s_filesz;
880		f = x64[dver][sver][encode][type].x_tom;
881	}
882	cnt = src->d_size / ssz;
883	if (dst->d_size < dsz * cnt) {
884		_elf_seterr(EREQ_DSZ, 0);
885		return (0);
886	}
887
888	ELFACCESSDATA(_encode, _elf_encode)
889	if ((_encode == (encode + 1)) && (dsz == ssz)) {
890		/*
891		 *	ld(1) frequently produces empty sections (eg. .dynsym,
892		 *	.dynstr, .symtab, .strtab, etc) so that the initial
893		 *	output image can be created of the correct size.  Later
894		 *	these sections are filled in with the associated data.
895		 *	So that we don't have to pre-allocate buffers for
896		 *	these segments, allow for the src destination to be 0.
897		 */
898		if (src->d_buf && src->d_buf != dst->d_buf)
899			(void) memcpy(dst->d_buf, src->d_buf, src->d_size);
900		dst->d_type = src->d_type;
901		dst->d_size = src->d_size;
902		return (dst);
903	}
904	if (cnt)
905		(*f)(dst->d_buf, src->d_buf, cnt);
906	dst->d_size = dsz * cnt;
907	dst->d_type = src->d_type;
908	return (dst);
909}
910
911
912Elf_Data *
913elf64_xlatetof(Elf_Data *dst, const Elf_Data *src, unsigned encode)
914{
915	return (xlate(dst, src, encode, 1));
916}
917
918
919Elf_Data *
920elf64_xlatetom(Elf_Data *dst, const Elf_Data *src, unsigned encode)
921{
922	return (xlate(dst, src, encode, 0));
923}
924
925
926/*
927 * xlate to file format
928 *
929 *	..._tof(name, data) -- macros
930 *
931 *	Recall that the file format must be no larger than the
932 *	memory format (equal versions).  Use "forward" copy.
933 *	All these routines require non-null, non-zero arguments.
934 */
935
936define(addr_tof, `
937static void
938$1(Byte *dst, Elf64_Addr *src, size_t cnt)
939{
940	Elf64_Addr	*end = src + cnt;
941
942	do {
943		tofa(dst, *src, A_$2);
944		dst += A_sizeof;
945	} while (++src < end);
946}')
947
948addr_tof(addr_2L_tof,L)
949addr_tof(addr_2M_tof,M)
950
951
952static void
953byte_to(Byte *dst, Byte *src, size_t cnt)
954{
955	if (dst != src)
956		(void) memcpy(dst, src, cnt);
957}
958
959
960define(dyn_11_tof, `
961static void
962$1(Byte *dst, Elf64_Dyn *src, size_t cnt)
963{
964	Elf64_Dyn	*end = src + cnt;
965
966	do {
967		tofx(dst, src->d_tag, D1_tag_$2);
968		tofx(dst, src->d_un.d_val, D1_val_$2);
969		dst += D1_sizeof;
970	} while (++src < end);
971}')
972
973dyn_11_tof(dyn_2L11_tof,L)
974dyn_11_tof(dyn_2M11_tof,M)
975
976
977define(ehdr_11_tof, `
978static void
979$1(Byte *dst, Elf64_Ehdr *src, size_t cnt)
980{
981	Elf64_Ehdr	*end = src + cnt;
982
983	do {
984		if (&dst[E1_ident] != src->e_ident)
985			(void) memcpy(&dst[E1_ident], src->e_ident, E1_Nident);
986		tofh(dst, src->e_type, E1_type_$2);
987		tofh(dst, src->e_machine, E1_machine_$2);
988		tofw(dst, src->e_version, E1_version_$2);
989		tofa(dst, src->e_entry, E1_entry_$2);
990		tofo(dst, src->e_phoff, E1_phoff_$2);
991		tofo(dst, src->e_shoff, E1_shoff_$2);
992		tofw(dst, src->e_flags, E1_flags_$2);
993		tofh(dst, src->e_ehsize, E1_ehsize_$2);
994		tofh(dst, src->e_phentsize, E1_phentsize_$2);
995		tofh(dst, src->e_phnum, E1_phnum_$2);
996		tofh(dst, src->e_shentsize, E1_shentsize_$2);
997		tofh(dst, src->e_shnum, E1_shnum_$2);
998		tofh(dst, src->e_shstrndx, E1_shstrndx_$2);
999		dst += E1_sizeof;
1000	} while (++src < end);
1001}')
1002
1003ehdr_11_tof(ehdr_2L11_tof,L)
1004ehdr_11_tof(ehdr_2M11_tof,M)
1005
1006
1007define(half_tof, `
1008static void
1009$1(Byte *dst, Elf64_Half *src, size_t cnt)
1010{
1011	Elf64_Half	*end = src + cnt;
1012
1013	do {
1014		tofh(dst, *src, H_$2);
1015		dst += H_sizeof;
1016	} while (++src < end);
1017}')
1018
1019half_tof(half_2L_tof,L)
1020half_tof(half_2M_tof,M)
1021
1022
1023define(move_11_tof, `
1024static void
1025$1(unsigned char *dst, Elf64_Move *src, size_t cnt)
1026{
1027	Elf64_Move	*end = src + cnt;
1028
1029	do {
1030		tofl(dst, src->m_value, M1_value_$2);
1031		tofw(dst, src->m_info, M1_info_$2);
1032		tofw(dst, src->m_poffset, M1_poffset_$2);
1033		tofh(dst, src->m_repeat, M1_repeat_$2);
1034		tofh(dst, src->m_stride, M1_stride_$2);
1035		dst += M1_sizeof;
1036	} while (++src < end);
1037}')
1038
1039move_11_tof(move_2L11_tof,L)
1040move_11_tof(move_2M11_tof,M)
1041
1042
1043define(movep_11_tof, `
1044static void
1045$1(unsigned char *dst, Elf64_Move *src, size_t cnt)
1046{
1047	Elf64_Move	*end = src + cnt;
1048
1049	do {
1050		tofl(dst, src->m_value, MP1_value_$2);
1051		tofw(dst, src->m_info, MP1_info_$2);
1052		tofw(dst, src->m_poffset, MP1_poffset_$2);
1053		tofh(dst, src->m_repeat, MP1_repeat_$2);
1054		tofh(dst, src->m_stride, MP1_stride_$2);
1055		dst += MP1_sizeof;
1056	} while (++src < end);
1057}')
1058
1059movep_11_tof(movep_2L11_tof,L)
1060movep_11_tof(movep_2M11_tof,M)
1061
1062
1063define(off_tof, `
1064static void
1065$1(Byte *dst, Elf64_Off *src, size_t cnt)
1066{
1067	Elf64_Off	*end = src + cnt;
1068
1069	do {
1070		tofo(dst, *src, O_$2);
1071		dst += O_sizeof;
1072	} while (++src < end);
1073}')
1074
1075off_tof(off_2L_tof,L)
1076off_tof(off_2M_tof,M)
1077
1078
1079define(note_11_tof, `
1080static void
1081$1(unsigned char *dst, Elf64_Nhdr *src, size_t cnt)
1082{
1083	/* LINTED */
1084	Elf64_Nhdr *	end = (Elf64_Nhdr *)((char *)src + cnt);
1085
1086	do {
1087		Elf64_Word	descsz, namesz;
1088
1089		/*
1090		 * cache size of desc & name fields - while rounding
1091		 * up their size.
1092		 */
1093		namesz = S_ROUND(src->n_namesz, sizeof (Elf64_Word));
1094		descsz = src->n_descsz;
1095
1096		/*
1097		 * Copy contents of Elf64_Nhdr
1098		 */
1099		tofw(dst, src->n_namesz, N1_namesz_$2);
1100		tofw(dst, src->n_descsz, N1_descsz_$2);
1101		tofw(dst, src->n_type, N1_type_$2);
1102
1103		/*
1104		 * Copy contents of Name field
1105		 */
1106		dst += N1_sizeof;
1107		src++;
1108		(void)memcpy(dst, src, namesz);
1109
1110		/*
1111		 * Copy contents of desc field
1112		 */
1113		dst += namesz;
1114		src = (Elf64_Nhdr *)((uintptr_t)src + namesz);
1115		(void)memcpy(dst, src, descsz);
1116		descsz = S_ROUND(descsz, sizeof (Elf64_Word));
1117		dst += descsz;
1118		src = (Elf64_Nhdr *)((uintptr_t)src + descsz);
1119	} while (src < end);
1120}')
1121
1122note_11_tof(note_2L11_tof,L)
1123note_11_tof(note_2M11_tof,M)
1124
1125
1126define(phdr_11_tof, `
1127static void
1128$1(Byte *dst, Elf64_Phdr *src, size_t cnt)
1129{
1130	Elf64_Phdr	*end = src + cnt;
1131
1132	do {
1133		tofw(dst, src->p_type, P1_type_$2);
1134		tofw(dst, src->p_flags, P1_flags_$2);
1135		tofo(dst, src->p_offset, P1_offset_$2);
1136		tofa(dst, src->p_vaddr, P1_vaddr_$2);
1137		tofa(dst, src->p_paddr, P1_paddr_$2);
1138		tofx(dst, src->p_filesz, P1_filesz_$2);
1139		tofx(dst, src->p_memsz, P1_memsz_$2);
1140		tofx(dst, src->p_align, P1_align_$2);
1141		dst += P1_sizeof;
1142	} while (++src < end);
1143}')
1144
1145phdr_11_tof(phdr_2L11_tof,L)
1146phdr_11_tof(phdr_2M11_tof,M)
1147
1148
1149define(rel_11_tof, `
1150static void
1151$1(Byte *dst, Elf64_Rel *src, size_t cnt)
1152{
1153	Elf64_Rel	*end = src + cnt;
1154
1155	do {
1156		tofa(dst, src->r_offset, R1_offset_$2);
1157		tofx(dst, src->r_info, R1_info_$2);
1158		dst += R1_sizeof;
1159	} while (++src < end);
1160}')
1161
1162rel_11_tof(rel_2L11_tof,L)
1163rel_11_tof(rel_2M11_tof,M)
1164
1165
1166define(rela_11_tof, `
1167static void
1168$1(Byte *dst, Elf64_Rela *src, size_t cnt)
1169{
1170	Elf64_Rela	*end = src + cnt;
1171
1172	do {
1173		tofa(dst, src->r_offset, RA1_offset_$2);
1174		tofx(dst, src->r_info, RA1_info_$2);
1175		/*CONSTANTCONDITION*/
1176		if (~(Elf64_Xword)0 == -(Elf64_Sxword)1) {	/* 2s comp */
1177			tofx(dst, src->r_addend, RA1_addend_$2);
1178		} else {
1179			Elf64_Xword	w;
1180
1181			if (src->r_addend < 0) {
1182				w = - src->r_addend;
1183				w = ~w + 1;
1184			} else
1185				w = src->r_addend;
1186			tofx(dst, w, RA1_addend_$2);
1187		}
1188		dst += RA1_sizeof;
1189	} while (++src < end);
1190}')
1191
1192rela_11_tof(rela_2L11_tof,L)
1193rela_11_tof(rela_2M11_tof,M)
1194
1195
1196define(shdr_11_tof, `
1197static void
1198$1(Byte *dst, Elf64_Shdr *src, size_t cnt)
1199{
1200	Elf64_Shdr	*end = src + cnt;
1201
1202	do {
1203		tofw(dst, src->sh_name, SH1_name_$2);
1204		tofw(dst, src->sh_type, SH1_type_$2);
1205		tofx(dst, src->sh_flags, SH1_flags_$2);
1206		tofa(dst, src->sh_addr, SH1_addr_$2);
1207		tofo(dst, src->sh_offset, SH1_offset_$2);
1208		tofx(dst, src->sh_size, SH1_size_$2);
1209		tofw(dst, src->sh_link, SH1_link_$2);
1210		tofw(dst, src->sh_info, SH1_info_$2);
1211		tofx(dst, src->sh_addralign, SH1_addralign_$2);
1212		tofx(dst, src->sh_entsize, SH1_entsize_$2);
1213		dst += SH1_sizeof;
1214	} while (++src < end);
1215}')
1216
1217shdr_11_tof(shdr_2L11_tof,L)
1218shdr_11_tof(shdr_2M11_tof,M)
1219
1220
1221define(sword_tof, `
1222static void
1223$1(Byte *dst, Elf64_Sword *src, size_t cnt)
1224{
1225	Elf64_Sword	*end = src + cnt;
1226
1227	do {
1228		/*CONSTANTCONDITION*/
1229		if (~(Elf64_Word)0 == -(Elf64_Sword)1) {	/* 2s comp */
1230			tofw(dst, *src, W_$2);
1231		} else {
1232			Elf64_Word	w;
1233
1234			if (*src < 0) {
1235				w = - *src;
1236				w = ~w + 1;
1237			} else
1238				w = *src;
1239			tofw(dst, w, W_$2);
1240		}
1241		dst += W_sizeof;
1242	} while (++src < end);
1243}')
1244
1245sword_tof(sword_2L_tof,L)
1246sword_tof(sword_2M_tof,M)
1247
1248
1249define(cap_11_tof, `
1250static void
1251$1(unsigned char *dst, Elf64_Cap *src, size_t cnt)
1252{
1253	Elf64_Cap	*end = src + cnt;
1254
1255	do {
1256		tofx(dst, src->c_tag, C1_tag_$2);
1257		tofx(dst, src->c_un.c_val, C1_val_$2);
1258		dst += C1_sizeof;
1259	} while (++src < end);
1260}')
1261
1262cap_11_tof(cap_2L11_tof,L)
1263cap_11_tof(cap_2M11_tof,M)
1264
1265
1266define(syminfo_11_tof, `
1267static void
1268$1(unsigned char *dst, Elf64_Syminfo *src, size_t cnt)
1269{
1270	Elf64_Syminfo	*end = src + cnt;
1271
1272	do {
1273		tofh(dst, src->si_boundto, SI1_boundto_$2);
1274		tofh(dst, src->si_flags, SI1_flags_$2);
1275		dst += SI1_sizeof;
1276	} while (++src < end);
1277}')
1278
1279syminfo_11_tof(syminfo_2L11_tof,L)
1280syminfo_11_tof(syminfo_2M11_tof,M)
1281
1282
1283define(sym_11_tof, `
1284static void
1285$1(Byte *dst, Elf64_Sym *src, size_t cnt)
1286{
1287	Elf64_Sym	*end = src + cnt;
1288
1289	do {
1290		tofw(dst, src->st_name, ST1_name_$2);
1291		tofb(dst, src->st_info, ST1_info_$2);
1292		tofb(dst, src->st_other, ST1_other_$2);
1293		tofh(dst, src->st_shndx, ST1_shndx_$2);
1294		tofa(dst, src->st_value, ST1_value_$2);
1295		tofx(dst, src->st_size, ST1_size_$2);
1296		dst += ST1_sizeof;
1297	} while (++src < end);
1298}')
1299
1300sym_11_tof(sym_2L11_tof,L)
1301sym_11_tof(sym_2M11_tof,M)
1302
1303
1304define(word_tof, `
1305static void
1306$1(Byte *dst, Elf64_Word *src, size_t cnt)
1307{
1308	Elf64_Word	*end = src + cnt;
1309
1310	do {
1311		tofw(dst, *src, W_$2);
1312		dst += W_sizeof;
1313	} while (++src < end);
1314}')
1315
1316word_tof(word_2L_tof,L)
1317word_tof(word_2M_tof,M)
1318
1319
1320define(verdef_11_tof, `
1321static void
1322$1(Byte *dst, Elf64_Verdef *src, size_t cnt)
1323{
1324	/* LINTED */
1325	Elf64_Verdef	*end = (Elf64_Verdef *)((Byte *)src + cnt);
1326
1327	do {
1328		Elf64_Verdef	*next_verdef;
1329		Elf64_Verdaux	*vaux;
1330		Elf64_Half	i;
1331		Byte		*vaux_dst;
1332		Byte		*dst_next;
1333
1334		/* LINTED */
1335		next_verdef = (Elf64_Verdef *)(src->vd_next ?
1336		    (Byte *)src + src->vd_next : (Byte *)end);
1337		dst_next = dst + src->vd_next;
1338
1339		/* LINTED */
1340		vaux = (Elf64_Verdaux *)((Byte *)src + src->vd_aux);
1341		vaux_dst = dst + src->vd_aux;
1342
1343		/*
1344		 * Convert auxilary structures
1345		 */
1346		for (i = 0; i < src->vd_cnt; i++) {
1347			Elf64_Verdaux	*vaux_next;
1348			Byte		*vaux_dst_next;
1349
1350			/*
1351			 * because our source and destination can be
1352			 * the same place we need to figure out the next
1353			 * location now.
1354			 */
1355			/* LINTED */
1356			vaux_next = (Elf64_Verdaux *)((Byte *)vaux +
1357			    vaux->vda_next);
1358			vaux_dst_next = vaux_dst + vaux->vda_next;
1359
1360			tofw(vaux_dst, vaux->vda_name, VDA1_name_$2);
1361			tofw(vaux_dst, vaux->vda_next, VDA1_next_$2);
1362			vaux_dst = vaux_dst_next;
1363			vaux = vaux_next;
1364		}
1365
1366		/*
1367		 * Convert Elf64_Verdef structure.
1368		 */
1369		tofh(dst, src->vd_version, VD1_version_$2);
1370		tofh(dst, src->vd_flags, VD1_flags_$2);
1371		tofh(dst, src->vd_ndx, VD1_ndx_$2);
1372		tofh(dst, src->vd_cnt, VD1_cnt_$2);
1373		tofw(dst, src->vd_hash, VD1_hash_$2);
1374		tofw(dst, src->vd_aux, VD1_aux_$2);
1375		tofw(dst, src->vd_next, VD1_next_$2);
1376		src = next_verdef;
1377		dst = dst_next;
1378	} while (src < end);
1379}')
1380
1381verdef_11_tof(verdef_2L11_tof, L)
1382verdef_11_tof(verdef_2M11_tof, M)
1383
1384define(verneed_11_tof, `
1385static void
1386$1(Byte *dst, Elf64_Verneed *src, size_t cnt)
1387{
1388	/* LINTED */
1389	Elf64_Verneed	*end = (Elf64_Verneed *)((char *)src + cnt);
1390
1391	do {
1392		Elf64_Verneed *	next_verneed;
1393		Elf64_Vernaux *	vaux;
1394		Elf64_Half	i;
1395		Byte *		vaux_dst;
1396		Byte *		dst_next;
1397
1398		/* LINTED */
1399		next_verneed = (Elf64_Verneed *)(src->vn_next ?
1400		    (Byte *)src + src->vn_next : (Byte *)end);
1401		dst_next = dst + src->vn_next;
1402
1403		/* LINTED */
1404		vaux = (Elf64_Vernaux *)((Byte *)src + src->vn_aux);
1405		vaux_dst = dst + src->vn_aux;
1406
1407		/*
1408		 * Convert auxilary structures first
1409		 */
1410		for (i = 0; i < src->vn_cnt; i++) {
1411			Elf64_Vernaux	*vaux_next;
1412			Byte		*vaux_dst_next;
1413
1414			/*
1415			 * because our source and destination can be
1416			 * the same place we need to figure out the
1417			 * next location now.
1418			 */
1419			/* LINTED */
1420			vaux_next = (Elf64_Vernaux *)((Byte *)vaux +
1421			    vaux->vna_next);
1422			vaux_dst_next = vaux_dst + vaux->vna_next;
1423
1424			tofw(vaux_dst, vaux->vna_hash, VNA1_hash_$2);
1425			tofh(vaux_dst, vaux->vna_flags, VNA1_flags_$2);
1426			tofh(vaux_dst, vaux->vna_other, VNA1_other_$2);
1427			tofw(vaux_dst, vaux->vna_name, VNA1_name_$2);
1428			tofw(vaux_dst, vaux->vna_next, VNA1_next_$2);
1429			vaux_dst = vaux_dst_next;
1430			vaux = vaux_next;
1431		}
1432
1433		/*
1434		 * Convert Elf64_Verneed structure.
1435		 */
1436		tofh(dst, src->vn_version, VN1_version_$2);
1437		tofh(dst, src->vn_cnt, VN1_cnt_$2);
1438		tofw(dst, src->vn_file, VN1_file_$2);
1439		tofw(dst, src->vn_aux, VN1_aux_$2);
1440		tofw(dst, src->vn_next, VN1_next_$2);
1441		src = next_verneed;
1442		dst = dst_next;
1443	} while (src < end);
1444}')
1445
1446verneed_11_tof(verneed_2L11_tof, L)
1447verneed_11_tof(verneed_2M11_tof, M)
1448
1449
1450define(sxword_tof, `
1451static void
1452$1(Byte *dst, Elf64_Sxword *src, size_t cnt)
1453{
1454	Elf64_Sxword *end = src + cnt;
1455
1456	do {
1457		/*CONSTANTCONDITION*/
1458		if (~(Elf64_Xword)0 == -(Elf64_Sxword)1) {	/* 2s comp */
1459			tofx(dst, *src, X_$2);
1460		}
1461		else {					/* unknown */
1462			Elf64_Xword w;
1463
1464			if (*src < 0) {
1465				w = - *src;
1466				w = ~w + 1;
1467			} else
1468				w = *src;
1469			tofx(dst, w, X_$2);
1470		}
1471		dst += X_sizeof;
1472	} while (++src < end);
1473}')
1474
1475sxword_tof(sxword_2L_tof,L)
1476sxword_tof(sxword_2M_tof,M)
1477
1478
1479define(xword_tof, `
1480static void
1481$1(Byte *dst, Elf64_Xword *src, size_t cnt)
1482{
1483	Elf64_Xword *end = src + cnt;
1484
1485	do {
1486		tofx(dst, *src, X_$2);
1487		dst += X_sizeof;
1488	} while (++src < end);
1489}')
1490
1491xword_tof(xword_2L_tof,L)
1492xword_tof(xword_2M_tof,M)
1493
1494
1495/*
1496 * xlate to memory format
1497 *
1498 *	..._tom(name, data) -- macros
1499 *
1500 *	Recall that the memory format may be larger than the
1501 *	file format (equal versions).  Use "backward" copy.
1502 *	All these routines require non-null, non-zero arguments.
1503 */
1504
1505
1506define(addr_tom, `
1507static void
1508$1(Elf64_Addr *dst, Byte *src, size_t cnt)
1509{
1510	Elf64_Addr	*end = dst;
1511
1512	dst += cnt;
1513	src += cnt * A_sizeof;
1514	while (dst-- > end) {
1515		src -= A_sizeof;
1516		*dst = toma(src, A_$2);
1517	}
1518}')
1519
1520addr_tom(addr_2L_tom,L)
1521addr_tom(addr_2M_tom,M)
1522
1523
1524define(dyn_11_tom, `
1525static void
1526$1(Elf64_Dyn *dst, Byte *src, size_t cnt)
1527{
1528	Elf64_Dyn	*end = dst + cnt;
1529
1530	do {
1531		dst->d_tag = tomx(src, D1_tag_$2);
1532		dst->d_un.d_val = tomx(src, D1_val_$2);
1533		src += D1_sizeof;
1534	} while (++dst < end);
1535}')
1536
1537dyn_11_tom(dyn_2L11_tom,L)
1538dyn_11_tom(dyn_2M11_tom,M)
1539
1540
1541define(ehdr_11_tom, `
1542static void
1543$1(Elf64_Ehdr *dst, Byte *src, size_t cnt)
1544{
1545	Elf64_Ehdr	*end = dst;
1546
1547	dst += cnt;
1548	src += cnt * E1_sizeof;
1549	while (dst-- > end) {
1550		src -= E1_sizeof;
1551		dst->e_shstrndx = tomh(src, E1_shstrndx_$2);
1552		dst->e_shnum = tomh(src, E1_shnum_$2);
1553		dst->e_shentsize = tomh(src, E1_shentsize_$2);
1554		dst->e_phnum = tomh(src, E1_phnum_$2);
1555		dst->e_phentsize = tomh(src, E1_phentsize_$2);
1556		dst->e_ehsize = tomh(src, E1_ehsize_$2);
1557		dst->e_flags = tomw(src, E1_flags_$2);
1558		dst->e_shoff = tomo(src, E1_shoff_$2);
1559		dst->e_phoff = tomo(src, E1_phoff_$2);
1560		dst->e_entry = toma(src, E1_entry_$2);
1561		dst->e_version = tomw(src, E1_version_$2);
1562		dst->e_machine = tomh(src, E1_machine_$2);
1563		dst->e_type = tomh(src, E1_type_$2);
1564		if (dst->e_ident != &src[E1_ident])
1565			(void) memcpy(dst->e_ident, &src[E1_ident], E1_Nident);
1566	}
1567}')
1568
1569ehdr_11_tom(ehdr_2L11_tom,L)
1570ehdr_11_tom(ehdr_2M11_tom,M)
1571
1572
1573define(half_tom, `
1574static void
1575$1(Elf64_Half *dst, Byte *src, size_t cnt)
1576{
1577	Elf64_Half	*end = dst;
1578
1579	dst += cnt;
1580	src += cnt * H_sizeof;
1581	while (dst-- > end) {
1582		src -= H_sizeof;
1583		*dst = tomh(src, H_$2);
1584	}
1585}')
1586
1587half_tom(half_2L_tom,L)
1588half_tom(half_2M_tom,M)
1589
1590
1591define(move_11_tom, `
1592static void
1593$1(Elf64_Move *dst, unsigned char *src, size_t cnt)
1594{
1595	Elf64_Move	*end = dst + cnt;
1596
1597	do {
1598		dst->m_value = toml(src, M1_value_$2);
1599		dst->m_info = tomw(src, M1_info_$2);
1600		dst->m_poffset = tomw(src, M1_poffset_$2);
1601		dst->m_repeat = tomh(src, M1_repeat_$2);
1602		dst->m_stride = tomh(src, M1_stride_$2);
1603		src += M1_sizeof;
1604	} while (++dst < end);
1605}')
1606
1607move_11_tom(move_2L11_tom,L)
1608move_11_tom(move_2M11_tom,M)
1609
1610
1611define(movep_11_tom, `
1612static void
1613$1(Elf64_Move *dst, unsigned char *src, size_t cnt)
1614{
1615	Elf64_Move	*end = dst + cnt;
1616
1617	do
1618	{
1619		dst->m_value = toml(src, MP1_value_$2);
1620		dst->m_info = tomw(src, MP1_info_$2);
1621		dst->m_poffset = tomw(src, MP1_poffset_$2);
1622		dst->m_repeat = tomh(src, MP1_repeat_$2);
1623		dst->m_stride = tomh(src, MP1_stride_$2);
1624		src += MP1_sizeof;
1625	} while (++dst < end);
1626}')
1627
1628movep_11_tom(movep_2L11_tom,L)
1629movep_11_tom(movep_2M11_tom,M)
1630
1631
1632define(note_11_tom, `
1633static void
1634$1(Elf64_Nhdr *dst, unsigned char *src, size_t cnt)
1635{
1636	/* LINTED */
1637	Elf64_Nhdr	*end = (Elf64_Nhdr *)((char *)dst + cnt);
1638
1639	while (dst < end)
1640	{
1641		Elf64_Nhdr *	nhdr;
1642		unsigned char *	namestr;
1643		void *		desc;
1644		Elf64_Word	field_sz;
1645
1646		dst->n_namesz = tomw(src, N1_namesz_$2);
1647		dst->n_descsz = tomw(src, N1_descsz_$2);
1648		dst->n_type = tomw(src, N1_type_$2);
1649		nhdr = dst;
1650		/* LINTED */
1651		dst = (Elf64_Nhdr *)((char *)dst + sizeof (Elf64_Nhdr));
1652		namestr = src + N1_sizeof;
1653		field_sz = S_ROUND(nhdr->n_namesz, sizeof (Elf64_Word));
1654		(void)memcpy((void *)dst, namestr, field_sz);
1655		desc = namestr + field_sz;
1656		/* LINTED */
1657		dst = (Elf64_Nhdr *)((char *)dst + field_sz);
1658		field_sz = nhdr->n_descsz;
1659		(void)memcpy(dst, desc, field_sz);
1660		field_sz = S_ROUND(field_sz, sizeof (Elf64_Word));
1661		/* LINTED */
1662		dst = (Elf64_Nhdr *)((char *)dst + field_sz);
1663		src = (unsigned char *)desc + field_sz;
1664	}
1665}')
1666
1667note_11_tom(note_2L11_tom,L)
1668note_11_tom(note_2M11_tom,M)
1669
1670define(off_tom, `
1671static void
1672$1(Elf64_Off *dst, Byte *src, size_t cnt)
1673{
1674	Elf64_Off	*end = dst;
1675
1676	dst += cnt;
1677	src += cnt * O_sizeof;
1678	while (dst-- > end) {
1679		src -= O_sizeof;
1680		*dst = tomo(src, O_$2);
1681	}
1682}')
1683
1684off_tom(off_2L_tom,L)
1685off_tom(off_2M_tom,M)
1686
1687
1688define(phdr_11_tom, `
1689static void
1690$1(Elf64_Phdr *dst, Byte *src, size_t cnt)
1691{
1692	Elf64_Phdr	*end = dst;
1693
1694	dst += cnt;
1695	src += cnt * P1_sizeof;
1696	while (dst-- > end) {
1697		src -= P1_sizeof;
1698		dst->p_align = tomx(src, P1_align_$2);
1699		dst->p_memsz = tomx(src, P1_memsz_$2);
1700		dst->p_filesz = tomx(src, P1_filesz_$2);
1701		dst->p_paddr = toma(src, P1_paddr_$2);
1702		dst->p_vaddr = toma(src, P1_vaddr_$2);
1703		dst->p_offset = tomo(src, P1_offset_$2);
1704		dst->p_flags = tomw(src, P1_flags_$2);
1705		dst->p_type = tomw(src, P1_type_$2);
1706	}
1707}')
1708
1709phdr_11_tom(phdr_2L11_tom,L)
1710phdr_11_tom(phdr_2M11_tom,M)
1711
1712
1713define(rel_11_tom, `
1714static void
1715$1(Elf64_Rel *dst, Byte *src, size_t cnt)
1716{
1717	Elf64_Rel	*end = dst;
1718
1719	dst += cnt;
1720	src += cnt * R1_sizeof;
1721	while (dst-- > end) {
1722		src -= R1_sizeof;
1723		dst->r_info = tomx(src, R1_info_$2);
1724		dst->r_offset = toma(src, R1_offset_$2);
1725	}
1726}')
1727
1728rel_11_tom(rel_2L11_tom,L)
1729rel_11_tom(rel_2M11_tom,M)
1730
1731
1732define(rela_11_tom, `
1733static void
1734$1(Elf64_Rela *dst, Byte *src, size_t cnt)
1735{
1736	Elf64_Rela *end = dst;
1737
1738	dst += cnt;
1739	src += cnt * RA1_sizeof;
1740	while (dst-- > end) {
1741		src -= RA1_sizeof;
1742		/*CONSTANTCONDITION*/
1743		if (~(Elf64_Xword)0 == -(Elf64_Sxword)1 &&	/* 2s comp */
1744		    ~(~(Elf64_Xword)0 >> 1) == HI64) {
1745			dst->r_addend = tomx(src, RA1_addend_$2);
1746		} else {
1747			union {
1748				Elf64_Xword w;
1749				Elf64_Sxword sw;
1750			} u;
1751
1752			if ((u.w = tomx(src, RA1_addend_$2)) & HI64) {
1753				/* LINTED */
1754				u.w |= ~(Elf64_Xword)LO63;
1755				u.w = ~u.w + 1;
1756				u.sw = -u.w;
1757			}
1758			dst->r_addend = u.sw;
1759		}
1760		dst->r_info = tomx(src, RA1_info_$2);
1761		dst->r_offset = toma(src, RA1_offset_$2);
1762	}
1763}')
1764
1765rela_11_tom(rela_2L11_tom,L)
1766rela_11_tom(rela_2M11_tom,M)
1767
1768
1769define(shdr_11_tom, `
1770static void
1771$1(Elf64_Shdr *dst, Byte *src, size_t cnt)
1772{
1773	Elf64_Shdr	*end = dst;
1774
1775	dst += cnt;
1776	src += cnt * SH1_sizeof;
1777	while (dst-- > end) {
1778		src -= SH1_sizeof;
1779		dst->sh_entsize = tomx(src, SH1_entsize_$2);
1780		dst->sh_addralign = tomx(src, SH1_addralign_$2);
1781		dst->sh_info = tomw(src, SH1_info_$2);
1782		dst->sh_link = tomw(src, SH1_link_$2);
1783		dst->sh_size = tomx(src, SH1_size_$2);
1784		dst->sh_offset = tomo(src, SH1_offset_$2);
1785		dst->sh_addr = toma(src, SH1_addr_$2);
1786		dst->sh_flags = tomx(src, SH1_flags_$2);
1787		dst->sh_type = tomw(src, SH1_type_$2);
1788		dst->sh_name = tomw(src, SH1_name_$2);
1789	}
1790}')
1791
1792shdr_11_tom(shdr_2L11_tom,L)
1793shdr_11_tom(shdr_2M11_tom,M)
1794
1795
1796define(sword_tom, `
1797static void
1798$1(Elf64_Sword *dst, Byte *src, size_t cnt)
1799{
1800	Elf64_Sword	*end = dst;
1801
1802	dst += cnt;
1803	src += cnt * W_sizeof;
1804	while (dst-- > end) {
1805		src -= W_sizeof;
1806		/*CONSTANTCONDITION*/
1807		if (~(Elf64_Word)0 == -(Elf64_Sword)1 &&
1808		    ~(~(Elf64_Word)0 >> 1) == HI32) {	/* 2s comp */
1809			*dst = tomw(src, W_$2);
1810		} else {
1811			union {
1812				Elf64_Word w;
1813				Elf64_Sword sw;
1814			} u;
1815
1816			if ((u.w = tomw(src, W_$2)) & HI32) {
1817				u.w |= ~(Elf64_Word)LO31;
1818				u.w = ~u.w + 1;
1819				u.sw = -u.w;
1820			}
1821			*dst = u.sw;
1822		}
1823	}
1824}')
1825
1826sword_tom(sword_2L_tom,L)
1827sword_tom(sword_2M_tom,M)
1828
1829
1830define(cap_11_tom, `
1831static void
1832$1(Elf64_Cap *dst, unsigned char *src, size_t cnt)
1833{
1834	Elf64_Cap	*end = dst + cnt;
1835
1836	do {
1837		dst->c_tag = tomx(src, C1_tag_$2);
1838		dst->c_un.c_val = tomx(src, C1_val_$2);
1839		src += C1_sizeof;
1840	} while (++dst < end);
1841}')
1842
1843cap_11_tom(cap_2L11_tom,L)
1844cap_11_tom(cap_2M11_tom,M)
1845
1846
1847define(syminfo_11_tom, `
1848static void
1849$1(Elf64_Syminfo *dst, unsigned char *src, size_t cnt)
1850{
1851	Elf64_Syminfo	*end = dst;
1852
1853	dst += cnt;
1854	src += cnt * SI1_sizeof;
1855	while (dst-- > end)
1856	{
1857		src -= SI1_sizeof;
1858		dst->si_boundto = tomh(src, SI1_boundto_$2);
1859		dst->si_flags = tomh(src, SI1_flags_$2);
1860	}
1861}')
1862
1863syminfo_11_tom(syminfo_2L11_tom,L)
1864syminfo_11_tom(syminfo_2M11_tom,M)
1865
1866
1867define(sym_11_tom, `
1868static void
1869$1(Elf64_Sym *dst, Byte *src, size_t cnt)
1870{
1871	Elf64_Sym	*end = dst;
1872
1873	dst += cnt;
1874	src += cnt * ST1_sizeof;
1875	while (dst-- > end) {
1876		src -= ST1_sizeof;
1877		dst->st_size = tomx(src, ST1_size_$2);
1878		dst->st_value = toma(src, ST1_value_$2);
1879		dst->st_shndx = tomh(src, ST1_shndx_$2);
1880		dst->st_other = tomb(src, ST1_other_$2);
1881		dst->st_info = tomb(src, ST1_info_$2);
1882		dst->st_name = tomw(src, ST1_name_$2);
1883	}
1884}')
1885
1886sym_11_tom(sym_2L11_tom,L)
1887sym_11_tom(sym_2M11_tom,M)
1888
1889
1890define(word_tom, `
1891static void
1892$1(Elf64_Word *dst, Byte *src, size_t cnt)
1893{
1894	Elf64_Word	*end = dst;
1895
1896	dst += cnt;
1897	src += cnt * W_sizeof;
1898	while (dst-- > end) {
1899		src -= W_sizeof;
1900		*dst = tomw(src, W_$2);
1901	}
1902}')
1903
1904word_tom(word_2L_tom,L)
1905word_tom(word_2M_tom,M)
1906
1907
1908define(verdef_11_tom, `
1909static void
1910$1(Elf64_Verdef *dst, Byte *src, size_t cnt)
1911{
1912	/* LINTED */
1913	Elf64_Verdef	*end = (Elf64_Verdef *)((Byte *)dst + cnt);
1914
1915	while (dst < end) {
1916		Elf64_Verdaux	*vaux;
1917		Byte		*src_vaux;
1918		Elf64_Half	i;
1919
1920		dst->vd_version = tomh(src, VD1_version_$2);
1921		dst->vd_flags = tomh(src, VD1_flags_$2);
1922		dst->vd_ndx = tomh(src, VD1_ndx_$2);
1923		dst->vd_cnt = tomh(src, VD1_cnt_$2);
1924		dst->vd_hash = tomw(src, VD1_hash_$2);
1925		dst->vd_aux = tomw(src, VD1_aux_$2);
1926		dst->vd_next = tomw(src, VD1_next_$2);
1927
1928		src_vaux = src + dst->vd_aux;
1929		/* LINTED */
1930		vaux = (Elf64_Verdaux *)((Byte *)dst + dst->vd_aux);
1931		for (i = 0; i < dst->vd_cnt; i++) {
1932			vaux->vda_name = tomw(src_vaux, VDA1_name_$2);
1933			vaux->vda_next = tomw(src_vaux, VDA1_next_$2);
1934			src_vaux += vaux->vda_next;
1935			/* LINTED */
1936			vaux = (Elf64_Verdaux *)((Byte *)vaux +
1937			    vaux->vda_next);
1938		}
1939		src += dst->vd_next;
1940		/* LINTED */
1941		dst = (Elf64_Verdef *)(dst->vd_next ?
1942		    (Byte *)dst + dst->vd_next : (Byte *)end);
1943	}
1944}')
1945
1946verdef_11_tom(verdef_2L11_tom,L)
1947verdef_11_tom(verdef_2M11_tom,M)
1948
1949
1950define(verneed_11_tom, `
1951static void
1952$1(Elf64_Verneed *dst, Byte *src, size_t cnt)
1953{
1954	/* LINTED */
1955	Elf64_Verneed	*end = (Elf64_Verneed *)((char *)dst + cnt);
1956
1957	while (dst < end) {
1958		Elf64_Vernaux *	vaux;
1959		Byte *		src_vaux;
1960		Elf64_Half	i;
1961
1962		dst->vn_version = tomh(src, VN1_version_$2);
1963		dst->vn_cnt = tomh(src, VN1_cnt_$2);
1964		dst->vn_file = tomw(src, VN1_file_$2);
1965		dst->vn_aux = tomw(src, VN1_aux_$2);
1966		dst->vn_next = tomw(src, VN1_next_$2);
1967
1968		src_vaux = src + dst->vn_aux;
1969		/* LINTED */
1970		vaux = (Elf64_Vernaux *)((Byte *)dst + dst->vn_aux);
1971		for (i = 0; i < dst->vn_cnt; i++) {
1972			vaux->vna_hash = tomw(src_vaux, VNA1_hash_$2);
1973			vaux->vna_flags = tomh(src_vaux, VNA1_flags_$2);
1974			vaux->vna_other = tomh(src_vaux, VNA1_other_$2);
1975			vaux->vna_name = tomw(src_vaux, VNA1_name_$2);
1976			vaux->vna_next = tomw(src_vaux, VNA1_next_$2);
1977			src_vaux += vaux->vna_next;
1978			/* LINTED */
1979			vaux = (Elf64_Vernaux *)((Byte *)vaux +
1980			    vaux->vna_next);
1981		}
1982		src += dst->vn_next;
1983		/* LINTED */
1984		dst = (Elf64_Verneed *)(dst->vn_next ?
1985		    (Byte *)dst + dst->vn_next : (Byte *)end);
1986	}
1987}')
1988
1989verneed_11_tom(verneed_2L11_tom,L)
1990verneed_11_tom(verneed_2M11_tom,M)
1991
1992
1993define(sxword_tom, `
1994static void
1995$1(Elf64_Sxword *dst, Byte *src, size_t cnt)
1996{
1997	Elf64_Sxword	*end = dst;
1998
1999	dst += cnt;
2000	src += cnt * X_sizeof;
2001	while (dst-- > end) {
2002		src -= X_sizeof;
2003		/*CONSTANTCONDITION*/
2004		if (~(Elf64_Xword)0 == -(Elf64_Sxword)1 &&
2005		    ~(~(Elf64_Xword)0 >> 1) == HI64) {	/* 2s comp */
2006			*dst = tomx(src, X_$2);
2007		} else {				/* other */
2008			union {
2009				Elf64_Xword w;
2010				Elf64_Sxword sw;
2011			} u;
2012
2013			if ((u.w = tomx(src, X_$2)) & HI64) {
2014				/* LINTED */
2015				u.w |= ~(Elf64_Xword)LO63;
2016				u.w = ~u.w + 1;
2017				u.sw = -u.w;
2018			}
2019			*dst = u.sw;
2020		}
2021	}
2022}')
2023
2024sxword_tom(sxword_2L_tom,L)
2025sxword_tom(sxword_2M_tom,M)
2026
2027
2028define(xword_tom, `
2029static void
2030$1(Elf64_Xword *dst, Byte *src, size_t cnt)
2031{
2032	Elf64_Xword	*end = dst;
2033
2034	dst += cnt;
2035	src += cnt * X_sizeof;
2036	while (dst-- > end) {
2037		src -= X_sizeof;
2038		*dst = tomx(src, X_$2);
2039	}
2040}')
2041
2042xword_tom(xword_2L_tom,L)
2043xword_tom(xword_2M_tom,M)
2044