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