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