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