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