17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 54899432aSab196087 * Common Development and Distribution License (the "License"). 64899432aSab196087 * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate /* 22*62b628a6SAli Bahrami * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 237c478bd9Sstevel@tonic-gate * Use is subject to license terms. 247c478bd9Sstevel@tonic-gate */ 257c478bd9Sstevel@tonic-gate 267c478bd9Sstevel@tonic-gate #include <string.h> 274899432aSab196087 #include "_libelf.h" 287c478bd9Sstevel@tonic-gate #include "decl.h" 297c478bd9Sstevel@tonic-gate #include "msg.h" 307c478bd9Sstevel@tonic-gate 317c478bd9Sstevel@tonic-gate 327c478bd9Sstevel@tonic-gate /* 337c478bd9Sstevel@tonic-gate * Find elf or it's class from a pointer to an Elf_Data struct. 347c478bd9Sstevel@tonic-gate * Warning: this Assumes that the Elf_Data is part of a libelf 357c478bd9Sstevel@tonic-gate * Dnode structure, which is expected to be true for any Elf_Data 367c478bd9Sstevel@tonic-gate * passed into libelf *except* for the xlatetof() and xlatetom() functions. 377c478bd9Sstevel@tonic-gate */ 387c478bd9Sstevel@tonic-gate #define EDATA_CLASS(edata) \ 397c478bd9Sstevel@tonic-gate (((Dnode *)(edata))->db_scn->s_elf->ed_class) 407c478bd9Sstevel@tonic-gate 417c478bd9Sstevel@tonic-gate #define EDATA_ELF(edata) \ 427c478bd9Sstevel@tonic-gate (((Dnode *)(edata))->db_scn->s_elf) 437c478bd9Sstevel@tonic-gate 447c478bd9Sstevel@tonic-gate #define EDATA_SCN(edata) \ 457c478bd9Sstevel@tonic-gate (((Dnode *)(edata))->db_scn) 467c478bd9Sstevel@tonic-gate 477c478bd9Sstevel@tonic-gate #define EDATA_READLOCKS(edata) \ 487c478bd9Sstevel@tonic-gate READLOCKS(EDATA_ELF((edata)), EDATA_SCN((edata))) 497c478bd9Sstevel@tonic-gate 507c478bd9Sstevel@tonic-gate #define EDATA_READUNLOCKS(edata) \ 517c478bd9Sstevel@tonic-gate READUNLOCKS(EDATA_ELF((edata)), EDATA_SCN((edata))) 527c478bd9Sstevel@tonic-gate 537c478bd9Sstevel@tonic-gate 547c478bd9Sstevel@tonic-gate size_t 557c478bd9Sstevel@tonic-gate gelf_fsize(Elf * elf, Elf_Type type, size_t count, unsigned ver) 567c478bd9Sstevel@tonic-gate { 577c478bd9Sstevel@tonic-gate int class; 587c478bd9Sstevel@tonic-gate 597c478bd9Sstevel@tonic-gate if (elf == NULL) 607c478bd9Sstevel@tonic-gate return (0); 617c478bd9Sstevel@tonic-gate 627c478bd9Sstevel@tonic-gate class = gelf_getclass(elf); 637c478bd9Sstevel@tonic-gate if (class == ELFCLASS32) 647c478bd9Sstevel@tonic-gate return (elf32_fsize(type, count, ver)); 657c478bd9Sstevel@tonic-gate else if (class == ELFCLASS64) 667c478bd9Sstevel@tonic-gate return (elf64_fsize(type, count, ver)); 677c478bd9Sstevel@tonic-gate 687c478bd9Sstevel@tonic-gate _elf_seterr(EREQ_CLASS, 0); 697c478bd9Sstevel@tonic-gate return (0); 707c478bd9Sstevel@tonic-gate } 717c478bd9Sstevel@tonic-gate 727c478bd9Sstevel@tonic-gate 737c478bd9Sstevel@tonic-gate int 747c478bd9Sstevel@tonic-gate gelf_getclass(Elf *elf) 757c478bd9Sstevel@tonic-gate { 767c478bd9Sstevel@tonic-gate if (elf == NULL) 777c478bd9Sstevel@tonic-gate return (0); 787c478bd9Sstevel@tonic-gate 797c478bd9Sstevel@tonic-gate /* 807c478bd9Sstevel@tonic-gate * Don't rely on the idents, a new ehdr doesn't have it! 817c478bd9Sstevel@tonic-gate */ 827c478bd9Sstevel@tonic-gate return (elf->ed_class); 837c478bd9Sstevel@tonic-gate } 847c478bd9Sstevel@tonic-gate 857c478bd9Sstevel@tonic-gate 867c478bd9Sstevel@tonic-gate GElf_Ehdr * 877c478bd9Sstevel@tonic-gate gelf_getehdr(Elf *elf, GElf_Ehdr *dst) 887c478bd9Sstevel@tonic-gate { 897c478bd9Sstevel@tonic-gate int class; 907c478bd9Sstevel@tonic-gate 917c478bd9Sstevel@tonic-gate if (elf == NULL) 927c478bd9Sstevel@tonic-gate return (NULL); 937c478bd9Sstevel@tonic-gate 947c478bd9Sstevel@tonic-gate class = gelf_getclass(elf); 957c478bd9Sstevel@tonic-gate if (class == ELFCLASS32) { 967c478bd9Sstevel@tonic-gate Elf32_Ehdr * e = elf32_getehdr(elf); 977c478bd9Sstevel@tonic-gate 987c478bd9Sstevel@tonic-gate if (e == NULL) 997c478bd9Sstevel@tonic-gate return (NULL); 1007c478bd9Sstevel@tonic-gate 1017c478bd9Sstevel@tonic-gate ELFRLOCK(elf); 1027c478bd9Sstevel@tonic-gate (void) memcpy(dst->e_ident, e->e_ident, EI_NIDENT); 1037c478bd9Sstevel@tonic-gate dst->e_type = e->e_type; 1047c478bd9Sstevel@tonic-gate dst->e_machine = e->e_machine; 1057c478bd9Sstevel@tonic-gate dst->e_version = e->e_version; 1067c478bd9Sstevel@tonic-gate dst->e_entry = (Elf64_Addr)e->e_entry; 1077c478bd9Sstevel@tonic-gate dst->e_phoff = (Elf64_Off)e->e_phoff; 1087c478bd9Sstevel@tonic-gate dst->e_shoff = (Elf64_Off)e->e_shoff; 1097c478bd9Sstevel@tonic-gate dst->e_flags = e->e_flags; 1107c478bd9Sstevel@tonic-gate dst->e_ehsize = e->e_ehsize; 1117c478bd9Sstevel@tonic-gate dst->e_phentsize = e->e_phentsize; 1127c478bd9Sstevel@tonic-gate dst->e_phnum = e->e_phnum; 1137c478bd9Sstevel@tonic-gate dst->e_shentsize = e->e_shentsize; 1147c478bd9Sstevel@tonic-gate dst->e_shnum = e->e_shnum; 1157c478bd9Sstevel@tonic-gate dst->e_shstrndx = e->e_shstrndx; 1167c478bd9Sstevel@tonic-gate ELFUNLOCK(elf); 1177c478bd9Sstevel@tonic-gate 1187c478bd9Sstevel@tonic-gate return (dst); 1197c478bd9Sstevel@tonic-gate } else if (class == ELFCLASS64) { 1207c478bd9Sstevel@tonic-gate Elf64_Ehdr * e = elf64_getehdr(elf); 1217c478bd9Sstevel@tonic-gate 1227c478bd9Sstevel@tonic-gate if (e == NULL) 1237c478bd9Sstevel@tonic-gate return (NULL); 1247c478bd9Sstevel@tonic-gate 1257c478bd9Sstevel@tonic-gate ELFRLOCK(elf); 1267c478bd9Sstevel@tonic-gate *dst = *e; 1277c478bd9Sstevel@tonic-gate ELFUNLOCK(elf); 1287c478bd9Sstevel@tonic-gate 1297c478bd9Sstevel@tonic-gate return (dst); 1307c478bd9Sstevel@tonic-gate } 1317c478bd9Sstevel@tonic-gate 1327c478bd9Sstevel@tonic-gate _elf_seterr(EREQ_CLASS, 0); 1337c478bd9Sstevel@tonic-gate return (NULL); 1347c478bd9Sstevel@tonic-gate } 1357c478bd9Sstevel@tonic-gate 1367c478bd9Sstevel@tonic-gate 1377c478bd9Sstevel@tonic-gate int 1387c478bd9Sstevel@tonic-gate gelf_update_ehdr(Elf *elf, GElf_Ehdr *src) 1397c478bd9Sstevel@tonic-gate { 1407c478bd9Sstevel@tonic-gate int class; 1417c478bd9Sstevel@tonic-gate 1427c478bd9Sstevel@tonic-gate if (elf == NULL) 1437c478bd9Sstevel@tonic-gate return (0); 1447c478bd9Sstevel@tonic-gate 1457c478bd9Sstevel@tonic-gate /* 1467c478bd9Sstevel@tonic-gate * In case elf isn't cooked. 1477c478bd9Sstevel@tonic-gate */ 1487c478bd9Sstevel@tonic-gate class = gelf_getclass(elf); 1497c478bd9Sstevel@tonic-gate if (class == ELFCLASSNONE) 1507c478bd9Sstevel@tonic-gate class = src->e_ident[EI_CLASS]; 1517c478bd9Sstevel@tonic-gate 1527c478bd9Sstevel@tonic-gate 1537c478bd9Sstevel@tonic-gate if (class == ELFCLASS32) { 1547c478bd9Sstevel@tonic-gate Elf32_Ehdr * d = elf32_getehdr(elf); 1557c478bd9Sstevel@tonic-gate 1567c478bd9Sstevel@tonic-gate if (d == NULL) 1577c478bd9Sstevel@tonic-gate return (0); 1587c478bd9Sstevel@tonic-gate 1597c478bd9Sstevel@tonic-gate ELFWLOCK(elf); 1607c478bd9Sstevel@tonic-gate (void) memcpy(d->e_ident, src->e_ident, EI_NIDENT); 1617c478bd9Sstevel@tonic-gate d->e_type = src->e_type; 1627c478bd9Sstevel@tonic-gate d->e_machine = src->e_machine; 1637c478bd9Sstevel@tonic-gate d->e_version = src->e_version; 1647c478bd9Sstevel@tonic-gate /* LINTED */ 1657c478bd9Sstevel@tonic-gate d->e_entry = (Elf32_Addr)src->e_entry; 1667c478bd9Sstevel@tonic-gate /* LINTED */ 1677c478bd9Sstevel@tonic-gate d->e_phoff = (Elf32_Off)src->e_phoff; 1687c478bd9Sstevel@tonic-gate /* LINTED */ 1697c478bd9Sstevel@tonic-gate d->e_shoff = (Elf32_Off)src->e_shoff; 1707c478bd9Sstevel@tonic-gate /* could memcpy the rest of these... */ 1717c478bd9Sstevel@tonic-gate d->e_flags = src->e_flags; 1727c478bd9Sstevel@tonic-gate d->e_ehsize = src->e_ehsize; 1737c478bd9Sstevel@tonic-gate d->e_phentsize = src->e_phentsize; 1747c478bd9Sstevel@tonic-gate d->e_phnum = src->e_phnum; 1757c478bd9Sstevel@tonic-gate d->e_shentsize = src->e_shentsize; 1767c478bd9Sstevel@tonic-gate d->e_shnum = src->e_shnum; 1777c478bd9Sstevel@tonic-gate d->e_shstrndx = src->e_shstrndx; 1787c478bd9Sstevel@tonic-gate ELFUNLOCK(elf); 1797c478bd9Sstevel@tonic-gate 1807c478bd9Sstevel@tonic-gate return (1); 1817c478bd9Sstevel@tonic-gate } else if (class == ELFCLASS64) { 1827c478bd9Sstevel@tonic-gate Elf64_Ehdr * d = elf64_getehdr(elf); 1837c478bd9Sstevel@tonic-gate 1847c478bd9Sstevel@tonic-gate if (d == NULL) 1857c478bd9Sstevel@tonic-gate return (0); 1867c478bd9Sstevel@tonic-gate 1877c478bd9Sstevel@tonic-gate ELFWLOCK(elf); 1887c478bd9Sstevel@tonic-gate *d = *(Elf64_Ehdr *)src; 1897c478bd9Sstevel@tonic-gate ELFUNLOCK(elf); 1907c478bd9Sstevel@tonic-gate 1917c478bd9Sstevel@tonic-gate return (1); 1927c478bd9Sstevel@tonic-gate } 1937c478bd9Sstevel@tonic-gate 1947c478bd9Sstevel@tonic-gate _elf_seterr(EREQ_CLASS, 0); 1957c478bd9Sstevel@tonic-gate return (0); 1967c478bd9Sstevel@tonic-gate } 1977c478bd9Sstevel@tonic-gate 1987c478bd9Sstevel@tonic-gate 1997c478bd9Sstevel@tonic-gate unsigned long 2007c478bd9Sstevel@tonic-gate gelf_newehdr(Elf *elf, int class) 2017c478bd9Sstevel@tonic-gate { 2027c478bd9Sstevel@tonic-gate if (elf == NULL) 2037c478bd9Sstevel@tonic-gate return (0); 2047c478bd9Sstevel@tonic-gate 2057c478bd9Sstevel@tonic-gate if (class == ELFCLASS32) 2067c478bd9Sstevel@tonic-gate return ((unsigned long)elf32_newehdr(elf)); 2077c478bd9Sstevel@tonic-gate else if (class == ELFCLASS64) 2087c478bd9Sstevel@tonic-gate return ((unsigned long)elf64_newehdr(elf)); 2097c478bd9Sstevel@tonic-gate 2107c478bd9Sstevel@tonic-gate _elf_seterr(EREQ_CLASS, 0); 2117c478bd9Sstevel@tonic-gate return (0); 2127c478bd9Sstevel@tonic-gate } 2137c478bd9Sstevel@tonic-gate 2147c478bd9Sstevel@tonic-gate 2157c478bd9Sstevel@tonic-gate GElf_Phdr * 2167c478bd9Sstevel@tonic-gate gelf_getphdr(Elf *elf, int ndx, GElf_Phdr *dst) 2177c478bd9Sstevel@tonic-gate { 2187c478bd9Sstevel@tonic-gate int class; 21930da1432Sahl size_t phnum; 2207c478bd9Sstevel@tonic-gate 2217c478bd9Sstevel@tonic-gate if (elf == NULL) 2227c478bd9Sstevel@tonic-gate return (NULL); 2237c478bd9Sstevel@tonic-gate 224*62b628a6SAli Bahrami if (elf_getphdrnum(elf, &phnum) == -1) 2257c478bd9Sstevel@tonic-gate return (NULL); 2267c478bd9Sstevel@tonic-gate 22730da1432Sahl if (phnum <= ndx) { 2287c478bd9Sstevel@tonic-gate _elf_seterr(EREQ_RAND, 0); 2297c478bd9Sstevel@tonic-gate return (NULL); 2307c478bd9Sstevel@tonic-gate } 2317c478bd9Sstevel@tonic-gate 2327c478bd9Sstevel@tonic-gate class = gelf_getclass(elf); 2337c478bd9Sstevel@tonic-gate if ((class != ELFCLASS32) && (class != ELFCLASS64)) { 2347c478bd9Sstevel@tonic-gate _elf_seterr(EREQ_CLASS, 0); 2357c478bd9Sstevel@tonic-gate return (NULL); 2367c478bd9Sstevel@tonic-gate } 2377c478bd9Sstevel@tonic-gate 2387c478bd9Sstevel@tonic-gate if (class == ELFCLASS32) { 2397c478bd9Sstevel@tonic-gate Elf32_Phdr *p = &((Elf32_Phdr *)elf32_getphdr(elf))[ndx]; 2407c478bd9Sstevel@tonic-gate 2417c478bd9Sstevel@tonic-gate ELFRLOCK(elf); 2427c478bd9Sstevel@tonic-gate dst->p_type = p->p_type; 2437c478bd9Sstevel@tonic-gate dst->p_flags = p->p_flags; 2447c478bd9Sstevel@tonic-gate dst->p_offset = (Elf64_Off)p->p_offset; 2457c478bd9Sstevel@tonic-gate dst->p_vaddr = (Elf64_Addr)p->p_vaddr; 2467c478bd9Sstevel@tonic-gate dst->p_paddr = (Elf64_Addr)p->p_paddr; 2477c478bd9Sstevel@tonic-gate dst->p_filesz = (Elf64_Xword)p->p_filesz; 2487c478bd9Sstevel@tonic-gate dst->p_memsz = (Elf64_Xword)p->p_memsz; 2497c478bd9Sstevel@tonic-gate dst->p_align = (Elf64_Xword)p->p_align; 2507c478bd9Sstevel@tonic-gate ELFUNLOCK(elf); 2517c478bd9Sstevel@tonic-gate } else if (class == ELFCLASS64) { 2527c478bd9Sstevel@tonic-gate Elf64_Phdr *phdrs = elf64_getphdr(elf); 2537c478bd9Sstevel@tonic-gate ELFRLOCK(elf); 2547c478bd9Sstevel@tonic-gate *dst = ((GElf_Phdr *)phdrs)[ndx]; 2557c478bd9Sstevel@tonic-gate ELFUNLOCK(elf); 2567c478bd9Sstevel@tonic-gate } 2577c478bd9Sstevel@tonic-gate 2587c478bd9Sstevel@tonic-gate return (dst); 2597c478bd9Sstevel@tonic-gate } 2607c478bd9Sstevel@tonic-gate 2617c478bd9Sstevel@tonic-gate 2627c478bd9Sstevel@tonic-gate int 2637c478bd9Sstevel@tonic-gate gelf_update_phdr(Elf *elf, int ndx, GElf_Phdr *src) 2647c478bd9Sstevel@tonic-gate { 2657c478bd9Sstevel@tonic-gate int class; 26630da1432Sahl size_t phnum; 2677c478bd9Sstevel@tonic-gate 2687c478bd9Sstevel@tonic-gate if (elf == NULL) 2697c478bd9Sstevel@tonic-gate return (0); 2707c478bd9Sstevel@tonic-gate 271*62b628a6SAli Bahrami if (elf_getphdrnum(elf, &phnum) == -1) 27230da1432Sahl return (NULL); 2737c478bd9Sstevel@tonic-gate 27430da1432Sahl if (phnum < ndx) { 2757c478bd9Sstevel@tonic-gate _elf_seterr(EREQ_RAND, 0); 2767c478bd9Sstevel@tonic-gate return (0); 2777c478bd9Sstevel@tonic-gate } 2787c478bd9Sstevel@tonic-gate 2797c478bd9Sstevel@tonic-gate class = gelf_getclass(elf); 2807c478bd9Sstevel@tonic-gate if (class == ELFCLASS32) { 2817c478bd9Sstevel@tonic-gate Elf32_Phdr *dst = &((Elf32_Phdr *)elf32_getphdr(elf))[ndx]; 2827c478bd9Sstevel@tonic-gate ELFWLOCK(elf); 2837c478bd9Sstevel@tonic-gate dst->p_type = src->p_type; 2847c478bd9Sstevel@tonic-gate dst->p_flags = src->p_flags; 2857c478bd9Sstevel@tonic-gate /* LINTED */ 2867c478bd9Sstevel@tonic-gate dst->p_offset = (Elf32_Off)src->p_offset; 2877c478bd9Sstevel@tonic-gate /* LINTED */ 2887c478bd9Sstevel@tonic-gate dst->p_vaddr = (Elf32_Addr)src->p_vaddr; 2897c478bd9Sstevel@tonic-gate /* LINTED */ 2907c478bd9Sstevel@tonic-gate dst->p_paddr = (Elf32_Addr)src->p_paddr; 2917c478bd9Sstevel@tonic-gate /* LINTED */ 2927c478bd9Sstevel@tonic-gate dst->p_filesz = (Elf32_Word)src->p_filesz; 2937c478bd9Sstevel@tonic-gate /* LINTED */ 2947c478bd9Sstevel@tonic-gate dst->p_memsz = (Elf32_Word)src->p_memsz; 2957c478bd9Sstevel@tonic-gate /* LINTED */ 2967c478bd9Sstevel@tonic-gate dst->p_align = (Elf32_Word)src->p_align; 2977c478bd9Sstevel@tonic-gate ELFUNLOCK(elf); 2987c478bd9Sstevel@tonic-gate } else if (class == ELFCLASS64) { 2997c478bd9Sstevel@tonic-gate Elf64_Phdr *dst = elf64_getphdr(elf); 3007c478bd9Sstevel@tonic-gate ELFWLOCK(elf); 3017c478bd9Sstevel@tonic-gate dst[ndx] = *(GElf_Phdr *)src; 3027c478bd9Sstevel@tonic-gate ELFUNLOCK(elf); 3037c478bd9Sstevel@tonic-gate } else { 3047c478bd9Sstevel@tonic-gate _elf_seterr(EREQ_CLASS, 0); 3057c478bd9Sstevel@tonic-gate return (0); 3067c478bd9Sstevel@tonic-gate } 3077c478bd9Sstevel@tonic-gate return (1); 3087c478bd9Sstevel@tonic-gate } 3097c478bd9Sstevel@tonic-gate 3107c478bd9Sstevel@tonic-gate 3117c478bd9Sstevel@tonic-gate unsigned long 3127c478bd9Sstevel@tonic-gate gelf_newphdr(Elf *elf, size_t phnum) 3137c478bd9Sstevel@tonic-gate { 3147c478bd9Sstevel@tonic-gate int class; 3157c478bd9Sstevel@tonic-gate 3167c478bd9Sstevel@tonic-gate if (elf == NULL) 3177c478bd9Sstevel@tonic-gate return (0); 3187c478bd9Sstevel@tonic-gate 3197c478bd9Sstevel@tonic-gate class = gelf_getclass(elf); 3207c478bd9Sstevel@tonic-gate if (class == ELFCLASS32) 3217c478bd9Sstevel@tonic-gate return ((unsigned long)elf32_newphdr(elf, phnum)); 3227c478bd9Sstevel@tonic-gate else if (class == ELFCLASS64) 3237c478bd9Sstevel@tonic-gate return ((unsigned long)elf64_newphdr(elf, phnum)); 3247c478bd9Sstevel@tonic-gate 3257c478bd9Sstevel@tonic-gate _elf_seterr(EREQ_CLASS, 0); 3267c478bd9Sstevel@tonic-gate return (0); 3277c478bd9Sstevel@tonic-gate } 3287c478bd9Sstevel@tonic-gate 3297c478bd9Sstevel@tonic-gate 3307c478bd9Sstevel@tonic-gate GElf_Shdr * 3317c478bd9Sstevel@tonic-gate gelf_getshdr(Elf_Scn *scn, GElf_Shdr *dst) 3327c478bd9Sstevel@tonic-gate { 3337c478bd9Sstevel@tonic-gate if (scn == NULL) 3347c478bd9Sstevel@tonic-gate return (NULL); 3357c478bd9Sstevel@tonic-gate 3367c478bd9Sstevel@tonic-gate if (scn->s_elf->ed_class == ELFCLASS32) { 3377c478bd9Sstevel@tonic-gate Elf32_Shdr *s = elf32_getshdr(scn); 3387c478bd9Sstevel@tonic-gate 3397c478bd9Sstevel@tonic-gate if (s == NULL) 3407c478bd9Sstevel@tonic-gate return (NULL); 3417c478bd9Sstevel@tonic-gate 3427c478bd9Sstevel@tonic-gate READLOCKS(scn->s_elf, scn); 3437c478bd9Sstevel@tonic-gate dst->sh_name = s->sh_name; 3447c478bd9Sstevel@tonic-gate dst->sh_type = s->sh_type; 3457c478bd9Sstevel@tonic-gate dst->sh_flags = (Elf64_Xword)s->sh_flags; 3467c478bd9Sstevel@tonic-gate dst->sh_addr = (Elf64_Addr)s->sh_addr; 3477c478bd9Sstevel@tonic-gate dst->sh_offset = (Elf64_Off)s->sh_offset; 3487c478bd9Sstevel@tonic-gate dst->sh_size = (Elf64_Xword)s->sh_size; 3497c478bd9Sstevel@tonic-gate dst->sh_link = s->sh_link; 3507c478bd9Sstevel@tonic-gate dst->sh_info = s->sh_info; 3517c478bd9Sstevel@tonic-gate dst->sh_addralign = (Elf64_Xword)s->sh_addralign; 3527c478bd9Sstevel@tonic-gate dst->sh_entsize = (Elf64_Xword)s->sh_entsize; 3537c478bd9Sstevel@tonic-gate READUNLOCKS(scn->s_elf, scn); 3547c478bd9Sstevel@tonic-gate 3557c478bd9Sstevel@tonic-gate return (dst); 3567c478bd9Sstevel@tonic-gate } else if (scn->s_elf->ed_class == ELFCLASS64) { 3577c478bd9Sstevel@tonic-gate Elf64_Shdr *s = elf64_getshdr(scn); 3587c478bd9Sstevel@tonic-gate 3597c478bd9Sstevel@tonic-gate if (s == NULL) 3607c478bd9Sstevel@tonic-gate return (NULL); 3617c478bd9Sstevel@tonic-gate 3627c478bd9Sstevel@tonic-gate READLOCKS(scn->s_elf, scn); 3637c478bd9Sstevel@tonic-gate *dst = *(Elf64_Shdr *)s; 3647c478bd9Sstevel@tonic-gate READUNLOCKS(scn->s_elf, scn); 3657c478bd9Sstevel@tonic-gate 3667c478bd9Sstevel@tonic-gate return (dst); 3677c478bd9Sstevel@tonic-gate } 3687c478bd9Sstevel@tonic-gate 3697c478bd9Sstevel@tonic-gate _elf_seterr(EREQ_CLASS, 0); 3707c478bd9Sstevel@tonic-gate return (NULL); 3717c478bd9Sstevel@tonic-gate } 3727c478bd9Sstevel@tonic-gate 3737c478bd9Sstevel@tonic-gate 3747c478bd9Sstevel@tonic-gate int 3757c478bd9Sstevel@tonic-gate gelf_update_shdr(Elf_Scn *scn, GElf_Shdr *src) 3767c478bd9Sstevel@tonic-gate { 3777c478bd9Sstevel@tonic-gate if (scn == NULL) 3787c478bd9Sstevel@tonic-gate return (0); 3797c478bd9Sstevel@tonic-gate 3807c478bd9Sstevel@tonic-gate if (scn->s_elf->ed_class == ELFCLASS32) { 3817c478bd9Sstevel@tonic-gate Elf32_Shdr *dst = elf32_getshdr(scn); 3827c478bd9Sstevel@tonic-gate 3837c478bd9Sstevel@tonic-gate if (dst == NULL) 3847c478bd9Sstevel@tonic-gate return (0); 3857c478bd9Sstevel@tonic-gate 3867c478bd9Sstevel@tonic-gate ELFWLOCK(scn->s_elf); 3877c478bd9Sstevel@tonic-gate dst->sh_name = src->sh_name; 3887c478bd9Sstevel@tonic-gate dst->sh_type = src->sh_type; 3897c478bd9Sstevel@tonic-gate /* LINTED */ 3907c478bd9Sstevel@tonic-gate dst->sh_flags = (Elf32_Word)src->sh_flags; 3917c478bd9Sstevel@tonic-gate /* LINTED */ 3927c478bd9Sstevel@tonic-gate dst->sh_addr = (Elf32_Addr)src->sh_addr; 3937c478bd9Sstevel@tonic-gate /* LINTED */ 3947c478bd9Sstevel@tonic-gate dst->sh_offset = (Elf32_Off) src->sh_offset; 3957c478bd9Sstevel@tonic-gate /* LINTED */ 3967c478bd9Sstevel@tonic-gate dst->sh_size = (Elf32_Word)src->sh_size; 3977c478bd9Sstevel@tonic-gate dst->sh_link = src->sh_link; 3987c478bd9Sstevel@tonic-gate dst->sh_info = src->sh_info; 3997c478bd9Sstevel@tonic-gate /* LINTED */ 4007c478bd9Sstevel@tonic-gate dst->sh_addralign = (Elf32_Word)src->sh_addralign; 4017c478bd9Sstevel@tonic-gate /* LINTED */ 4027c478bd9Sstevel@tonic-gate dst->sh_entsize = (Elf32_Word)src->sh_entsize; 4037c478bd9Sstevel@tonic-gate 4047c478bd9Sstevel@tonic-gate ELFUNLOCK(scn->s_elf); 4057c478bd9Sstevel@tonic-gate return (1); 4067c478bd9Sstevel@tonic-gate } else if (scn->s_elf->ed_class == ELFCLASS64) { 4077c478bd9Sstevel@tonic-gate Elf64_Shdr * dst = elf64_getshdr(scn); 4087c478bd9Sstevel@tonic-gate 4097c478bd9Sstevel@tonic-gate if (dst == NULL) 4107c478bd9Sstevel@tonic-gate return (0); 4117c478bd9Sstevel@tonic-gate 4127c478bd9Sstevel@tonic-gate ELFWLOCK(scn->s_elf); 4137c478bd9Sstevel@tonic-gate *dst = *(Elf64_Shdr *)src; 4147c478bd9Sstevel@tonic-gate ELFUNLOCK(scn->s_elf); 4157c478bd9Sstevel@tonic-gate return (1); 4167c478bd9Sstevel@tonic-gate } 4177c478bd9Sstevel@tonic-gate 4187c478bd9Sstevel@tonic-gate _elf_seterr(EREQ_CLASS, 0); 4197c478bd9Sstevel@tonic-gate return (0); 4207c478bd9Sstevel@tonic-gate } 4217c478bd9Sstevel@tonic-gate 4227c478bd9Sstevel@tonic-gate 4237c478bd9Sstevel@tonic-gate /* 4247c478bd9Sstevel@tonic-gate * gelf_xlatetof/gelf_xlatetom use 'elf' to find the class 4257c478bd9Sstevel@tonic-gate * because these are the odd case where the Elf_Data structs 4267c478bd9Sstevel@tonic-gate * might not have been allocated by libelf (and therefore 4277c478bd9Sstevel@tonic-gate * don't have Dnode's associated with them). 4287c478bd9Sstevel@tonic-gate */ 4297c478bd9Sstevel@tonic-gate Elf_Data * 4307c478bd9Sstevel@tonic-gate gelf_xlatetof(Elf *elf, Elf_Data *dst, const Elf_Data *src, unsigned encode) 4317c478bd9Sstevel@tonic-gate { 4327c478bd9Sstevel@tonic-gate int class; 4337c478bd9Sstevel@tonic-gate 4347c478bd9Sstevel@tonic-gate if ((elf == NULL) || (dst == NULL) || (src == NULL)) 4357c478bd9Sstevel@tonic-gate return (NULL); 4367c478bd9Sstevel@tonic-gate 4377c478bd9Sstevel@tonic-gate class = gelf_getclass(elf); 4387c478bd9Sstevel@tonic-gate if (class == ELFCLASS32) 4397c478bd9Sstevel@tonic-gate return (elf32_xlatetof(dst, src, encode)); 4407c478bd9Sstevel@tonic-gate else if (class == ELFCLASS64) 4417c478bd9Sstevel@tonic-gate return (elf64_xlatetof(dst, src, encode)); 4427c478bd9Sstevel@tonic-gate 4437c478bd9Sstevel@tonic-gate _elf_seterr(EREQ_CLASS, 0); 4447c478bd9Sstevel@tonic-gate return (NULL); 4457c478bd9Sstevel@tonic-gate } 4467c478bd9Sstevel@tonic-gate 4477c478bd9Sstevel@tonic-gate 4487c478bd9Sstevel@tonic-gate Elf_Data * 4497c478bd9Sstevel@tonic-gate gelf_xlatetom(Elf *elf, Elf_Data *dst, const Elf_Data *src, unsigned encode) 4507c478bd9Sstevel@tonic-gate { 4517c478bd9Sstevel@tonic-gate int class; 4527c478bd9Sstevel@tonic-gate 4537c478bd9Sstevel@tonic-gate if ((elf == NULL) || (dst == NULL) || (src == NULL)) 4547c478bd9Sstevel@tonic-gate return (NULL); 4557c478bd9Sstevel@tonic-gate 4567c478bd9Sstevel@tonic-gate class = gelf_getclass(elf); 4577c478bd9Sstevel@tonic-gate if (class == ELFCLASS32) 4587c478bd9Sstevel@tonic-gate return (elf32_xlatetom(dst, src, encode)); 4597c478bd9Sstevel@tonic-gate else if (class == ELFCLASS64) 4607c478bd9Sstevel@tonic-gate return (elf64_xlatetom(dst, src, encode)); 4617c478bd9Sstevel@tonic-gate 4627c478bd9Sstevel@tonic-gate _elf_seterr(EREQ_CLASS, 0); 4637c478bd9Sstevel@tonic-gate return (NULL); 4647c478bd9Sstevel@tonic-gate } 4657c478bd9Sstevel@tonic-gate 4667c478bd9Sstevel@tonic-gate 4677c478bd9Sstevel@tonic-gate GElf_Sym * 4687c478bd9Sstevel@tonic-gate gelf_getsym(Elf_Data * data, int ndx, GElf_Sym * dst) 4697c478bd9Sstevel@tonic-gate { 4707c478bd9Sstevel@tonic-gate int class; 4717c478bd9Sstevel@tonic-gate size_t entsize; 4727c478bd9Sstevel@tonic-gate 4737c478bd9Sstevel@tonic-gate if (data == NULL) 4747c478bd9Sstevel@tonic-gate return (NULL); 4757c478bd9Sstevel@tonic-gate 4767c478bd9Sstevel@tonic-gate class = EDATA_CLASS(data); 4777c478bd9Sstevel@tonic-gate if (class == ELFCLASS32) 4787c478bd9Sstevel@tonic-gate entsize = sizeof (Elf32_Sym); 4797c478bd9Sstevel@tonic-gate else if (class == ELFCLASS64) 4807c478bd9Sstevel@tonic-gate entsize = sizeof (GElf_Sym); 4817c478bd9Sstevel@tonic-gate else { 4827c478bd9Sstevel@tonic-gate _elf_seterr(EREQ_CLASS, 0); 4837c478bd9Sstevel@tonic-gate return (NULL); 4847c478bd9Sstevel@tonic-gate } 4857c478bd9Sstevel@tonic-gate 4867c478bd9Sstevel@tonic-gate EDATA_READLOCKS(data); 4877c478bd9Sstevel@tonic-gate 488f7ba47a3Sab196087 if ((entsize * ndx) >= data->d_size) { 4897c478bd9Sstevel@tonic-gate _elf_seterr(EREQ_RAND, 0); 4907c478bd9Sstevel@tonic-gate dst = NULL; 4917c478bd9Sstevel@tonic-gate } else if (class == ELFCLASS32) { 4927c478bd9Sstevel@tonic-gate Elf32_Sym *s; 4937c478bd9Sstevel@tonic-gate s = &(((Elf32_Sym *)data->d_buf)[ndx]); 4947c478bd9Sstevel@tonic-gate dst->st_name = s->st_name; 4957c478bd9Sstevel@tonic-gate dst->st_value = (Elf64_Addr)s->st_value; 4967c478bd9Sstevel@tonic-gate dst->st_size = (Elf64_Xword)s->st_size; 4977c478bd9Sstevel@tonic-gate dst->st_info = ELF64_ST_INFO(ELF32_ST_BIND(s->st_info), 4987c478bd9Sstevel@tonic-gate ELF32_ST_TYPE(s->st_info)); 4997c478bd9Sstevel@tonic-gate dst->st_other = s->st_other; 5007c478bd9Sstevel@tonic-gate dst->st_shndx = s->st_shndx; 5017c478bd9Sstevel@tonic-gate } else 5027c478bd9Sstevel@tonic-gate *dst = ((GElf_Sym *)data->d_buf)[ndx]; 5037c478bd9Sstevel@tonic-gate 5047c478bd9Sstevel@tonic-gate EDATA_READUNLOCKS(data); 5057c478bd9Sstevel@tonic-gate return (dst); 5067c478bd9Sstevel@tonic-gate } 5077c478bd9Sstevel@tonic-gate 5087c478bd9Sstevel@tonic-gate 5097c478bd9Sstevel@tonic-gate int 5107c478bd9Sstevel@tonic-gate gelf_update_sym(Elf_Data *dst, int ndx, GElf_Sym *src) 5117c478bd9Sstevel@tonic-gate { 5127c478bd9Sstevel@tonic-gate int class, rc = 1; 5137c478bd9Sstevel@tonic-gate size_t entsize; 5147c478bd9Sstevel@tonic-gate 5157c478bd9Sstevel@tonic-gate if (dst == NULL) 5167c478bd9Sstevel@tonic-gate return (0); 5177c478bd9Sstevel@tonic-gate 5187c478bd9Sstevel@tonic-gate class = EDATA_CLASS(dst); 5197c478bd9Sstevel@tonic-gate if (class == ELFCLASS32) 5207c478bd9Sstevel@tonic-gate entsize = sizeof (Elf32_Sym); 5217c478bd9Sstevel@tonic-gate else if (class == ELFCLASS64) 5227c478bd9Sstevel@tonic-gate entsize = sizeof (GElf_Sym); 5237c478bd9Sstevel@tonic-gate else { 5247c478bd9Sstevel@tonic-gate _elf_seterr(EREQ_CLASS, 0); 5257c478bd9Sstevel@tonic-gate return (0); 5267c478bd9Sstevel@tonic-gate } 5277c478bd9Sstevel@tonic-gate 5287c478bd9Sstevel@tonic-gate ELFWLOCK(EDATA_ELF(dst)); 5297c478bd9Sstevel@tonic-gate 530f7ba47a3Sab196087 if ((entsize * ndx) >= dst->d_size) { 5317c478bd9Sstevel@tonic-gate _elf_seterr(EREQ_RAND, 0); 5327c478bd9Sstevel@tonic-gate rc = 0; 5337c478bd9Sstevel@tonic-gate } else if (class == ELFCLASS32) { 5347c478bd9Sstevel@tonic-gate Elf32_Sym * d; 5357c478bd9Sstevel@tonic-gate 5367c478bd9Sstevel@tonic-gate d = &(((Elf32_Sym *)dst->d_buf)[ndx]); 5377c478bd9Sstevel@tonic-gate d->st_name = src->st_name; 5387c478bd9Sstevel@tonic-gate /* LINTED */ 5397c478bd9Sstevel@tonic-gate d->st_value = (Elf32_Addr)src->st_value; 5407c478bd9Sstevel@tonic-gate /* LINTED */ 5417c478bd9Sstevel@tonic-gate d->st_size = (Elf32_Word)src->st_size; 5427c478bd9Sstevel@tonic-gate d->st_info = ELF32_ST_INFO(ELF64_ST_BIND(src->st_info), 5437c478bd9Sstevel@tonic-gate ELF64_ST_TYPE(src->st_info)); 5447c478bd9Sstevel@tonic-gate d->st_other = src->st_other; 5457c478bd9Sstevel@tonic-gate d->st_shndx = src->st_shndx; 5467c478bd9Sstevel@tonic-gate } else 5477c478bd9Sstevel@tonic-gate ((Elf64_Sym *)dst->d_buf)[ndx] = *((Elf64_Sym *)src); 5487c478bd9Sstevel@tonic-gate 5497c478bd9Sstevel@tonic-gate ELFUNLOCK(EDATA_ELF(dst)); 5507c478bd9Sstevel@tonic-gate return (rc); 5517c478bd9Sstevel@tonic-gate } 5527c478bd9Sstevel@tonic-gate 5537c478bd9Sstevel@tonic-gate 5547c478bd9Sstevel@tonic-gate GElf_Syminfo * 5557c478bd9Sstevel@tonic-gate gelf_getsyminfo(Elf_Data *data, int ndx, GElf_Syminfo *dst) 5567c478bd9Sstevel@tonic-gate { 5577c478bd9Sstevel@tonic-gate int class; 5587c478bd9Sstevel@tonic-gate size_t entsize; 5597c478bd9Sstevel@tonic-gate 5607c478bd9Sstevel@tonic-gate if (data == NULL) 5617c478bd9Sstevel@tonic-gate return (NULL); 5627c478bd9Sstevel@tonic-gate 5637c478bd9Sstevel@tonic-gate class = EDATA_CLASS(data); 5647c478bd9Sstevel@tonic-gate if (class == ELFCLASS32) 5657c478bd9Sstevel@tonic-gate entsize = sizeof (Elf32_Syminfo); 5667c478bd9Sstevel@tonic-gate else if (class == ELFCLASS64) 5677c478bd9Sstevel@tonic-gate entsize = sizeof (GElf_Syminfo); 5687c478bd9Sstevel@tonic-gate else { 5697c478bd9Sstevel@tonic-gate _elf_seterr(EREQ_CLASS, 0); 5707c478bd9Sstevel@tonic-gate return (NULL); 5717c478bd9Sstevel@tonic-gate } 5727c478bd9Sstevel@tonic-gate EDATA_READLOCKS(data); 5737c478bd9Sstevel@tonic-gate 574f7ba47a3Sab196087 if ((entsize * ndx) >= data->d_size) { 5757c478bd9Sstevel@tonic-gate _elf_seterr(EREQ_RAND, 0); 5767c478bd9Sstevel@tonic-gate dst = NULL; 5777c478bd9Sstevel@tonic-gate } else if (class == ELFCLASS32) { 5787c478bd9Sstevel@tonic-gate Elf32_Syminfo * si; 5797c478bd9Sstevel@tonic-gate 5807c478bd9Sstevel@tonic-gate si = &(((Elf32_Syminfo *)data->d_buf)[ndx]); 5817c478bd9Sstevel@tonic-gate dst->si_boundto = si->si_boundto; 5827c478bd9Sstevel@tonic-gate dst->si_flags = si->si_flags; 5837c478bd9Sstevel@tonic-gate } else 5847c478bd9Sstevel@tonic-gate *dst = ((GElf_Syminfo *)data->d_buf)[ndx]; 5857c478bd9Sstevel@tonic-gate 5867c478bd9Sstevel@tonic-gate EDATA_READUNLOCKS(data); 5877c478bd9Sstevel@tonic-gate return (dst); 5887c478bd9Sstevel@tonic-gate } 5897c478bd9Sstevel@tonic-gate 5907c478bd9Sstevel@tonic-gate int 5917c478bd9Sstevel@tonic-gate gelf_update_syminfo(Elf_Data *dst, int ndx, GElf_Syminfo *src) 5927c478bd9Sstevel@tonic-gate { 5937c478bd9Sstevel@tonic-gate int class, rc = 1; 5947c478bd9Sstevel@tonic-gate size_t entsize; 5957c478bd9Sstevel@tonic-gate 5967c478bd9Sstevel@tonic-gate if (dst == NULL) 5977c478bd9Sstevel@tonic-gate return (0); 5987c478bd9Sstevel@tonic-gate 5997c478bd9Sstevel@tonic-gate class = EDATA_CLASS(dst); 6007c478bd9Sstevel@tonic-gate if (class == ELFCLASS32) 6017c478bd9Sstevel@tonic-gate entsize = sizeof (Elf32_Syminfo); 6027c478bd9Sstevel@tonic-gate else if (class == ELFCLASS64) 6037c478bd9Sstevel@tonic-gate entsize = sizeof (GElf_Syminfo); 6047c478bd9Sstevel@tonic-gate else { 6057c478bd9Sstevel@tonic-gate _elf_seterr(EREQ_CLASS, 0); 6067c478bd9Sstevel@tonic-gate return (0); 6077c478bd9Sstevel@tonic-gate } 6087c478bd9Sstevel@tonic-gate ELFWLOCK(EDATA_ELF(dst)); 6097c478bd9Sstevel@tonic-gate 610f7ba47a3Sab196087 if ((entsize * ndx) >= dst->d_size) { 6117c478bd9Sstevel@tonic-gate _elf_seterr(EREQ_RAND, 0); 6127c478bd9Sstevel@tonic-gate rc = 0; 6137c478bd9Sstevel@tonic-gate } else if (class == ELFCLASS32) { 6147c478bd9Sstevel@tonic-gate Elf32_Syminfo * d = &(((Elf32_Syminfo *)dst->d_buf)[ndx]); 6157c478bd9Sstevel@tonic-gate d->si_boundto = src->si_boundto; 6167c478bd9Sstevel@tonic-gate d->si_flags = src->si_flags; 6177c478bd9Sstevel@tonic-gate } else 6187c478bd9Sstevel@tonic-gate ((Elf64_Syminfo *)dst->d_buf)[ndx] = *((Elf64_Syminfo *)src); 6197c478bd9Sstevel@tonic-gate 6207c478bd9Sstevel@tonic-gate ELFUNLOCK(EDATA_ELF(dst)); 6217c478bd9Sstevel@tonic-gate return (rc); 6227c478bd9Sstevel@tonic-gate } 6237c478bd9Sstevel@tonic-gate 6247c478bd9Sstevel@tonic-gate GElf_Dyn * 6257c478bd9Sstevel@tonic-gate gelf_getdyn(Elf_Data *data, int ndx, GElf_Dyn *dst) 6267c478bd9Sstevel@tonic-gate { 6277c478bd9Sstevel@tonic-gate int class; 6287c478bd9Sstevel@tonic-gate size_t entsize; 6297c478bd9Sstevel@tonic-gate 6307c478bd9Sstevel@tonic-gate if (data == NULL) 6317c478bd9Sstevel@tonic-gate return (NULL); 6327c478bd9Sstevel@tonic-gate 6337c478bd9Sstevel@tonic-gate class = EDATA_CLASS(data); 6347c478bd9Sstevel@tonic-gate if (class == ELFCLASS32) 6357c478bd9Sstevel@tonic-gate entsize = sizeof (Elf32_Dyn); 6367c478bd9Sstevel@tonic-gate else if (class == ELFCLASS64) 6377c478bd9Sstevel@tonic-gate entsize = sizeof (GElf_Dyn); 6387c478bd9Sstevel@tonic-gate else { 6397c478bd9Sstevel@tonic-gate _elf_seterr(EREQ_CLASS, 0); 6407c478bd9Sstevel@tonic-gate return (NULL); 6417c478bd9Sstevel@tonic-gate } 6427c478bd9Sstevel@tonic-gate EDATA_READLOCKS(data); 6437c478bd9Sstevel@tonic-gate 644f7ba47a3Sab196087 if ((entsize * ndx) >= data->d_size) { 6457c478bd9Sstevel@tonic-gate _elf_seterr(EREQ_RAND, 0); 6467c478bd9Sstevel@tonic-gate dst = NULL; 6477c478bd9Sstevel@tonic-gate } else if (class == ELFCLASS32) { 6487c478bd9Sstevel@tonic-gate Elf32_Dyn * d = &((Elf32_Dyn *)data->d_buf)[ndx]; 6497c478bd9Sstevel@tonic-gate 6507c478bd9Sstevel@tonic-gate dst->d_tag = (Elf32_Sword)d->d_tag; 6517c478bd9Sstevel@tonic-gate dst->d_un.d_val = (Elf32_Word) d->d_un.d_val; 6527c478bd9Sstevel@tonic-gate } else 6537c478bd9Sstevel@tonic-gate *dst = ((Elf64_Dyn *)data->d_buf)[ndx]; 6547c478bd9Sstevel@tonic-gate 6557c478bd9Sstevel@tonic-gate EDATA_READUNLOCKS(data); 6567c478bd9Sstevel@tonic-gate return (dst); 6577c478bd9Sstevel@tonic-gate } 6587c478bd9Sstevel@tonic-gate 6597c478bd9Sstevel@tonic-gate 6607c478bd9Sstevel@tonic-gate int 6617c478bd9Sstevel@tonic-gate gelf_update_dyn(Elf_Data *dst, int ndx, GElf_Dyn *src) 6627c478bd9Sstevel@tonic-gate { 6637c478bd9Sstevel@tonic-gate int class, rc = 1; 6647c478bd9Sstevel@tonic-gate size_t entsize; 6657c478bd9Sstevel@tonic-gate 6667c478bd9Sstevel@tonic-gate if (dst == NULL) 6677c478bd9Sstevel@tonic-gate return (0); 6687c478bd9Sstevel@tonic-gate 6697c478bd9Sstevel@tonic-gate class = EDATA_CLASS(dst); 6707c478bd9Sstevel@tonic-gate if (class == ELFCLASS32) 6717c478bd9Sstevel@tonic-gate entsize = sizeof (Elf32_Dyn); 6727c478bd9Sstevel@tonic-gate else if (class == ELFCLASS64) 6737c478bd9Sstevel@tonic-gate entsize = sizeof (GElf_Dyn); 6747c478bd9Sstevel@tonic-gate else { 6757c478bd9Sstevel@tonic-gate _elf_seterr(EREQ_CLASS, 0); 6767c478bd9Sstevel@tonic-gate return (0); 6777c478bd9Sstevel@tonic-gate } 6787c478bd9Sstevel@tonic-gate ELFWLOCK(EDATA_ELF(dst)); 6797c478bd9Sstevel@tonic-gate 680f7ba47a3Sab196087 if ((entsize * ndx) >= dst->d_size) { 6817c478bd9Sstevel@tonic-gate _elf_seterr(EREQ_RAND, 0); 6827c478bd9Sstevel@tonic-gate rc = 0; 6837c478bd9Sstevel@tonic-gate } else if (class == ELFCLASS32) { 6847c478bd9Sstevel@tonic-gate Elf32_Dyn * d = &((Elf32_Dyn *)dst->d_buf)[ndx]; 6857c478bd9Sstevel@tonic-gate 6867c478bd9Sstevel@tonic-gate /* LINTED */ 6877c478bd9Sstevel@tonic-gate d->d_tag = (Elf32_Word)src->d_tag; 6887c478bd9Sstevel@tonic-gate /* LINTED */ 6897c478bd9Sstevel@tonic-gate d->d_un.d_val = (Elf32_Word)src->d_un.d_val; 6907c478bd9Sstevel@tonic-gate } else 6917c478bd9Sstevel@tonic-gate ((Elf64_Dyn *)dst->d_buf)[ndx] = *(Elf64_Dyn*)src; 6927c478bd9Sstevel@tonic-gate 6937c478bd9Sstevel@tonic-gate ELFUNLOCK(EDATA_ELF(dst)); 6947c478bd9Sstevel@tonic-gate return (rc); 6957c478bd9Sstevel@tonic-gate } 6967c478bd9Sstevel@tonic-gate 6977c478bd9Sstevel@tonic-gate 6987c478bd9Sstevel@tonic-gate 6997c478bd9Sstevel@tonic-gate GElf_Sym * 7007c478bd9Sstevel@tonic-gate gelf_getsymshndx(Elf_Data *symdata, Elf_Data *shndxdata, 7017c478bd9Sstevel@tonic-gate int ndx, GElf_Sym *symptr, Elf32_Word *xshndx) 7027c478bd9Sstevel@tonic-gate { 7037c478bd9Sstevel@tonic-gate if (gelf_getsym(symdata, ndx, symptr) == 0) 7047c478bd9Sstevel@tonic-gate return (NULL); 7057c478bd9Sstevel@tonic-gate if (shndxdata && xshndx) { 7067c478bd9Sstevel@tonic-gate EDATA_READLOCKS(shndxdata); 707f7ba47a3Sab196087 if ((ndx * sizeof (Elf32_Word)) >= shndxdata->d_size) { 7087c478bd9Sstevel@tonic-gate _elf_seterr(EREQ_RAND, 0); 7097c478bd9Sstevel@tonic-gate EDATA_READUNLOCKS(shndxdata); 7107c478bd9Sstevel@tonic-gate return (NULL); 7117c478bd9Sstevel@tonic-gate } 7127c478bd9Sstevel@tonic-gate *xshndx = (((Elf32_Word *)shndxdata->d_buf)[ndx]); 7137c478bd9Sstevel@tonic-gate EDATA_READUNLOCKS(shndxdata); 7147c478bd9Sstevel@tonic-gate } else { 7157c478bd9Sstevel@tonic-gate *xshndx = 0; 7167c478bd9Sstevel@tonic-gate } 7177c478bd9Sstevel@tonic-gate return (symptr); 7187c478bd9Sstevel@tonic-gate } 7197c478bd9Sstevel@tonic-gate 7207c478bd9Sstevel@tonic-gate int 7217c478bd9Sstevel@tonic-gate gelf_update_symshndx(Elf_Data *symdata, Elf_Data *shndxdata, 7227c478bd9Sstevel@tonic-gate int ndx, GElf_Sym *symptr, Elf32_Word xshndx) 7237c478bd9Sstevel@tonic-gate { 7247c478bd9Sstevel@tonic-gate if (gelf_update_sym(symdata, ndx, symptr) == 0) 7257c478bd9Sstevel@tonic-gate return (0); 7267c478bd9Sstevel@tonic-gate if (shndxdata) { 7277c478bd9Sstevel@tonic-gate ELFWLOCK(EDATA_ELF(shndxdata)); 728f7ba47a3Sab196087 if ((ndx * sizeof (Elf32_Word)) >= shndxdata->d_size) { 7297c478bd9Sstevel@tonic-gate _elf_seterr(EREQ_RAND, 0); 7307c478bd9Sstevel@tonic-gate ELFUNLOCK(EDATA_ELF(shndxdata)); 7317c478bd9Sstevel@tonic-gate return (0); 7327c478bd9Sstevel@tonic-gate } 7337c478bd9Sstevel@tonic-gate ((Elf32_Word *)shndxdata->d_buf)[ndx] = xshndx; 7347c478bd9Sstevel@tonic-gate ELFUNLOCK(EDATA_ELF(shndxdata)); 7357c478bd9Sstevel@tonic-gate } 7367c478bd9Sstevel@tonic-gate return (1); 7377c478bd9Sstevel@tonic-gate } 7387c478bd9Sstevel@tonic-gate 7397c478bd9Sstevel@tonic-gate 7407c478bd9Sstevel@tonic-gate GElf_Move * 7417c478bd9Sstevel@tonic-gate gelf_getmove(Elf_Data *src, int ndx, GElf_Move *dst) 7427c478bd9Sstevel@tonic-gate { 7437c478bd9Sstevel@tonic-gate int class; 7447c478bd9Sstevel@tonic-gate size_t entsize; 7457c478bd9Sstevel@tonic-gate 7467c478bd9Sstevel@tonic-gate if (src == NULL) 7477c478bd9Sstevel@tonic-gate return (NULL); 7487c478bd9Sstevel@tonic-gate 7497c478bd9Sstevel@tonic-gate class = EDATA_CLASS(src); 7507c478bd9Sstevel@tonic-gate if (class == ELFCLASS32) 7517c478bd9Sstevel@tonic-gate entsize = sizeof (Elf32_Move); 7527c478bd9Sstevel@tonic-gate else if (class == ELFCLASS64) 7537c478bd9Sstevel@tonic-gate entsize = sizeof (GElf_Move); 7547c478bd9Sstevel@tonic-gate else { 7557c478bd9Sstevel@tonic-gate _elf_seterr(EREQ_CLASS, 0); 7567c478bd9Sstevel@tonic-gate return (NULL); 7577c478bd9Sstevel@tonic-gate } 7587c478bd9Sstevel@tonic-gate EDATA_READLOCKS(src); 7597c478bd9Sstevel@tonic-gate 760f7ba47a3Sab196087 if ((entsize * ndx) >= src->d_size) { 7617c478bd9Sstevel@tonic-gate _elf_seterr(EREQ_RAND, 0); 7627c478bd9Sstevel@tonic-gate dst = NULL; 7637c478bd9Sstevel@tonic-gate } else if (class == ELFCLASS32) { 7647c478bd9Sstevel@tonic-gate Elf32_Move * m = &((Elf32_Move *)src->d_buf)[ndx]; 7657c478bd9Sstevel@tonic-gate 7667c478bd9Sstevel@tonic-gate dst->m_poffset = (Elf64_Word)m->m_poffset; 7677c478bd9Sstevel@tonic-gate dst->m_repeat = (Elf64_Xword)m->m_repeat; 7687c478bd9Sstevel@tonic-gate dst->m_stride = (Elf64_Half)m->m_stride; 7697c478bd9Sstevel@tonic-gate dst->m_value = (Elf64_Xword)m->m_value; 770f7ba47a3Sab196087 dst->m_info = ELF64_M_INFO(ELF32_M_SYM(m->m_info), 7717c478bd9Sstevel@tonic-gate ELF32_M_SIZE(m->m_info)); 772f7ba47a3Sab196087 } else { 7737c478bd9Sstevel@tonic-gate *dst = ((Elf64_Move *)src->d_buf)[ndx]; 774f7ba47a3Sab196087 } 7757c478bd9Sstevel@tonic-gate 7767c478bd9Sstevel@tonic-gate EDATA_READUNLOCKS(src); 7777c478bd9Sstevel@tonic-gate return (dst); 7787c478bd9Sstevel@tonic-gate } 7797c478bd9Sstevel@tonic-gate 7807c478bd9Sstevel@tonic-gate int 7817c478bd9Sstevel@tonic-gate gelf_update_move(Elf_Data *dest, int ndx, GElf_Move *src) 7827c478bd9Sstevel@tonic-gate { 7837c478bd9Sstevel@tonic-gate int class, rc = 1; 7847c478bd9Sstevel@tonic-gate size_t entsize; 7857c478bd9Sstevel@tonic-gate 7867c478bd9Sstevel@tonic-gate if (dest == NULL) 7877c478bd9Sstevel@tonic-gate return (0); 7887c478bd9Sstevel@tonic-gate 7897c478bd9Sstevel@tonic-gate class = EDATA_CLASS(dest); 7907c478bd9Sstevel@tonic-gate if (class == ELFCLASS32) 7917c478bd9Sstevel@tonic-gate entsize = sizeof (Elf32_Move); 7927c478bd9Sstevel@tonic-gate else if (class == ELFCLASS64) 7937c478bd9Sstevel@tonic-gate entsize = sizeof (GElf_Move); 7947c478bd9Sstevel@tonic-gate else { 7957c478bd9Sstevel@tonic-gate _elf_seterr(EREQ_CLASS, 0); 7967c478bd9Sstevel@tonic-gate return (0); 7977c478bd9Sstevel@tonic-gate } 7987c478bd9Sstevel@tonic-gate ELFWLOCK(EDATA_ELF(dest)); 7997c478bd9Sstevel@tonic-gate 800f7ba47a3Sab196087 if ((entsize * ndx) >= dest->d_size) { 8017c478bd9Sstevel@tonic-gate _elf_seterr(EREQ_RAND, 0); 8027c478bd9Sstevel@tonic-gate rc = 0; 8037c478bd9Sstevel@tonic-gate } else if (class == ELFCLASS32) { 8047c478bd9Sstevel@tonic-gate Elf32_Move * m = &((Elf32_Move *)dest->d_buf)[ndx]; 8057c478bd9Sstevel@tonic-gate 8067c478bd9Sstevel@tonic-gate m->m_poffset = (Elf32_Word)src->m_poffset; 8077c478bd9Sstevel@tonic-gate m->m_repeat = (Elf32_Half)src->m_repeat; 8087c478bd9Sstevel@tonic-gate m->m_stride = (Elf32_Half)src->m_stride; 8097c478bd9Sstevel@tonic-gate m->m_value = (Elf32_Lword)src->m_value; 810f7ba47a3Sab196087 m->m_info = (Elf32_Word)ELF32_M_INFO(ELF64_M_SYM(src->m_info), 8117c478bd9Sstevel@tonic-gate ELF64_M_SIZE(src->m_info)); 812f7ba47a3Sab196087 } else { 8137c478bd9Sstevel@tonic-gate ((Elf64_Move *)dest->d_buf)[ndx] = *(Elf64_Move *)src; 814f7ba47a3Sab196087 } 8157c478bd9Sstevel@tonic-gate 8167c478bd9Sstevel@tonic-gate ELFUNLOCK(EDATA_ELF(dest)); 8177c478bd9Sstevel@tonic-gate return (rc); 8187c478bd9Sstevel@tonic-gate } 8197c478bd9Sstevel@tonic-gate 8207c478bd9Sstevel@tonic-gate 8217c478bd9Sstevel@tonic-gate GElf_Rela * 8227c478bd9Sstevel@tonic-gate gelf_getrela(Elf_Data *src, int ndx, GElf_Rela *dst) 8237c478bd9Sstevel@tonic-gate { 8247c478bd9Sstevel@tonic-gate int class; 8257c478bd9Sstevel@tonic-gate size_t entsize; 8267c478bd9Sstevel@tonic-gate 8277c478bd9Sstevel@tonic-gate if (src == NULL) 8287c478bd9Sstevel@tonic-gate return (NULL); 8297c478bd9Sstevel@tonic-gate 8307c478bd9Sstevel@tonic-gate class = EDATA_CLASS(src); 8317c478bd9Sstevel@tonic-gate if (class == ELFCLASS32) 8327c478bd9Sstevel@tonic-gate entsize = sizeof (Elf32_Rela); 8337c478bd9Sstevel@tonic-gate else if (class == ELFCLASS64) 8347c478bd9Sstevel@tonic-gate entsize = sizeof (GElf_Rela); 8357c478bd9Sstevel@tonic-gate else { 8367c478bd9Sstevel@tonic-gate _elf_seterr(EREQ_CLASS, 0); 8377c478bd9Sstevel@tonic-gate return (NULL); 8387c478bd9Sstevel@tonic-gate } 8397c478bd9Sstevel@tonic-gate EDATA_READLOCKS(src); 8407c478bd9Sstevel@tonic-gate 841f7ba47a3Sab196087 if ((entsize * ndx) >= src->d_size) { 8427c478bd9Sstevel@tonic-gate _elf_seterr(EREQ_RAND, 0); 8437c478bd9Sstevel@tonic-gate dst = NULL; 8447c478bd9Sstevel@tonic-gate } else if (class == ELFCLASS32) { 8457c478bd9Sstevel@tonic-gate Elf32_Rela * r = &((Elf32_Rela *)src->d_buf)[ndx]; 8467c478bd9Sstevel@tonic-gate 8477c478bd9Sstevel@tonic-gate dst->r_offset = (GElf_Addr)r->r_offset; 8487c478bd9Sstevel@tonic-gate dst->r_addend = (GElf_Addr)r->r_addend; 8497c478bd9Sstevel@tonic-gate 8507c478bd9Sstevel@tonic-gate /* 8517c478bd9Sstevel@tonic-gate * Elf32 will never have the extra data field that 8527c478bd9Sstevel@tonic-gate * Elf64's r_info field can have, so ignore it. 8537c478bd9Sstevel@tonic-gate */ 8547c478bd9Sstevel@tonic-gate /* LINTED */ 8557c478bd9Sstevel@tonic-gate dst->r_info = ELF64_R_INFO( 8567c478bd9Sstevel@tonic-gate ELF32_R_SYM(r->r_info), 8577c478bd9Sstevel@tonic-gate ELF32_R_TYPE(r->r_info)); 8587c478bd9Sstevel@tonic-gate } else 8597c478bd9Sstevel@tonic-gate *dst = ((Elf64_Rela *)src->d_buf)[ndx]; 8607c478bd9Sstevel@tonic-gate 8617c478bd9Sstevel@tonic-gate EDATA_READUNLOCKS(src); 8627c478bd9Sstevel@tonic-gate return (dst); 8637c478bd9Sstevel@tonic-gate } 8647c478bd9Sstevel@tonic-gate 8657c478bd9Sstevel@tonic-gate 8667c478bd9Sstevel@tonic-gate int 8677c478bd9Sstevel@tonic-gate gelf_update_rela(Elf_Data *dst, int ndx, GElf_Rela *src) 8687c478bd9Sstevel@tonic-gate { 8697c478bd9Sstevel@tonic-gate int class, rc = 1; 8707c478bd9Sstevel@tonic-gate size_t entsize; 8717c478bd9Sstevel@tonic-gate 8727c478bd9Sstevel@tonic-gate if (dst == NULL) 8737c478bd9Sstevel@tonic-gate return (0); 8747c478bd9Sstevel@tonic-gate 8757c478bd9Sstevel@tonic-gate class = EDATA_CLASS(dst); 8767c478bd9Sstevel@tonic-gate if (class == ELFCLASS32) 8777c478bd9Sstevel@tonic-gate entsize = sizeof (Elf32_Rela); 8787c478bd9Sstevel@tonic-gate else if (class == ELFCLASS64) 8797c478bd9Sstevel@tonic-gate entsize = sizeof (GElf_Rela); 8807c478bd9Sstevel@tonic-gate else { 8817c478bd9Sstevel@tonic-gate _elf_seterr(EREQ_CLASS, 0); 8827c478bd9Sstevel@tonic-gate return (0); 8837c478bd9Sstevel@tonic-gate } 8847c478bd9Sstevel@tonic-gate ELFWLOCK(EDATA_ELF(dst)); 8857c478bd9Sstevel@tonic-gate 886f7ba47a3Sab196087 if ((entsize * ndx) >= dst->d_size) { 8877c478bd9Sstevel@tonic-gate _elf_seterr(EREQ_RAND, 0); 8887c478bd9Sstevel@tonic-gate rc = 0; 8897c478bd9Sstevel@tonic-gate } else if (class == ELFCLASS32) { 8907c478bd9Sstevel@tonic-gate Elf32_Rela * r = &((Elf32_Rela *)dst->d_buf)[ndx]; 8917c478bd9Sstevel@tonic-gate 8927c478bd9Sstevel@tonic-gate /* LINTED */ 8937c478bd9Sstevel@tonic-gate r->r_offset = (Elf32_Addr) src->r_offset; 8947c478bd9Sstevel@tonic-gate /* LINTED */ 8957c478bd9Sstevel@tonic-gate r->r_addend = (Elf32_Sword)src->r_addend; 8967c478bd9Sstevel@tonic-gate 8977c478bd9Sstevel@tonic-gate /* 8987c478bd9Sstevel@tonic-gate * Elf32 will never have the extra data field that 8997c478bd9Sstevel@tonic-gate * Elf64's r_info field can have, so ignore it. 9007c478bd9Sstevel@tonic-gate */ 9017c478bd9Sstevel@tonic-gate /* LINTED */ 902f7ba47a3Sab196087 r->r_info = ELF32_R_INFO(ELF64_R_SYM(src->r_info), 9037c478bd9Sstevel@tonic-gate ELF64_R_TYPE(src->r_info)); 904f7ba47a3Sab196087 } else { 9057c478bd9Sstevel@tonic-gate ((Elf64_Rela *)dst->d_buf)[ndx] = *(Elf64_Rela *)src; 906f7ba47a3Sab196087 } 9077c478bd9Sstevel@tonic-gate 9087c478bd9Sstevel@tonic-gate ELFUNLOCK(EDATA_ELF(dst)); 9097c478bd9Sstevel@tonic-gate 9107c478bd9Sstevel@tonic-gate return (rc); 9117c478bd9Sstevel@tonic-gate } 9127c478bd9Sstevel@tonic-gate 9137c478bd9Sstevel@tonic-gate 9147c478bd9Sstevel@tonic-gate GElf_Rel * 9157c478bd9Sstevel@tonic-gate gelf_getrel(Elf_Data *src, int ndx, GElf_Rel *dst) 9167c478bd9Sstevel@tonic-gate { 9177c478bd9Sstevel@tonic-gate int class; 9187c478bd9Sstevel@tonic-gate size_t entsize; 9197c478bd9Sstevel@tonic-gate 9207c478bd9Sstevel@tonic-gate if (src == NULL) 9217c478bd9Sstevel@tonic-gate return (NULL); 9227c478bd9Sstevel@tonic-gate 9237c478bd9Sstevel@tonic-gate class = EDATA_CLASS(src); 9247c478bd9Sstevel@tonic-gate if (class == ELFCLASS32) 9257c478bd9Sstevel@tonic-gate entsize = sizeof (Elf32_Rel); 9267c478bd9Sstevel@tonic-gate else if (class == ELFCLASS64) 9277c478bd9Sstevel@tonic-gate entsize = sizeof (GElf_Rel); 9287c478bd9Sstevel@tonic-gate else { 9297c478bd9Sstevel@tonic-gate _elf_seterr(EREQ_CLASS, 0); 9307c478bd9Sstevel@tonic-gate return (NULL); 9317c478bd9Sstevel@tonic-gate } 9327c478bd9Sstevel@tonic-gate EDATA_READLOCKS(src); 9337c478bd9Sstevel@tonic-gate 934f7ba47a3Sab196087 if ((entsize * ndx) >= src->d_size) { 9357c478bd9Sstevel@tonic-gate _elf_seterr(EREQ_RAND, 0); 9367c478bd9Sstevel@tonic-gate dst = NULL; 9377c478bd9Sstevel@tonic-gate } else if (class == ELFCLASS32) { 9387c478bd9Sstevel@tonic-gate Elf32_Rel * r = &((Elf32_Rel *)src->d_buf)[ndx]; 9397c478bd9Sstevel@tonic-gate 9407c478bd9Sstevel@tonic-gate dst->r_offset = (GElf_Addr)r->r_offset; 9417c478bd9Sstevel@tonic-gate 9427c478bd9Sstevel@tonic-gate /* 9437c478bd9Sstevel@tonic-gate * Elf32 will never have the extra data field that 9447c478bd9Sstevel@tonic-gate * Elf64's r_info field can have, so ignore it. 9457c478bd9Sstevel@tonic-gate */ 9467c478bd9Sstevel@tonic-gate /* LINTED */ 9477c478bd9Sstevel@tonic-gate dst->r_info = ELF64_R_INFO(ELF32_R_SYM(r->r_info), 9487c478bd9Sstevel@tonic-gate ELF32_R_TYPE(r->r_info)); 9497c478bd9Sstevel@tonic-gate } else 9507c478bd9Sstevel@tonic-gate *dst = ((Elf64_Rel *)src->d_buf)[ndx]; 9517c478bd9Sstevel@tonic-gate 9527c478bd9Sstevel@tonic-gate EDATA_READUNLOCKS(src); 9537c478bd9Sstevel@tonic-gate return (dst); 9547c478bd9Sstevel@tonic-gate } 9557c478bd9Sstevel@tonic-gate 9567c478bd9Sstevel@tonic-gate 9577c478bd9Sstevel@tonic-gate int 9587c478bd9Sstevel@tonic-gate gelf_update_rel(Elf_Data *dst, int ndx, GElf_Rel *src) 9597c478bd9Sstevel@tonic-gate { 9607c478bd9Sstevel@tonic-gate int class, rc = 1; 9617c478bd9Sstevel@tonic-gate size_t entsize; 9627c478bd9Sstevel@tonic-gate 9637c478bd9Sstevel@tonic-gate if (dst == NULL) 9647c478bd9Sstevel@tonic-gate return (0); 9657c478bd9Sstevel@tonic-gate 9667c478bd9Sstevel@tonic-gate class = EDATA_CLASS(dst); 9677c478bd9Sstevel@tonic-gate if (class == ELFCLASS32) 9687c478bd9Sstevel@tonic-gate entsize = sizeof (Elf32_Rel); 9697c478bd9Sstevel@tonic-gate else if (class == ELFCLASS64) 9707c478bd9Sstevel@tonic-gate entsize = sizeof (GElf_Rel); 9717c478bd9Sstevel@tonic-gate else { 9727c478bd9Sstevel@tonic-gate _elf_seterr(EREQ_CLASS, 0); 9737c478bd9Sstevel@tonic-gate return (0); 9747c478bd9Sstevel@tonic-gate } 9757c478bd9Sstevel@tonic-gate ELFWLOCK(EDATA_ELF(dst)); 9767c478bd9Sstevel@tonic-gate 977f7ba47a3Sab196087 if ((entsize * ndx) >= dst->d_size) { 9787c478bd9Sstevel@tonic-gate _elf_seterr(EREQ_RAND, 0); 9797c478bd9Sstevel@tonic-gate rc = 0; 9807c478bd9Sstevel@tonic-gate } else if (class == ELFCLASS32) { 9817c478bd9Sstevel@tonic-gate Elf32_Rel * r = &((Elf32_Rel *)dst->d_buf)[ndx]; 9827c478bd9Sstevel@tonic-gate 9837c478bd9Sstevel@tonic-gate /* LINTED */ 9847c478bd9Sstevel@tonic-gate r->r_offset = (Elf32_Addr) src->r_offset; 9857c478bd9Sstevel@tonic-gate 9867c478bd9Sstevel@tonic-gate /* 9877c478bd9Sstevel@tonic-gate * Elf32 will never have the extra data field that 9887c478bd9Sstevel@tonic-gate * Elf64's r_info field can have, so ignore it. 9897c478bd9Sstevel@tonic-gate */ 9907c478bd9Sstevel@tonic-gate /* LINTED */ 991f7ba47a3Sab196087 r->r_info = ELF32_R_INFO(ELF64_R_SYM(src->r_info), 9927c478bd9Sstevel@tonic-gate ELF64_R_TYPE(src->r_info)); 9937c478bd9Sstevel@tonic-gate 994f7ba47a3Sab196087 } else { 9957c478bd9Sstevel@tonic-gate ((Elf64_Rel *)dst->d_buf)[ndx] = *(Elf64_Rel *)src; 996f7ba47a3Sab196087 } 9977c478bd9Sstevel@tonic-gate 9987c478bd9Sstevel@tonic-gate ELFUNLOCK(EDATA_ELF(dst)); 9997c478bd9Sstevel@tonic-gate return (rc); 10007c478bd9Sstevel@tonic-gate } 10017c478bd9Sstevel@tonic-gate 10027c478bd9Sstevel@tonic-gate long 10037c478bd9Sstevel@tonic-gate gelf_checksum(Elf *elf) 10047c478bd9Sstevel@tonic-gate { 10057c478bd9Sstevel@tonic-gate int class = gelf_getclass(elf); 10067c478bd9Sstevel@tonic-gate 10077c478bd9Sstevel@tonic-gate if (class == ELFCLASS32) 10087c478bd9Sstevel@tonic-gate return (elf32_checksum(elf)); 10097c478bd9Sstevel@tonic-gate else if (class == ELFCLASS64) 10107c478bd9Sstevel@tonic-gate return (elf64_checksum(elf)); 10117c478bd9Sstevel@tonic-gate 10127c478bd9Sstevel@tonic-gate _elf_seterr(EREQ_CLASS, 0); 10137c478bd9Sstevel@tonic-gate return (0); 10147c478bd9Sstevel@tonic-gate } 10157c478bd9Sstevel@tonic-gate 10167c478bd9Sstevel@tonic-gate GElf_Cap * 10177c478bd9Sstevel@tonic-gate gelf_getcap(Elf_Data *data, int ndx, GElf_Cap *dst) 10187c478bd9Sstevel@tonic-gate { 10197c478bd9Sstevel@tonic-gate int class; 10207c478bd9Sstevel@tonic-gate size_t entsize; 10217c478bd9Sstevel@tonic-gate 10227c478bd9Sstevel@tonic-gate if (data == NULL) 10237c478bd9Sstevel@tonic-gate return (NULL); 10247c478bd9Sstevel@tonic-gate 10257c478bd9Sstevel@tonic-gate class = EDATA_CLASS(data); 10267c478bd9Sstevel@tonic-gate if (class == ELFCLASS32) 10277c478bd9Sstevel@tonic-gate entsize = sizeof (Elf32_Cap); 10287c478bd9Sstevel@tonic-gate else if (class == ELFCLASS64) 10297c478bd9Sstevel@tonic-gate entsize = sizeof (GElf_Cap); 10307c478bd9Sstevel@tonic-gate else { 10317c478bd9Sstevel@tonic-gate _elf_seterr(EREQ_CLASS, 0); 10327c478bd9Sstevel@tonic-gate return (NULL); 10337c478bd9Sstevel@tonic-gate } 10347c478bd9Sstevel@tonic-gate 10357c478bd9Sstevel@tonic-gate EDATA_READLOCKS(data); 10367c478bd9Sstevel@tonic-gate 1037f7ba47a3Sab196087 if ((entsize * ndx) >= data->d_size) { 10387c478bd9Sstevel@tonic-gate _elf_seterr(EREQ_RAND, 0); 10397c478bd9Sstevel@tonic-gate dst = NULL; 10407c478bd9Sstevel@tonic-gate } else if (class == ELFCLASS32) { 10417c478bd9Sstevel@tonic-gate Elf32_Cap *c = &(((Elf32_Cap *)data->d_buf)[ndx]); 10427c478bd9Sstevel@tonic-gate 10437c478bd9Sstevel@tonic-gate dst->c_tag = (Elf64_Xword)c->c_tag; 10447c478bd9Sstevel@tonic-gate dst->c_un.c_val = (Elf64_Xword)c->c_un.c_val; 10457c478bd9Sstevel@tonic-gate } else 10467c478bd9Sstevel@tonic-gate *dst = ((GElf_Cap *)data->d_buf)[ndx]; 10477c478bd9Sstevel@tonic-gate 10487c478bd9Sstevel@tonic-gate EDATA_READUNLOCKS(data); 10497c478bd9Sstevel@tonic-gate return (dst); 10507c478bd9Sstevel@tonic-gate } 10517c478bd9Sstevel@tonic-gate 10527c478bd9Sstevel@tonic-gate int 10537c478bd9Sstevel@tonic-gate gelf_update_cap(Elf_Data *dst, int ndx, GElf_Cap *src) 10547c478bd9Sstevel@tonic-gate { 10557c478bd9Sstevel@tonic-gate int class, rc = 1; 10567c478bd9Sstevel@tonic-gate size_t entsize; 10577c478bd9Sstevel@tonic-gate 10587c478bd9Sstevel@tonic-gate if (dst == NULL) 10597c478bd9Sstevel@tonic-gate return (0); 10607c478bd9Sstevel@tonic-gate 10617c478bd9Sstevel@tonic-gate class = EDATA_CLASS(dst); 10627c478bd9Sstevel@tonic-gate if (class == ELFCLASS32) 10637c478bd9Sstevel@tonic-gate entsize = sizeof (Elf32_Cap); 10647c478bd9Sstevel@tonic-gate else if (class == ELFCLASS64) 10657c478bd9Sstevel@tonic-gate entsize = sizeof (GElf_Cap); 10667c478bd9Sstevel@tonic-gate else { 10677c478bd9Sstevel@tonic-gate _elf_seterr(EREQ_CLASS, 0); 10687c478bd9Sstevel@tonic-gate return (0); 10697c478bd9Sstevel@tonic-gate } 10707c478bd9Sstevel@tonic-gate 10717c478bd9Sstevel@tonic-gate ELFWLOCK(EDATA_ELF(dst)); 10727c478bd9Sstevel@tonic-gate 1073f7ba47a3Sab196087 if ((entsize * ndx) >= dst->d_size) { 10747c478bd9Sstevel@tonic-gate _elf_seterr(EREQ_RAND, 0); 10757c478bd9Sstevel@tonic-gate rc = 0; 10767c478bd9Sstevel@tonic-gate } else if (class == ELFCLASS32) { 10777c478bd9Sstevel@tonic-gate Elf32_Cap *c = &(((Elf32_Cap *)dst->d_buf)[ndx]); 10787c478bd9Sstevel@tonic-gate 10797c478bd9Sstevel@tonic-gate c->c_tag = (Elf32_Word)src->c_tag; 10807c478bd9Sstevel@tonic-gate c->c_un.c_val = (Elf32_Word)src->c_un.c_val; 10817c478bd9Sstevel@tonic-gate } else 10827c478bd9Sstevel@tonic-gate ((Elf64_Cap *)dst->d_buf)[ndx] = *((Elf64_Cap *)src); 10837c478bd9Sstevel@tonic-gate 10847c478bd9Sstevel@tonic-gate ELFUNLOCK(EDATA_ELF(dst)); 10857c478bd9Sstevel@tonic-gate return (rc); 10867c478bd9Sstevel@tonic-gate } 10874899432aSab196087 10884899432aSab196087 /* 10894899432aSab196087 * If the specified object has a dynamic section, and that section 10904899432aSab196087 * contains a DT_FLAGS_1 entry, then return the value of that entry. 10914899432aSab196087 * Otherwise, return 0. 10924899432aSab196087 */ 10934899432aSab196087 GElf_Xword 10944899432aSab196087 _gelf_getdyndtflags_1(Elf *elf) 10954899432aSab196087 { 10964899432aSab196087 Elf_Scn *scn = NULL; 10974899432aSab196087 Elf_Data *data; 10984899432aSab196087 GElf_Shdr shdr; 10994899432aSab196087 GElf_Dyn dyn; 11004899432aSab196087 int i, n; 11014899432aSab196087 11024899432aSab196087 while (scn = elf_nextscn(elf, scn)) { 11034899432aSab196087 if (gelf_getshdr(scn, &shdr) == NULL) 11044899432aSab196087 break; 11054899432aSab196087 if (shdr.sh_type != SHT_DYNAMIC) 11064899432aSab196087 continue; 11074899432aSab196087 if (data = elf_getdata(scn, NULL)) { 11084899432aSab196087 n = shdr.sh_size / shdr.sh_entsize; 11094899432aSab196087 for (i = 0; i < n; i++) { 11104899432aSab196087 (void) gelf_getdyn(data, i, &dyn); 11114899432aSab196087 if (dyn.d_tag == DT_FLAGS_1) { 11124899432aSab196087 return (dyn.d_un.d_val); 11134899432aSab196087 } 11144899432aSab196087 } 11154899432aSab196087 } 11164899432aSab196087 break; 11174899432aSab196087 } 11184899432aSab196087 return (0); 11194899432aSab196087 } 1120