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