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