xref: /titanic_50/usr/src/cmd/sgs/libelf/common/xlate64.m4 (revision 03831d35f7499c87d51205817c93e9a8d42c4bae)
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 2006 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
743_elf64_entsz(Elf64_Word shtype, unsigned ver)
744{
745	Elf_Type	ttype;
746
747	if (shtype >= sizeof (mtype[0]) / sizeof (mtype[0][0]) ||
748	    (ttype = mtype[ver - 1][shtype]) == ELF_T_BYTE)
749		return (0);
750	return (fmsize[ver - 1][ttype].s_filesz);
751}
752
753
754size_t
755elf64_fsize(Elf_Type type, size_t count, unsigned ver)
756{
757	if (--ver >= EV_CURRENT) {
758		_elf_seterr(EREQ_VER, 0);
759		return (0);
760	}
761	if ((unsigned)type >= ELF_T_NUM) {
762		_elf_seterr(EREQ_TYPE, 0);
763		return (0);
764	}
765	return (fmsize[ver][type].s_filesz * count);
766}
767
768
769size_t
770_elf64_msize(Elf_Type type, unsigned ver)
771{
772	return (fmsize[ver - 1][type].s_memsz);
773}
774
775
776Elf_Type
777/* ARGSUSED */
778_elf64_mtype(Elf * elf, Elf64_Word shtype, unsigned ver)
779{
780	Elf64_Ehdr *	ehdr = (Elf64_Ehdr *)elf->ed_ehdr;
781
782	if (shtype < SHT_NUM)
783		return (mtype[ver - 1][shtype]);
784
785	switch (shtype) {
786	case SHT_SUNW_dof:
787		return (ELF_T_BYTE);
788	case SHT_SUNW_cap:
789		return (ELF_T_CAP);
790	case SHT_SUNW_SIGNATURE:
791		return (ELF_T_BYTE);
792	case SHT_SUNW_ANNOTATE:
793		return (ELF_T_BYTE);
794	case SHT_SUNW_DEBUGSTR:
795		return (ELF_T_BYTE);
796	case SHT_SUNW_DEBUG:
797		return (ELF_T_BYTE);
798	case SHT_SUNW_move:
799		/*
800		 * Right now - the only 64bit binaries I know
801		 * about with a move is SPARC - and SPARC
802		 * binaries pad the size of the move.
803		 */
804		return (ELF_T_MOVEP);
805	case SHT_SUNW_COMDAT:
806		return (ELF_T_BYTE);
807	case SHT_SUNW_syminfo:
808		return (ELF_T_SYMINFO);
809	case SHT_SUNW_verdef:
810		return (ELF_T_VDEF);
811	case SHT_SUNW_verneed:
812		return (ELF_T_VNEED);
813	case SHT_SUNW_versym:
814		return (ELF_T_HALF);
815	};
816
817	/*
818	 * Check for the sparc specific section types
819	 * below.
820	 */
821	if (((ehdr->e_machine == EM_SPARC) ||
822	    (ehdr->e_machine == EM_SPARC32PLUS) ||
823	    (ehdr->e_machine == EM_SPARCV9)) &&
824	    (shtype == SHT_SPARC_GOTDATA))
825		return (ELF_T_BYTE);
826
827	/*
828	 * Check for the amd64 specific section types
829	 * below.
830	 */
831	if ((ehdr->e_machine == EM_AMD64) &&
832	    (shtype == SHT_AMD64_UNWIND))
833		return (ELF_T_BYTE);
834
835	/*
836	 * And the default is ELF_T_BYTE - but we should
837	 * certainly have caught any sections we know about
838	 * above.  This is for unknown sections to libelf.
839	 */
840	return (ELF_T_BYTE);
841}
842
843
844static Elf_Data *
845xlate(Elf_Data *dst, const Elf_Data *src, unsigned encode, int tof)
846						/* !0 -> xlatetof */
847{
848	size_t		cnt, dsz, ssz;
849	unsigned	type;
850	unsigned	dver, sver;
851	void		(*f)();
852	unsigned	_encode;
853
854	if (dst == 0 || src == 0)
855		return (0);
856	if (--encode >= (ELFDATANUM - 1)) {
857		_elf_seterr(EREQ_ENCODE, 0);
858		return (0);
859	}
860	if ((dver = dst->d_version - 1) >= EV_CURRENT ||
861	    (sver = src->d_version - 1) >= EV_CURRENT) {
862		_elf_seterr(EREQ_VER, 0);
863		return (0);
864	}
865	if ((type = src->d_type) >= ELF_T_NUM) {
866		_elf_seterr(EREQ_TYPE, 0);
867		return (0);
868	}
869
870	if (tof) {
871		dsz = fmsize[dver][type].s_filesz;
872		ssz = fmsize[sver][type].s_memsz;
873		f = x64[dver][sver][encode][type].x_tof;
874	} else {
875		dsz = fmsize[dver][type].s_memsz;
876		ssz = fmsize[sver][type].s_filesz;
877		f = x64[dver][sver][encode][type].x_tom;
878	}
879	cnt = src->d_size / ssz;
880	if (dst->d_size < dsz * cnt) {
881		_elf_seterr(EREQ_DSZ, 0);
882		return (0);
883	}
884
885	ELFACCESSDATA(_encode, _elf_encode)
886	if ((_encode == (encode + 1)) && (dsz == ssz)) {
887		/*
888		 *	ld(1) frequently produces empty sections (eg. .dynsym,
889		 *	.dynstr, .symtab, .strtab, etc) so that the initial
890		 *	output image can be created of the correct size.  Later
891		 *	these sections are filled in with the associated data.
892		 *	So that we don't have to pre-allocate buffers for
893		 *	these segments, allow for the src destination to be 0.
894		 */
895		if (src->d_buf && src->d_buf != dst->d_buf)
896			(void) memcpy(dst->d_buf, src->d_buf, src->d_size);
897		dst->d_type = src->d_type;
898		dst->d_size = src->d_size;
899		return (dst);
900	}
901	if (cnt)
902		(*f)(dst->d_buf, src->d_buf, cnt);
903	dst->d_size = dsz * cnt;
904	dst->d_type = src->d_type;
905	return (dst);
906}
907
908
909Elf_Data *
910elf64_xlatetof(Elf_Data *dst, const Elf_Data *src, unsigned encode)
911{
912	return (xlate(dst, src, encode, 1));
913}
914
915
916Elf_Data *
917elf64_xlatetom(Elf_Data *dst, const Elf_Data *src, unsigned encode)
918{
919	return (xlate(dst, src, encode, 0));
920}
921
922
923/*
924 * xlate to file format
925 *
926 *	..._tof(name, data) -- macros
927 *
928 *	Recall that the file format must be no larger than the
929 *	memory format (equal versions).  Use "forward" copy.
930 *	All these routines require non-null, non-zero arguments.
931 */
932
933define(addr_tof, `
934static void
935$1(Byte *dst, Elf64_Addr *src, size_t cnt)
936{
937	Elf64_Addr	*end = src + cnt;
938
939	do {
940		tofa(dst, *src, A_$2);
941		dst += A_sizeof;
942	} while (++src < end);
943}')
944
945addr_tof(addr_2L_tof,L)
946addr_tof(addr_2M_tof,M)
947
948
949static void
950byte_to(Byte *dst, Byte *src, size_t cnt)
951{
952	if (dst != src)
953		(void) memcpy(dst, src, cnt);
954}
955
956
957define(dyn_11_tof, `
958static void
959$1(Byte *dst, Elf64_Dyn *src, size_t cnt)
960{
961	Elf64_Dyn	*end = src + cnt;
962
963	do {
964		tofx(dst, src->d_tag, D1_tag_$2);
965		tofx(dst, src->d_un.d_val, D1_val_$2);
966		dst += D1_sizeof;
967	} while (++src < end);
968}')
969
970dyn_11_tof(dyn_2L11_tof,L)
971dyn_11_tof(dyn_2M11_tof,M)
972
973
974define(ehdr_11_tof, `
975static void
976$1(Byte *dst, Elf64_Ehdr *src, size_t cnt)
977{
978	Elf64_Ehdr	*end = src + cnt;
979
980	do {
981		if (&dst[E1_ident] != src->e_ident)
982			(void) memcpy(&dst[E1_ident], src->e_ident, E1_Nident);
983		tofh(dst, src->e_type, E1_type_$2);
984		tofh(dst, src->e_machine, E1_machine_$2);
985		tofw(dst, src->e_version, E1_version_$2);
986		tofa(dst, src->e_entry, E1_entry_$2);
987		tofo(dst, src->e_phoff, E1_phoff_$2);
988		tofo(dst, src->e_shoff, E1_shoff_$2);
989		tofw(dst, src->e_flags, E1_flags_$2);
990		tofh(dst, src->e_ehsize, E1_ehsize_$2);
991		tofh(dst, src->e_phentsize, E1_phentsize_$2);
992		tofh(dst, src->e_phnum, E1_phnum_$2);
993		tofh(dst, src->e_shentsize, E1_shentsize_$2);
994		tofh(dst, src->e_shnum, E1_shnum_$2);
995		tofh(dst, src->e_shstrndx, E1_shstrndx_$2);
996		dst += E1_sizeof;
997	} while (++src < end);
998}')
999
1000ehdr_11_tof(ehdr_2L11_tof,L)
1001ehdr_11_tof(ehdr_2M11_tof,M)
1002
1003
1004define(half_tof, `
1005static void
1006$1(Byte *dst, Elf64_Half *src, size_t cnt)
1007{
1008	Elf64_Half	*end = src + cnt;
1009
1010	do {
1011		tofh(dst, *src, H_$2);
1012		dst += H_sizeof;
1013	} while (++src < end);
1014}')
1015
1016half_tof(half_2L_tof,L)
1017half_tof(half_2M_tof,M)
1018
1019
1020define(move_11_tof, `
1021static void
1022$1(unsigned char *dst, Elf64_Move *src, size_t cnt)
1023{
1024	Elf64_Move	*end = src + cnt;
1025
1026	do {
1027		tofl(dst, src->m_value, M1_value_$2);
1028		tofw(dst, src->m_info, M1_info_$2);
1029		tofw(dst, src->m_poffset, M1_poffset_$2);
1030		tofh(dst, src->m_repeat, M1_repeat_$2);
1031		tofh(dst, src->m_stride, M1_stride_$2);
1032		dst += M1_sizeof;
1033	} while (++src < end);
1034}')
1035
1036move_11_tof(move_2L11_tof,L)
1037move_11_tof(move_2M11_tof,M)
1038
1039
1040define(movep_11_tof, `
1041static void
1042$1(unsigned char *dst, Elf64_Move *src, size_t cnt)
1043{
1044	Elf64_Move	*end = src + cnt;
1045
1046	do {
1047		tofl(dst, src->m_value, MP1_value_$2);
1048		tofw(dst, src->m_info, MP1_info_$2);
1049		tofw(dst, src->m_poffset, MP1_poffset_$2);
1050		tofh(dst, src->m_repeat, MP1_repeat_$2);
1051		tofh(dst, src->m_stride, MP1_stride_$2);
1052		dst += MP1_sizeof;
1053	} while (++src < end);
1054}')
1055
1056movep_11_tof(movep_2L11_tof,L)
1057movep_11_tof(movep_2M11_tof,M)
1058
1059
1060define(off_tof, `
1061static void
1062$1(Byte *dst, Elf64_Off *src, size_t cnt)
1063{
1064	Elf64_Off	*end = src + cnt;
1065
1066	do {
1067		tofo(dst, *src, O_$2);
1068		dst += O_sizeof;
1069	} while (++src < end);
1070}')
1071
1072off_tof(off_2L_tof,L)
1073off_tof(off_2M_tof,M)
1074
1075
1076define(note_11_tof, `
1077static void
1078$1(unsigned char *dst, Elf64_Nhdr *src, size_t cnt)
1079{
1080	/* LINTED */
1081	Elf64_Nhdr *	end = (Elf64_Nhdr *)((char *)src + cnt);
1082
1083	do {
1084		Elf64_Word	descsz, namesz;
1085
1086		/*
1087		 * cache size of desc & name fields - while rounding
1088		 * up their size.
1089		 */
1090		namesz = S_ROUND(src->n_namesz, sizeof (Elf64_Word));
1091		descsz = src->n_descsz;
1092
1093		/*
1094		 * Copy contents of Elf64_Nhdr
1095		 */
1096		tofw(dst, src->n_namesz, N1_namesz_$2);
1097		tofw(dst, src->n_descsz, N1_descsz_$2);
1098		tofw(dst, src->n_type, N1_type_$2);
1099
1100		/*
1101		 * Copy contents of Name field
1102		 */
1103		dst += N1_sizeof;
1104		src++;
1105		(void)memcpy(dst, src, namesz);
1106
1107		/*
1108		 * Copy contents of desc field
1109		 */
1110		dst += namesz;
1111		src = (Elf64_Nhdr *)((uintptr_t)src + namesz);
1112		(void)memcpy(dst, src, descsz);
1113		descsz = S_ROUND(descsz, sizeof (Elf64_Word));
1114		dst += descsz;
1115		src = (Elf64_Nhdr *)((uintptr_t)src + descsz);
1116	} while (src < end);
1117}')
1118
1119note_11_tof(note_2L11_tof,L)
1120note_11_tof(note_2M11_tof,M)
1121
1122
1123define(phdr_11_tof, `
1124static void
1125$1(Byte *dst, Elf64_Phdr *src, size_t cnt)
1126{
1127	Elf64_Phdr	*end = src + cnt;
1128
1129	do {
1130		tofw(dst, src->p_type, P1_type_$2);
1131		tofw(dst, src->p_flags, P1_flags_$2);
1132		tofo(dst, src->p_offset, P1_offset_$2);
1133		tofa(dst, src->p_vaddr, P1_vaddr_$2);
1134		tofa(dst, src->p_paddr, P1_paddr_$2);
1135		tofx(dst, src->p_filesz, P1_filesz_$2);
1136		tofx(dst, src->p_memsz, P1_memsz_$2);
1137		tofx(dst, src->p_align, P1_align_$2);
1138		dst += P1_sizeof;
1139	} while (++src < end);
1140}')
1141
1142phdr_11_tof(phdr_2L11_tof,L)
1143phdr_11_tof(phdr_2M11_tof,M)
1144
1145
1146define(rel_11_tof, `
1147static void
1148$1(Byte *dst, Elf64_Rel *src, size_t cnt)
1149{
1150	Elf64_Rel	*end = src + cnt;
1151
1152	do {
1153		tofa(dst, src->r_offset, R1_offset_$2);
1154		tofx(dst, src->r_info, R1_info_$2);
1155		dst += R1_sizeof;
1156	} while (++src < end);
1157}')
1158
1159rel_11_tof(rel_2L11_tof,L)
1160rel_11_tof(rel_2M11_tof,M)
1161
1162
1163define(rela_11_tof, `
1164static void
1165$1(Byte *dst, Elf64_Rela *src, size_t cnt)
1166{
1167	Elf64_Rela	*end = src + cnt;
1168
1169	do {
1170		tofa(dst, src->r_offset, RA1_offset_$2);
1171		tofx(dst, src->r_info, RA1_info_$2);
1172		/*CONSTANTCONDITION*/
1173		if (~(Elf64_Xword)0 == -(Elf64_Sxword)1) {	/* 2s comp */
1174			tofx(dst, src->r_addend, RA1_addend_$2);
1175		} else {
1176			Elf64_Xword	w;
1177
1178			if (src->r_addend < 0) {
1179				w = - src->r_addend;
1180				w = ~w + 1;
1181			} else
1182				w = src->r_addend;
1183			tofx(dst, w, RA1_addend_$2);
1184		}
1185		dst += RA1_sizeof;
1186	} while (++src < end);
1187}')
1188
1189rela_11_tof(rela_2L11_tof,L)
1190rela_11_tof(rela_2M11_tof,M)
1191
1192
1193define(shdr_11_tof, `
1194static void
1195$1(Byte *dst, Elf64_Shdr *src, size_t cnt)
1196{
1197	Elf64_Shdr	*end = src + cnt;
1198
1199	do {
1200		tofw(dst, src->sh_name, SH1_name_$2);
1201		tofw(dst, src->sh_type, SH1_type_$2);
1202		tofx(dst, src->sh_flags, SH1_flags_$2);
1203		tofa(dst, src->sh_addr, SH1_addr_$2);
1204		tofo(dst, src->sh_offset, SH1_offset_$2);
1205		tofx(dst, src->sh_size, SH1_size_$2);
1206		tofw(dst, src->sh_link, SH1_link_$2);
1207		tofw(dst, src->sh_info, SH1_info_$2);
1208		tofx(dst, src->sh_addralign, SH1_addralign_$2);
1209		tofx(dst, src->sh_entsize, SH1_entsize_$2);
1210		dst += SH1_sizeof;
1211	} while (++src < end);
1212}')
1213
1214shdr_11_tof(shdr_2L11_tof,L)
1215shdr_11_tof(shdr_2M11_tof,M)
1216
1217
1218define(sword_tof, `
1219static void
1220$1(Byte *dst, Elf64_Sword *src, size_t cnt)
1221{
1222	Elf64_Sword	*end = src + cnt;
1223
1224	do {
1225		/*CONSTANTCONDITION*/
1226		if (~(Elf64_Word)0 == -(Elf64_Sword)1) {	/* 2s comp */
1227			tofw(dst, *src, W_$2);
1228		} else {
1229			Elf64_Word	w;
1230
1231			if (*src < 0) {
1232				w = - *src;
1233				w = ~w + 1;
1234			} else
1235				w = *src;
1236			tofw(dst, w, W_$2);
1237		}
1238		dst += W_sizeof;
1239	} while (++src < end);
1240}')
1241
1242sword_tof(sword_2L_tof,L)
1243sword_tof(sword_2M_tof,M)
1244
1245
1246define(cap_11_tof, `
1247static void
1248$1(unsigned char *dst, Elf64_Cap *src, size_t cnt)
1249{
1250	Elf64_Cap	*end = src + cnt;
1251
1252	do {
1253		tofx(dst, src->c_tag, C1_tag_$2);
1254		tofx(dst, src->c_un.c_val, C1_val_$2);
1255		dst += C1_sizeof;
1256	} while (++src < end);
1257}')
1258
1259cap_11_tof(cap_2L11_tof,L)
1260cap_11_tof(cap_2M11_tof,M)
1261
1262
1263define(syminfo_11_tof, `
1264static void
1265$1(unsigned char *dst, Elf64_Syminfo *src, size_t cnt)
1266{
1267	Elf64_Syminfo	*end = src + cnt;
1268
1269	do {
1270		tofh(dst, src->si_boundto, SI1_boundto_$2);
1271		tofh(dst, src->si_flags, SI1_flags_$2);
1272		dst += SI1_sizeof;
1273	} while (++src < end);
1274}')
1275
1276syminfo_11_tof(syminfo_2L11_tof,L)
1277syminfo_11_tof(syminfo_2M11_tof,M)
1278
1279
1280define(sym_11_tof, `
1281static void
1282$1(Byte *dst, Elf64_Sym *src, size_t cnt)
1283{
1284	Elf64_Sym	*end = src + cnt;
1285
1286	do {
1287		tofw(dst, src->st_name, ST1_name_$2);
1288		tofb(dst, src->st_info, ST1_info_$2);
1289		tofb(dst, src->st_other, ST1_other_$2);
1290		tofh(dst, src->st_shndx, ST1_shndx_$2);
1291		tofa(dst, src->st_value, ST1_value_$2);
1292		tofx(dst, src->st_size, ST1_size_$2);
1293		dst += ST1_sizeof;
1294	} while (++src < end);
1295}')
1296
1297sym_11_tof(sym_2L11_tof,L)
1298sym_11_tof(sym_2M11_tof,M)
1299
1300
1301define(word_tof, `
1302static void
1303$1(Byte *dst, Elf64_Word *src, size_t cnt)
1304{
1305	Elf64_Word	*end = src + cnt;
1306
1307	do {
1308		tofw(dst, *src, W_$2);
1309		dst += W_sizeof;
1310	} while (++src < end);
1311}')
1312
1313word_tof(word_2L_tof,L)
1314word_tof(word_2M_tof,M)
1315
1316
1317define(verdef_11_tof, `
1318static void
1319$1(Byte *dst, Elf64_Verdef *src, size_t cnt)
1320{
1321	/* LINTED */
1322	Elf64_Verdef	*end = (Elf64_Verdef *)((Byte *)src + cnt);
1323
1324	do {
1325		Elf64_Verdef	*next_verdef;
1326		Elf64_Verdaux	*vaux;
1327		Elf64_Half	i;
1328		Byte		*vaux_dst;
1329		Byte		*dst_next;
1330
1331		/* LINTED */
1332		next_verdef = (Elf64_Verdef *)(src->vd_next ?
1333		    (Byte *)src + src->vd_next : (Byte *)end);
1334		dst_next = dst + src->vd_next;
1335
1336		/* LINTED */
1337		vaux = (Elf64_Verdaux *)((Byte *)src + src->vd_aux);
1338		vaux_dst = dst + src->vd_aux;
1339
1340		/*
1341		 * Convert auxilary structures
1342		 */
1343		for (i = 0; i < src->vd_cnt; i++) {
1344			Elf64_Verdaux	*vaux_next;
1345			Byte		*vaux_dst_next;
1346
1347			/*
1348			 * because our source and destination can be
1349			 * the same place we need to figure out the next
1350			 * location now.
1351			 */
1352			/* LINTED */
1353			vaux_next = (Elf64_Verdaux *)((Byte *)vaux +
1354			    vaux->vda_next);
1355			vaux_dst_next = vaux_dst + vaux->vda_next;
1356
1357			tofw(vaux_dst, vaux->vda_name, VDA1_name_$2);
1358			tofw(vaux_dst, vaux->vda_next, VDA1_next_$2);
1359			vaux_dst = vaux_dst_next;
1360			vaux = vaux_next;
1361		}
1362
1363		/*
1364		 * Convert Elf64_Verdef structure.
1365		 */
1366		tofh(dst, src->vd_version, VD1_version_$2);
1367		tofh(dst, src->vd_flags, VD1_flags_$2);
1368		tofh(dst, src->vd_ndx, VD1_ndx_$2);
1369		tofh(dst, src->vd_cnt, VD1_cnt_$2);
1370		tofw(dst, src->vd_hash, VD1_hash_$2);
1371		tofw(dst, src->vd_aux, VD1_aux_$2);
1372		tofw(dst, src->vd_next, VD1_next_$2);
1373		src = next_verdef;
1374		dst = dst_next;
1375	} while (src < end);
1376}')
1377
1378verdef_11_tof(verdef_2L11_tof, L)
1379verdef_11_tof(verdef_2M11_tof, M)
1380
1381define(verneed_11_tof, `
1382static void
1383$1(Byte *dst, Elf64_Verneed *src, size_t cnt)
1384{
1385	/* LINTED */
1386	Elf64_Verneed	*end = (Elf64_Verneed *)((char *)src + cnt);
1387
1388	do {
1389		Elf64_Verneed *	next_verneed;
1390		Elf64_Vernaux *	vaux;
1391		Elf64_Half	i;
1392		Byte *		vaux_dst;
1393		Byte *		dst_next;
1394
1395		/* LINTED */
1396		next_verneed = (Elf64_Verneed *)(src->vn_next ?
1397		    (Byte *)src + src->vn_next : (Byte *)end);
1398		dst_next = dst + src->vn_next;
1399
1400		/* LINTED */
1401		vaux = (Elf64_Vernaux *)((Byte *)src + src->vn_aux);
1402		vaux_dst = dst + src->vn_aux;
1403
1404		/*
1405		 * Convert auxilary structures first
1406		 */
1407		for (i = 0; i < src->vn_cnt; i++) {
1408			Elf64_Vernaux	*vaux_next;
1409			Byte		*vaux_dst_next;
1410
1411			/*
1412			 * because our source and destination can be
1413			 * the same place we need to figure out the
1414			 * next location now.
1415			 */
1416			/* LINTED */
1417			vaux_next = (Elf64_Vernaux *)((Byte *)vaux +
1418			    vaux->vna_next);
1419			vaux_dst_next = vaux_dst + vaux->vna_next;
1420
1421			tofw(vaux_dst, vaux->vna_hash, VNA1_hash_$2);
1422			tofh(vaux_dst, vaux->vna_flags, VNA1_flags_$2);
1423			tofh(vaux_dst, vaux->vna_other, VNA1_other_$2);
1424			tofw(vaux_dst, vaux->vna_name, VNA1_name_$2);
1425			tofw(vaux_dst, vaux->vna_next, VNA1_next_$2);
1426			vaux_dst = vaux_dst_next;
1427			vaux = vaux_next;
1428		}
1429
1430		/*
1431		 * Convert Elf64_Verneed structure.
1432		 */
1433		tofh(dst, src->vn_version, VN1_version_$2);
1434		tofh(dst, src->vn_cnt, VN1_cnt_$2);
1435		tofw(dst, src->vn_file, VN1_file_$2);
1436		tofw(dst, src->vn_aux, VN1_aux_$2);
1437		tofw(dst, src->vn_next, VN1_next_$2);
1438		src = next_verneed;
1439		dst = dst_next;
1440	} while (src < end);
1441}')
1442
1443verneed_11_tof(verneed_2L11_tof, L)
1444verneed_11_tof(verneed_2M11_tof, M)
1445
1446
1447define(sxword_tof, `
1448static void
1449$1(Byte *dst, Elf64_Sxword *src, size_t cnt)
1450{
1451	Elf64_Sxword *end = src + cnt;
1452
1453	do {
1454		/*CONSTANTCONDITION*/
1455		if (~(Elf64_Xword)0 == -(Elf64_Sxword)1) {	/* 2s comp */
1456			tofx(dst, *src, X_$2);
1457		}
1458		else {					/* unknown */
1459			Elf64_Xword w;
1460
1461			if (*src < 0) {
1462				w = - *src;
1463				w = ~w + 1;
1464			} else
1465				w = *src;
1466			tofx(dst, w, X_$2);
1467		}
1468		dst += X_sizeof;
1469	} while (++src < end);
1470}')
1471
1472sxword_tof(sxword_2L_tof,L)
1473sxword_tof(sxword_2M_tof,M)
1474
1475
1476define(xword_tof, `
1477static void
1478$1(Byte *dst, Elf64_Xword *src, size_t cnt)
1479{
1480	Elf64_Xword *end = src + cnt;
1481
1482	do {
1483		tofx(dst, *src, X_$2);
1484		dst += X_sizeof;
1485	} while (++src < end);
1486}')
1487
1488xword_tof(xword_2L_tof,L)
1489xword_tof(xword_2M_tof,M)
1490
1491
1492/*
1493 * xlate to memory format
1494 *
1495 *	..._tom(name, data) -- macros
1496 *
1497 *	Recall that the memory format may be larger than the
1498 *	file format (equal versions).  Use "backward" copy.
1499 *	All these routines require non-null, non-zero arguments.
1500 */
1501
1502
1503define(addr_tom, `
1504static void
1505$1(Elf64_Addr *dst, Byte *src, size_t cnt)
1506{
1507	Elf64_Addr	*end = dst;
1508
1509	dst += cnt;
1510	src += cnt * A_sizeof;
1511	while (dst-- > end) {
1512		src -= A_sizeof;
1513		*dst = toma(src, A_$2);
1514	}
1515}')
1516
1517addr_tom(addr_2L_tom,L)
1518addr_tom(addr_2M_tom,M)
1519
1520
1521define(dyn_11_tom, `
1522static void
1523$1(Elf64_Dyn *dst, Byte *src, size_t cnt)
1524{
1525	Elf64_Dyn	*end = dst + cnt;
1526
1527	do {
1528		dst->d_tag = tomx(src, D1_tag_$2);
1529		dst->d_un.d_val = tomx(src, D1_val_$2);
1530		src += D1_sizeof;
1531	} while (++dst < end);
1532}')
1533
1534dyn_11_tom(dyn_2L11_tom,L)
1535dyn_11_tom(dyn_2M11_tom,M)
1536
1537
1538define(ehdr_11_tom, `
1539static void
1540$1(Elf64_Ehdr *dst, Byte *src, size_t cnt)
1541{
1542	Elf64_Ehdr	*end = dst;
1543
1544	dst += cnt;
1545	src += cnt * E1_sizeof;
1546	while (dst-- > end) {
1547		src -= E1_sizeof;
1548		dst->e_shstrndx = tomh(src, E1_shstrndx_$2);
1549		dst->e_shnum = tomh(src, E1_shnum_$2);
1550		dst->e_shentsize = tomh(src, E1_shentsize_$2);
1551		dst->e_phnum = tomh(src, E1_phnum_$2);
1552		dst->e_phentsize = tomh(src, E1_phentsize_$2);
1553		dst->e_ehsize = tomh(src, E1_ehsize_$2);
1554		dst->e_flags = tomw(src, E1_flags_$2);
1555		dst->e_shoff = tomo(src, E1_shoff_$2);
1556		dst->e_phoff = tomo(src, E1_phoff_$2);
1557		dst->e_entry = toma(src, E1_entry_$2);
1558		dst->e_version = tomw(src, E1_version_$2);
1559		dst->e_machine = tomh(src, E1_machine_$2);
1560		dst->e_type = tomh(src, E1_type_$2);
1561		if (dst->e_ident != &src[E1_ident])
1562			(void) memcpy(dst->e_ident, &src[E1_ident], E1_Nident);
1563	}
1564}')
1565
1566ehdr_11_tom(ehdr_2L11_tom,L)
1567ehdr_11_tom(ehdr_2M11_tom,M)
1568
1569
1570define(half_tom, `
1571static void
1572$1(Elf64_Half *dst, Byte *src, size_t cnt)
1573{
1574	Elf64_Half	*end = dst;
1575
1576	dst += cnt;
1577	src += cnt * H_sizeof;
1578	while (dst-- > end) {
1579		src -= H_sizeof;
1580		*dst = tomh(src, H_$2);
1581	}
1582}')
1583
1584half_tom(half_2L_tom,L)
1585half_tom(half_2M_tom,M)
1586
1587
1588define(move_11_tom, `
1589static void
1590$1(Elf64_Move *dst, unsigned char *src, size_t cnt)
1591{
1592	Elf64_Move	*end = dst + cnt;
1593
1594	do {
1595		dst->m_value = toml(src, M1_value_$2);
1596		dst->m_info = tomw(src, M1_info_$2);
1597		dst->m_poffset = tomw(src, M1_poffset_$2);
1598		dst->m_repeat = tomh(src, M1_repeat_$2);
1599		dst->m_stride = tomh(src, M1_stride_$2);
1600		src += M1_sizeof;
1601	} while (++dst < end);
1602}')
1603
1604move_11_tom(move_2L11_tom,L)
1605move_11_tom(move_2M11_tom,M)
1606
1607
1608define(movep_11_tom, `
1609static void
1610$1(Elf64_Move *dst, unsigned char *src, size_t cnt)
1611{
1612	Elf64_Move	*end = dst + cnt;
1613
1614	do
1615	{
1616		dst->m_value = toml(src, MP1_value_$2);
1617		dst->m_info = tomw(src, MP1_info_$2);
1618		dst->m_poffset = tomw(src, MP1_poffset_$2);
1619		dst->m_repeat = tomh(src, MP1_repeat_$2);
1620		dst->m_stride = tomh(src, MP1_stride_$2);
1621		src += MP1_sizeof;
1622	} while (++dst < end);
1623}')
1624
1625movep_11_tom(movep_2L11_tom,L)
1626movep_11_tom(movep_2M11_tom,M)
1627
1628
1629define(note_11_tom, `
1630static void
1631$1(Elf64_Nhdr *dst, unsigned char *src, size_t cnt)
1632{
1633	/* LINTED */
1634	Elf64_Nhdr	*end = (Elf64_Nhdr *)((char *)dst + cnt);
1635
1636	while (dst < end)
1637	{
1638		Elf64_Nhdr *	nhdr;
1639		unsigned char *	namestr;
1640		void *		desc;
1641		Elf64_Word	field_sz;
1642
1643		dst->n_namesz = tomw(src, N1_namesz_$2);
1644		dst->n_descsz = tomw(src, N1_descsz_$2);
1645		dst->n_type = tomw(src, N1_type_$2);
1646		nhdr = dst;
1647		/* LINTED */
1648		dst = (Elf64_Nhdr *)((char *)dst + sizeof (Elf64_Nhdr));
1649		namestr = src + N1_sizeof;
1650		field_sz = S_ROUND(nhdr->n_namesz, sizeof (Elf64_Word));
1651		(void)memcpy((void *)dst, namestr, field_sz);
1652		desc = namestr + field_sz;
1653		/* LINTED */
1654		dst = (Elf64_Nhdr *)((char *)dst + field_sz);
1655		field_sz = nhdr->n_descsz;
1656		(void)memcpy(dst, desc, field_sz);
1657		field_sz = S_ROUND(field_sz, sizeof (Elf64_Word));
1658		/* LINTED */
1659		dst = (Elf64_Nhdr *)((char *)dst + field_sz);
1660		src = (unsigned char *)desc + field_sz;
1661	}
1662}')
1663
1664note_11_tom(note_2L11_tom,L)
1665note_11_tom(note_2M11_tom,M)
1666
1667define(off_tom, `
1668static void
1669$1(Elf64_Off *dst, Byte *src, size_t cnt)
1670{
1671	Elf64_Off	*end = dst;
1672
1673	dst += cnt;
1674	src += cnt * O_sizeof;
1675	while (dst-- > end) {
1676		src -= O_sizeof;
1677		*dst = tomo(src, O_$2);
1678	}
1679}')
1680
1681off_tom(off_2L_tom,L)
1682off_tom(off_2M_tom,M)
1683
1684
1685define(phdr_11_tom, `
1686static void
1687$1(Elf64_Phdr *dst, Byte *src, size_t cnt)
1688{
1689	Elf64_Phdr	*end = dst;
1690
1691	dst += cnt;
1692	src += cnt * P1_sizeof;
1693	while (dst-- > end) {
1694		src -= P1_sizeof;
1695		dst->p_align = tomx(src, P1_align_$2);
1696		dst->p_memsz = tomx(src, P1_memsz_$2);
1697		dst->p_filesz = tomx(src, P1_filesz_$2);
1698		dst->p_paddr = toma(src, P1_paddr_$2);
1699		dst->p_vaddr = toma(src, P1_vaddr_$2);
1700		dst->p_offset = tomo(src, P1_offset_$2);
1701		dst->p_flags = tomw(src, P1_flags_$2);
1702		dst->p_type = tomw(src, P1_type_$2);
1703	}
1704}')
1705
1706phdr_11_tom(phdr_2L11_tom,L)
1707phdr_11_tom(phdr_2M11_tom,M)
1708
1709
1710define(rel_11_tom, `
1711static void
1712$1(Elf64_Rel *dst, Byte *src, size_t cnt)
1713{
1714	Elf64_Rel	*end = dst;
1715
1716	dst += cnt;
1717	src += cnt * R1_sizeof;
1718	while (dst-- > end) {
1719		src -= R1_sizeof;
1720		dst->r_info = tomx(src, R1_info_$2);
1721		dst->r_offset = toma(src, R1_offset_$2);
1722	}
1723}')
1724
1725rel_11_tom(rel_2L11_tom,L)
1726rel_11_tom(rel_2M11_tom,M)
1727
1728
1729define(rela_11_tom, `
1730static void
1731$1(Elf64_Rela *dst, Byte *src, size_t cnt)
1732{
1733	Elf64_Rela *end = dst;
1734
1735	dst += cnt;
1736	src += cnt * RA1_sizeof;
1737	while (dst-- > end) {
1738		src -= RA1_sizeof;
1739		/*CONSTANTCONDITION*/
1740		if (~(Elf64_Xword)0 == -(Elf64_Sxword)1 &&	/* 2s comp */
1741		    ~(~(Elf64_Xword)0 >> 1) == HI64) {
1742			dst->r_addend = tomx(src, RA1_addend_$2);
1743		} else {
1744			union {
1745				Elf64_Xword w;
1746				Elf64_Sxword sw;
1747			} u;
1748
1749			if ((u.w = tomx(src, RA1_addend_$2)) & HI64) {
1750				/* LINTED */
1751				u.w |= ~(Elf64_Xword)LO63;
1752				u.w = ~u.w + 1;
1753				u.sw = -u.w;
1754			}
1755			dst->r_addend = u.sw;
1756		}
1757		dst->r_info = tomx(src, RA1_info_$2);
1758		dst->r_offset = toma(src, RA1_offset_$2);
1759	}
1760}')
1761
1762rela_11_tom(rela_2L11_tom,L)
1763rela_11_tom(rela_2M11_tom,M)
1764
1765
1766define(shdr_11_tom, `
1767static void
1768$1(Elf64_Shdr *dst, Byte *src, size_t cnt)
1769{
1770	Elf64_Shdr	*end = dst;
1771
1772	dst += cnt;
1773	src += cnt * SH1_sizeof;
1774	while (dst-- > end) {
1775		src -= SH1_sizeof;
1776		dst->sh_entsize = tomx(src, SH1_entsize_$2);
1777		dst->sh_addralign = tomx(src, SH1_addralign_$2);
1778		dst->sh_info = tomw(src, SH1_info_$2);
1779		dst->sh_link = tomw(src, SH1_link_$2);
1780		dst->sh_size = tomx(src, SH1_size_$2);
1781		dst->sh_offset = tomo(src, SH1_offset_$2);
1782		dst->sh_addr = toma(src, SH1_addr_$2);
1783		dst->sh_flags = tomx(src, SH1_flags_$2);
1784		dst->sh_type = tomw(src, SH1_type_$2);
1785		dst->sh_name = tomw(src, SH1_name_$2);
1786	}
1787}')
1788
1789shdr_11_tom(shdr_2L11_tom,L)
1790shdr_11_tom(shdr_2M11_tom,M)
1791
1792
1793define(sword_tom, `
1794static void
1795$1(Elf64_Sword *dst, Byte *src, size_t cnt)
1796{
1797	Elf64_Sword	*end = dst;
1798
1799	dst += cnt;
1800	src += cnt * W_sizeof;
1801	while (dst-- > end) {
1802		src -= W_sizeof;
1803		/*CONSTANTCONDITION*/
1804		if (~(Elf64_Word)0 == -(Elf64_Sword)1 &&
1805		    ~(~(Elf64_Word)0 >> 1) == HI32) {	/* 2s comp */
1806			*dst = tomw(src, W_$2);
1807		} else {
1808			union {
1809				Elf64_Word w;
1810				Elf64_Sword sw;
1811			} u;
1812
1813			if ((u.w = tomw(src, W_$2)) & HI32) {
1814				u.w |= ~(Elf64_Word)LO31;
1815				u.w = ~u.w + 1;
1816				u.sw = -u.w;
1817			}
1818			*dst = u.sw;
1819		}
1820	}
1821}')
1822
1823sword_tom(sword_2L_tom,L)
1824sword_tom(sword_2M_tom,M)
1825
1826
1827define(cap_11_tom, `
1828static void
1829$1(Elf64_Cap *dst, unsigned char *src, size_t cnt)
1830{
1831	Elf64_Cap	*end = dst + cnt;
1832
1833	do {
1834		dst->c_tag = tomx(src, C1_tag_$2);
1835		dst->c_un.c_val = tomx(src, C1_val_$2);
1836		src += C1_sizeof;
1837	} while (++dst < end);
1838}')
1839
1840cap_11_tom(cap_2L11_tom,L)
1841cap_11_tom(cap_2M11_tom,M)
1842
1843
1844define(syminfo_11_tom, `
1845static void
1846$1(Elf64_Syminfo *dst, unsigned char *src, size_t cnt)
1847{
1848	Elf64_Syminfo	*end = dst;
1849
1850	dst += cnt;
1851	src += cnt * SI1_sizeof;
1852	while (dst-- > end)
1853	{
1854		src -= SI1_sizeof;
1855		dst->si_boundto = tomh(src, SI1_boundto_$2);
1856		dst->si_flags = tomh(src, SI1_flags_$2);
1857	}
1858}')
1859
1860syminfo_11_tom(syminfo_2L11_tom,L)
1861syminfo_11_tom(syminfo_2M11_tom,M)
1862
1863
1864define(sym_11_tom, `
1865static void
1866$1(Elf64_Sym *dst, Byte *src, size_t cnt)
1867{
1868	Elf64_Sym	*end = dst;
1869
1870	dst += cnt;
1871	src += cnt * ST1_sizeof;
1872	while (dst-- > end) {
1873		src -= ST1_sizeof;
1874		dst->st_size = tomx(src, ST1_size_$2);
1875		dst->st_value = toma(src, ST1_value_$2);
1876		dst->st_shndx = tomh(src, ST1_shndx_$2);
1877		dst->st_other = tomb(src, ST1_other_$2);
1878		dst->st_info = tomb(src, ST1_info_$2);
1879		dst->st_name = tomw(src, ST1_name_$2);
1880	}
1881}')
1882
1883sym_11_tom(sym_2L11_tom,L)
1884sym_11_tom(sym_2M11_tom,M)
1885
1886
1887define(word_tom, `
1888static void
1889$1(Elf64_Word *dst, Byte *src, size_t cnt)
1890{
1891	Elf64_Word	*end = dst;
1892
1893	dst += cnt;
1894	src += cnt * W_sizeof;
1895	while (dst-- > end) {
1896		src -= W_sizeof;
1897		*dst = tomw(src, W_$2);
1898	}
1899}')
1900
1901word_tom(word_2L_tom,L)
1902word_tom(word_2M_tom,M)
1903
1904
1905define(verdef_11_tom, `
1906static void
1907$1(Elf64_Verdef *dst, Byte *src, size_t cnt)
1908{
1909	/* LINTED */
1910	Elf64_Verdef	*end = (Elf64_Verdef *)((Byte *)dst + cnt);
1911
1912	while (dst < end) {
1913		Elf64_Verdaux	*vaux;
1914		Byte		*src_vaux;
1915		Elf64_Half	i;
1916
1917		dst->vd_version = tomh(src, VD1_version_$2);
1918		dst->vd_flags = tomh(src, VD1_flags_$2);
1919		dst->vd_ndx = tomh(src, VD1_ndx_$2);
1920		dst->vd_cnt = tomh(src, VD1_cnt_$2);
1921		dst->vd_hash = tomw(src, VD1_hash_$2);
1922		dst->vd_aux = tomw(src, VD1_aux_$2);
1923		dst->vd_next = tomw(src, VD1_next_$2);
1924
1925		src_vaux = src + dst->vd_aux;
1926		/* LINTED */
1927		vaux = (Elf64_Verdaux *)((Byte *)dst + dst->vd_aux);
1928		for (i = 0; i < dst->vd_cnt; i++) {
1929			vaux->vda_name = tomw(src_vaux, VDA1_name_$2);
1930			vaux->vda_next = tomw(src_vaux, VDA1_next_$2);
1931			src_vaux += vaux->vda_next;
1932			/* LINTED */
1933			vaux = (Elf64_Verdaux *)((Byte *)vaux +
1934			    vaux->vda_next);
1935		}
1936		src += dst->vd_next;
1937		/* LINTED */
1938		dst = (Elf64_Verdef *)(dst->vd_next ?
1939		    (Byte *)dst + dst->vd_next : (Byte *)end);
1940	}
1941}')
1942
1943verdef_11_tom(verdef_2L11_tom,L)
1944verdef_11_tom(verdef_2M11_tom,M)
1945
1946
1947define(verneed_11_tom, `
1948static void
1949$1(Elf64_Verneed *dst, Byte *src, size_t cnt)
1950{
1951	/* LINTED */
1952	Elf64_Verneed	*end = (Elf64_Verneed *)((char *)dst + cnt);
1953
1954	while (dst < end) {
1955		Elf64_Vernaux *	vaux;
1956		Byte *		src_vaux;
1957		Elf64_Half	i;
1958
1959		dst->vn_version = tomh(src, VN1_version_$2);
1960		dst->vn_cnt = tomh(src, VN1_cnt_$2);
1961		dst->vn_file = tomw(src, VN1_file_$2);
1962		dst->vn_aux = tomw(src, VN1_aux_$2);
1963		dst->vn_next = tomw(src, VN1_next_$2);
1964
1965		src_vaux = src + dst->vn_aux;
1966		/* LINTED */
1967		vaux = (Elf64_Vernaux *)((Byte *)dst + dst->vn_aux);
1968		for (i = 0; i < dst->vn_cnt; i++) {
1969			vaux->vna_hash = tomw(src_vaux, VNA1_hash_$2);
1970			vaux->vna_flags = tomh(src_vaux, VNA1_flags_$2);
1971			vaux->vna_other = tomh(src_vaux, VNA1_other_$2);
1972			vaux->vna_name = tomw(src_vaux, VNA1_name_$2);
1973			vaux->vna_next = tomw(src_vaux, VNA1_next_$2);
1974			src_vaux += vaux->vna_next;
1975			/* LINTED */
1976			vaux = (Elf64_Vernaux *)((Byte *)vaux +
1977			    vaux->vna_next);
1978		}
1979		src += dst->vn_next;
1980		/* LINTED */
1981		dst = (Elf64_Verneed *)(dst->vn_next ?
1982		    (Byte *)dst + dst->vn_next : (Byte *)end);
1983	}
1984}')
1985
1986verneed_11_tom(verneed_2L11_tom,L)
1987verneed_11_tom(verneed_2M11_tom,M)
1988
1989
1990define(sxword_tom, `
1991static void
1992$1(Elf64_Sxword *dst, Byte *src, size_t cnt)
1993{
1994	Elf64_Sxword	*end = dst;
1995
1996	dst += cnt;
1997	src += cnt * X_sizeof;
1998	while (dst-- > end) {
1999		src -= X_sizeof;
2000		/*CONSTANTCONDITION*/
2001		if (~(Elf64_Xword)0 == -(Elf64_Sxword)1 &&
2002		    ~(~(Elf64_Xword)0 >> 1) == HI64) {	/* 2s comp */
2003			*dst = tomx(src, X_$2);
2004		} else {				/* other */
2005			union {
2006				Elf64_Xword w;
2007				Elf64_Sxword sw;
2008			} u;
2009
2010			if ((u.w = tomx(src, X_$2)) & HI64) {
2011				/* LINTED */
2012				u.w |= ~(Elf64_Xword)LO63;
2013				u.w = ~u.w + 1;
2014				u.sw = -u.w;
2015			}
2016			*dst = u.sw;
2017		}
2018	}
2019}')
2020
2021sxword_tom(sxword_2L_tom,L)
2022sxword_tom(sxword_2M_tom,M)
2023
2024
2025define(xword_tom, `
2026static void
2027$1(Elf64_Xword *dst, Byte *src, size_t cnt)
2028{
2029	Elf64_Xword	*end = dst;
2030
2031	dst += cnt;
2032	src += cnt * X_sizeof;
2033	while (dst-- > end) {
2034		src -= X_sizeof;
2035		*dst = tomx(src, X_$2);
2036	}
2037}')
2038
2039xword_tom(xword_2L_tom,L)
2040xword_tom(xword_2M_tom,M)
2041