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