xref: /onnv-gate/usr/src/cmd/sgs/libelf/common/gelf.c (revision 0:68f95e015346)
1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate  * CDDL HEADER START
3*0Sstevel@tonic-gate  *
4*0Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*0Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*0Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*0Sstevel@tonic-gate  * with the License.
8*0Sstevel@tonic-gate  *
9*0Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*0Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*0Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*0Sstevel@tonic-gate  * and limitations under the License.
13*0Sstevel@tonic-gate  *
14*0Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*0Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*0Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*0Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*0Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*0Sstevel@tonic-gate  *
20*0Sstevel@tonic-gate  * CDDL HEADER END
21*0Sstevel@tonic-gate  */
22*0Sstevel@tonic-gate /*
23*0Sstevel@tonic-gate  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24*0Sstevel@tonic-gate  * Use is subject to license terms.
25*0Sstevel@tonic-gate  */
26*0Sstevel@tonic-gate 
27*0Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
28*0Sstevel@tonic-gate 
29*0Sstevel@tonic-gate #include <string.h>
30*0Sstevel@tonic-gate #include "gelf.h"
31*0Sstevel@tonic-gate #include "decl.h"
32*0Sstevel@tonic-gate #include "msg.h"
33*0Sstevel@tonic-gate 
34*0Sstevel@tonic-gate 
35*0Sstevel@tonic-gate /*
36*0Sstevel@tonic-gate  * Find elf or it's class from a pointer to an Elf_Data struct.
37*0Sstevel@tonic-gate  * Warning:  this Assumes that the Elf_Data is part of a libelf
38*0Sstevel@tonic-gate  * Dnode structure, which is expected to be true for any Elf_Data
39*0Sstevel@tonic-gate  * passed into libelf *except* for the xlatetof() and xlatetom() functions.
40*0Sstevel@tonic-gate  */
41*0Sstevel@tonic-gate #define	EDATA_CLASS(edata) \
42*0Sstevel@tonic-gate 	(((Dnode *)(edata))->db_scn->s_elf->ed_class)
43*0Sstevel@tonic-gate 
44*0Sstevel@tonic-gate #define	EDATA_ELF(edata) \
45*0Sstevel@tonic-gate 	(((Dnode *)(edata))->db_scn->s_elf)
46*0Sstevel@tonic-gate 
47*0Sstevel@tonic-gate #define	EDATA_SCN(edata) \
48*0Sstevel@tonic-gate 	(((Dnode *)(edata))->db_scn)
49*0Sstevel@tonic-gate 
50*0Sstevel@tonic-gate #define	EDATA_READLOCKS(edata) \
51*0Sstevel@tonic-gate 	READLOCKS(EDATA_ELF((edata)), EDATA_SCN((edata)))
52*0Sstevel@tonic-gate 
53*0Sstevel@tonic-gate #define	EDATA_READUNLOCKS(edata) \
54*0Sstevel@tonic-gate 	READUNLOCKS(EDATA_ELF((edata)), EDATA_SCN((edata)))
55*0Sstevel@tonic-gate 
56*0Sstevel@tonic-gate 
57*0Sstevel@tonic-gate size_t
58*0Sstevel@tonic-gate gelf_fsize(Elf * elf, Elf_Type type, size_t count, unsigned ver)
59*0Sstevel@tonic-gate {
60*0Sstevel@tonic-gate 	int class;
61*0Sstevel@tonic-gate 
62*0Sstevel@tonic-gate 	if (elf == NULL)
63*0Sstevel@tonic-gate 		return (0);
64*0Sstevel@tonic-gate 
65*0Sstevel@tonic-gate 	class = gelf_getclass(elf);
66*0Sstevel@tonic-gate 	if (class == ELFCLASS32)
67*0Sstevel@tonic-gate 		return (elf32_fsize(type, count, ver));
68*0Sstevel@tonic-gate 	else if (class == ELFCLASS64)
69*0Sstevel@tonic-gate 		return (elf64_fsize(type, count, ver));
70*0Sstevel@tonic-gate 
71*0Sstevel@tonic-gate 	_elf_seterr(EREQ_CLASS, 0);
72*0Sstevel@tonic-gate 	return (0);
73*0Sstevel@tonic-gate }
74*0Sstevel@tonic-gate 
75*0Sstevel@tonic-gate 
76*0Sstevel@tonic-gate int
77*0Sstevel@tonic-gate gelf_getclass(Elf *elf)
78*0Sstevel@tonic-gate {
79*0Sstevel@tonic-gate 	if (elf == NULL)
80*0Sstevel@tonic-gate 		return (0);
81*0Sstevel@tonic-gate 
82*0Sstevel@tonic-gate 	/*
83*0Sstevel@tonic-gate 	 * Don't rely on the idents, a new ehdr doesn't have it!
84*0Sstevel@tonic-gate 	 */
85*0Sstevel@tonic-gate 	return (elf->ed_class);
86*0Sstevel@tonic-gate }
87*0Sstevel@tonic-gate 
88*0Sstevel@tonic-gate 
89*0Sstevel@tonic-gate GElf_Ehdr *
90*0Sstevel@tonic-gate gelf_getehdr(Elf *elf, GElf_Ehdr *dst)
91*0Sstevel@tonic-gate {
92*0Sstevel@tonic-gate 	int class;
93*0Sstevel@tonic-gate 
94*0Sstevel@tonic-gate 	if (elf == NULL)
95*0Sstevel@tonic-gate 		return (NULL);
96*0Sstevel@tonic-gate 
97*0Sstevel@tonic-gate 	class = gelf_getclass(elf);
98*0Sstevel@tonic-gate 	if (class == ELFCLASS32) {
99*0Sstevel@tonic-gate 		Elf32_Ehdr * e		= elf32_getehdr(elf);
100*0Sstevel@tonic-gate 
101*0Sstevel@tonic-gate 		if (e == NULL)
102*0Sstevel@tonic-gate 			return (NULL);
103*0Sstevel@tonic-gate 
104*0Sstevel@tonic-gate 		ELFRLOCK(elf);
105*0Sstevel@tonic-gate 		(void) memcpy(dst->e_ident, e->e_ident, EI_NIDENT);
106*0Sstevel@tonic-gate 		dst->e_type		= e->e_type;
107*0Sstevel@tonic-gate 		dst->e_machine		= e->e_machine;
108*0Sstevel@tonic-gate 		dst->e_version		= e->e_version;
109*0Sstevel@tonic-gate 		dst->e_entry		= (Elf64_Addr)e->e_entry;
110*0Sstevel@tonic-gate 		dst->e_phoff		= (Elf64_Off)e->e_phoff;
111*0Sstevel@tonic-gate 		dst->e_shoff		= (Elf64_Off)e->e_shoff;
112*0Sstevel@tonic-gate 		dst->e_flags		= e->e_flags;
113*0Sstevel@tonic-gate 		dst->e_ehsize		= e->e_ehsize;
114*0Sstevel@tonic-gate 		dst->e_phentsize	= e->e_phentsize;
115*0Sstevel@tonic-gate 		dst->e_phnum		= e->e_phnum;
116*0Sstevel@tonic-gate 		dst->e_shentsize	= e->e_shentsize;
117*0Sstevel@tonic-gate 		dst->e_shnum		= e->e_shnum;
118*0Sstevel@tonic-gate 		dst->e_shstrndx		= e->e_shstrndx;
119*0Sstevel@tonic-gate 		ELFUNLOCK(elf);
120*0Sstevel@tonic-gate 
121*0Sstevel@tonic-gate 		return (dst);
122*0Sstevel@tonic-gate 	} else if (class == ELFCLASS64) {
123*0Sstevel@tonic-gate 		Elf64_Ehdr * e		= elf64_getehdr(elf);
124*0Sstevel@tonic-gate 
125*0Sstevel@tonic-gate 		if (e == NULL)
126*0Sstevel@tonic-gate 			return (NULL);
127*0Sstevel@tonic-gate 
128*0Sstevel@tonic-gate 		ELFRLOCK(elf);
129*0Sstevel@tonic-gate 		*dst			= *e;
130*0Sstevel@tonic-gate 		ELFUNLOCK(elf);
131*0Sstevel@tonic-gate 
132*0Sstevel@tonic-gate 		return (dst);
133*0Sstevel@tonic-gate 	}
134*0Sstevel@tonic-gate 
135*0Sstevel@tonic-gate 	_elf_seterr(EREQ_CLASS, 0);
136*0Sstevel@tonic-gate 	return (NULL);
137*0Sstevel@tonic-gate }
138*0Sstevel@tonic-gate 
139*0Sstevel@tonic-gate 
140*0Sstevel@tonic-gate int
141*0Sstevel@tonic-gate gelf_update_ehdr(Elf *elf, GElf_Ehdr *src)
142*0Sstevel@tonic-gate {
143*0Sstevel@tonic-gate 	int class;
144*0Sstevel@tonic-gate 
145*0Sstevel@tonic-gate 	if (elf == NULL)
146*0Sstevel@tonic-gate 		return (0);
147*0Sstevel@tonic-gate 
148*0Sstevel@tonic-gate 	/*
149*0Sstevel@tonic-gate 	 * In case elf isn't cooked.
150*0Sstevel@tonic-gate 	 */
151*0Sstevel@tonic-gate 	class = gelf_getclass(elf);
152*0Sstevel@tonic-gate 	if (class == ELFCLASSNONE)
153*0Sstevel@tonic-gate 		class = src->e_ident[EI_CLASS];
154*0Sstevel@tonic-gate 
155*0Sstevel@tonic-gate 
156*0Sstevel@tonic-gate 	if (class == ELFCLASS32) {
157*0Sstevel@tonic-gate 		Elf32_Ehdr * d	= elf32_getehdr(elf);
158*0Sstevel@tonic-gate 
159*0Sstevel@tonic-gate 		if (d == NULL)
160*0Sstevel@tonic-gate 			return (0);
161*0Sstevel@tonic-gate 
162*0Sstevel@tonic-gate 		ELFWLOCK(elf);
163*0Sstevel@tonic-gate 		(void) memcpy(d->e_ident, src->e_ident, EI_NIDENT);
164*0Sstevel@tonic-gate 		d->e_type	= src->e_type;
165*0Sstevel@tonic-gate 		d->e_machine	= src->e_machine;
166*0Sstevel@tonic-gate 		d->e_version	= src->e_version;
167*0Sstevel@tonic-gate 		/* LINTED */
168*0Sstevel@tonic-gate 		d->e_entry	= (Elf32_Addr)src->e_entry;
169*0Sstevel@tonic-gate 		/* LINTED */
170*0Sstevel@tonic-gate 		d->e_phoff	= (Elf32_Off)src->e_phoff;
171*0Sstevel@tonic-gate 		/* LINTED */
172*0Sstevel@tonic-gate 		d->e_shoff	= (Elf32_Off)src->e_shoff;
173*0Sstevel@tonic-gate 		/* could memcpy the rest of these... */
174*0Sstevel@tonic-gate 		d->e_flags	= src->e_flags;
175*0Sstevel@tonic-gate 		d->e_ehsize	= src->e_ehsize;
176*0Sstevel@tonic-gate 		d->e_phentsize	= src->e_phentsize;
177*0Sstevel@tonic-gate 		d->e_phnum	= src->e_phnum;
178*0Sstevel@tonic-gate 		d->e_shentsize	= src->e_shentsize;
179*0Sstevel@tonic-gate 		d->e_shnum	= src->e_shnum;
180*0Sstevel@tonic-gate 		d->e_shstrndx	= src->e_shstrndx;
181*0Sstevel@tonic-gate 		ELFUNLOCK(elf);
182*0Sstevel@tonic-gate 
183*0Sstevel@tonic-gate 		return (1);
184*0Sstevel@tonic-gate 	} else if (class == ELFCLASS64) {
185*0Sstevel@tonic-gate 		Elf64_Ehdr * d	= elf64_getehdr(elf);
186*0Sstevel@tonic-gate 
187*0Sstevel@tonic-gate 		if (d == NULL)
188*0Sstevel@tonic-gate 			return (0);
189*0Sstevel@tonic-gate 
190*0Sstevel@tonic-gate 		ELFWLOCK(elf);
191*0Sstevel@tonic-gate 		*d		= *(Elf64_Ehdr *)src;
192*0Sstevel@tonic-gate 		ELFUNLOCK(elf);
193*0Sstevel@tonic-gate 
194*0Sstevel@tonic-gate 		return (1);
195*0Sstevel@tonic-gate 	}
196*0Sstevel@tonic-gate 
197*0Sstevel@tonic-gate 	_elf_seterr(EREQ_CLASS, 0);
198*0Sstevel@tonic-gate 	return (0);
199*0Sstevel@tonic-gate }
200*0Sstevel@tonic-gate 
201*0Sstevel@tonic-gate 
202*0Sstevel@tonic-gate unsigned long
203*0Sstevel@tonic-gate gelf_newehdr(Elf *elf, int class)
204*0Sstevel@tonic-gate {
205*0Sstevel@tonic-gate 	if (elf == NULL)
206*0Sstevel@tonic-gate 		return (0);
207*0Sstevel@tonic-gate 
208*0Sstevel@tonic-gate 	if (class == ELFCLASS32)
209*0Sstevel@tonic-gate 		return ((unsigned long)elf32_newehdr(elf));
210*0Sstevel@tonic-gate 	else if (class == ELFCLASS64)
211*0Sstevel@tonic-gate 		return ((unsigned long)elf64_newehdr(elf));
212*0Sstevel@tonic-gate 
213*0Sstevel@tonic-gate 	_elf_seterr(EREQ_CLASS, 0);
214*0Sstevel@tonic-gate 	return (0);
215*0Sstevel@tonic-gate }
216*0Sstevel@tonic-gate 
217*0Sstevel@tonic-gate 
218*0Sstevel@tonic-gate GElf_Phdr *
219*0Sstevel@tonic-gate gelf_getphdr(Elf *elf, int ndx, GElf_Phdr *dst)
220*0Sstevel@tonic-gate {
221*0Sstevel@tonic-gate 	int		class;
222*0Sstevel@tonic-gate 	GElf_Ehdr	ehdr;
223*0Sstevel@tonic-gate 
224*0Sstevel@tonic-gate 	if (elf == NULL)
225*0Sstevel@tonic-gate 		return (NULL);
226*0Sstevel@tonic-gate 
227*0Sstevel@tonic-gate 	if (gelf_getehdr(elf, &ehdr) == NULL)
228*0Sstevel@tonic-gate 		return (NULL);
229*0Sstevel@tonic-gate 
230*0Sstevel@tonic-gate 	if (ehdr.e_phnum < ndx) {
231*0Sstevel@tonic-gate 		_elf_seterr(EREQ_RAND, 0);
232*0Sstevel@tonic-gate 		return (NULL);
233*0Sstevel@tonic-gate 	}
234*0Sstevel@tonic-gate 
235*0Sstevel@tonic-gate 	class = gelf_getclass(elf);
236*0Sstevel@tonic-gate 	if ((class != ELFCLASS32) && (class != ELFCLASS64)) {
237*0Sstevel@tonic-gate 		_elf_seterr(EREQ_CLASS, 0);
238*0Sstevel@tonic-gate 		return (NULL);
239*0Sstevel@tonic-gate 	}
240*0Sstevel@tonic-gate 
241*0Sstevel@tonic-gate 	if (class == ELFCLASS32) {
242*0Sstevel@tonic-gate 		Elf32_Phdr *p	= &((Elf32_Phdr *)elf32_getphdr(elf))[ndx];
243*0Sstevel@tonic-gate 
244*0Sstevel@tonic-gate 		ELFRLOCK(elf);
245*0Sstevel@tonic-gate 		dst->p_type	= p->p_type;
246*0Sstevel@tonic-gate 		dst->p_flags	= p->p_flags;
247*0Sstevel@tonic-gate 		dst->p_offset	= (Elf64_Off)p->p_offset;
248*0Sstevel@tonic-gate 		dst->p_vaddr	= (Elf64_Addr)p->p_vaddr;
249*0Sstevel@tonic-gate 		dst->p_paddr	= (Elf64_Addr)p->p_paddr;
250*0Sstevel@tonic-gate 		dst->p_filesz	= (Elf64_Xword)p->p_filesz;
251*0Sstevel@tonic-gate 		dst->p_memsz	= (Elf64_Xword)p->p_memsz;
252*0Sstevel@tonic-gate 		dst->p_align	= (Elf64_Xword)p->p_align;
253*0Sstevel@tonic-gate 		ELFUNLOCK(elf);
254*0Sstevel@tonic-gate 	} else if (class == ELFCLASS64) {
255*0Sstevel@tonic-gate 		Elf64_Phdr *phdrs = elf64_getphdr(elf);
256*0Sstevel@tonic-gate 		ELFRLOCK(elf);
257*0Sstevel@tonic-gate 		*dst = ((GElf_Phdr *)phdrs)[ndx];
258*0Sstevel@tonic-gate 		ELFUNLOCK(elf);
259*0Sstevel@tonic-gate 	}
260*0Sstevel@tonic-gate 
261*0Sstevel@tonic-gate 	return (dst);
262*0Sstevel@tonic-gate }
263*0Sstevel@tonic-gate 
264*0Sstevel@tonic-gate 
265*0Sstevel@tonic-gate int
266*0Sstevel@tonic-gate gelf_update_phdr(Elf *elf, int ndx, GElf_Phdr *src)
267*0Sstevel@tonic-gate {
268*0Sstevel@tonic-gate 	int		class;
269*0Sstevel@tonic-gate 	GElf_Ehdr	ehdr;
270*0Sstevel@tonic-gate 
271*0Sstevel@tonic-gate 	if (elf == NULL)
272*0Sstevel@tonic-gate 		return (0);
273*0Sstevel@tonic-gate 
274*0Sstevel@tonic-gate 	if (gelf_getehdr(elf, &ehdr) == NULL)
275*0Sstevel@tonic-gate 		return (0);
276*0Sstevel@tonic-gate 
277*0Sstevel@tonic-gate 	if (ehdr.e_phnum < ndx) {
278*0Sstevel@tonic-gate 		_elf_seterr(EREQ_RAND, 0);
279*0Sstevel@tonic-gate 		return (0);
280*0Sstevel@tonic-gate 	}
281*0Sstevel@tonic-gate 
282*0Sstevel@tonic-gate 	class = gelf_getclass(elf);
283*0Sstevel@tonic-gate 	if (class == ELFCLASS32) {
284*0Sstevel@tonic-gate 		Elf32_Phdr *dst	= &((Elf32_Phdr *)elf32_getphdr(elf))[ndx];
285*0Sstevel@tonic-gate 		ELFWLOCK(elf);
286*0Sstevel@tonic-gate 		dst->p_type	= src->p_type;
287*0Sstevel@tonic-gate 		dst->p_flags	= src->p_flags;
288*0Sstevel@tonic-gate 		/* LINTED */
289*0Sstevel@tonic-gate 		dst->p_offset	= (Elf32_Off)src->p_offset;
290*0Sstevel@tonic-gate 		/* LINTED */
291*0Sstevel@tonic-gate 		dst->p_vaddr	= (Elf32_Addr)src->p_vaddr;
292*0Sstevel@tonic-gate 		/* LINTED */
293*0Sstevel@tonic-gate 		dst->p_paddr	= (Elf32_Addr)src->p_paddr;
294*0Sstevel@tonic-gate 		/* LINTED */
295*0Sstevel@tonic-gate 		dst->p_filesz	= (Elf32_Word)src->p_filesz;
296*0Sstevel@tonic-gate 		/* LINTED */
297*0Sstevel@tonic-gate 		dst->p_memsz	= (Elf32_Word)src->p_memsz;
298*0Sstevel@tonic-gate 		/* LINTED */
299*0Sstevel@tonic-gate 		dst->p_align	= (Elf32_Word)src->p_align;
300*0Sstevel@tonic-gate 		ELFUNLOCK(elf);
301*0Sstevel@tonic-gate 	} else if (class == ELFCLASS64) {
302*0Sstevel@tonic-gate 		Elf64_Phdr *dst = elf64_getphdr(elf);
303*0Sstevel@tonic-gate 		ELFWLOCK(elf);
304*0Sstevel@tonic-gate 		dst[ndx] = *(GElf_Phdr *)src;
305*0Sstevel@tonic-gate 		ELFUNLOCK(elf);
306*0Sstevel@tonic-gate 	} else {
307*0Sstevel@tonic-gate 		_elf_seterr(EREQ_CLASS, 0);
308*0Sstevel@tonic-gate 		return (0);
309*0Sstevel@tonic-gate 	}
310*0Sstevel@tonic-gate 	return (1);
311*0Sstevel@tonic-gate }
312*0Sstevel@tonic-gate 
313*0Sstevel@tonic-gate 
314*0Sstevel@tonic-gate unsigned long
315*0Sstevel@tonic-gate gelf_newphdr(Elf *elf, size_t phnum)
316*0Sstevel@tonic-gate {
317*0Sstevel@tonic-gate 	int class;
318*0Sstevel@tonic-gate 
319*0Sstevel@tonic-gate 	if (elf == NULL)
320*0Sstevel@tonic-gate 		return (0);
321*0Sstevel@tonic-gate 
322*0Sstevel@tonic-gate 	class = gelf_getclass(elf);
323*0Sstevel@tonic-gate 	if (class == ELFCLASS32)
324*0Sstevel@tonic-gate 		return ((unsigned long)elf32_newphdr(elf, phnum));
325*0Sstevel@tonic-gate 	else if (class == ELFCLASS64)
326*0Sstevel@tonic-gate 		return ((unsigned long)elf64_newphdr(elf, phnum));
327*0Sstevel@tonic-gate 
328*0Sstevel@tonic-gate 	_elf_seterr(EREQ_CLASS, 0);
329*0Sstevel@tonic-gate 	return (0);
330*0Sstevel@tonic-gate }
331*0Sstevel@tonic-gate 
332*0Sstevel@tonic-gate 
333*0Sstevel@tonic-gate GElf_Shdr *
334*0Sstevel@tonic-gate gelf_getshdr(Elf_Scn *scn,  GElf_Shdr *dst)
335*0Sstevel@tonic-gate {
336*0Sstevel@tonic-gate 	if (scn == NULL)
337*0Sstevel@tonic-gate 		return (NULL);
338*0Sstevel@tonic-gate 
339*0Sstevel@tonic-gate 	if (scn->s_elf->ed_class == ELFCLASS32) {
340*0Sstevel@tonic-gate 		Elf32_Shdr *s		= elf32_getshdr(scn);
341*0Sstevel@tonic-gate 
342*0Sstevel@tonic-gate 		if (s == NULL)
343*0Sstevel@tonic-gate 			return (NULL);
344*0Sstevel@tonic-gate 
345*0Sstevel@tonic-gate 		READLOCKS(scn->s_elf, scn);
346*0Sstevel@tonic-gate 		dst->sh_name		= s->sh_name;
347*0Sstevel@tonic-gate 		dst->sh_type		= s->sh_type;
348*0Sstevel@tonic-gate 		dst->sh_flags		= (Elf64_Xword)s->sh_flags;
349*0Sstevel@tonic-gate 		dst->sh_addr		= (Elf64_Addr)s->sh_addr;
350*0Sstevel@tonic-gate 		dst->sh_offset		= (Elf64_Off)s->sh_offset;
351*0Sstevel@tonic-gate 		dst->sh_size		= (Elf64_Xword)s->sh_size;
352*0Sstevel@tonic-gate 		dst->sh_link		= s->sh_link;
353*0Sstevel@tonic-gate 		dst->sh_info		= s->sh_info;
354*0Sstevel@tonic-gate 		dst->sh_addralign	= (Elf64_Xword)s->sh_addralign;
355*0Sstevel@tonic-gate 		dst->sh_entsize		= (Elf64_Xword)s->sh_entsize;
356*0Sstevel@tonic-gate 		READUNLOCKS(scn->s_elf, scn);
357*0Sstevel@tonic-gate 
358*0Sstevel@tonic-gate 		return (dst);
359*0Sstevel@tonic-gate 	} else if (scn->s_elf->ed_class == ELFCLASS64) {
360*0Sstevel@tonic-gate 		Elf64_Shdr *s		= elf64_getshdr(scn);
361*0Sstevel@tonic-gate 
362*0Sstevel@tonic-gate 		if (s == NULL)
363*0Sstevel@tonic-gate 			return (NULL);
364*0Sstevel@tonic-gate 
365*0Sstevel@tonic-gate 		READLOCKS(scn->s_elf, scn);
366*0Sstevel@tonic-gate 		*dst			= *(Elf64_Shdr *)s;
367*0Sstevel@tonic-gate 		READUNLOCKS(scn->s_elf, scn);
368*0Sstevel@tonic-gate 
369*0Sstevel@tonic-gate 		return (dst);
370*0Sstevel@tonic-gate 	}
371*0Sstevel@tonic-gate 
372*0Sstevel@tonic-gate 	_elf_seterr(EREQ_CLASS, 0);
373*0Sstevel@tonic-gate 	return (NULL);
374*0Sstevel@tonic-gate }
375*0Sstevel@tonic-gate 
376*0Sstevel@tonic-gate 
377*0Sstevel@tonic-gate int
378*0Sstevel@tonic-gate gelf_update_shdr(Elf_Scn *scn, GElf_Shdr *src)
379*0Sstevel@tonic-gate {
380*0Sstevel@tonic-gate 	if (scn == NULL)
381*0Sstevel@tonic-gate 		return (0);
382*0Sstevel@tonic-gate 
383*0Sstevel@tonic-gate 	if (scn->s_elf->ed_class == ELFCLASS32) {
384*0Sstevel@tonic-gate 		Elf32_Shdr *dst	= elf32_getshdr(scn);
385*0Sstevel@tonic-gate 
386*0Sstevel@tonic-gate 		if (dst == NULL)
387*0Sstevel@tonic-gate 			return (0);
388*0Sstevel@tonic-gate 
389*0Sstevel@tonic-gate 		ELFWLOCK(scn->s_elf);
390*0Sstevel@tonic-gate 		dst->sh_name		= src->sh_name;
391*0Sstevel@tonic-gate 		dst->sh_type		= src->sh_type;
392*0Sstevel@tonic-gate 		/* LINTED */
393*0Sstevel@tonic-gate 		dst->sh_flags		= (Elf32_Word)src->sh_flags;
394*0Sstevel@tonic-gate 		/* LINTED */
395*0Sstevel@tonic-gate 		dst->sh_addr		= (Elf32_Addr)src->sh_addr;
396*0Sstevel@tonic-gate 		/* LINTED */
397*0Sstevel@tonic-gate 		dst->sh_offset		= (Elf32_Off) src->sh_offset;
398*0Sstevel@tonic-gate 		/* LINTED */
399*0Sstevel@tonic-gate 		dst->sh_size		= (Elf32_Word)src->sh_size;
400*0Sstevel@tonic-gate 		dst->sh_link		= src->sh_link;
401*0Sstevel@tonic-gate 		dst->sh_info		= src->sh_info;
402*0Sstevel@tonic-gate 		/* LINTED */
403*0Sstevel@tonic-gate 		dst->sh_addralign	= (Elf32_Word)src->sh_addralign;
404*0Sstevel@tonic-gate 		/* LINTED */
405*0Sstevel@tonic-gate 		dst->sh_entsize		= (Elf32_Word)src->sh_entsize;
406*0Sstevel@tonic-gate 
407*0Sstevel@tonic-gate 		ELFUNLOCK(scn->s_elf);
408*0Sstevel@tonic-gate 		return (1);
409*0Sstevel@tonic-gate 	} else if (scn->s_elf->ed_class == ELFCLASS64) {
410*0Sstevel@tonic-gate 		Elf64_Shdr * dst	= elf64_getshdr(scn);
411*0Sstevel@tonic-gate 
412*0Sstevel@tonic-gate 		if (dst == NULL)
413*0Sstevel@tonic-gate 			return (0);
414*0Sstevel@tonic-gate 
415*0Sstevel@tonic-gate 		ELFWLOCK(scn->s_elf);
416*0Sstevel@tonic-gate 		*dst			= *(Elf64_Shdr *)src;
417*0Sstevel@tonic-gate 		ELFUNLOCK(scn->s_elf);
418*0Sstevel@tonic-gate 		return (1);
419*0Sstevel@tonic-gate 	}
420*0Sstevel@tonic-gate 
421*0Sstevel@tonic-gate 	_elf_seterr(EREQ_CLASS, 0);
422*0Sstevel@tonic-gate 	return (0);
423*0Sstevel@tonic-gate }
424*0Sstevel@tonic-gate 
425*0Sstevel@tonic-gate 
426*0Sstevel@tonic-gate /*
427*0Sstevel@tonic-gate  * gelf_xlatetof/gelf_xlatetom use 'elf' to find the class
428*0Sstevel@tonic-gate  * because these are the odd case where the Elf_Data structs
429*0Sstevel@tonic-gate  * might not have been allocated by libelf (and therefore
430*0Sstevel@tonic-gate  * don't have Dnode's associated with them).
431*0Sstevel@tonic-gate  */
432*0Sstevel@tonic-gate Elf_Data *
433*0Sstevel@tonic-gate gelf_xlatetof(Elf *elf, Elf_Data *dst, const Elf_Data *src, unsigned encode)
434*0Sstevel@tonic-gate {
435*0Sstevel@tonic-gate 	int class;
436*0Sstevel@tonic-gate 
437*0Sstevel@tonic-gate 	if ((elf == NULL) || (dst == NULL) || (src == NULL))
438*0Sstevel@tonic-gate 		return (NULL);
439*0Sstevel@tonic-gate 
440*0Sstevel@tonic-gate 	class = gelf_getclass(elf);
441*0Sstevel@tonic-gate 	if (class == ELFCLASS32)
442*0Sstevel@tonic-gate 		return (elf32_xlatetof(dst, src, encode));
443*0Sstevel@tonic-gate 	else if (class == ELFCLASS64)
444*0Sstevel@tonic-gate 		return (elf64_xlatetof(dst, src, encode));
445*0Sstevel@tonic-gate 
446*0Sstevel@tonic-gate 	_elf_seterr(EREQ_CLASS, 0);
447*0Sstevel@tonic-gate 	return (NULL);
448*0Sstevel@tonic-gate }
449*0Sstevel@tonic-gate 
450*0Sstevel@tonic-gate 
451*0Sstevel@tonic-gate Elf_Data *
452*0Sstevel@tonic-gate gelf_xlatetom(Elf *elf, Elf_Data *dst, const Elf_Data *src, unsigned encode)
453*0Sstevel@tonic-gate {
454*0Sstevel@tonic-gate 	int class;
455*0Sstevel@tonic-gate 
456*0Sstevel@tonic-gate 	if ((elf == NULL) || (dst == NULL) || (src == NULL))
457*0Sstevel@tonic-gate 		return (NULL);
458*0Sstevel@tonic-gate 
459*0Sstevel@tonic-gate 	class = gelf_getclass(elf);
460*0Sstevel@tonic-gate 	if (class == ELFCLASS32)
461*0Sstevel@tonic-gate 		return (elf32_xlatetom(dst, src, encode));
462*0Sstevel@tonic-gate 	else if (class == ELFCLASS64)
463*0Sstevel@tonic-gate 		return (elf64_xlatetom(dst, src, encode));
464*0Sstevel@tonic-gate 
465*0Sstevel@tonic-gate 	_elf_seterr(EREQ_CLASS, 0);
466*0Sstevel@tonic-gate 	return (NULL);
467*0Sstevel@tonic-gate }
468*0Sstevel@tonic-gate 
469*0Sstevel@tonic-gate 
470*0Sstevel@tonic-gate GElf_Sym *
471*0Sstevel@tonic-gate gelf_getsym(Elf_Data * data, int ndx, GElf_Sym * dst)
472*0Sstevel@tonic-gate {
473*0Sstevel@tonic-gate 	int	class;
474*0Sstevel@tonic-gate 	size_t	entsize;
475*0Sstevel@tonic-gate 
476*0Sstevel@tonic-gate 	if (data == NULL)
477*0Sstevel@tonic-gate 		return (NULL);
478*0Sstevel@tonic-gate 
479*0Sstevel@tonic-gate 	class = EDATA_CLASS(data);
480*0Sstevel@tonic-gate 	if (class == ELFCLASS32)
481*0Sstevel@tonic-gate 		entsize = sizeof (Elf32_Sym);
482*0Sstevel@tonic-gate 	else if (class == ELFCLASS64)
483*0Sstevel@tonic-gate 		entsize = sizeof (GElf_Sym);
484*0Sstevel@tonic-gate 	else {
485*0Sstevel@tonic-gate 		_elf_seterr(EREQ_CLASS, 0);
486*0Sstevel@tonic-gate 		return (NULL);
487*0Sstevel@tonic-gate 	}
488*0Sstevel@tonic-gate 
489*0Sstevel@tonic-gate 	EDATA_READLOCKS(data);
490*0Sstevel@tonic-gate 
491*0Sstevel@tonic-gate 	if ((entsize * ndx) > data->d_size) {
492*0Sstevel@tonic-gate 		_elf_seterr(EREQ_RAND, 0);
493*0Sstevel@tonic-gate 		dst = NULL;
494*0Sstevel@tonic-gate 	} else if (class == ELFCLASS32) {
495*0Sstevel@tonic-gate 		Elf32_Sym	*s;
496*0Sstevel@tonic-gate 		s		= &(((Elf32_Sym *)data->d_buf)[ndx]);
497*0Sstevel@tonic-gate 		dst->st_name	= s->st_name;
498*0Sstevel@tonic-gate 		dst->st_value	= (Elf64_Addr)s->st_value;
499*0Sstevel@tonic-gate 		dst->st_size	= (Elf64_Xword)s->st_size;
500*0Sstevel@tonic-gate 		dst->st_info	= ELF64_ST_INFO(ELF32_ST_BIND(s->st_info),
501*0Sstevel@tonic-gate 					ELF32_ST_TYPE(s->st_info));
502*0Sstevel@tonic-gate 		dst->st_other	= s->st_other;
503*0Sstevel@tonic-gate 		dst->st_shndx	= s->st_shndx;
504*0Sstevel@tonic-gate 	} else
505*0Sstevel@tonic-gate 		*dst = ((GElf_Sym *)data->d_buf)[ndx];
506*0Sstevel@tonic-gate 
507*0Sstevel@tonic-gate 	EDATA_READUNLOCKS(data);
508*0Sstevel@tonic-gate 	return (dst);
509*0Sstevel@tonic-gate }
510*0Sstevel@tonic-gate 
511*0Sstevel@tonic-gate 
512*0Sstevel@tonic-gate int
513*0Sstevel@tonic-gate gelf_update_sym(Elf_Data *dst, int ndx, GElf_Sym *src)
514*0Sstevel@tonic-gate {
515*0Sstevel@tonic-gate 	int	class, rc = 1;
516*0Sstevel@tonic-gate 	size_t	entsize;
517*0Sstevel@tonic-gate 
518*0Sstevel@tonic-gate 	if (dst == NULL)
519*0Sstevel@tonic-gate 		return (0);
520*0Sstevel@tonic-gate 
521*0Sstevel@tonic-gate 	class = EDATA_CLASS(dst);
522*0Sstevel@tonic-gate 	if (class == ELFCLASS32)
523*0Sstevel@tonic-gate 		entsize = sizeof (Elf32_Sym);
524*0Sstevel@tonic-gate 	else if (class == ELFCLASS64)
525*0Sstevel@tonic-gate 		entsize = sizeof (GElf_Sym);
526*0Sstevel@tonic-gate 	else {
527*0Sstevel@tonic-gate 		_elf_seterr(EREQ_CLASS, 0);
528*0Sstevel@tonic-gate 		return (0);
529*0Sstevel@tonic-gate 	}
530*0Sstevel@tonic-gate 
531*0Sstevel@tonic-gate 	ELFWLOCK(EDATA_ELF(dst));
532*0Sstevel@tonic-gate 
533*0Sstevel@tonic-gate 	if ((entsize * ndx) > dst->d_size) {
534*0Sstevel@tonic-gate 		_elf_seterr(EREQ_RAND, 0);
535*0Sstevel@tonic-gate 		rc = 0;
536*0Sstevel@tonic-gate 	} else if (class == ELFCLASS32) {
537*0Sstevel@tonic-gate 		Elf32_Sym * d;
538*0Sstevel@tonic-gate 
539*0Sstevel@tonic-gate 		d		= &(((Elf32_Sym *)dst->d_buf)[ndx]);
540*0Sstevel@tonic-gate 		d->st_name	= src->st_name;
541*0Sstevel@tonic-gate 		/* LINTED */
542*0Sstevel@tonic-gate 		d->st_value	= (Elf32_Addr)src->st_value;
543*0Sstevel@tonic-gate 		/* LINTED */
544*0Sstevel@tonic-gate 		d->st_size	= (Elf32_Word)src->st_size;
545*0Sstevel@tonic-gate 		d->st_info	= ELF32_ST_INFO(ELF64_ST_BIND(src->st_info),
546*0Sstevel@tonic-gate 					ELF64_ST_TYPE(src->st_info));
547*0Sstevel@tonic-gate 		d->st_other	= src->st_other;
548*0Sstevel@tonic-gate 		d->st_shndx	= src->st_shndx;
549*0Sstevel@tonic-gate 	} else
550*0Sstevel@tonic-gate 		((Elf64_Sym *)dst->d_buf)[ndx] = *((Elf64_Sym *)src);
551*0Sstevel@tonic-gate 
552*0Sstevel@tonic-gate 	ELFUNLOCK(EDATA_ELF(dst));
553*0Sstevel@tonic-gate 	return (rc);
554*0Sstevel@tonic-gate }
555*0Sstevel@tonic-gate 
556*0Sstevel@tonic-gate 
557*0Sstevel@tonic-gate GElf_Syminfo *
558*0Sstevel@tonic-gate gelf_getsyminfo(Elf_Data *data, int ndx, GElf_Syminfo *dst)
559*0Sstevel@tonic-gate {
560*0Sstevel@tonic-gate 	int	class;
561*0Sstevel@tonic-gate 	size_t	entsize;
562*0Sstevel@tonic-gate 
563*0Sstevel@tonic-gate 	if (data == NULL)
564*0Sstevel@tonic-gate 		return (NULL);
565*0Sstevel@tonic-gate 
566*0Sstevel@tonic-gate 	class = EDATA_CLASS(data);
567*0Sstevel@tonic-gate 	if (class == ELFCLASS32)
568*0Sstevel@tonic-gate 		entsize = sizeof (Elf32_Syminfo);
569*0Sstevel@tonic-gate 	else if (class == ELFCLASS64)
570*0Sstevel@tonic-gate 		entsize = sizeof (GElf_Syminfo);
571*0Sstevel@tonic-gate 	else {
572*0Sstevel@tonic-gate 		_elf_seterr(EREQ_CLASS, 0);
573*0Sstevel@tonic-gate 		return (NULL);
574*0Sstevel@tonic-gate 	}
575*0Sstevel@tonic-gate 	EDATA_READLOCKS(data);
576*0Sstevel@tonic-gate 
577*0Sstevel@tonic-gate 	if ((entsize * ndx) > data->d_size) {
578*0Sstevel@tonic-gate 		_elf_seterr(EREQ_RAND, 0);
579*0Sstevel@tonic-gate 		dst = NULL;
580*0Sstevel@tonic-gate 	} else if (class == ELFCLASS32) {
581*0Sstevel@tonic-gate 		Elf32_Syminfo *	si;
582*0Sstevel@tonic-gate 
583*0Sstevel@tonic-gate 		si		= &(((Elf32_Syminfo *)data->d_buf)[ndx]);
584*0Sstevel@tonic-gate 		dst->si_boundto = si->si_boundto;
585*0Sstevel@tonic-gate 		dst->si_flags	= si->si_flags;
586*0Sstevel@tonic-gate 	} else
587*0Sstevel@tonic-gate 		*dst		= ((GElf_Syminfo *)data->d_buf)[ndx];
588*0Sstevel@tonic-gate 
589*0Sstevel@tonic-gate 	EDATA_READUNLOCKS(data);
590*0Sstevel@tonic-gate 	return (dst);
591*0Sstevel@tonic-gate }
592*0Sstevel@tonic-gate 
593*0Sstevel@tonic-gate int
594*0Sstevel@tonic-gate gelf_update_syminfo(Elf_Data *dst, int ndx, GElf_Syminfo *src)
595*0Sstevel@tonic-gate {
596*0Sstevel@tonic-gate 	int	class, rc = 1;
597*0Sstevel@tonic-gate 	size_t	entsize;
598*0Sstevel@tonic-gate 
599*0Sstevel@tonic-gate 	if (dst == NULL)
600*0Sstevel@tonic-gate 		return (0);
601*0Sstevel@tonic-gate 
602*0Sstevel@tonic-gate 	class = EDATA_CLASS(dst);
603*0Sstevel@tonic-gate 	if (class == ELFCLASS32)
604*0Sstevel@tonic-gate 		entsize = sizeof (Elf32_Syminfo);
605*0Sstevel@tonic-gate 	else if (class == ELFCLASS64)
606*0Sstevel@tonic-gate 		entsize = sizeof (GElf_Syminfo);
607*0Sstevel@tonic-gate 	else {
608*0Sstevel@tonic-gate 		_elf_seterr(EREQ_CLASS, 0);
609*0Sstevel@tonic-gate 		return (0);
610*0Sstevel@tonic-gate 	}
611*0Sstevel@tonic-gate 	ELFWLOCK(EDATA_ELF(dst));
612*0Sstevel@tonic-gate 
613*0Sstevel@tonic-gate 	if ((entsize * ndx) > dst->d_size) {
614*0Sstevel@tonic-gate 		_elf_seterr(EREQ_RAND, 0);
615*0Sstevel@tonic-gate 		rc = 0;
616*0Sstevel@tonic-gate 	} else if (class == ELFCLASS32) {
617*0Sstevel@tonic-gate 		Elf32_Syminfo * d	= &(((Elf32_Syminfo *)dst->d_buf)[ndx]);
618*0Sstevel@tonic-gate 		d->si_boundto		= src->si_boundto;
619*0Sstevel@tonic-gate 		d->si_flags		= src->si_flags;
620*0Sstevel@tonic-gate 	} else
621*0Sstevel@tonic-gate 		((Elf64_Syminfo *)dst->d_buf)[ndx] = *((Elf64_Syminfo *)src);
622*0Sstevel@tonic-gate 
623*0Sstevel@tonic-gate 	ELFUNLOCK(EDATA_ELF(dst));
624*0Sstevel@tonic-gate 	return (rc);
625*0Sstevel@tonic-gate }
626*0Sstevel@tonic-gate 
627*0Sstevel@tonic-gate GElf_Dyn *
628*0Sstevel@tonic-gate gelf_getdyn(Elf_Data *data, int ndx, GElf_Dyn *dst)
629*0Sstevel@tonic-gate {
630*0Sstevel@tonic-gate 	int	class;
631*0Sstevel@tonic-gate 	size_t	entsize;
632*0Sstevel@tonic-gate 
633*0Sstevel@tonic-gate 	if (data == NULL)
634*0Sstevel@tonic-gate 		return (NULL);
635*0Sstevel@tonic-gate 
636*0Sstevel@tonic-gate 	class = EDATA_CLASS(data);
637*0Sstevel@tonic-gate 	if (class == ELFCLASS32)
638*0Sstevel@tonic-gate 		entsize = sizeof (Elf32_Dyn);
639*0Sstevel@tonic-gate 	else if (class == ELFCLASS64)
640*0Sstevel@tonic-gate 		entsize = sizeof (GElf_Dyn);
641*0Sstevel@tonic-gate 	else {
642*0Sstevel@tonic-gate 		_elf_seterr(EREQ_CLASS, 0);
643*0Sstevel@tonic-gate 		return (NULL);
644*0Sstevel@tonic-gate 	}
645*0Sstevel@tonic-gate 	EDATA_READLOCKS(data);
646*0Sstevel@tonic-gate 
647*0Sstevel@tonic-gate 	if ((entsize * ndx) > data->d_size) {
648*0Sstevel@tonic-gate 		_elf_seterr(EREQ_RAND, 0);
649*0Sstevel@tonic-gate 		dst = NULL;
650*0Sstevel@tonic-gate 	} else if (class == ELFCLASS32) {
651*0Sstevel@tonic-gate 		Elf32_Dyn * d = &((Elf32_Dyn *)data->d_buf)[ndx];
652*0Sstevel@tonic-gate 
653*0Sstevel@tonic-gate 		dst->d_tag	= (Elf32_Sword)d->d_tag;
654*0Sstevel@tonic-gate 		dst->d_un.d_val	= (Elf32_Word) d->d_un.d_val;
655*0Sstevel@tonic-gate 	} else
656*0Sstevel@tonic-gate 		*dst = ((Elf64_Dyn *)data->d_buf)[ndx];
657*0Sstevel@tonic-gate 
658*0Sstevel@tonic-gate 	EDATA_READUNLOCKS(data);
659*0Sstevel@tonic-gate 	return (dst);
660*0Sstevel@tonic-gate }
661*0Sstevel@tonic-gate 
662*0Sstevel@tonic-gate 
663*0Sstevel@tonic-gate int
664*0Sstevel@tonic-gate gelf_update_dyn(Elf_Data *dst, int ndx, GElf_Dyn *src)
665*0Sstevel@tonic-gate {
666*0Sstevel@tonic-gate 	int	class, rc = 1;
667*0Sstevel@tonic-gate 	size_t	entsize;
668*0Sstevel@tonic-gate 
669*0Sstevel@tonic-gate 	if (dst == NULL)
670*0Sstevel@tonic-gate 		return (0);
671*0Sstevel@tonic-gate 
672*0Sstevel@tonic-gate 	class = EDATA_CLASS(dst);
673*0Sstevel@tonic-gate 	if (class == ELFCLASS32)
674*0Sstevel@tonic-gate 		entsize = sizeof (Elf32_Dyn);
675*0Sstevel@tonic-gate 	else if (class == ELFCLASS64)
676*0Sstevel@tonic-gate 		entsize = sizeof (GElf_Dyn);
677*0Sstevel@tonic-gate 	else {
678*0Sstevel@tonic-gate 		_elf_seterr(EREQ_CLASS, 0);
679*0Sstevel@tonic-gate 		return (0);
680*0Sstevel@tonic-gate 	}
681*0Sstevel@tonic-gate 	ELFWLOCK(EDATA_ELF(dst));
682*0Sstevel@tonic-gate 
683*0Sstevel@tonic-gate 	if ((entsize * ndx) > dst->d_size) {
684*0Sstevel@tonic-gate 		_elf_seterr(EREQ_RAND, 0);
685*0Sstevel@tonic-gate 		rc = 0;
686*0Sstevel@tonic-gate 	} else if (class == ELFCLASS32) {
687*0Sstevel@tonic-gate 		Elf32_Dyn * d = &((Elf32_Dyn *)dst->d_buf)[ndx];
688*0Sstevel@tonic-gate 
689*0Sstevel@tonic-gate 		/* LINTED */
690*0Sstevel@tonic-gate 		d->d_tag	= (Elf32_Word)src->d_tag;
691*0Sstevel@tonic-gate 		/* LINTED */
692*0Sstevel@tonic-gate 		d->d_un.d_val	= (Elf32_Word)src->d_un.d_val;
693*0Sstevel@tonic-gate 	} else
694*0Sstevel@tonic-gate 		((Elf64_Dyn *)dst->d_buf)[ndx] = *(Elf64_Dyn*)src;
695*0Sstevel@tonic-gate 
696*0Sstevel@tonic-gate 	ELFUNLOCK(EDATA_ELF(dst));
697*0Sstevel@tonic-gate 	return (rc);
698*0Sstevel@tonic-gate }
699*0Sstevel@tonic-gate 
700*0Sstevel@tonic-gate 
701*0Sstevel@tonic-gate 
702*0Sstevel@tonic-gate GElf_Sym *
703*0Sstevel@tonic-gate gelf_getsymshndx(Elf_Data *symdata, Elf_Data *shndxdata,
704*0Sstevel@tonic-gate 	int ndx, GElf_Sym *symptr, Elf32_Word *xshndx)
705*0Sstevel@tonic-gate {
706*0Sstevel@tonic-gate 	if (gelf_getsym(symdata, ndx, symptr) == 0)
707*0Sstevel@tonic-gate 		return (NULL);
708*0Sstevel@tonic-gate 	if (shndxdata && xshndx) {
709*0Sstevel@tonic-gate 		EDATA_READLOCKS(shndxdata);
710*0Sstevel@tonic-gate 		if ((ndx * sizeof (Elf32_Word)) > shndxdata->d_size) {
711*0Sstevel@tonic-gate 			_elf_seterr(EREQ_RAND, 0);
712*0Sstevel@tonic-gate 			EDATA_READUNLOCKS(shndxdata);
713*0Sstevel@tonic-gate 			return (NULL);
714*0Sstevel@tonic-gate 		}
715*0Sstevel@tonic-gate 		*xshndx = (((Elf32_Word *)shndxdata->d_buf)[ndx]);
716*0Sstevel@tonic-gate 		EDATA_READUNLOCKS(shndxdata);
717*0Sstevel@tonic-gate 	} else {
718*0Sstevel@tonic-gate 		*xshndx = 0;
719*0Sstevel@tonic-gate 	}
720*0Sstevel@tonic-gate 	return (symptr);
721*0Sstevel@tonic-gate }
722*0Sstevel@tonic-gate 
723*0Sstevel@tonic-gate int
724*0Sstevel@tonic-gate gelf_update_symshndx(Elf_Data *symdata, Elf_Data *shndxdata,
725*0Sstevel@tonic-gate 	int ndx, GElf_Sym *symptr, Elf32_Word xshndx)
726*0Sstevel@tonic-gate {
727*0Sstevel@tonic-gate 	if (gelf_update_sym(symdata, ndx, symptr) == 0)
728*0Sstevel@tonic-gate 		return (0);
729*0Sstevel@tonic-gate 	if (shndxdata) {
730*0Sstevel@tonic-gate 		ELFWLOCK(EDATA_ELF(shndxdata));
731*0Sstevel@tonic-gate 		if ((ndx * sizeof (Elf32_Word)) > shndxdata->d_size) {
732*0Sstevel@tonic-gate 			_elf_seterr(EREQ_RAND, 0);
733*0Sstevel@tonic-gate 			ELFUNLOCK(EDATA_ELF(shndxdata));
734*0Sstevel@tonic-gate 			return (0);
735*0Sstevel@tonic-gate 		}
736*0Sstevel@tonic-gate 		((Elf32_Word *)shndxdata->d_buf)[ndx] = xshndx;
737*0Sstevel@tonic-gate 		ELFUNLOCK(EDATA_ELF(shndxdata));
738*0Sstevel@tonic-gate 	}
739*0Sstevel@tonic-gate 	return (1);
740*0Sstevel@tonic-gate }
741*0Sstevel@tonic-gate 
742*0Sstevel@tonic-gate 
743*0Sstevel@tonic-gate GElf_Move *
744*0Sstevel@tonic-gate gelf_getmove(Elf_Data *src, int ndx, GElf_Move *dst)
745*0Sstevel@tonic-gate {
746*0Sstevel@tonic-gate 	int	class;
747*0Sstevel@tonic-gate 	size_t	entsize;
748*0Sstevel@tonic-gate 
749*0Sstevel@tonic-gate 	if (src == NULL)
750*0Sstevel@tonic-gate 		return (NULL);
751*0Sstevel@tonic-gate 
752*0Sstevel@tonic-gate 	class = EDATA_CLASS(src);
753*0Sstevel@tonic-gate 	if (class == ELFCLASS32)
754*0Sstevel@tonic-gate 		entsize = sizeof (Elf32_Move);
755*0Sstevel@tonic-gate 	else if (class == ELFCLASS64)
756*0Sstevel@tonic-gate 		entsize = sizeof (GElf_Move);
757*0Sstevel@tonic-gate 	else {
758*0Sstevel@tonic-gate 		_elf_seterr(EREQ_CLASS, 0);
759*0Sstevel@tonic-gate 		return (NULL);
760*0Sstevel@tonic-gate 	}
761*0Sstevel@tonic-gate 	EDATA_READLOCKS(src);
762*0Sstevel@tonic-gate 
763*0Sstevel@tonic-gate 	if ((entsize * ndx) > src->d_size) {
764*0Sstevel@tonic-gate 		_elf_seterr(EREQ_RAND, 0);
765*0Sstevel@tonic-gate 		dst = NULL;
766*0Sstevel@tonic-gate 	} else if (class == ELFCLASS32) {
767*0Sstevel@tonic-gate 		Elf32_Move * m = &((Elf32_Move *)src->d_buf)[ndx];
768*0Sstevel@tonic-gate 
769*0Sstevel@tonic-gate 		dst->m_poffset = (Elf64_Word)m->m_poffset;
770*0Sstevel@tonic-gate 		dst->m_repeat = (Elf64_Xword)m->m_repeat;
771*0Sstevel@tonic-gate 		dst->m_stride = (Elf64_Half)m->m_stride;
772*0Sstevel@tonic-gate 		dst->m_value = (Elf64_Xword)m->m_value;
773*0Sstevel@tonic-gate 		dst->m_info = ELF64_M_INFO(
774*0Sstevel@tonic-gate 			ELF32_M_SYM(m->m_info),
775*0Sstevel@tonic-gate 			ELF32_M_SIZE(m->m_info));
776*0Sstevel@tonic-gate 	} else
777*0Sstevel@tonic-gate 		*dst = ((Elf64_Move *)src->d_buf)[ndx];
778*0Sstevel@tonic-gate 
779*0Sstevel@tonic-gate 	EDATA_READUNLOCKS(src);
780*0Sstevel@tonic-gate 	return (dst);
781*0Sstevel@tonic-gate }
782*0Sstevel@tonic-gate 
783*0Sstevel@tonic-gate int
784*0Sstevel@tonic-gate gelf_update_move(Elf_Data *dest, int ndx, GElf_Move *src)
785*0Sstevel@tonic-gate {
786*0Sstevel@tonic-gate 	int	class, rc = 1;
787*0Sstevel@tonic-gate 	size_t	entsize;
788*0Sstevel@tonic-gate 
789*0Sstevel@tonic-gate 	if (dest == NULL)
790*0Sstevel@tonic-gate 		return (0);
791*0Sstevel@tonic-gate 
792*0Sstevel@tonic-gate 	class = EDATA_CLASS(dest);
793*0Sstevel@tonic-gate 	if (class == ELFCLASS32)
794*0Sstevel@tonic-gate 		entsize = sizeof (Elf32_Move);
795*0Sstevel@tonic-gate 	else if (class == ELFCLASS64)
796*0Sstevel@tonic-gate 		entsize = sizeof (GElf_Move);
797*0Sstevel@tonic-gate 	else {
798*0Sstevel@tonic-gate 		_elf_seterr(EREQ_CLASS, 0);
799*0Sstevel@tonic-gate 		return (0);
800*0Sstevel@tonic-gate 	}
801*0Sstevel@tonic-gate 	ELFWLOCK(EDATA_ELF(dest));
802*0Sstevel@tonic-gate 
803*0Sstevel@tonic-gate 	if ((entsize * ndx) > dest->d_size) {
804*0Sstevel@tonic-gate 		_elf_seterr(EREQ_RAND, 0);
805*0Sstevel@tonic-gate 		rc = 0;
806*0Sstevel@tonic-gate 	} else if (class == ELFCLASS32) {
807*0Sstevel@tonic-gate 		Elf32_Move * m = &((Elf32_Move *)dest->d_buf)[ndx];
808*0Sstevel@tonic-gate 
809*0Sstevel@tonic-gate 		m->m_poffset = (Elf32_Word)src->m_poffset;
810*0Sstevel@tonic-gate 		m->m_repeat = (Elf32_Half)src->m_repeat;
811*0Sstevel@tonic-gate 		m->m_stride = (Elf32_Half)src->m_stride;
812*0Sstevel@tonic-gate 		m->m_value = (Elf32_Lword)src->m_value;
813*0Sstevel@tonic-gate 		m->m_info = (Elf32_Word)ELF32_M_INFO(
814*0Sstevel@tonic-gate 				ELF64_M_SYM(src->m_info),
815*0Sstevel@tonic-gate 				ELF64_M_SIZE(src->m_info));
816*0Sstevel@tonic-gate 	} else
817*0Sstevel@tonic-gate 		((Elf64_Move *)dest->d_buf)[ndx] = *(Elf64_Move *)src;
818*0Sstevel@tonic-gate 
819*0Sstevel@tonic-gate 	ELFUNLOCK(EDATA_ELF(dest));
820*0Sstevel@tonic-gate 	return (rc);
821*0Sstevel@tonic-gate }
822*0Sstevel@tonic-gate 
823*0Sstevel@tonic-gate 
824*0Sstevel@tonic-gate GElf_Rela *
825*0Sstevel@tonic-gate gelf_getrela(Elf_Data *src, int ndx, GElf_Rela *dst)
826*0Sstevel@tonic-gate {
827*0Sstevel@tonic-gate 	int	class;
828*0Sstevel@tonic-gate 	size_t	entsize;
829*0Sstevel@tonic-gate 
830*0Sstevel@tonic-gate 	if (src == NULL)
831*0Sstevel@tonic-gate 		return (NULL);
832*0Sstevel@tonic-gate 
833*0Sstevel@tonic-gate 	class = EDATA_CLASS(src);
834*0Sstevel@tonic-gate 	if (class == ELFCLASS32)
835*0Sstevel@tonic-gate 		entsize = sizeof (Elf32_Rela);
836*0Sstevel@tonic-gate 	else if (class == ELFCLASS64)
837*0Sstevel@tonic-gate 		entsize = sizeof (GElf_Rela);
838*0Sstevel@tonic-gate 	else {
839*0Sstevel@tonic-gate 		_elf_seterr(EREQ_CLASS, 0);
840*0Sstevel@tonic-gate 		return (NULL);
841*0Sstevel@tonic-gate 	}
842*0Sstevel@tonic-gate 	EDATA_READLOCKS(src);
843*0Sstevel@tonic-gate 
844*0Sstevel@tonic-gate 	if ((entsize * ndx) > src->d_size) {
845*0Sstevel@tonic-gate 		_elf_seterr(EREQ_RAND, 0);
846*0Sstevel@tonic-gate 		dst = NULL;
847*0Sstevel@tonic-gate 	} else if (class == ELFCLASS32) {
848*0Sstevel@tonic-gate 		Elf32_Rela * r = &((Elf32_Rela *)src->d_buf)[ndx];
849*0Sstevel@tonic-gate 
850*0Sstevel@tonic-gate 		dst->r_offset	= (GElf_Addr)r->r_offset;
851*0Sstevel@tonic-gate 		dst->r_addend	= (GElf_Addr)r->r_addend;
852*0Sstevel@tonic-gate 
853*0Sstevel@tonic-gate 		/*
854*0Sstevel@tonic-gate 		 * Elf32 will never have the extra data field that
855*0Sstevel@tonic-gate 		 * Elf64's r_info field can have, so ignore it.
856*0Sstevel@tonic-gate 		 */
857*0Sstevel@tonic-gate 		/* LINTED */
858*0Sstevel@tonic-gate 		dst->r_info	= ELF64_R_INFO(
859*0Sstevel@tonic-gate 		    ELF32_R_SYM(r->r_info),
860*0Sstevel@tonic-gate 		    ELF32_R_TYPE(r->r_info));
861*0Sstevel@tonic-gate 	} else
862*0Sstevel@tonic-gate 		*dst = ((Elf64_Rela *)src->d_buf)[ndx];
863*0Sstevel@tonic-gate 
864*0Sstevel@tonic-gate 	EDATA_READUNLOCKS(src);
865*0Sstevel@tonic-gate 	return (dst);
866*0Sstevel@tonic-gate }
867*0Sstevel@tonic-gate 
868*0Sstevel@tonic-gate 
869*0Sstevel@tonic-gate int
870*0Sstevel@tonic-gate gelf_update_rela(Elf_Data *dst, int ndx, GElf_Rela *src)
871*0Sstevel@tonic-gate {
872*0Sstevel@tonic-gate 	int	class, rc = 1;
873*0Sstevel@tonic-gate 	size_t	entsize;
874*0Sstevel@tonic-gate 
875*0Sstevel@tonic-gate 	if (dst == NULL)
876*0Sstevel@tonic-gate 		return (0);
877*0Sstevel@tonic-gate 
878*0Sstevel@tonic-gate 	class = EDATA_CLASS(dst);
879*0Sstevel@tonic-gate 	if (class == ELFCLASS32)
880*0Sstevel@tonic-gate 		entsize = sizeof (Elf32_Rela);
881*0Sstevel@tonic-gate 	else if (class == ELFCLASS64)
882*0Sstevel@tonic-gate 		entsize = sizeof (GElf_Rela);
883*0Sstevel@tonic-gate 	else {
884*0Sstevel@tonic-gate 		_elf_seterr(EREQ_CLASS, 0);
885*0Sstevel@tonic-gate 		return (0);
886*0Sstevel@tonic-gate 	}
887*0Sstevel@tonic-gate 	ELFWLOCK(EDATA_ELF(dst));
888*0Sstevel@tonic-gate 
889*0Sstevel@tonic-gate 	if ((entsize * ndx) > dst->d_size) {
890*0Sstevel@tonic-gate 		_elf_seterr(EREQ_RAND, 0);
891*0Sstevel@tonic-gate 		rc = 0;
892*0Sstevel@tonic-gate 	} else if (class == ELFCLASS32) {
893*0Sstevel@tonic-gate 		Elf32_Rela * r = &((Elf32_Rela *)dst->d_buf)[ndx];
894*0Sstevel@tonic-gate 
895*0Sstevel@tonic-gate 		/* LINTED */
896*0Sstevel@tonic-gate 		r->r_offset	= (Elf32_Addr) src->r_offset;
897*0Sstevel@tonic-gate 		/* LINTED */
898*0Sstevel@tonic-gate 		r->r_addend	= (Elf32_Sword)src->r_addend;
899*0Sstevel@tonic-gate 
900*0Sstevel@tonic-gate 		/*
901*0Sstevel@tonic-gate 		 * Elf32 will never have the extra data field that
902*0Sstevel@tonic-gate 		 * Elf64's r_info field can have, so ignore it.
903*0Sstevel@tonic-gate 		 */
904*0Sstevel@tonic-gate 		/* LINTED */
905*0Sstevel@tonic-gate 		r->r_info	= ELF32_R_INFO(
906*0Sstevel@tonic-gate 					ELF64_R_SYM(src->r_info),
907*0Sstevel@tonic-gate 					ELF64_R_TYPE(src->r_info));
908*0Sstevel@tonic-gate 	} else
909*0Sstevel@tonic-gate 		((Elf64_Rela *)dst->d_buf)[ndx] = *(Elf64_Rela *)src;
910*0Sstevel@tonic-gate 
911*0Sstevel@tonic-gate 	ELFUNLOCK(EDATA_ELF(dst));
912*0Sstevel@tonic-gate 
913*0Sstevel@tonic-gate 	return (rc);
914*0Sstevel@tonic-gate }
915*0Sstevel@tonic-gate 
916*0Sstevel@tonic-gate 
917*0Sstevel@tonic-gate GElf_Rel *
918*0Sstevel@tonic-gate gelf_getrel(Elf_Data *src, int ndx, GElf_Rel *dst)
919*0Sstevel@tonic-gate {
920*0Sstevel@tonic-gate 	int	class;
921*0Sstevel@tonic-gate 	size_t	entsize;
922*0Sstevel@tonic-gate 
923*0Sstevel@tonic-gate 	if (src == NULL)
924*0Sstevel@tonic-gate 		return (NULL);
925*0Sstevel@tonic-gate 
926*0Sstevel@tonic-gate 	class = EDATA_CLASS(src);
927*0Sstevel@tonic-gate 	if (class == ELFCLASS32)
928*0Sstevel@tonic-gate 		entsize = sizeof (Elf32_Rel);
929*0Sstevel@tonic-gate 	else if (class == ELFCLASS64)
930*0Sstevel@tonic-gate 		entsize = sizeof (GElf_Rel);
931*0Sstevel@tonic-gate 	else {
932*0Sstevel@tonic-gate 		_elf_seterr(EREQ_CLASS, 0);
933*0Sstevel@tonic-gate 		return (NULL);
934*0Sstevel@tonic-gate 	}
935*0Sstevel@tonic-gate 	EDATA_READLOCKS(src);
936*0Sstevel@tonic-gate 
937*0Sstevel@tonic-gate 	if ((entsize * ndx) > src->d_size) {
938*0Sstevel@tonic-gate 		_elf_seterr(EREQ_RAND, 0);
939*0Sstevel@tonic-gate 		dst = NULL;
940*0Sstevel@tonic-gate 	} else if (class == ELFCLASS32) {
941*0Sstevel@tonic-gate 		Elf32_Rel * r = &((Elf32_Rel *)src->d_buf)[ndx];
942*0Sstevel@tonic-gate 
943*0Sstevel@tonic-gate 		dst->r_offset	= (GElf_Addr)r->r_offset;
944*0Sstevel@tonic-gate 
945*0Sstevel@tonic-gate 		/*
946*0Sstevel@tonic-gate 		 * Elf32 will never have the extra data field that
947*0Sstevel@tonic-gate 		 * Elf64's r_info field can have, so ignore it.
948*0Sstevel@tonic-gate 		 */
949*0Sstevel@tonic-gate 		/* LINTED */
950*0Sstevel@tonic-gate 		dst->r_info	= ELF64_R_INFO(ELF32_R_SYM(r->r_info),
951*0Sstevel@tonic-gate 					ELF32_R_TYPE(r->r_info));
952*0Sstevel@tonic-gate 	} else
953*0Sstevel@tonic-gate 		*dst = ((Elf64_Rel *)src->d_buf)[ndx];
954*0Sstevel@tonic-gate 
955*0Sstevel@tonic-gate 	EDATA_READUNLOCKS(src);
956*0Sstevel@tonic-gate 	return (dst);
957*0Sstevel@tonic-gate }
958*0Sstevel@tonic-gate 
959*0Sstevel@tonic-gate 
960*0Sstevel@tonic-gate int
961*0Sstevel@tonic-gate gelf_update_rel(Elf_Data *dst, int ndx, GElf_Rel *src)
962*0Sstevel@tonic-gate {
963*0Sstevel@tonic-gate 	int	class, rc = 1;
964*0Sstevel@tonic-gate 	size_t	entsize;
965*0Sstevel@tonic-gate 
966*0Sstevel@tonic-gate 	if (dst == NULL)
967*0Sstevel@tonic-gate 		return (0);
968*0Sstevel@tonic-gate 
969*0Sstevel@tonic-gate 	class = EDATA_CLASS(dst);
970*0Sstevel@tonic-gate 	if (class == ELFCLASS32)
971*0Sstevel@tonic-gate 		entsize = sizeof (Elf32_Rel);
972*0Sstevel@tonic-gate 	else if (class == ELFCLASS64)
973*0Sstevel@tonic-gate 		entsize = sizeof (GElf_Rel);
974*0Sstevel@tonic-gate 	else {
975*0Sstevel@tonic-gate 		_elf_seterr(EREQ_CLASS, 0);
976*0Sstevel@tonic-gate 		return (0);
977*0Sstevel@tonic-gate 	}
978*0Sstevel@tonic-gate 	ELFWLOCK(EDATA_ELF(dst));
979*0Sstevel@tonic-gate 
980*0Sstevel@tonic-gate 	if ((entsize * ndx) > dst->d_size) {
981*0Sstevel@tonic-gate 		_elf_seterr(EREQ_RAND, 0);
982*0Sstevel@tonic-gate 		rc = 0;
983*0Sstevel@tonic-gate 	} else if (class == ELFCLASS32) {
984*0Sstevel@tonic-gate 		Elf32_Rel * r = &((Elf32_Rel *)dst->d_buf)[ndx];
985*0Sstevel@tonic-gate 
986*0Sstevel@tonic-gate 		/* LINTED */
987*0Sstevel@tonic-gate 		r->r_offset	= (Elf32_Addr) src->r_offset;
988*0Sstevel@tonic-gate 
989*0Sstevel@tonic-gate 		/*
990*0Sstevel@tonic-gate 		 * Elf32 will never have the extra data field that
991*0Sstevel@tonic-gate 		 * Elf64's r_info field can have, so ignore it.
992*0Sstevel@tonic-gate 		 */
993*0Sstevel@tonic-gate 		/* LINTED */
994*0Sstevel@tonic-gate 		r->r_info	= ELF32_R_INFO(
995*0Sstevel@tonic-gate 					ELF64_R_SYM(src->r_info),
996*0Sstevel@tonic-gate 					ELF64_R_TYPE(src->r_info));
997*0Sstevel@tonic-gate 
998*0Sstevel@tonic-gate 	} else
999*0Sstevel@tonic-gate 		((Elf64_Rel *)dst->d_buf)[ndx] = *(Elf64_Rel *)src;
1000*0Sstevel@tonic-gate 
1001*0Sstevel@tonic-gate 	ELFUNLOCK(EDATA_ELF(dst));
1002*0Sstevel@tonic-gate 	return (rc);
1003*0Sstevel@tonic-gate }
1004*0Sstevel@tonic-gate 
1005*0Sstevel@tonic-gate long
1006*0Sstevel@tonic-gate gelf_checksum(Elf *elf)
1007*0Sstevel@tonic-gate {
1008*0Sstevel@tonic-gate 	int class = gelf_getclass(elf);
1009*0Sstevel@tonic-gate 
1010*0Sstevel@tonic-gate 	if (class == ELFCLASS32)
1011*0Sstevel@tonic-gate 		return (elf32_checksum(elf));
1012*0Sstevel@tonic-gate 	else if (class == ELFCLASS64)
1013*0Sstevel@tonic-gate 		return (elf64_checksum(elf));
1014*0Sstevel@tonic-gate 
1015*0Sstevel@tonic-gate 	_elf_seterr(EREQ_CLASS, 0);
1016*0Sstevel@tonic-gate 	return (0);
1017*0Sstevel@tonic-gate }
1018*0Sstevel@tonic-gate 
1019*0Sstevel@tonic-gate GElf_Cap *
1020*0Sstevel@tonic-gate gelf_getcap(Elf_Data *data, int ndx, GElf_Cap *dst)
1021*0Sstevel@tonic-gate {
1022*0Sstevel@tonic-gate 	int	class;
1023*0Sstevel@tonic-gate 	size_t	entsize;
1024*0Sstevel@tonic-gate 
1025*0Sstevel@tonic-gate 	if (data == NULL)
1026*0Sstevel@tonic-gate 		return (NULL);
1027*0Sstevel@tonic-gate 
1028*0Sstevel@tonic-gate 	class = EDATA_CLASS(data);
1029*0Sstevel@tonic-gate 	if (class == ELFCLASS32)
1030*0Sstevel@tonic-gate 		entsize = sizeof (Elf32_Cap);
1031*0Sstevel@tonic-gate 	else if (class == ELFCLASS64)
1032*0Sstevel@tonic-gate 		entsize = sizeof (GElf_Cap);
1033*0Sstevel@tonic-gate 	else {
1034*0Sstevel@tonic-gate 		_elf_seterr(EREQ_CLASS, 0);
1035*0Sstevel@tonic-gate 		return (NULL);
1036*0Sstevel@tonic-gate 	}
1037*0Sstevel@tonic-gate 
1038*0Sstevel@tonic-gate 	EDATA_READLOCKS(data);
1039*0Sstevel@tonic-gate 
1040*0Sstevel@tonic-gate 	if ((entsize * ndx) > data->d_size) {
1041*0Sstevel@tonic-gate 		_elf_seterr(EREQ_RAND, 0);
1042*0Sstevel@tonic-gate 		dst = NULL;
1043*0Sstevel@tonic-gate 	} else if (class == ELFCLASS32) {
1044*0Sstevel@tonic-gate 		Elf32_Cap	*c = &(((Elf32_Cap *)data->d_buf)[ndx]);
1045*0Sstevel@tonic-gate 
1046*0Sstevel@tonic-gate 		dst->c_tag = (Elf64_Xword)c->c_tag;
1047*0Sstevel@tonic-gate 		dst->c_un.c_val = (Elf64_Xword)c->c_un.c_val;
1048*0Sstevel@tonic-gate 	} else
1049*0Sstevel@tonic-gate 		*dst = ((GElf_Cap *)data->d_buf)[ndx];
1050*0Sstevel@tonic-gate 
1051*0Sstevel@tonic-gate 	EDATA_READUNLOCKS(data);
1052*0Sstevel@tonic-gate 	return (dst);
1053*0Sstevel@tonic-gate }
1054*0Sstevel@tonic-gate 
1055*0Sstevel@tonic-gate int
1056*0Sstevel@tonic-gate gelf_update_cap(Elf_Data *dst, int ndx, GElf_Cap *src)
1057*0Sstevel@tonic-gate {
1058*0Sstevel@tonic-gate 	int	class, rc = 1;
1059*0Sstevel@tonic-gate 	size_t	entsize;
1060*0Sstevel@tonic-gate 
1061*0Sstevel@tonic-gate 	if (dst == NULL)
1062*0Sstevel@tonic-gate 		return (0);
1063*0Sstevel@tonic-gate 
1064*0Sstevel@tonic-gate 	class = EDATA_CLASS(dst);
1065*0Sstevel@tonic-gate 	if (class == ELFCLASS32)
1066*0Sstevel@tonic-gate 		entsize = sizeof (Elf32_Cap);
1067*0Sstevel@tonic-gate 	else if (class == ELFCLASS64)
1068*0Sstevel@tonic-gate 		entsize = sizeof (GElf_Cap);
1069*0Sstevel@tonic-gate 	else {
1070*0Sstevel@tonic-gate 		_elf_seterr(EREQ_CLASS, 0);
1071*0Sstevel@tonic-gate 		return (0);
1072*0Sstevel@tonic-gate 	}
1073*0Sstevel@tonic-gate 
1074*0Sstevel@tonic-gate 	ELFWLOCK(EDATA_ELF(dst));
1075*0Sstevel@tonic-gate 
1076*0Sstevel@tonic-gate 	if ((entsize * ndx) > dst->d_size) {
1077*0Sstevel@tonic-gate 		_elf_seterr(EREQ_RAND, 0);
1078*0Sstevel@tonic-gate 		rc = 0;
1079*0Sstevel@tonic-gate 	} else if (class == ELFCLASS32) {
1080*0Sstevel@tonic-gate 		Elf32_Cap	*c = &(((Elf32_Cap *)dst->d_buf)[ndx]);
1081*0Sstevel@tonic-gate 
1082*0Sstevel@tonic-gate 		c->c_tag = (Elf32_Word)src->c_tag;
1083*0Sstevel@tonic-gate 		c->c_un.c_val = (Elf32_Word)src->c_un.c_val;
1084*0Sstevel@tonic-gate 	} else
1085*0Sstevel@tonic-gate 		((Elf64_Cap *)dst->d_buf)[ndx] = *((Elf64_Cap *)src);
1086*0Sstevel@tonic-gate 
1087*0Sstevel@tonic-gate 	ELFUNLOCK(EDATA_ELF(dst));
1088*0Sstevel@tonic-gate 	return (rc);
1089*0Sstevel@tonic-gate }
1090