xref: /onnv-gate/usr/src/cmd/sgs/libelf/common/gelf.c (revision 9900:1b86d65a4f9e)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
51698Sab196087  * Common Development and Distribution License (the "License").
61698Sab196087  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
210Sstevel@tonic-gate /*
22*9900SAli.Bahrami@Sun.COM  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
230Sstevel@tonic-gate  * Use is subject to license terms.
240Sstevel@tonic-gate  */
250Sstevel@tonic-gate 
260Sstevel@tonic-gate #include <string.h>
271698Sab196087 #include "_libelf.h"
280Sstevel@tonic-gate #include "decl.h"
290Sstevel@tonic-gate #include "msg.h"
300Sstevel@tonic-gate 
310Sstevel@tonic-gate 
320Sstevel@tonic-gate /*
330Sstevel@tonic-gate  * Find elf or it's class from a pointer to an Elf_Data struct.
340Sstevel@tonic-gate  * Warning:  this Assumes that the Elf_Data is part of a libelf
350Sstevel@tonic-gate  * Dnode structure, which is expected to be true for any Elf_Data
360Sstevel@tonic-gate  * passed into libelf *except* for the xlatetof() and xlatetom() functions.
370Sstevel@tonic-gate  */
380Sstevel@tonic-gate #define	EDATA_CLASS(edata) \
390Sstevel@tonic-gate 	(((Dnode *)(edata))->db_scn->s_elf->ed_class)
400Sstevel@tonic-gate 
410Sstevel@tonic-gate #define	EDATA_ELF(edata) \
420Sstevel@tonic-gate 	(((Dnode *)(edata))->db_scn->s_elf)
430Sstevel@tonic-gate 
440Sstevel@tonic-gate #define	EDATA_SCN(edata) \
450Sstevel@tonic-gate 	(((Dnode *)(edata))->db_scn)
460Sstevel@tonic-gate 
470Sstevel@tonic-gate #define	EDATA_READLOCKS(edata) \
480Sstevel@tonic-gate 	READLOCKS(EDATA_ELF((edata)), EDATA_SCN((edata)))
490Sstevel@tonic-gate 
500Sstevel@tonic-gate #define	EDATA_READUNLOCKS(edata) \
510Sstevel@tonic-gate 	READUNLOCKS(EDATA_ELF((edata)), EDATA_SCN((edata)))
520Sstevel@tonic-gate 
530Sstevel@tonic-gate 
540Sstevel@tonic-gate size_t
gelf_fsize(Elf * elf,Elf_Type type,size_t count,unsigned ver)550Sstevel@tonic-gate gelf_fsize(Elf * elf, Elf_Type type, size_t count, unsigned ver)
560Sstevel@tonic-gate {
570Sstevel@tonic-gate 	int class;
580Sstevel@tonic-gate 
590Sstevel@tonic-gate 	if (elf == NULL)
600Sstevel@tonic-gate 		return (0);
610Sstevel@tonic-gate 
620Sstevel@tonic-gate 	class = gelf_getclass(elf);
630Sstevel@tonic-gate 	if (class == ELFCLASS32)
640Sstevel@tonic-gate 		return (elf32_fsize(type, count, ver));
650Sstevel@tonic-gate 	else if (class == ELFCLASS64)
660Sstevel@tonic-gate 		return (elf64_fsize(type, count, ver));
670Sstevel@tonic-gate 
680Sstevel@tonic-gate 	_elf_seterr(EREQ_CLASS, 0);
690Sstevel@tonic-gate 	return (0);
700Sstevel@tonic-gate }
710Sstevel@tonic-gate 
720Sstevel@tonic-gate 
730Sstevel@tonic-gate int
gelf_getclass(Elf * elf)740Sstevel@tonic-gate gelf_getclass(Elf *elf)
750Sstevel@tonic-gate {
760Sstevel@tonic-gate 	if (elf == NULL)
770Sstevel@tonic-gate 		return (0);
780Sstevel@tonic-gate 
790Sstevel@tonic-gate 	/*
800Sstevel@tonic-gate 	 * Don't rely on the idents, a new ehdr doesn't have it!
810Sstevel@tonic-gate 	 */
820Sstevel@tonic-gate 	return (elf->ed_class);
830Sstevel@tonic-gate }
840Sstevel@tonic-gate 
850Sstevel@tonic-gate 
860Sstevel@tonic-gate GElf_Ehdr *
gelf_getehdr(Elf * elf,GElf_Ehdr * dst)870Sstevel@tonic-gate gelf_getehdr(Elf *elf, GElf_Ehdr *dst)
880Sstevel@tonic-gate {
890Sstevel@tonic-gate 	int class;
900Sstevel@tonic-gate 
910Sstevel@tonic-gate 	if (elf == NULL)
920Sstevel@tonic-gate 		return (NULL);
930Sstevel@tonic-gate 
940Sstevel@tonic-gate 	class = gelf_getclass(elf);
950Sstevel@tonic-gate 	if (class == ELFCLASS32) {
960Sstevel@tonic-gate 		Elf32_Ehdr * e		= elf32_getehdr(elf);
970Sstevel@tonic-gate 
980Sstevel@tonic-gate 		if (e == NULL)
990Sstevel@tonic-gate 			return (NULL);
1000Sstevel@tonic-gate 
1010Sstevel@tonic-gate 		ELFRLOCK(elf);
1020Sstevel@tonic-gate 		(void) memcpy(dst->e_ident, e->e_ident, EI_NIDENT);
1030Sstevel@tonic-gate 		dst->e_type		= e->e_type;
1040Sstevel@tonic-gate 		dst->e_machine		= e->e_machine;
1050Sstevel@tonic-gate 		dst->e_version		= e->e_version;
1060Sstevel@tonic-gate 		dst->e_entry		= (Elf64_Addr)e->e_entry;
1070Sstevel@tonic-gate 		dst->e_phoff		= (Elf64_Off)e->e_phoff;
1080Sstevel@tonic-gate 		dst->e_shoff		= (Elf64_Off)e->e_shoff;
1090Sstevel@tonic-gate 		dst->e_flags		= e->e_flags;
1100Sstevel@tonic-gate 		dst->e_ehsize		= e->e_ehsize;
1110Sstevel@tonic-gate 		dst->e_phentsize	= e->e_phentsize;
1120Sstevel@tonic-gate 		dst->e_phnum		= e->e_phnum;
1130Sstevel@tonic-gate 		dst->e_shentsize	= e->e_shentsize;
1140Sstevel@tonic-gate 		dst->e_shnum		= e->e_shnum;
1150Sstevel@tonic-gate 		dst->e_shstrndx		= e->e_shstrndx;
1160Sstevel@tonic-gate 		ELFUNLOCK(elf);
1170Sstevel@tonic-gate 
1180Sstevel@tonic-gate 		return (dst);
1190Sstevel@tonic-gate 	} else if (class == ELFCLASS64) {
1200Sstevel@tonic-gate 		Elf64_Ehdr * e		= elf64_getehdr(elf);
1210Sstevel@tonic-gate 
1220Sstevel@tonic-gate 		if (e == NULL)
1230Sstevel@tonic-gate 			return (NULL);
1240Sstevel@tonic-gate 
1250Sstevel@tonic-gate 		ELFRLOCK(elf);
1260Sstevel@tonic-gate 		*dst			= *e;
1270Sstevel@tonic-gate 		ELFUNLOCK(elf);
1280Sstevel@tonic-gate 
1290Sstevel@tonic-gate 		return (dst);
1300Sstevel@tonic-gate 	}
1310Sstevel@tonic-gate 
1320Sstevel@tonic-gate 	_elf_seterr(EREQ_CLASS, 0);
1330Sstevel@tonic-gate 	return (NULL);
1340Sstevel@tonic-gate }
1350Sstevel@tonic-gate 
1360Sstevel@tonic-gate 
1370Sstevel@tonic-gate int
gelf_update_ehdr(Elf * elf,GElf_Ehdr * src)1380Sstevel@tonic-gate gelf_update_ehdr(Elf *elf, GElf_Ehdr *src)
1390Sstevel@tonic-gate {
1400Sstevel@tonic-gate 	int class;
1410Sstevel@tonic-gate 
1420Sstevel@tonic-gate 	if (elf == NULL)
1430Sstevel@tonic-gate 		return (0);
1440Sstevel@tonic-gate 
1450Sstevel@tonic-gate 	/*
1460Sstevel@tonic-gate 	 * In case elf isn't cooked.
1470Sstevel@tonic-gate 	 */
1480Sstevel@tonic-gate 	class = gelf_getclass(elf);
1490Sstevel@tonic-gate 	if (class == ELFCLASSNONE)
1500Sstevel@tonic-gate 		class = src->e_ident[EI_CLASS];
1510Sstevel@tonic-gate 
1520Sstevel@tonic-gate 
1530Sstevel@tonic-gate 	if (class == ELFCLASS32) {
1540Sstevel@tonic-gate 		Elf32_Ehdr * d	= elf32_getehdr(elf);
1550Sstevel@tonic-gate 
1560Sstevel@tonic-gate 		if (d == NULL)
1570Sstevel@tonic-gate 			return (0);
1580Sstevel@tonic-gate 
1590Sstevel@tonic-gate 		ELFWLOCK(elf);
1600Sstevel@tonic-gate 		(void) memcpy(d->e_ident, src->e_ident, EI_NIDENT);
1610Sstevel@tonic-gate 		d->e_type	= src->e_type;
1620Sstevel@tonic-gate 		d->e_machine	= src->e_machine;
1630Sstevel@tonic-gate 		d->e_version	= src->e_version;
1640Sstevel@tonic-gate 		/* LINTED */
1650Sstevel@tonic-gate 		d->e_entry	= (Elf32_Addr)src->e_entry;
1660Sstevel@tonic-gate 		/* LINTED */
1670Sstevel@tonic-gate 		d->e_phoff	= (Elf32_Off)src->e_phoff;
1680Sstevel@tonic-gate 		/* LINTED */
1690Sstevel@tonic-gate 		d->e_shoff	= (Elf32_Off)src->e_shoff;
1700Sstevel@tonic-gate 		/* could memcpy the rest of these... */
1710Sstevel@tonic-gate 		d->e_flags	= src->e_flags;
1720Sstevel@tonic-gate 		d->e_ehsize	= src->e_ehsize;
1730Sstevel@tonic-gate 		d->e_phentsize	= src->e_phentsize;
1740Sstevel@tonic-gate 		d->e_phnum	= src->e_phnum;
1750Sstevel@tonic-gate 		d->e_shentsize	= src->e_shentsize;
1760Sstevel@tonic-gate 		d->e_shnum	= src->e_shnum;
1770Sstevel@tonic-gate 		d->e_shstrndx	= src->e_shstrndx;
1780Sstevel@tonic-gate 		ELFUNLOCK(elf);
1790Sstevel@tonic-gate 
1800Sstevel@tonic-gate 		return (1);
1810Sstevel@tonic-gate 	} else if (class == ELFCLASS64) {
1820Sstevel@tonic-gate 		Elf64_Ehdr * d	= elf64_getehdr(elf);
1830Sstevel@tonic-gate 
1840Sstevel@tonic-gate 		if (d == NULL)
1850Sstevel@tonic-gate 			return (0);
1860Sstevel@tonic-gate 
1870Sstevel@tonic-gate 		ELFWLOCK(elf);
1880Sstevel@tonic-gate 		*d		= *(Elf64_Ehdr *)src;
1890Sstevel@tonic-gate 		ELFUNLOCK(elf);
1900Sstevel@tonic-gate 
1910Sstevel@tonic-gate 		return (1);
1920Sstevel@tonic-gate 	}
1930Sstevel@tonic-gate 
1940Sstevel@tonic-gate 	_elf_seterr(EREQ_CLASS, 0);
1950Sstevel@tonic-gate 	return (0);
1960Sstevel@tonic-gate }
1970Sstevel@tonic-gate 
1980Sstevel@tonic-gate 
1990Sstevel@tonic-gate unsigned long
gelf_newehdr(Elf * elf,int class)2000Sstevel@tonic-gate gelf_newehdr(Elf *elf, int class)
2010Sstevel@tonic-gate {
2020Sstevel@tonic-gate 	if (elf == NULL)
2030Sstevel@tonic-gate 		return (0);
2040Sstevel@tonic-gate 
2050Sstevel@tonic-gate 	if (class == ELFCLASS32)
2060Sstevel@tonic-gate 		return ((unsigned long)elf32_newehdr(elf));
2070Sstevel@tonic-gate 	else if (class == ELFCLASS64)
2080Sstevel@tonic-gate 		return ((unsigned long)elf64_newehdr(elf));
2090Sstevel@tonic-gate 
2100Sstevel@tonic-gate 	_elf_seterr(EREQ_CLASS, 0);
2110Sstevel@tonic-gate 	return (0);
2120Sstevel@tonic-gate }
2130Sstevel@tonic-gate 
2140Sstevel@tonic-gate 
2150Sstevel@tonic-gate GElf_Phdr *
gelf_getphdr(Elf * elf,int ndx,GElf_Phdr * dst)2160Sstevel@tonic-gate gelf_getphdr(Elf *elf, int ndx, GElf_Phdr *dst)
2170Sstevel@tonic-gate {
2180Sstevel@tonic-gate 	int		class;
219942Sahl 	size_t		phnum;
2200Sstevel@tonic-gate 
2210Sstevel@tonic-gate 	if (elf == NULL)
2220Sstevel@tonic-gate 		return (NULL);
2230Sstevel@tonic-gate 
224*9900SAli.Bahrami@Sun.COM 	if (elf_getphdrnum(elf, &phnum) == -1)
2250Sstevel@tonic-gate 		return (NULL);
2260Sstevel@tonic-gate 
227942Sahl 	if (phnum <= ndx) {
2280Sstevel@tonic-gate 		_elf_seterr(EREQ_RAND, 0);
2290Sstevel@tonic-gate 		return (NULL);
2300Sstevel@tonic-gate 	}
2310Sstevel@tonic-gate 
2320Sstevel@tonic-gate 	class = gelf_getclass(elf);
2330Sstevel@tonic-gate 	if ((class != ELFCLASS32) && (class != ELFCLASS64)) {
2340Sstevel@tonic-gate 		_elf_seterr(EREQ_CLASS, 0);
2350Sstevel@tonic-gate 		return (NULL);
2360Sstevel@tonic-gate 	}
2370Sstevel@tonic-gate 
2380Sstevel@tonic-gate 	if (class == ELFCLASS32) {
2390Sstevel@tonic-gate 		Elf32_Phdr *p	= &((Elf32_Phdr *)elf32_getphdr(elf))[ndx];
2400Sstevel@tonic-gate 
2410Sstevel@tonic-gate 		ELFRLOCK(elf);
2420Sstevel@tonic-gate 		dst->p_type	= p->p_type;
2430Sstevel@tonic-gate 		dst->p_flags	= p->p_flags;
2440Sstevel@tonic-gate 		dst->p_offset	= (Elf64_Off)p->p_offset;
2450Sstevel@tonic-gate 		dst->p_vaddr	= (Elf64_Addr)p->p_vaddr;
2460Sstevel@tonic-gate 		dst->p_paddr	= (Elf64_Addr)p->p_paddr;
2470Sstevel@tonic-gate 		dst->p_filesz	= (Elf64_Xword)p->p_filesz;
2480Sstevel@tonic-gate 		dst->p_memsz	= (Elf64_Xword)p->p_memsz;
2490Sstevel@tonic-gate 		dst->p_align	= (Elf64_Xword)p->p_align;
2500Sstevel@tonic-gate 		ELFUNLOCK(elf);
2510Sstevel@tonic-gate 	} else if (class == ELFCLASS64) {
2520Sstevel@tonic-gate 		Elf64_Phdr *phdrs = elf64_getphdr(elf);
2530Sstevel@tonic-gate 		ELFRLOCK(elf);
2540Sstevel@tonic-gate 		*dst = ((GElf_Phdr *)phdrs)[ndx];
2550Sstevel@tonic-gate 		ELFUNLOCK(elf);
2560Sstevel@tonic-gate 	}
2570Sstevel@tonic-gate 
2580Sstevel@tonic-gate 	return (dst);
2590Sstevel@tonic-gate }
2600Sstevel@tonic-gate 
2610Sstevel@tonic-gate 
2620Sstevel@tonic-gate int
gelf_update_phdr(Elf * elf,int ndx,GElf_Phdr * src)2630Sstevel@tonic-gate gelf_update_phdr(Elf *elf, int ndx, GElf_Phdr *src)
2640Sstevel@tonic-gate {
2650Sstevel@tonic-gate 	int		class;
266942Sahl 	size_t		phnum;
2670Sstevel@tonic-gate 
2680Sstevel@tonic-gate 	if (elf == NULL)
2690Sstevel@tonic-gate 		return (0);
2700Sstevel@tonic-gate 
271*9900SAli.Bahrami@Sun.COM 	if (elf_getphdrnum(elf, &phnum) == -1)
272942Sahl 		return (NULL);
2730Sstevel@tonic-gate 
274942Sahl 	if (phnum < ndx) {
2750Sstevel@tonic-gate 		_elf_seterr(EREQ_RAND, 0);
2760Sstevel@tonic-gate 		return (0);
2770Sstevel@tonic-gate 	}
2780Sstevel@tonic-gate 
2790Sstevel@tonic-gate 	class = gelf_getclass(elf);
2800Sstevel@tonic-gate 	if (class == ELFCLASS32) {
2810Sstevel@tonic-gate 		Elf32_Phdr *dst	= &((Elf32_Phdr *)elf32_getphdr(elf))[ndx];
2820Sstevel@tonic-gate 		ELFWLOCK(elf);
2830Sstevel@tonic-gate 		dst->p_type	= src->p_type;
2840Sstevel@tonic-gate 		dst->p_flags	= src->p_flags;
2850Sstevel@tonic-gate 		/* LINTED */
2860Sstevel@tonic-gate 		dst->p_offset	= (Elf32_Off)src->p_offset;
2870Sstevel@tonic-gate 		/* LINTED */
2880Sstevel@tonic-gate 		dst->p_vaddr	= (Elf32_Addr)src->p_vaddr;
2890Sstevel@tonic-gate 		/* LINTED */
2900Sstevel@tonic-gate 		dst->p_paddr	= (Elf32_Addr)src->p_paddr;
2910Sstevel@tonic-gate 		/* LINTED */
2920Sstevel@tonic-gate 		dst->p_filesz	= (Elf32_Word)src->p_filesz;
2930Sstevel@tonic-gate 		/* LINTED */
2940Sstevel@tonic-gate 		dst->p_memsz	= (Elf32_Word)src->p_memsz;
2950Sstevel@tonic-gate 		/* LINTED */
2960Sstevel@tonic-gate 		dst->p_align	= (Elf32_Word)src->p_align;
2970Sstevel@tonic-gate 		ELFUNLOCK(elf);
2980Sstevel@tonic-gate 	} else if (class == ELFCLASS64) {
2990Sstevel@tonic-gate 		Elf64_Phdr *dst = elf64_getphdr(elf);
3000Sstevel@tonic-gate 		ELFWLOCK(elf);
3010Sstevel@tonic-gate 		dst[ndx] = *(GElf_Phdr *)src;
3020Sstevel@tonic-gate 		ELFUNLOCK(elf);
3030Sstevel@tonic-gate 	} else {
3040Sstevel@tonic-gate 		_elf_seterr(EREQ_CLASS, 0);
3050Sstevel@tonic-gate 		return (0);
3060Sstevel@tonic-gate 	}
3070Sstevel@tonic-gate 	return (1);
3080Sstevel@tonic-gate }
3090Sstevel@tonic-gate 
3100Sstevel@tonic-gate 
3110Sstevel@tonic-gate unsigned long
gelf_newphdr(Elf * elf,size_t phnum)3120Sstevel@tonic-gate gelf_newphdr(Elf *elf, size_t phnum)
3130Sstevel@tonic-gate {
3140Sstevel@tonic-gate 	int class;
3150Sstevel@tonic-gate 
3160Sstevel@tonic-gate 	if (elf == NULL)
3170Sstevel@tonic-gate 		return (0);
3180Sstevel@tonic-gate 
3190Sstevel@tonic-gate 	class = gelf_getclass(elf);
3200Sstevel@tonic-gate 	if (class == ELFCLASS32)
3210Sstevel@tonic-gate 		return ((unsigned long)elf32_newphdr(elf, phnum));
3220Sstevel@tonic-gate 	else if (class == ELFCLASS64)
3230Sstevel@tonic-gate 		return ((unsigned long)elf64_newphdr(elf, phnum));
3240Sstevel@tonic-gate 
3250Sstevel@tonic-gate 	_elf_seterr(EREQ_CLASS, 0);
3260Sstevel@tonic-gate 	return (0);
3270Sstevel@tonic-gate }
3280Sstevel@tonic-gate 
3290Sstevel@tonic-gate 
3300Sstevel@tonic-gate GElf_Shdr *
gelf_getshdr(Elf_Scn * scn,GElf_Shdr * dst)3310Sstevel@tonic-gate gelf_getshdr(Elf_Scn *scn,  GElf_Shdr *dst)
3320Sstevel@tonic-gate {
3330Sstevel@tonic-gate 	if (scn == NULL)
3340Sstevel@tonic-gate 		return (NULL);
3350Sstevel@tonic-gate 
3360Sstevel@tonic-gate 	if (scn->s_elf->ed_class == ELFCLASS32) {
3370Sstevel@tonic-gate 		Elf32_Shdr *s		= elf32_getshdr(scn);
3380Sstevel@tonic-gate 
3390Sstevel@tonic-gate 		if (s == NULL)
3400Sstevel@tonic-gate 			return (NULL);
3410Sstevel@tonic-gate 
3420Sstevel@tonic-gate 		READLOCKS(scn->s_elf, scn);
3430Sstevel@tonic-gate 		dst->sh_name		= s->sh_name;
3440Sstevel@tonic-gate 		dst->sh_type		= s->sh_type;
3450Sstevel@tonic-gate 		dst->sh_flags		= (Elf64_Xword)s->sh_flags;
3460Sstevel@tonic-gate 		dst->sh_addr		= (Elf64_Addr)s->sh_addr;
3470Sstevel@tonic-gate 		dst->sh_offset		= (Elf64_Off)s->sh_offset;
3480Sstevel@tonic-gate 		dst->sh_size		= (Elf64_Xword)s->sh_size;
3490Sstevel@tonic-gate 		dst->sh_link		= s->sh_link;
3500Sstevel@tonic-gate 		dst->sh_info		= s->sh_info;
3510Sstevel@tonic-gate 		dst->sh_addralign	= (Elf64_Xword)s->sh_addralign;
3520Sstevel@tonic-gate 		dst->sh_entsize		= (Elf64_Xword)s->sh_entsize;
3530Sstevel@tonic-gate 		READUNLOCKS(scn->s_elf, scn);
3540Sstevel@tonic-gate 
3550Sstevel@tonic-gate 		return (dst);
3560Sstevel@tonic-gate 	} else if (scn->s_elf->ed_class == ELFCLASS64) {
3570Sstevel@tonic-gate 		Elf64_Shdr *s		= elf64_getshdr(scn);
3580Sstevel@tonic-gate 
3590Sstevel@tonic-gate 		if (s == NULL)
3600Sstevel@tonic-gate 			return (NULL);
3610Sstevel@tonic-gate 
3620Sstevel@tonic-gate 		READLOCKS(scn->s_elf, scn);
3630Sstevel@tonic-gate 		*dst			= *(Elf64_Shdr *)s;
3640Sstevel@tonic-gate 		READUNLOCKS(scn->s_elf, scn);
3650Sstevel@tonic-gate 
3660Sstevel@tonic-gate 		return (dst);
3670Sstevel@tonic-gate 	}
3680Sstevel@tonic-gate 
3690Sstevel@tonic-gate 	_elf_seterr(EREQ_CLASS, 0);
3700Sstevel@tonic-gate 	return (NULL);
3710Sstevel@tonic-gate }
3720Sstevel@tonic-gate 
3730Sstevel@tonic-gate 
3740Sstevel@tonic-gate int
gelf_update_shdr(Elf_Scn * scn,GElf_Shdr * src)3750Sstevel@tonic-gate gelf_update_shdr(Elf_Scn *scn, GElf_Shdr *src)
3760Sstevel@tonic-gate {
3770Sstevel@tonic-gate 	if (scn == NULL)
3780Sstevel@tonic-gate 		return (0);
3790Sstevel@tonic-gate 
3800Sstevel@tonic-gate 	if (scn->s_elf->ed_class == ELFCLASS32) {
3810Sstevel@tonic-gate 		Elf32_Shdr *dst	= elf32_getshdr(scn);
3820Sstevel@tonic-gate 
3830Sstevel@tonic-gate 		if (dst == NULL)
3840Sstevel@tonic-gate 			return (0);
3850Sstevel@tonic-gate 
3860Sstevel@tonic-gate 		ELFWLOCK(scn->s_elf);
3870Sstevel@tonic-gate 		dst->sh_name		= src->sh_name;
3880Sstevel@tonic-gate 		dst->sh_type		= src->sh_type;
3890Sstevel@tonic-gate 		/* LINTED */
3900Sstevel@tonic-gate 		dst->sh_flags		= (Elf32_Word)src->sh_flags;
3910Sstevel@tonic-gate 		/* LINTED */
3920Sstevel@tonic-gate 		dst->sh_addr		= (Elf32_Addr)src->sh_addr;
3930Sstevel@tonic-gate 		/* LINTED */
3940Sstevel@tonic-gate 		dst->sh_offset		= (Elf32_Off) src->sh_offset;
3950Sstevel@tonic-gate 		/* LINTED */
3960Sstevel@tonic-gate 		dst->sh_size		= (Elf32_Word)src->sh_size;
3970Sstevel@tonic-gate 		dst->sh_link		= src->sh_link;
3980Sstevel@tonic-gate 		dst->sh_info		= src->sh_info;
3990Sstevel@tonic-gate 		/* LINTED */
4000Sstevel@tonic-gate 		dst->sh_addralign	= (Elf32_Word)src->sh_addralign;
4010Sstevel@tonic-gate 		/* LINTED */
4020Sstevel@tonic-gate 		dst->sh_entsize		= (Elf32_Word)src->sh_entsize;
4030Sstevel@tonic-gate 
4040Sstevel@tonic-gate 		ELFUNLOCK(scn->s_elf);
4050Sstevel@tonic-gate 		return (1);
4060Sstevel@tonic-gate 	} else if (scn->s_elf->ed_class == ELFCLASS64) {
4070Sstevel@tonic-gate 		Elf64_Shdr * dst	= elf64_getshdr(scn);
4080Sstevel@tonic-gate 
4090Sstevel@tonic-gate 		if (dst == NULL)
4100Sstevel@tonic-gate 			return (0);
4110Sstevel@tonic-gate 
4120Sstevel@tonic-gate 		ELFWLOCK(scn->s_elf);
4130Sstevel@tonic-gate 		*dst			= *(Elf64_Shdr *)src;
4140Sstevel@tonic-gate 		ELFUNLOCK(scn->s_elf);
4150Sstevel@tonic-gate 		return (1);
4160Sstevel@tonic-gate 	}
4170Sstevel@tonic-gate 
4180Sstevel@tonic-gate 	_elf_seterr(EREQ_CLASS, 0);
4190Sstevel@tonic-gate 	return (0);
4200Sstevel@tonic-gate }
4210Sstevel@tonic-gate 
4220Sstevel@tonic-gate 
4230Sstevel@tonic-gate /*
4240Sstevel@tonic-gate  * gelf_xlatetof/gelf_xlatetom use 'elf' to find the class
4250Sstevel@tonic-gate  * because these are the odd case where the Elf_Data structs
4260Sstevel@tonic-gate  * might not have been allocated by libelf (and therefore
4270Sstevel@tonic-gate  * don't have Dnode's associated with them).
4280Sstevel@tonic-gate  */
4290Sstevel@tonic-gate Elf_Data *
gelf_xlatetof(Elf * elf,Elf_Data * dst,const Elf_Data * src,unsigned encode)4300Sstevel@tonic-gate gelf_xlatetof(Elf *elf, Elf_Data *dst, const Elf_Data *src, unsigned encode)
4310Sstevel@tonic-gate {
4320Sstevel@tonic-gate 	int class;
4330Sstevel@tonic-gate 
4340Sstevel@tonic-gate 	if ((elf == NULL) || (dst == NULL) || (src == NULL))
4350Sstevel@tonic-gate 		return (NULL);
4360Sstevel@tonic-gate 
4370Sstevel@tonic-gate 	class = gelf_getclass(elf);
4380Sstevel@tonic-gate 	if (class == ELFCLASS32)
4390Sstevel@tonic-gate 		return (elf32_xlatetof(dst, src, encode));
4400Sstevel@tonic-gate 	else if (class == ELFCLASS64)
4410Sstevel@tonic-gate 		return (elf64_xlatetof(dst, src, encode));
4420Sstevel@tonic-gate 
4430Sstevel@tonic-gate 	_elf_seterr(EREQ_CLASS, 0);
4440Sstevel@tonic-gate 	return (NULL);
4450Sstevel@tonic-gate }
4460Sstevel@tonic-gate 
4470Sstevel@tonic-gate 
4480Sstevel@tonic-gate Elf_Data *
gelf_xlatetom(Elf * elf,Elf_Data * dst,const Elf_Data * src,unsigned encode)4490Sstevel@tonic-gate gelf_xlatetom(Elf *elf, Elf_Data *dst, const Elf_Data *src, unsigned encode)
4500Sstevel@tonic-gate {
4510Sstevel@tonic-gate 	int class;
4520Sstevel@tonic-gate 
4530Sstevel@tonic-gate 	if ((elf == NULL) || (dst == NULL) || (src == NULL))
4540Sstevel@tonic-gate 		return (NULL);
4550Sstevel@tonic-gate 
4560Sstevel@tonic-gate 	class = gelf_getclass(elf);
4570Sstevel@tonic-gate 	if (class == ELFCLASS32)
4580Sstevel@tonic-gate 		return (elf32_xlatetom(dst, src, encode));
4590Sstevel@tonic-gate 	else if (class == ELFCLASS64)
4600Sstevel@tonic-gate 		return (elf64_xlatetom(dst, src, encode));
4610Sstevel@tonic-gate 
4620Sstevel@tonic-gate 	_elf_seterr(EREQ_CLASS, 0);
4630Sstevel@tonic-gate 	return (NULL);
4640Sstevel@tonic-gate }
4650Sstevel@tonic-gate 
4660Sstevel@tonic-gate 
4670Sstevel@tonic-gate GElf_Sym *
gelf_getsym(Elf_Data * data,int ndx,GElf_Sym * dst)4680Sstevel@tonic-gate gelf_getsym(Elf_Data * data, int ndx, GElf_Sym * dst)
4690Sstevel@tonic-gate {
4700Sstevel@tonic-gate 	int	class;
4710Sstevel@tonic-gate 	size_t	entsize;
4720Sstevel@tonic-gate 
4730Sstevel@tonic-gate 	if (data == NULL)
4740Sstevel@tonic-gate 		return (NULL);
4750Sstevel@tonic-gate 
4760Sstevel@tonic-gate 	class = EDATA_CLASS(data);
4770Sstevel@tonic-gate 	if (class == ELFCLASS32)
4780Sstevel@tonic-gate 		entsize = sizeof (Elf32_Sym);
4790Sstevel@tonic-gate 	else if (class == ELFCLASS64)
4800Sstevel@tonic-gate 		entsize = sizeof (GElf_Sym);
4810Sstevel@tonic-gate 	else {
4820Sstevel@tonic-gate 		_elf_seterr(EREQ_CLASS, 0);
4830Sstevel@tonic-gate 		return (NULL);
4840Sstevel@tonic-gate 	}
4850Sstevel@tonic-gate 
4860Sstevel@tonic-gate 	EDATA_READLOCKS(data);
4870Sstevel@tonic-gate 
4884991Sab196087 	if ((entsize * ndx) >= data->d_size) {
4890Sstevel@tonic-gate 		_elf_seterr(EREQ_RAND, 0);
4900Sstevel@tonic-gate 		dst = NULL;
4910Sstevel@tonic-gate 	} else if (class == ELFCLASS32) {
4920Sstevel@tonic-gate 		Elf32_Sym	*s;
4930Sstevel@tonic-gate 		s		= &(((Elf32_Sym *)data->d_buf)[ndx]);
4940Sstevel@tonic-gate 		dst->st_name	= s->st_name;
4950Sstevel@tonic-gate 		dst->st_value	= (Elf64_Addr)s->st_value;
4960Sstevel@tonic-gate 		dst->st_size	= (Elf64_Xword)s->st_size;
4970Sstevel@tonic-gate 		dst->st_info	= ELF64_ST_INFO(ELF32_ST_BIND(s->st_info),
4984991Sab196087 		    ELF32_ST_TYPE(s->st_info));
4990Sstevel@tonic-gate 		dst->st_other	= s->st_other;
5000Sstevel@tonic-gate 		dst->st_shndx	= s->st_shndx;
5010Sstevel@tonic-gate 	} else
5020Sstevel@tonic-gate 		*dst = ((GElf_Sym *)data->d_buf)[ndx];
5030Sstevel@tonic-gate 
5040Sstevel@tonic-gate 	EDATA_READUNLOCKS(data);
5050Sstevel@tonic-gate 	return (dst);
5060Sstevel@tonic-gate }
5070Sstevel@tonic-gate 
5080Sstevel@tonic-gate 
5090Sstevel@tonic-gate int
gelf_update_sym(Elf_Data * dst,int ndx,GElf_Sym * src)5100Sstevel@tonic-gate gelf_update_sym(Elf_Data *dst, int ndx, GElf_Sym *src)
5110Sstevel@tonic-gate {
5120Sstevel@tonic-gate 	int	class, rc = 1;
5130Sstevel@tonic-gate 	size_t	entsize;
5140Sstevel@tonic-gate 
5150Sstevel@tonic-gate 	if (dst == NULL)
5160Sstevel@tonic-gate 		return (0);
5170Sstevel@tonic-gate 
5180Sstevel@tonic-gate 	class = EDATA_CLASS(dst);
5190Sstevel@tonic-gate 	if (class == ELFCLASS32)
5200Sstevel@tonic-gate 		entsize = sizeof (Elf32_Sym);
5210Sstevel@tonic-gate 	else if (class == ELFCLASS64)
5220Sstevel@tonic-gate 		entsize = sizeof (GElf_Sym);
5230Sstevel@tonic-gate 	else {
5240Sstevel@tonic-gate 		_elf_seterr(EREQ_CLASS, 0);
5250Sstevel@tonic-gate 		return (0);
5260Sstevel@tonic-gate 	}
5270Sstevel@tonic-gate 
5280Sstevel@tonic-gate 	ELFWLOCK(EDATA_ELF(dst));
5290Sstevel@tonic-gate 
5304991Sab196087 	if ((entsize * ndx) >= dst->d_size) {
5310Sstevel@tonic-gate 		_elf_seterr(EREQ_RAND, 0);
5320Sstevel@tonic-gate 		rc = 0;
5330Sstevel@tonic-gate 	} else if (class == ELFCLASS32) {
5340Sstevel@tonic-gate 		Elf32_Sym * d;
5350Sstevel@tonic-gate 
5360Sstevel@tonic-gate 		d		= &(((Elf32_Sym *)dst->d_buf)[ndx]);
5370Sstevel@tonic-gate 		d->st_name	= src->st_name;
5380Sstevel@tonic-gate 		/* LINTED */
5390Sstevel@tonic-gate 		d->st_value	= (Elf32_Addr)src->st_value;
5400Sstevel@tonic-gate 		/* LINTED */
5410Sstevel@tonic-gate 		d->st_size	= (Elf32_Word)src->st_size;
5420Sstevel@tonic-gate 		d->st_info	= ELF32_ST_INFO(ELF64_ST_BIND(src->st_info),
5434991Sab196087 		    ELF64_ST_TYPE(src->st_info));
5440Sstevel@tonic-gate 		d->st_other	= src->st_other;
5450Sstevel@tonic-gate 		d->st_shndx	= src->st_shndx;
5460Sstevel@tonic-gate 	} else
5470Sstevel@tonic-gate 		((Elf64_Sym *)dst->d_buf)[ndx] = *((Elf64_Sym *)src);
5480Sstevel@tonic-gate 
5490Sstevel@tonic-gate 	ELFUNLOCK(EDATA_ELF(dst));
5500Sstevel@tonic-gate 	return (rc);
5510Sstevel@tonic-gate }
5520Sstevel@tonic-gate 
5530Sstevel@tonic-gate 
5540Sstevel@tonic-gate GElf_Syminfo *
gelf_getsyminfo(Elf_Data * data,int ndx,GElf_Syminfo * dst)5550Sstevel@tonic-gate gelf_getsyminfo(Elf_Data *data, int ndx, GElf_Syminfo *dst)
5560Sstevel@tonic-gate {
5570Sstevel@tonic-gate 	int	class;
5580Sstevel@tonic-gate 	size_t	entsize;
5590Sstevel@tonic-gate 
5600Sstevel@tonic-gate 	if (data == NULL)
5610Sstevel@tonic-gate 		return (NULL);
5620Sstevel@tonic-gate 
5630Sstevel@tonic-gate 	class = EDATA_CLASS(data);
5640Sstevel@tonic-gate 	if (class == ELFCLASS32)
5650Sstevel@tonic-gate 		entsize = sizeof (Elf32_Syminfo);
5660Sstevel@tonic-gate 	else if (class == ELFCLASS64)
5670Sstevel@tonic-gate 		entsize = sizeof (GElf_Syminfo);
5680Sstevel@tonic-gate 	else {
5690Sstevel@tonic-gate 		_elf_seterr(EREQ_CLASS, 0);
5700Sstevel@tonic-gate 		return (NULL);
5710Sstevel@tonic-gate 	}
5720Sstevel@tonic-gate 	EDATA_READLOCKS(data);
5730Sstevel@tonic-gate 
5744991Sab196087 	if ((entsize * ndx) >= data->d_size) {
5750Sstevel@tonic-gate 		_elf_seterr(EREQ_RAND, 0);
5760Sstevel@tonic-gate 		dst = NULL;
5770Sstevel@tonic-gate 	} else if (class == ELFCLASS32) {
5780Sstevel@tonic-gate 		Elf32_Syminfo *	si;
5790Sstevel@tonic-gate 
5800Sstevel@tonic-gate 		si		= &(((Elf32_Syminfo *)data->d_buf)[ndx]);
5810Sstevel@tonic-gate 		dst->si_boundto = si->si_boundto;
5820Sstevel@tonic-gate 		dst->si_flags	= si->si_flags;
5830Sstevel@tonic-gate 	} else
5840Sstevel@tonic-gate 		*dst		= ((GElf_Syminfo *)data->d_buf)[ndx];
5850Sstevel@tonic-gate 
5860Sstevel@tonic-gate 	EDATA_READUNLOCKS(data);
5870Sstevel@tonic-gate 	return (dst);
5880Sstevel@tonic-gate }
5890Sstevel@tonic-gate 
5900Sstevel@tonic-gate int
gelf_update_syminfo(Elf_Data * dst,int ndx,GElf_Syminfo * src)5910Sstevel@tonic-gate gelf_update_syminfo(Elf_Data *dst, int ndx, GElf_Syminfo *src)
5920Sstevel@tonic-gate {
5930Sstevel@tonic-gate 	int	class, rc = 1;
5940Sstevel@tonic-gate 	size_t	entsize;
5950Sstevel@tonic-gate 
5960Sstevel@tonic-gate 	if (dst == NULL)
5970Sstevel@tonic-gate 		return (0);
5980Sstevel@tonic-gate 
5990Sstevel@tonic-gate 	class = EDATA_CLASS(dst);
6000Sstevel@tonic-gate 	if (class == ELFCLASS32)
6010Sstevel@tonic-gate 		entsize = sizeof (Elf32_Syminfo);
6020Sstevel@tonic-gate 	else if (class == ELFCLASS64)
6030Sstevel@tonic-gate 		entsize = sizeof (GElf_Syminfo);
6040Sstevel@tonic-gate 	else {
6050Sstevel@tonic-gate 		_elf_seterr(EREQ_CLASS, 0);
6060Sstevel@tonic-gate 		return (0);
6070Sstevel@tonic-gate 	}
6080Sstevel@tonic-gate 	ELFWLOCK(EDATA_ELF(dst));
6090Sstevel@tonic-gate 
6104991Sab196087 	if ((entsize * ndx) >= dst->d_size) {
6110Sstevel@tonic-gate 		_elf_seterr(EREQ_RAND, 0);
6120Sstevel@tonic-gate 		rc = 0;
6130Sstevel@tonic-gate 	} else if (class == ELFCLASS32) {
6140Sstevel@tonic-gate 		Elf32_Syminfo * d	= &(((Elf32_Syminfo *)dst->d_buf)[ndx]);
6150Sstevel@tonic-gate 		d->si_boundto		= src->si_boundto;
6160Sstevel@tonic-gate 		d->si_flags		= src->si_flags;
6170Sstevel@tonic-gate 	} else
6180Sstevel@tonic-gate 		((Elf64_Syminfo *)dst->d_buf)[ndx] = *((Elf64_Syminfo *)src);
6190Sstevel@tonic-gate 
6200Sstevel@tonic-gate 	ELFUNLOCK(EDATA_ELF(dst));
6210Sstevel@tonic-gate 	return (rc);
6220Sstevel@tonic-gate }
6230Sstevel@tonic-gate 
6240Sstevel@tonic-gate GElf_Dyn *
gelf_getdyn(Elf_Data * data,int ndx,GElf_Dyn * dst)6250Sstevel@tonic-gate gelf_getdyn(Elf_Data *data, int ndx, GElf_Dyn *dst)
6260Sstevel@tonic-gate {
6270Sstevel@tonic-gate 	int	class;
6280Sstevel@tonic-gate 	size_t	entsize;
6290Sstevel@tonic-gate 
6300Sstevel@tonic-gate 	if (data == NULL)
6310Sstevel@tonic-gate 		return (NULL);
6320Sstevel@tonic-gate 
6330Sstevel@tonic-gate 	class = EDATA_CLASS(data);
6340Sstevel@tonic-gate 	if (class == ELFCLASS32)
6350Sstevel@tonic-gate 		entsize = sizeof (Elf32_Dyn);
6360Sstevel@tonic-gate 	else if (class == ELFCLASS64)
6370Sstevel@tonic-gate 		entsize = sizeof (GElf_Dyn);
6380Sstevel@tonic-gate 	else {
6390Sstevel@tonic-gate 		_elf_seterr(EREQ_CLASS, 0);
6400Sstevel@tonic-gate 		return (NULL);
6410Sstevel@tonic-gate 	}
6420Sstevel@tonic-gate 	EDATA_READLOCKS(data);
6430Sstevel@tonic-gate 
6444991Sab196087 	if ((entsize * ndx) >= data->d_size) {
6450Sstevel@tonic-gate 		_elf_seterr(EREQ_RAND, 0);
6460Sstevel@tonic-gate 		dst = NULL;
6470Sstevel@tonic-gate 	} else if (class == ELFCLASS32) {
6480Sstevel@tonic-gate 		Elf32_Dyn * d = &((Elf32_Dyn *)data->d_buf)[ndx];
6490Sstevel@tonic-gate 
6500Sstevel@tonic-gate 		dst->d_tag	= (Elf32_Sword)d->d_tag;
6510Sstevel@tonic-gate 		dst->d_un.d_val	= (Elf32_Word) d->d_un.d_val;
6520Sstevel@tonic-gate 	} else
6530Sstevel@tonic-gate 		*dst = ((Elf64_Dyn *)data->d_buf)[ndx];
6540Sstevel@tonic-gate 
6550Sstevel@tonic-gate 	EDATA_READUNLOCKS(data);
6560Sstevel@tonic-gate 	return (dst);
6570Sstevel@tonic-gate }
6580Sstevel@tonic-gate 
6590Sstevel@tonic-gate 
6600Sstevel@tonic-gate int
gelf_update_dyn(Elf_Data * dst,int ndx,GElf_Dyn * src)6610Sstevel@tonic-gate gelf_update_dyn(Elf_Data *dst, int ndx, GElf_Dyn *src)
6620Sstevel@tonic-gate {
6630Sstevel@tonic-gate 	int	class, rc = 1;
6640Sstevel@tonic-gate 	size_t	entsize;
6650Sstevel@tonic-gate 
6660Sstevel@tonic-gate 	if (dst == NULL)
6670Sstevel@tonic-gate 		return (0);
6680Sstevel@tonic-gate 
6690Sstevel@tonic-gate 	class = EDATA_CLASS(dst);
6700Sstevel@tonic-gate 	if (class == ELFCLASS32)
6710Sstevel@tonic-gate 		entsize = sizeof (Elf32_Dyn);
6720Sstevel@tonic-gate 	else if (class == ELFCLASS64)
6730Sstevel@tonic-gate 		entsize = sizeof (GElf_Dyn);
6740Sstevel@tonic-gate 	else {
6750Sstevel@tonic-gate 		_elf_seterr(EREQ_CLASS, 0);
6760Sstevel@tonic-gate 		return (0);
6770Sstevel@tonic-gate 	}
6780Sstevel@tonic-gate 	ELFWLOCK(EDATA_ELF(dst));
6790Sstevel@tonic-gate 
6804991Sab196087 	if ((entsize * ndx) >= dst->d_size) {
6810Sstevel@tonic-gate 		_elf_seterr(EREQ_RAND, 0);
6820Sstevel@tonic-gate 		rc = 0;
6830Sstevel@tonic-gate 	} else if (class == ELFCLASS32) {
6840Sstevel@tonic-gate 		Elf32_Dyn * d = &((Elf32_Dyn *)dst->d_buf)[ndx];
6850Sstevel@tonic-gate 
6860Sstevel@tonic-gate 		/* LINTED */
6870Sstevel@tonic-gate 		d->d_tag	= (Elf32_Word)src->d_tag;
6880Sstevel@tonic-gate 		/* LINTED */
6890Sstevel@tonic-gate 		d->d_un.d_val	= (Elf32_Word)src->d_un.d_val;
6900Sstevel@tonic-gate 	} else
6910Sstevel@tonic-gate 		((Elf64_Dyn *)dst->d_buf)[ndx] = *(Elf64_Dyn*)src;
6920Sstevel@tonic-gate 
6930Sstevel@tonic-gate 	ELFUNLOCK(EDATA_ELF(dst));
6940Sstevel@tonic-gate 	return (rc);
6950Sstevel@tonic-gate }
6960Sstevel@tonic-gate 
6970Sstevel@tonic-gate 
6980Sstevel@tonic-gate 
6990Sstevel@tonic-gate GElf_Sym *
gelf_getsymshndx(Elf_Data * symdata,Elf_Data * shndxdata,int ndx,GElf_Sym * symptr,Elf32_Word * xshndx)7000Sstevel@tonic-gate gelf_getsymshndx(Elf_Data *symdata, Elf_Data *shndxdata,
7010Sstevel@tonic-gate 	int ndx, GElf_Sym *symptr, Elf32_Word *xshndx)
7020Sstevel@tonic-gate {
7030Sstevel@tonic-gate 	if (gelf_getsym(symdata, ndx, symptr) == 0)
7040Sstevel@tonic-gate 		return (NULL);
7050Sstevel@tonic-gate 	if (shndxdata && xshndx) {
7060Sstevel@tonic-gate 		EDATA_READLOCKS(shndxdata);
7074991Sab196087 		if ((ndx * sizeof (Elf32_Word)) >= shndxdata->d_size) {
7080Sstevel@tonic-gate 			_elf_seterr(EREQ_RAND, 0);
7090Sstevel@tonic-gate 			EDATA_READUNLOCKS(shndxdata);
7100Sstevel@tonic-gate 			return (NULL);
7110Sstevel@tonic-gate 		}
7120Sstevel@tonic-gate 		*xshndx = (((Elf32_Word *)shndxdata->d_buf)[ndx]);
7130Sstevel@tonic-gate 		EDATA_READUNLOCKS(shndxdata);
7140Sstevel@tonic-gate 	} else {
7150Sstevel@tonic-gate 		*xshndx = 0;
7160Sstevel@tonic-gate 	}
7170Sstevel@tonic-gate 	return (symptr);
7180Sstevel@tonic-gate }
7190Sstevel@tonic-gate 
7200Sstevel@tonic-gate int
gelf_update_symshndx(Elf_Data * symdata,Elf_Data * shndxdata,int ndx,GElf_Sym * symptr,Elf32_Word xshndx)7210Sstevel@tonic-gate gelf_update_symshndx(Elf_Data *symdata, Elf_Data *shndxdata,
7220Sstevel@tonic-gate 	int ndx, GElf_Sym *symptr, Elf32_Word xshndx)
7230Sstevel@tonic-gate {
7240Sstevel@tonic-gate 	if (gelf_update_sym(symdata, ndx, symptr) == 0)
7250Sstevel@tonic-gate 		return (0);
7260Sstevel@tonic-gate 	if (shndxdata) {
7270Sstevel@tonic-gate 		ELFWLOCK(EDATA_ELF(shndxdata));
7284991Sab196087 		if ((ndx * sizeof (Elf32_Word)) >= shndxdata->d_size) {
7290Sstevel@tonic-gate 			_elf_seterr(EREQ_RAND, 0);
7300Sstevel@tonic-gate 			ELFUNLOCK(EDATA_ELF(shndxdata));
7310Sstevel@tonic-gate 			return (0);
7320Sstevel@tonic-gate 		}
7330Sstevel@tonic-gate 		((Elf32_Word *)shndxdata->d_buf)[ndx] = xshndx;
7340Sstevel@tonic-gate 		ELFUNLOCK(EDATA_ELF(shndxdata));
7350Sstevel@tonic-gate 	}
7360Sstevel@tonic-gate 	return (1);
7370Sstevel@tonic-gate }
7380Sstevel@tonic-gate 
7390Sstevel@tonic-gate 
7400Sstevel@tonic-gate GElf_Move *
gelf_getmove(Elf_Data * src,int ndx,GElf_Move * dst)7410Sstevel@tonic-gate gelf_getmove(Elf_Data *src, int ndx, GElf_Move *dst)
7420Sstevel@tonic-gate {
7430Sstevel@tonic-gate 	int	class;
7440Sstevel@tonic-gate 	size_t	entsize;
7450Sstevel@tonic-gate 
7460Sstevel@tonic-gate 	if (src == NULL)
7470Sstevel@tonic-gate 		return (NULL);
7480Sstevel@tonic-gate 
7490Sstevel@tonic-gate 	class = EDATA_CLASS(src);
7500Sstevel@tonic-gate 	if (class == ELFCLASS32)
7510Sstevel@tonic-gate 		entsize = sizeof (Elf32_Move);
7520Sstevel@tonic-gate 	else if (class == ELFCLASS64)
7530Sstevel@tonic-gate 		entsize = sizeof (GElf_Move);
7540Sstevel@tonic-gate 	else {
7550Sstevel@tonic-gate 		_elf_seterr(EREQ_CLASS, 0);
7560Sstevel@tonic-gate 		return (NULL);
7570Sstevel@tonic-gate 	}
7580Sstevel@tonic-gate 	EDATA_READLOCKS(src);
7590Sstevel@tonic-gate 
7604991Sab196087 	if ((entsize * ndx) >= src->d_size) {
7610Sstevel@tonic-gate 		_elf_seterr(EREQ_RAND, 0);
7620Sstevel@tonic-gate 		dst = NULL;
7630Sstevel@tonic-gate 	} else if (class == ELFCLASS32) {
7640Sstevel@tonic-gate 		Elf32_Move * m = &((Elf32_Move *)src->d_buf)[ndx];
7650Sstevel@tonic-gate 
7660Sstevel@tonic-gate 		dst->m_poffset = (Elf64_Word)m->m_poffset;
7670Sstevel@tonic-gate 		dst->m_repeat = (Elf64_Xword)m->m_repeat;
7680Sstevel@tonic-gate 		dst->m_stride = (Elf64_Half)m->m_stride;
7690Sstevel@tonic-gate 		dst->m_value = (Elf64_Xword)m->m_value;
7704991Sab196087 		dst->m_info = ELF64_M_INFO(ELF32_M_SYM(m->m_info),
7714991Sab196087 		    ELF32_M_SIZE(m->m_info));
7724991Sab196087 	} else {
7730Sstevel@tonic-gate 		*dst = ((Elf64_Move *)src->d_buf)[ndx];
7744991Sab196087 	}
7750Sstevel@tonic-gate 
7760Sstevel@tonic-gate 	EDATA_READUNLOCKS(src);
7770Sstevel@tonic-gate 	return (dst);
7780Sstevel@tonic-gate }
7790Sstevel@tonic-gate 
7800Sstevel@tonic-gate int
gelf_update_move(Elf_Data * dest,int ndx,GElf_Move * src)7810Sstevel@tonic-gate gelf_update_move(Elf_Data *dest, int ndx, GElf_Move *src)
7820Sstevel@tonic-gate {
7830Sstevel@tonic-gate 	int	class, rc = 1;
7840Sstevel@tonic-gate 	size_t	entsize;
7850Sstevel@tonic-gate 
7860Sstevel@tonic-gate 	if (dest == NULL)
7870Sstevel@tonic-gate 		return (0);
7880Sstevel@tonic-gate 
7890Sstevel@tonic-gate 	class = EDATA_CLASS(dest);
7900Sstevel@tonic-gate 	if (class == ELFCLASS32)
7910Sstevel@tonic-gate 		entsize = sizeof (Elf32_Move);
7920Sstevel@tonic-gate 	else if (class == ELFCLASS64)
7930Sstevel@tonic-gate 		entsize = sizeof (GElf_Move);
7940Sstevel@tonic-gate 	else {
7950Sstevel@tonic-gate 		_elf_seterr(EREQ_CLASS, 0);
7960Sstevel@tonic-gate 		return (0);
7970Sstevel@tonic-gate 	}
7980Sstevel@tonic-gate 	ELFWLOCK(EDATA_ELF(dest));
7990Sstevel@tonic-gate 
8004991Sab196087 	if ((entsize * ndx) >= dest->d_size) {
8010Sstevel@tonic-gate 		_elf_seterr(EREQ_RAND, 0);
8020Sstevel@tonic-gate 		rc = 0;
8030Sstevel@tonic-gate 	} else if (class == ELFCLASS32) {
8040Sstevel@tonic-gate 		Elf32_Move * m = &((Elf32_Move *)dest->d_buf)[ndx];
8050Sstevel@tonic-gate 
8060Sstevel@tonic-gate 		m->m_poffset = (Elf32_Word)src->m_poffset;
8070Sstevel@tonic-gate 		m->m_repeat = (Elf32_Half)src->m_repeat;
8080Sstevel@tonic-gate 		m->m_stride = (Elf32_Half)src->m_stride;
8090Sstevel@tonic-gate 		m->m_value = (Elf32_Lword)src->m_value;
8104991Sab196087 		m->m_info = (Elf32_Word)ELF32_M_INFO(ELF64_M_SYM(src->m_info),
8114991Sab196087 		    ELF64_M_SIZE(src->m_info));
8124991Sab196087 	} else {
8130Sstevel@tonic-gate 		((Elf64_Move *)dest->d_buf)[ndx] = *(Elf64_Move *)src;
8144991Sab196087 	}
8150Sstevel@tonic-gate 
8160Sstevel@tonic-gate 	ELFUNLOCK(EDATA_ELF(dest));
8170Sstevel@tonic-gate 	return (rc);
8180Sstevel@tonic-gate }
8190Sstevel@tonic-gate 
8200Sstevel@tonic-gate 
8210Sstevel@tonic-gate GElf_Rela *
gelf_getrela(Elf_Data * src,int ndx,GElf_Rela * dst)8220Sstevel@tonic-gate gelf_getrela(Elf_Data *src, int ndx, GElf_Rela *dst)
8230Sstevel@tonic-gate {
8240Sstevel@tonic-gate 	int	class;
8250Sstevel@tonic-gate 	size_t	entsize;
8260Sstevel@tonic-gate 
8270Sstevel@tonic-gate 	if (src == NULL)
8280Sstevel@tonic-gate 		return (NULL);
8290Sstevel@tonic-gate 
8300Sstevel@tonic-gate 	class = EDATA_CLASS(src);
8310Sstevel@tonic-gate 	if (class == ELFCLASS32)
8320Sstevel@tonic-gate 		entsize = sizeof (Elf32_Rela);
8330Sstevel@tonic-gate 	else if (class == ELFCLASS64)
8340Sstevel@tonic-gate 		entsize = sizeof (GElf_Rela);
8350Sstevel@tonic-gate 	else {
8360Sstevel@tonic-gate 		_elf_seterr(EREQ_CLASS, 0);
8370Sstevel@tonic-gate 		return (NULL);
8380Sstevel@tonic-gate 	}
8390Sstevel@tonic-gate 	EDATA_READLOCKS(src);
8400Sstevel@tonic-gate 
8414991Sab196087 	if ((entsize * ndx) >= src->d_size) {
8420Sstevel@tonic-gate 		_elf_seterr(EREQ_RAND, 0);
8430Sstevel@tonic-gate 		dst = NULL;
8440Sstevel@tonic-gate 	} else if (class == ELFCLASS32) {
8450Sstevel@tonic-gate 		Elf32_Rela * r = &((Elf32_Rela *)src->d_buf)[ndx];
8460Sstevel@tonic-gate 
8470Sstevel@tonic-gate 		dst->r_offset	= (GElf_Addr)r->r_offset;
8480Sstevel@tonic-gate 		dst->r_addend	= (GElf_Addr)r->r_addend;
8490Sstevel@tonic-gate 
8500Sstevel@tonic-gate 		/*
8510Sstevel@tonic-gate 		 * Elf32 will never have the extra data field that
8520Sstevel@tonic-gate 		 * Elf64's r_info field can have, so ignore it.
8530Sstevel@tonic-gate 		 */
8540Sstevel@tonic-gate 		/* LINTED */
8550Sstevel@tonic-gate 		dst->r_info	= ELF64_R_INFO(
8560Sstevel@tonic-gate 		    ELF32_R_SYM(r->r_info),
8570Sstevel@tonic-gate 		    ELF32_R_TYPE(r->r_info));
8580Sstevel@tonic-gate 	} else
8590Sstevel@tonic-gate 		*dst = ((Elf64_Rela *)src->d_buf)[ndx];
8600Sstevel@tonic-gate 
8610Sstevel@tonic-gate 	EDATA_READUNLOCKS(src);
8620Sstevel@tonic-gate 	return (dst);
8630Sstevel@tonic-gate }
8640Sstevel@tonic-gate 
8650Sstevel@tonic-gate 
8660Sstevel@tonic-gate int
gelf_update_rela(Elf_Data * dst,int ndx,GElf_Rela * src)8670Sstevel@tonic-gate gelf_update_rela(Elf_Data *dst, int ndx, GElf_Rela *src)
8680Sstevel@tonic-gate {
8690Sstevel@tonic-gate 	int	class, rc = 1;
8700Sstevel@tonic-gate 	size_t	entsize;
8710Sstevel@tonic-gate 
8720Sstevel@tonic-gate 	if (dst == NULL)
8730Sstevel@tonic-gate 		return (0);
8740Sstevel@tonic-gate 
8750Sstevel@tonic-gate 	class = EDATA_CLASS(dst);
8760Sstevel@tonic-gate 	if (class == ELFCLASS32)
8770Sstevel@tonic-gate 		entsize = sizeof (Elf32_Rela);
8780Sstevel@tonic-gate 	else if (class == ELFCLASS64)
8790Sstevel@tonic-gate 		entsize = sizeof (GElf_Rela);
8800Sstevel@tonic-gate 	else {
8810Sstevel@tonic-gate 		_elf_seterr(EREQ_CLASS, 0);
8820Sstevel@tonic-gate 		return (0);
8830Sstevel@tonic-gate 	}
8840Sstevel@tonic-gate 	ELFWLOCK(EDATA_ELF(dst));
8850Sstevel@tonic-gate 
8864991Sab196087 	if ((entsize * ndx) >= dst->d_size) {
8870Sstevel@tonic-gate 		_elf_seterr(EREQ_RAND, 0);
8880Sstevel@tonic-gate 		rc = 0;
8890Sstevel@tonic-gate 	} else if (class == ELFCLASS32) {
8900Sstevel@tonic-gate 		Elf32_Rela * r = &((Elf32_Rela *)dst->d_buf)[ndx];
8910Sstevel@tonic-gate 
8920Sstevel@tonic-gate 		/* LINTED */
8930Sstevel@tonic-gate 		r->r_offset	= (Elf32_Addr) src->r_offset;
8940Sstevel@tonic-gate 		/* LINTED */
8950Sstevel@tonic-gate 		r->r_addend	= (Elf32_Sword)src->r_addend;
8960Sstevel@tonic-gate 
8970Sstevel@tonic-gate 		/*
8980Sstevel@tonic-gate 		 * Elf32 will never have the extra data field that
8990Sstevel@tonic-gate 		 * Elf64's r_info field can have, so ignore it.
9000Sstevel@tonic-gate 		 */
9010Sstevel@tonic-gate 		/* LINTED */
9024991Sab196087 		r->r_info	= ELF32_R_INFO(ELF64_R_SYM(src->r_info),
9034991Sab196087 		    ELF64_R_TYPE(src->r_info));
9044991Sab196087 	} else {
9050Sstevel@tonic-gate 		((Elf64_Rela *)dst->d_buf)[ndx] = *(Elf64_Rela *)src;
9064991Sab196087 	}
9070Sstevel@tonic-gate 
9080Sstevel@tonic-gate 	ELFUNLOCK(EDATA_ELF(dst));
9090Sstevel@tonic-gate 
9100Sstevel@tonic-gate 	return (rc);
9110Sstevel@tonic-gate }
9120Sstevel@tonic-gate 
9130Sstevel@tonic-gate 
9140Sstevel@tonic-gate GElf_Rel *
gelf_getrel(Elf_Data * src,int ndx,GElf_Rel * dst)9150Sstevel@tonic-gate gelf_getrel(Elf_Data *src, int ndx, GElf_Rel *dst)
9160Sstevel@tonic-gate {
9170Sstevel@tonic-gate 	int	class;
9180Sstevel@tonic-gate 	size_t	entsize;
9190Sstevel@tonic-gate 
9200Sstevel@tonic-gate 	if (src == NULL)
9210Sstevel@tonic-gate 		return (NULL);
9220Sstevel@tonic-gate 
9230Sstevel@tonic-gate 	class = EDATA_CLASS(src);
9240Sstevel@tonic-gate 	if (class == ELFCLASS32)
9250Sstevel@tonic-gate 		entsize = sizeof (Elf32_Rel);
9260Sstevel@tonic-gate 	else if (class == ELFCLASS64)
9270Sstevel@tonic-gate 		entsize = sizeof (GElf_Rel);
9280Sstevel@tonic-gate 	else {
9290Sstevel@tonic-gate 		_elf_seterr(EREQ_CLASS, 0);
9300Sstevel@tonic-gate 		return (NULL);
9310Sstevel@tonic-gate 	}
9320Sstevel@tonic-gate 	EDATA_READLOCKS(src);
9330Sstevel@tonic-gate 
9344991Sab196087 	if ((entsize * ndx) >= src->d_size) {
9350Sstevel@tonic-gate 		_elf_seterr(EREQ_RAND, 0);
9360Sstevel@tonic-gate 		dst = NULL;
9370Sstevel@tonic-gate 	} else if (class == ELFCLASS32) {
9380Sstevel@tonic-gate 		Elf32_Rel * r = &((Elf32_Rel *)src->d_buf)[ndx];
9390Sstevel@tonic-gate 
9400Sstevel@tonic-gate 		dst->r_offset	= (GElf_Addr)r->r_offset;
9410Sstevel@tonic-gate 
9420Sstevel@tonic-gate 		/*
9430Sstevel@tonic-gate 		 * Elf32 will never have the extra data field that
9440Sstevel@tonic-gate 		 * Elf64's r_info field can have, so ignore it.
9450Sstevel@tonic-gate 		 */
9460Sstevel@tonic-gate 		/* LINTED */
9470Sstevel@tonic-gate 		dst->r_info	= ELF64_R_INFO(ELF32_R_SYM(r->r_info),
9484991Sab196087 		    ELF32_R_TYPE(r->r_info));
9490Sstevel@tonic-gate 	} else
9500Sstevel@tonic-gate 		*dst = ((Elf64_Rel *)src->d_buf)[ndx];
9510Sstevel@tonic-gate 
9520Sstevel@tonic-gate 	EDATA_READUNLOCKS(src);
9530Sstevel@tonic-gate 	return (dst);
9540Sstevel@tonic-gate }
9550Sstevel@tonic-gate 
9560Sstevel@tonic-gate 
9570Sstevel@tonic-gate int
gelf_update_rel(Elf_Data * dst,int ndx,GElf_Rel * src)9580Sstevel@tonic-gate gelf_update_rel(Elf_Data *dst, int ndx, GElf_Rel *src)
9590Sstevel@tonic-gate {
9600Sstevel@tonic-gate 	int	class, rc = 1;
9610Sstevel@tonic-gate 	size_t	entsize;
9620Sstevel@tonic-gate 
9630Sstevel@tonic-gate 	if (dst == NULL)
9640Sstevel@tonic-gate 		return (0);
9650Sstevel@tonic-gate 
9660Sstevel@tonic-gate 	class = EDATA_CLASS(dst);
9670Sstevel@tonic-gate 	if (class == ELFCLASS32)
9680Sstevel@tonic-gate 		entsize = sizeof (Elf32_Rel);
9690Sstevel@tonic-gate 	else if (class == ELFCLASS64)
9700Sstevel@tonic-gate 		entsize = sizeof (GElf_Rel);
9710Sstevel@tonic-gate 	else {
9720Sstevel@tonic-gate 		_elf_seterr(EREQ_CLASS, 0);
9730Sstevel@tonic-gate 		return (0);
9740Sstevel@tonic-gate 	}
9750Sstevel@tonic-gate 	ELFWLOCK(EDATA_ELF(dst));
9760Sstevel@tonic-gate 
9774991Sab196087 	if ((entsize * ndx) >= dst->d_size) {
9780Sstevel@tonic-gate 		_elf_seterr(EREQ_RAND, 0);
9790Sstevel@tonic-gate 		rc = 0;
9800Sstevel@tonic-gate 	} else if (class == ELFCLASS32) {
9810Sstevel@tonic-gate 		Elf32_Rel * r = &((Elf32_Rel *)dst->d_buf)[ndx];
9820Sstevel@tonic-gate 
9830Sstevel@tonic-gate 		/* LINTED */
9840Sstevel@tonic-gate 		r->r_offset	= (Elf32_Addr) src->r_offset;
9850Sstevel@tonic-gate 
9860Sstevel@tonic-gate 		/*
9870Sstevel@tonic-gate 		 * Elf32 will never have the extra data field that
9880Sstevel@tonic-gate 		 * Elf64's r_info field can have, so ignore it.
9890Sstevel@tonic-gate 		 */
9900Sstevel@tonic-gate 		/* LINTED */
9914991Sab196087 		r->r_info	= ELF32_R_INFO(ELF64_R_SYM(src->r_info),
9924991Sab196087 		    ELF64_R_TYPE(src->r_info));
9930Sstevel@tonic-gate 
9944991Sab196087 	} else {
9950Sstevel@tonic-gate 		((Elf64_Rel *)dst->d_buf)[ndx] = *(Elf64_Rel *)src;
9964991Sab196087 	}
9970Sstevel@tonic-gate 
9980Sstevel@tonic-gate 	ELFUNLOCK(EDATA_ELF(dst));
9990Sstevel@tonic-gate 	return (rc);
10000Sstevel@tonic-gate }
10010Sstevel@tonic-gate 
10020Sstevel@tonic-gate long
gelf_checksum(Elf * elf)10030Sstevel@tonic-gate gelf_checksum(Elf *elf)
10040Sstevel@tonic-gate {
10050Sstevel@tonic-gate 	int class = gelf_getclass(elf);
10060Sstevel@tonic-gate 
10070Sstevel@tonic-gate 	if (class == ELFCLASS32)
10080Sstevel@tonic-gate 		return (elf32_checksum(elf));
10090Sstevel@tonic-gate 	else if (class == ELFCLASS64)
10100Sstevel@tonic-gate 		return (elf64_checksum(elf));
10110Sstevel@tonic-gate 
10120Sstevel@tonic-gate 	_elf_seterr(EREQ_CLASS, 0);
10130Sstevel@tonic-gate 	return (0);
10140Sstevel@tonic-gate }
10150Sstevel@tonic-gate 
10160Sstevel@tonic-gate GElf_Cap *
gelf_getcap(Elf_Data * data,int ndx,GElf_Cap * dst)10170Sstevel@tonic-gate gelf_getcap(Elf_Data *data, int ndx, GElf_Cap *dst)
10180Sstevel@tonic-gate {
10190Sstevel@tonic-gate 	int	class;
10200Sstevel@tonic-gate 	size_t	entsize;
10210Sstevel@tonic-gate 
10220Sstevel@tonic-gate 	if (data == NULL)
10230Sstevel@tonic-gate 		return (NULL);
10240Sstevel@tonic-gate 
10250Sstevel@tonic-gate 	class = EDATA_CLASS(data);
10260Sstevel@tonic-gate 	if (class == ELFCLASS32)
10270Sstevel@tonic-gate 		entsize = sizeof (Elf32_Cap);
10280Sstevel@tonic-gate 	else if (class == ELFCLASS64)
10290Sstevel@tonic-gate 		entsize = sizeof (GElf_Cap);
10300Sstevel@tonic-gate 	else {
10310Sstevel@tonic-gate 		_elf_seterr(EREQ_CLASS, 0);
10320Sstevel@tonic-gate 		return (NULL);
10330Sstevel@tonic-gate 	}
10340Sstevel@tonic-gate 
10350Sstevel@tonic-gate 	EDATA_READLOCKS(data);
10360Sstevel@tonic-gate 
10374991Sab196087 	if ((entsize * ndx) >= data->d_size) {
10380Sstevel@tonic-gate 		_elf_seterr(EREQ_RAND, 0);
10390Sstevel@tonic-gate 		dst = NULL;
10400Sstevel@tonic-gate 	} else if (class == ELFCLASS32) {
10410Sstevel@tonic-gate 		Elf32_Cap	*c = &(((Elf32_Cap *)data->d_buf)[ndx]);
10420Sstevel@tonic-gate 
10430Sstevel@tonic-gate 		dst->c_tag = (Elf64_Xword)c->c_tag;
10440Sstevel@tonic-gate 		dst->c_un.c_val = (Elf64_Xword)c->c_un.c_val;
10450Sstevel@tonic-gate 	} else
10460Sstevel@tonic-gate 		*dst = ((GElf_Cap *)data->d_buf)[ndx];
10470Sstevel@tonic-gate 
10480Sstevel@tonic-gate 	EDATA_READUNLOCKS(data);
10490Sstevel@tonic-gate 	return (dst);
10500Sstevel@tonic-gate }
10510Sstevel@tonic-gate 
10520Sstevel@tonic-gate int
gelf_update_cap(Elf_Data * dst,int ndx,GElf_Cap * src)10530Sstevel@tonic-gate gelf_update_cap(Elf_Data *dst, int ndx, GElf_Cap *src)
10540Sstevel@tonic-gate {
10550Sstevel@tonic-gate 	int	class, rc = 1;
10560Sstevel@tonic-gate 	size_t	entsize;
10570Sstevel@tonic-gate 
10580Sstevel@tonic-gate 	if (dst == NULL)
10590Sstevel@tonic-gate 		return (0);
10600Sstevel@tonic-gate 
10610Sstevel@tonic-gate 	class = EDATA_CLASS(dst);
10620Sstevel@tonic-gate 	if (class == ELFCLASS32)
10630Sstevel@tonic-gate 		entsize = sizeof (Elf32_Cap);
10640Sstevel@tonic-gate 	else if (class == ELFCLASS64)
10650Sstevel@tonic-gate 		entsize = sizeof (GElf_Cap);
10660Sstevel@tonic-gate 	else {
10670Sstevel@tonic-gate 		_elf_seterr(EREQ_CLASS, 0);
10680Sstevel@tonic-gate 		return (0);
10690Sstevel@tonic-gate 	}
10700Sstevel@tonic-gate 
10710Sstevel@tonic-gate 	ELFWLOCK(EDATA_ELF(dst));
10720Sstevel@tonic-gate 
10734991Sab196087 	if ((entsize * ndx) >= dst->d_size) {
10740Sstevel@tonic-gate 		_elf_seterr(EREQ_RAND, 0);
10750Sstevel@tonic-gate 		rc = 0;
10760Sstevel@tonic-gate 	} else if (class == ELFCLASS32) {
10770Sstevel@tonic-gate 		Elf32_Cap	*c = &(((Elf32_Cap *)dst->d_buf)[ndx]);
10780Sstevel@tonic-gate 
10790Sstevel@tonic-gate 		c->c_tag = (Elf32_Word)src->c_tag;
10800Sstevel@tonic-gate 		c->c_un.c_val = (Elf32_Word)src->c_un.c_val;
10810Sstevel@tonic-gate 	} else
10820Sstevel@tonic-gate 		((Elf64_Cap *)dst->d_buf)[ndx] = *((Elf64_Cap *)src);
10830Sstevel@tonic-gate 
10840Sstevel@tonic-gate 	ELFUNLOCK(EDATA_ELF(dst));
10850Sstevel@tonic-gate 	return (rc);
10860Sstevel@tonic-gate }
10871698Sab196087 
10881698Sab196087 /*
10891698Sab196087  * If the specified object has a dynamic section, and that section
10901698Sab196087  * contains a DT_FLAGS_1 entry, then return the value of that entry.
10911698Sab196087  * Otherwise, return 0.
10921698Sab196087  */
10931698Sab196087 GElf_Xword
_gelf_getdyndtflags_1(Elf * elf)10941698Sab196087 _gelf_getdyndtflags_1(Elf *elf)
10951698Sab196087 {
10961698Sab196087 	Elf_Scn *scn = NULL;
10971698Sab196087 	Elf_Data *data;
10981698Sab196087 	GElf_Shdr shdr;
10991698Sab196087 	GElf_Dyn dyn;
11001698Sab196087 	int i, n;
11011698Sab196087 
11021698Sab196087 	while (scn = elf_nextscn(elf, scn)) {
11031698Sab196087 		if (gelf_getshdr(scn, &shdr) == NULL)
11041698Sab196087 			break;
11051698Sab196087 		if (shdr.sh_type != SHT_DYNAMIC)
11061698Sab196087 			continue;
11071698Sab196087 		if (data = elf_getdata(scn, NULL)) {
11081698Sab196087 			n = shdr.sh_size / shdr.sh_entsize;
11091698Sab196087 			for (i = 0; i < n; i++) {
11101698Sab196087 				(void) gelf_getdyn(data, i, &dyn);
11111698Sab196087 				if (dyn.d_tag == DT_FLAGS_1) {
11121698Sab196087 					return (dyn.d_un.d_val);
11131698Sab196087 				}
11141698Sab196087 			}
11151698Sab196087 		}
11161698Sab196087 		break;
11171698Sab196087 	}
11181698Sab196087 	return (0);
11191698Sab196087 }
1120