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