xref: /titanic_52/usr/src/cmd/sgs/libelf/common/xlate64.m4 (revision 5bbb4db2c3f208d12bf0fd11769728f9e5ba66a2)
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	"%Z%%M%	%I%	%E% SMI"
28
29#include <memory.h>
30#include <libelf.h>
31#include <link.h>
32#include <sys/elf_SPARC.h>
33#include <sys/elf_amd64.h>
34#include <decl.h>
35#include <msg.h>
36#include <sgs.h>
37
38
39/*
40 * fmsize:  Array used to determine what size the the structures
41 *	    are (for memory image & file image).
42 *
43 * x64:  Translation routines - to file & to memory.
44 *
45 * What must be done when adding a new type for conversion:
46 *
47 * The first question is whether you need a new ELF_T_* type
48 * to be created.  If you've introduced a new structure - then
49 * it will need to be described - this is done by:
50 *
51 * o adding a new type ELF_T_* to usr/src/head/libelf.h
52 * o Create a new macro to define the bytes contained in the structure. Take a
53 *   look at the 'Syminfo_1' macro defined below.  The declarations describe
54 *   the structure based off of the field size of each element of the structure.
55 * o Add a entry to the fmsize table for the new ELF_T_* type.
56 * o Create a <newtype>_11_tof macro.  Take a look at 'syminfo_11_tof'.
57 * o Create a <newtype>_11_tom macro.  Take a look at 'syminfo_11_tom'.
58 * o The <newtype>_11_tof & <newtype>_11_tom results in conversion routines
59 *   <newtype>_2L11_tof, <newtype>_2L11_tom, <newtype>_2M11_tof,
60 *   <newtype>_2M11_tom being created in xlate.c.  These routines
61 *   need to be added to the 'x64[]' array.
62 * o Add entries to getdata.c::align32[] and getdata.c::align64[].  These
63 *   tables define what the alignment requirements for a data type are.
64 *
65 * In order to tie a section header type (SHT_*) to a data
66 * structure you need to update elf64_mtype() so that it can
67 * make the association.  If you are introducing a new section built
68 * on a basic datatype (SHT_INIT_ARRAY) then this is all the updating
69 * that needs to be done.
70 *
71 *
72 * ELF translation routines
73 *
74 *	These routines make a subtle implicit assumption.
75 *	The file representations of all structures are "packed,"
76 *	meaning no implicit padding bytes occur.  This might not
77 *	be the case for the memory representations.  Consequently,
78 *	the memory representations ALWAYS contain at least as many
79 *	bytes as the file representations.  Otherwise, the memory
80 *	structures would lose information, meaning they're not
81 *	implemented properly.
82 *
83 *	The words above apply to structures with the same members.
84 *	If a future version changes the number of members, the
85 *	relative structure sizes for different version must be
86 *	tested with the compiler.
87 */
88
89#define	HI32	0x80000000UL
90#define	LO31	0x7fffffffUL
91
92#define	HI64	0x8000000000000000ULL
93#define	LO63	0x7fffffffffffffffULL
94
95/*
96 *	These macros create indexes for accessing the bytes of
97 *	words and halfwords for ELFCLASS64 data representations
98 *	(currently ELFDATA2LSB and ELFDATA2MSB).  In all cases,
99 *
100 *	x = ((((((((((((X_7 << 8) + X_6) << 8) + X_5) << 8) + X_4) << 8
101 *		+ X_3) << 8) + X_2) << 8) + X_1) << 8) + X_0
102 *	w = (((((X_3 << 8) + X_2) << 8) + X_1) << 8) + X_0
103 *	h = (X_1 << 8) + X_0
104 *
105 *	These assume the file representations for Addr, Off,
106 *	Sword, and Word use 4 bytes, but the memory def's for
107 *	the types may differ.
108 *
109 *	Naming convention:
110 *		..._L	ELFDATA2LSB
111 *		..._M	ELFDATA2MSB
112 *
113 *	enuma_*(n)	define enum names for addr n
114 *	enumb_*(n)	define enum names for byte n
115 *	enumh_*(n)	define enum names for half n
116 *	enumo_*(n)	define enum names for off n
117 *	enumw_*(n)	define enum names for word n
118 *	enumx_*(n)	define enum names for xword n
119 *	enuml_*(n)	define enum names for Lword n
120 *	tofa(d,s,n)	xlate addr n from mem s to file d
121 *	tofb(d,s,n)	xlate byte n from mem s to file d
122 *	tofh(d,s,n)	xlate half n from mem s to file d
123 *	tofo(d,s,n)	xlate off n from mem s to file d
124 *	tofw(d,s,n)	xlate word n from mem s to file d
125 *	tofx(d,s,n)	xlate xword n from mem s to file d
126 *	tofl(d,s,n)	xlate Lword n from mem s to file d
127 *	toma(s,n)	xlate addr n from file s to expression value
128 *	tomb(s,n)	xlate byte n from file s to expression value
129 *	tomh(s,n)	xlate half n from file s to expression value
130 *	tomo(s,n)	xlate off n from file s to expression value
131 *	tomw(s,n)	xlate word n from file s to expression value
132 *	tomx(s,n)	xlate xword n from file s to expression value
133 *	toml(s,n)	xlate Lword n from file s to expression value
134 *
135 *	tof*() macros must move a multi-byte value into a temporary
136 *	because ``in place'' conversions are allowed.  If a temp is not
137 *	used for multi-byte objects, storing an initial destination byte
138 *	may clobber a source byte not yet examined.
139 *
140 *	tom*() macros compute an expression value from the source
141 *	without touching the destination; so they're safe.
142 */
143
144define(enuma_L, `$1_L0, $1_L1, $1_L2, $1_L3, $1_L4, $1_L5, $1_L6, $1_L7')dnl
145define(enuma_M, `$1_M7, $1_M6, $1_M5, $1_M4, $1_M3, $1_M2, $1_M1, $1_M0')dnl
146define(enumb_L, `$1_L')dnl
147define(enumb_M, `$1_M')dnl
148define(enumh_L, `$1_L0, $1_L1')dnl
149define(enumh_M, `$1_M1, $1_M0')dnl
150define(enumo_L, `$1_L0, $1_L1, $1_L2, $1_L3, $1_L4, $1_L5, $1_L6, $1_L7')dnl
151define(enumo_M, `$1_M7, $1_M6, $1_M5, $1_M4, $1_M3, $1_M2, $1_M1, $1_M0')dnl
152define(enumw_L, `$1_L0, $1_L1, $1_L2, $1_L3')dnl
153define(enumw_M, `$1_M3, $1_M2, $1_M1, $1_M0')dnl
154define(enumx_L, `$1_L0, $1_L1, $1_L2, $1_L3, $1_L4, $1_L5, $1_L6, $1_L7')dnl
155define(enumx_M, `$1_M7, $1_M6, $1_M5, $1_M4, $1_M3, $1_M2, $1_M1, $1_M0')dnl
156define(enuml_L, `$1_L0, $1_L1, $1_L2, $1_L3, $1_L4, $1_L5, $1_L6, $1_L7')dnl
157define(enuml_M, `$1_M7, $1_M6, $1_M5, $1_M4, $1_M3, $1_M2, $1_M1, $1_M0')dnl
158
159define(tofa, `{	Elf64_Addr _t_ = $2;
160		($1)[$3`'0] = (Byte)_t_,
161		($1)[$3`'1] = (Byte)(_t_>>8),
162		($1)[$3`'2] = (Byte)(_t_>>16),
163		($1)[$3`'3] = (Byte)(_t_>>24),
164		($1)[$3`'4] = (Byte)(_t_>>32),
165		($1)[$3`'5] = (Byte)(_t_>>40),
166		($1)[$3`'6] = (Byte)(_t_>>48),
167		($1)[$3`'7] = (Byte)(_t_>>56); }')dnl
168define(tofb, `($1)[$3] = (Byte)($2)')dnl
169define(tofh, `{ Elf64_Half _t_ = $2;
170		($1)[$3`'0] = (Byte)_t_,
171		($1)[$3`'1] = (Byte)(_t_>>8); }')dnl
172define(tofo, `{ Elf64_Off _t_ = $2;
173		($1)[$3`'0] = (Byte)_t_,
174		($1)[$3`'1] = (Byte)(_t_>>8),
175		($1)[$3`'2] = (Byte)(_t_>>16),
176		($1)[$3`'3] = (Byte)(_t_>>24),
177		($1)[$3`'4] = (Byte)(_t_>>32),
178		($1)[$3`'5] = (Byte)(_t_>>40),
179		($1)[$3`'6] = (Byte)(_t_>>48),
180		($1)[$3`'7] = (Byte)(_t_>>56); }')dnl
181define(tofw, `{ Elf64_Word _t_ = $2;
182		($1)[$3`'0] = (Byte)_t_,
183		($1)[$3`'1] = (Byte)(_t_>>8),
184		($1)[$3`'2] = (Byte)(_t_>>16),
185		($1)[$3`'3] = (Byte)(_t_>>24); }')dnl
186define(tofx, `{ Elf64_Xword _t_ = $2;
187		($1)[$3`'0] = (Byte)_t_,
188		($1)[$3`'1] = (Byte)(_t_>>8),
189		($1)[$3`'2] = (Byte)(_t_>>16),
190		($1)[$3`'3] = (Byte)(_t_>>24),
191		($1)[$3`'4] = (Byte)(_t_>>32),
192		($1)[$3`'5] = (Byte)(_t_>>40),
193		($1)[$3`'6] = (Byte)(_t_>>48),
194		($1)[$3`'7] = (Byte)(_t_>>56); }')dnl
195define(tofl, `{ Elf64_Lword _t_ = $2;
196		($1)[$3`'0] = (Byte)_t_,
197		($1)[$3`'1] = (Byte)(_t_>>8),
198		($1)[$3`'2] = (Byte)(_t_>>16),
199		($1)[$3`'3] = (Byte)(_t_>>24),
200		($1)[$3`'4] = (Byte)(_t_>>32),
201		($1)[$3`'5] = (Byte)(_t_>>40),
202		($1)[$3`'6] = (Byte)(_t_>>48),
203		($1)[$3`'7] = (Byte)(_t_>>56); }')dnl
204
205define(toma, `(((((((((((Elf64_Addr)($1)[$2`'7]<<8)
206		+($1)[$2`'6]<<8)
207		+($1)[$2`'5]<<8)
208		+($1)[$2`'4]<<8)
209		+($1)[$2`'3]<<8)
210		+($1)[$2`'2])<<8)
211		+($1)[$2`'1])<<8)
212		+($1)[$2`'0])')dnl
213define(tomb, `((Byte)($1)[$2])')dnl
214define(tomh, `(((Elf64_Half)($1)[$2`'1]<<8)+($1)[$2`'0])')dnl
215define(tomo, `(((((((((((Elf64_Off)($1)[$2`'7]<<8)
216		+($1)[$2`'6]<<8)
217		+($1)[$2`'5]<<8)
218		+($1)[$2`'4]<<8)
219		+($1)[$2`'3]<<8)
220		+($1)[$2`'2])<<8)
221		+($1)[$2`'1])<<8)
222		+($1)[$2`'0])')dnl
223define(tomw, `(((((((Elf64_Word)($1)[$2`'3]<<8)
224		+($1)[$2`'2])<<8)
225		+($1)[$2`'1])<<8)
226		+($1)[$2`'0])')dnl
227define(tomx, `(((((((((((Elf64_Xword)($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(toml, `(((((((((((Elf64_Lword)($1)[$2`'7]<<8)
236		+($1)[$2`'6]<<8)
237		+($1)[$2`'5]<<8)
238		+($1)[$2`'4]<<8)
239		+($1)[$2`'3]<<8)
240		+($1)[$2`'2])<<8)
241		+($1)[$2`'1])<<8)
242		+($1)[$2`'0])')dnl
243
244
245/*
246 * ELF data object indexes
247 *	The enums are broken apart to get around deficiencies
248 *	in some compilers.
249 */
250
251define(Addr, `
252enum
253{
254	enuma_$1(A)`'ifelse(`$2', `', `', `,
255	A_sizeof')
256};')
257
258Addr(L)
259Addr(M,1)
260
261
262define(Half, `
263enum
264{
265	enumh_$1(H)`'ifelse(`$2', `', `', `,
266	H_sizeof')
267};')
268
269Half(L)
270Half(M,1)
271
272define(Lword, `
273enum
274{
275	enuml_$1(L)`'ifelse(`$2', `', `', `,
276	L_sizeof')
277};')
278
279Lword(L)
280Lword(M,1)
281
282define(Move_1, `
283enum
284{
285	enuml_$1(M1_value),
286	enumx_$1(M1_info),
287	enumx_$1(M1_poffset),
288	enumh_$1(M1_repeat),
289	enumh_$1(M1_stride)`'ifelse(`$2', `', `', `,
290	M1_sizeof')
291};')
292
293Move_1(L)
294Move_1(M,1)
295
296
297define(MoveP_1, `
298enum
299{
300	enuml_$1(MP1_value),
301	enumx_$1(MP1_info),
302	enumx_$1(MP1_poffset),
303	enumh_$1(MP1_repeat),
304	enumh_$1(MP1_stride),
305	enumw_$1(MP1_padding)`'ifelse(`$2', `', `', `,
306	MP1_sizeof')
307};')
308
309MoveP_1(L)
310MoveP_1(M,1)
311
312
313define(Off, `
314enum
315{
316	enumo_$1(O)`'ifelse(`$2', `', `', `,
317	O_sizeof')
318};')
319
320Off(L)
321Off(M,1)
322
323
324define(Word, `
325enum
326{
327	enumw_$1(W)`'ifelse(`$2', `', `', `,
328	W_sizeof')
329};')
330
331Word(L)
332Word(M,1)
333
334
335define(Xword, `
336enum
337{
338	enumx_$1(X)`'ifelse(`$2',`', `', `,
339	X_sizeof')
340};')
341
342Xword(L)
343Xword(M,1)
344
345
346define(Dyn_1, `
347enum
348{
349	enumx_$1(D1_tag),
350	enumx_$1(D1_val)`'ifelse(`$2', `', `', `,
351	D1_sizeof')
352};')
353
354Dyn_1(L)
355Dyn_1(M,1)
356
357
358#define	E1_Nident	16
359
360define(Ehdr_1, `
361enum {
362	ifelse(`$2', `', `E1_ident, ')E1_ident_$1_Z = E1_Nident - 1,
363	enumh_$1(E1_type),
364	enumh_$1(E1_machine),
365	enumw_$1(E1_version),
366	enuma_$1(E1_entry),
367	enumo_$1(E1_phoff),
368	enumo_$1(E1_shoff),
369	enumw_$1(E1_flags),
370	enumh_$1(E1_ehsize),
371	enumh_$1(E1_phentsize),
372	enumh_$1(E1_phnum),
373	enumh_$1(E1_shentsize),
374	enumh_$1(E1_shnum),
375	enumh_$1(E1_shstrndx)`'ifelse(`$2', `', `', `,
376	E1_sizeof')
377};')
378
379Ehdr_1(L)
380Ehdr_1(M,1)
381
382define(Nhdr_1, `
383enum
384{
385	enumw_$1(N1_namesz),
386	enumw_$1(N1_descsz),
387	enumw_$1(N1_type)`'ifelse(`$2', `', `', `,
388	N1_sizeof')
389};')
390
391Nhdr_1(L)
392Nhdr_1(M,1)
393
394define(Phdr_1, `
395enum
396{
397	enumw_$1(P1_type),
398	enumw_$1(P1_flags),
399	enumo_$1(P1_offset),
400	enuma_$1(P1_vaddr),
401	enuma_$1(P1_paddr),
402	enumx_$1(P1_filesz),
403	enumx_$1(P1_memsz),
404	enumx_$1(P1_align)`'ifelse(`$2', `', `', `,
405	P1_sizeof')
406};')
407
408Phdr_1(L)
409Phdr_1(M,1)
410
411
412define(Rel_1, `
413enum
414{
415	enuma_$1(R1_offset),
416	enumx_$1(R1_info)`'ifelse(`$2', `', `', `,
417	R1_sizeof')
418};')
419
420Rel_1(L)
421Rel_1(M,1)
422
423
424define(Rela_1, `
425enum
426{
427	enuma_$1(RA1_offset),
428	enumx_$1(RA1_info),
429	enumx_$1(RA1_addend)`'ifelse(`$2', `', `', `,
430	RA1_sizeof')
431};')
432
433Rela_1(L)
434Rela_1(M,1)
435
436
437define(Shdr_1, `
438enum
439{
440	enumw_$1(SH1_name),
441	enumw_$1(SH1_type),
442	enumx_$1(SH1_flags),
443	enuma_$1(SH1_addr),
444	enumo_$1(SH1_offset),
445	enumx_$1(SH1_size),
446	enumw_$1(SH1_link),
447	enumw_$1(SH1_info),
448	enumx_$1(SH1_addralign),
449	enumx_$1(SH1_entsize)`'ifelse(`$2', `', `', `,
450	SH1_sizeof')
451};')
452
453Shdr_1(L)
454Shdr_1(M,1)
455
456
457define(Sym_1, `
458enum
459{
460	enumw_$1(ST1_name),
461	enumb_$1(ST1_info),
462	enumb_$1(ST1_other),
463	enumh_$1(ST1_shndx),
464	enuma_$1(ST1_value),
465	enumx_$1(ST1_size)`'ifelse(`$2', `', `', `,
466	ST1_sizeof')
467};')
468
469Sym_1(L)
470Sym_1(M,1)
471
472
473define(Syminfo_1, `
474enum
475{
476	enumh_$1(SI1_boundto),
477	enumh_$1(SI1_flags)`'ifelse(`$2', `', `', `,
478	SI1_sizeof')
479};')
480
481Syminfo_1(L)
482Syminfo_1(M,1)
483
484
485define(Cap_1, `
486enum
487{
488	enumx_$1(C1_tag),
489	enumx_$1(C1_val)`'ifelse(`$2', `', `', `,
490	C1_sizeof')
491};')
492
493Cap_1(L)
494Cap_1(M,1)
495
496
497define(Verdef_1, `
498enum
499{
500	enumh_$1(VD1_version),
501	enumh_$1(VD1_flags),
502	enumh_$1(VD1_ndx),
503	enumh_$1(VD1_cnt),
504	enumw_$1(VD1_hash),
505	enumw_$1(VD1_aux),
506	enumw_$1(VD1_next)`'ifelse(`$2', `', `', `,
507	VD1_sizeof')
508};')
509
510Verdef_1(L)
511Verdef_1(M,1)
512
513
514define(Verdaux_1, `
515enum
516{
517	enumw_$1(VDA1_name),
518	enumw_$1(VDA1_next)`'ifelse(`$2', `', `', `,
519	VDA1_sizeof')
520};')
521
522Verdaux_1(L)
523Verdaux_1(M,1)
524
525
526define(Verneed_1, `
527enum
528{
529	enumh_$1(VN1_version),
530	enumh_$1(VN1_cnt),
531	enumw_$1(VN1_file),
532	enumw_$1(VN1_aux),
533	enumw_$1(VN1_next)`'ifelse(`$2', `', `', `,
534	VN1_sizeof')
535};')
536
537Verneed_1(L)
538Verneed_1(M,1)
539
540
541define(Vernaux_1, `
542enum
543{
544	enumw_$1(VNA1_hash),
545	enumh_$1(VNA1_flags),
546	enumh_$1(VNA1_other),
547	enumw_$1(VNA1_name),
548	enumw_$1(VNA1_next)`'ifelse(`$2', `', `', `,
549	VNA1_sizeof')
550};')
551
552Vernaux_1(L)
553Vernaux_1(M,1)
554
555
556/*
557 *	Translation function declarations.
558 *
559 *		<object>_<data><dver><sver>_tof
560 *		<object>_<data><dver><sver>_tom
561 *	where
562 *		<data>	2L	ELFDATA2LSB
563 *			2M	ELFDATA2MSB
564 */
565
566static void	addr_2L_tof(), addr_2L_tom(),
567		addr_2M_tof(), addr_2M_tom(),
568		byte_to(),
569		dyn_2L11_tof(), dyn_2L11_tom(),
570		dyn_2M11_tof(), dyn_2M11_tom(),
571		ehdr_2L11_tof(), ehdr_2L11_tom(),
572		ehdr_2M11_tof(), ehdr_2M11_tom(),
573		half_2L_tof(), half_2L_tom(),
574		half_2M_tof(), half_2M_tom(),
575		move_2L11_tof(), move_2L11_tom(),
576		move_2M11_tof(), move_2M11_tom(),
577		movep_2L11_tof(), movep_2L11_tom(),
578		movep_2M11_tof(), movep_2M11_tom(),
579		off_2L_tof(), off_2L_tom(),
580		off_2M_tof(), off_2M_tom(),
581		note_2L11_tof(), note_2L11_tom(),
582		note_2M11_tof(), note_2M11_tom(),
583		phdr_2L11_tof(), phdr_2L11_tom(),
584		phdr_2M11_tof(), phdr_2M11_tom(),
585		rel_2L11_tof(), rel_2L11_tom(),
586		rel_2M11_tof(), rel_2M11_tom(),
587		rela_2L11_tof(), rela_2L11_tom(),
588		rela_2M11_tof(), rela_2M11_tom(),
589		shdr_2L11_tof(), shdr_2L11_tom(),
590		shdr_2M11_tof(), shdr_2M11_tom(),
591		sword_2L_tof(), sword_2L_tom(),
592		sword_2M_tof(), sword_2M_tom(),
593		sym_2L11_tof(), sym_2L11_tom(),
594		sym_2M11_tof(), sym_2M11_tom(),
595		syminfo_2L11_tof(), syminfo_2L11_tom(),
596		syminfo_2M11_tof(), syminfo_2M11_tom(),
597		word_2L_tof(), word_2L_tom(),
598		word_2M_tof(), word_2M_tom(),
599		verdef_2L11_tof(), verdef_2L11_tom(),
600		verdef_2M11_tof(), verdef_2M11_tom(),
601		verneed_2L11_tof(), verneed_2L11_tom(),
602		verneed_2M11_tof(), verneed_2M11_tom(),
603		sxword_2L_tof(), sxword_2L_tom(),
604		sxword_2M_tof(), sxword_2M_tom(),
605		xword_2L_tof(), xword_2L_tom(),
606		xword_2M_tof(), xword_2M_tom(),
607		cap_2L11_tof(), cap_2L11_tom(),
608		cap_2M11_tof(), cap_2M11_tom();
609
610
611/*
612 *	x64 [dst_version - 1] [src_version - 1] [encode - 1] [type]
613 */
614
615static struct {
616	void	(*x_tof)(),
617		(*x_tom)();
618} x64 [EV_CURRENT] [EV_CURRENT] [ELFDATANUM - 1] [ELF_T_NUM] = {
619	{
620		{
621			{			/* [1-1][1-1][2LSB-1][.] */
622/* BYTE */			{ byte_to, byte_to },
623/* ADDR */			{ addr_2L_tof, addr_2L_tom },
624/* DYN */			{ dyn_2L11_tof, dyn_2L11_tom },
625/* EHDR */			{ ehdr_2L11_tof, ehdr_2L11_tom },
626/* HALF */			{ half_2L_tof, half_2L_tom },
627/* OFF */			{ off_2L_tof, off_2L_tom },
628/* PHDR */			{ phdr_2L11_tof, phdr_2L11_tom },
629/* RELA */			{ rela_2L11_tof, rela_2L11_tom },
630/* REL */			{ rel_2L11_tof, rel_2L11_tom },
631/* SHDR */			{ shdr_2L11_tof, shdr_2L11_tom },
632/* SWORD */			{ sword_2L_tof, sword_2L_tom },
633/* SYM */			{ sym_2L11_tof, sym_2L11_tom },
634/* WORD */			{ word_2L_tof, word_2L_tom },
635/* VERDEF */			{ verdef_2L11_tof, verdef_2L11_tom},
636/* VERNEED */			{ verneed_2L11_tof, verneed_2L11_tom},
637/* SXWORD */			{ sxword_2L_tof, sxword_2L_tom },
638/* XWORD */			{ xword_2L_tof, xword_2L_tom },
639/* SYMINFO */			{ syminfo_2L11_tof, syminfo_2L11_tom },
640/* NOTE */			{ note_2L11_tof, note_2L11_tom },
641/* MOVE */			{ move_2L11_tof, move_2L11_tom },
642/* MOVEP */			{ movep_2L11_tof, movep_2L11_tom },
643/* CAP */			{ cap_2L11_tof, cap_2L11_tom },
644			},
645			{			/* [1-1][1-1][2MSB-1][.] */
646/* BYTE */			{ byte_to, byte_to },
647/* ADDR */			{ addr_2M_tof, addr_2M_tom },
648/* DYN */			{ dyn_2M11_tof, dyn_2M11_tom },
649/* EHDR */			{ ehdr_2M11_tof, ehdr_2M11_tom },
650/* HALF */			{ half_2M_tof, half_2M_tom },
651/* OFF */			{ off_2M_tof, off_2M_tom },
652/* PHDR */			{ phdr_2M11_tof, phdr_2M11_tom },
653/* RELA */			{ rela_2M11_tof, rela_2M11_tom },
654/* REL */			{ rel_2M11_tof, rel_2M11_tom },
655/* SHDR */			{ shdr_2M11_tof, shdr_2M11_tom },
656/* SWORD */			{ sword_2M_tof, sword_2M_tom },
657/* SYM */			{ sym_2M11_tof, sym_2M11_tom },
658/* WORD */			{ word_2M_tof, word_2M_tom },
659/* VERDEF */			{ verdef_2M11_tof, verdef_2M11_tom},
660/* VERNEED */			{ verneed_2M11_tof, verneed_2M11_tom},
661/* SXWORD */			{ sxword_2M_tof, sxword_2M_tom },
662/* XWORD */			{ xword_2M_tof, xword_2M_tom },
663/* SYMINFO */			{ syminfo_2M11_tof, syminfo_2M11_tom },
664/* NOTE */			{ note_2M11_tof, note_2M11_tom },
665/* MOVE */			{ move_2M11_tof, move_2M11_tom },
666/* MOVEP */			{ movep_2M11_tof, movep_2M11_tom },
667/* CAP */			{ cap_2M11_tof, cap_2M11_tom },
668			},
669		},
670	},
671};
672
673
674/*
675 *	size [version - 1] [type]
676 */
677
678static const struct {
679	size_t	s_filesz,
680		s_memsz;
681} fmsize [EV_CURRENT] [ELF_T_NUM] =
682{
683	{					/* [1-1][.] */
684/* BYTE */	{ 1, 1 },
685/* ADDR */	{ A_sizeof, sizeof (Elf64_Addr) },
686/* DYN */	{ D1_sizeof, sizeof (Elf64_Dyn) },
687/* EHDR */	{ E1_sizeof, sizeof (Elf64_Ehdr) },
688/* HALF */	{ H_sizeof, sizeof (Elf64_Half) },
689/* OFF */	{ O_sizeof, sizeof (Elf64_Off) },
690/* PHDR */	{ P1_sizeof, sizeof (Elf64_Phdr) },
691/* RELA */	{ RA1_sizeof, sizeof (Elf64_Rela) },
692/* REL */	{ R1_sizeof, sizeof (Elf64_Rel) },
693/* SHDR */	{ SH1_sizeof, sizeof (Elf64_Shdr) },
694/* SWORD */	{ W_sizeof, sizeof (Elf64_Sword) },
695/* SYM */	{ ST1_sizeof, sizeof (Elf64_Sym) },
696/* WORD */	{ W_sizeof, sizeof (Elf64_Word) },
697/* VERDEF */	{ 1, 1 },	/* both VERDEF & VERNEED have varying size */
698/* VERNEED */	{ 1, 1 },	/* structures so we set their sizes to 1 */
699/* SXWORD */	{ X_sizeof, sizeof (Elf64_Sxword) },
700/* XWORD */	{ X_sizeof, sizeof (Elf64_Xword) },
701/* SYMINFO */	{ SI1_sizeof, sizeof (Elf64_Syminfo) },
702/* NOTE */	{ 1, 1},	/* NOTE has varying sized data we can't */
703				/*  use the usual table magic. */
704/* MOVE */	{ M1_sizeof, sizeof (Elf64_Move) },
705/* MOVEP */	{ MP1_sizeof, sizeof (Elf64_Move) },
706/* CAP */	{ C1_sizeof, sizeof (Elf64_Cap) },
707	},
708};
709
710
711/*
712 *	memory type [version - 1] [section type]
713 */
714
715static const Elf_Type	mtype[EV_CURRENT][SHT_NUM] =
716{
717	{			/* [1-1][.] */
718/* NULL */		ELF_T_BYTE,
719/* PROGBITS */		ELF_T_BYTE,
720/* SYMTAB */		ELF_T_SYM,
721/* STRTAB */		ELF_T_BYTE,
722/* RELA */		ELF_T_RELA,
723/* HASH */		ELF_T_WORD,
724/* DYNAMIC */		ELF_T_DYN,
725/* NOTE */		ELF_T_NOTE,
726/* NOBITS */		ELF_T_BYTE,
727/* REL */		ELF_T_REL,
728/* SHLIB */		ELF_T_BYTE,
729/* DYNSYM */		ELF_T_SYM,
730/* UNKNOWN12 */		ELF_T_BYTE,
731/* UNKNOWN13 */		ELF_T_BYTE,
732/* INIT_ARRAY */	ELF_T_ADDR,
733/* FINI_ARRAY */	ELF_T_ADDR,
734/* PREINIT_ARRAY */	ELF_T_ADDR,
735/* GROUP */		ELF_T_WORD,
736/* SYMTAB_SHNDX */	ELF_T_WORD
737	},
738};
739
740
741size_t
742elf64_fsize(Elf_Type type, size_t count, unsigned ver)
743{
744	if (--ver >= EV_CURRENT) {
745		_elf_seterr(EREQ_VER, 0);
746		return (0);
747	}
748	if ((unsigned)type >= ELF_T_NUM) {
749		_elf_seterr(EREQ_TYPE, 0);
750		return (0);
751	}
752	return (fmsize[ver][type].s_filesz * count);
753}
754
755
756size_t
757_elf64_msize(Elf_Type type, unsigned ver)
758{
759	return (fmsize[ver - 1][type].s_memsz);
760}
761
762
763Elf_Type
764/* ARGSUSED */
765_elf64_mtype(Elf * elf, Elf64_Word shtype, unsigned ver)
766{
767	Elf64_Ehdr *	ehdr = (Elf64_Ehdr *)elf->ed_ehdr;
768
769	if (shtype < SHT_NUM)
770		return (mtype[ver - 1][shtype]);
771
772	switch (shtype) {
773	case SHT_SUNW_symsort:
774	case SHT_SUNW_tlssort:
775		return (ELF_T_WORD);
776	case SHT_SUNW_LDYNSYM:
777		return (ELF_T_SYM);
778	case SHT_SUNW_dof:
779		return (ELF_T_BYTE);
780	case SHT_SUNW_cap:
781		return (ELF_T_CAP);
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