10Sstevel@tonic-gate /* 20Sstevel@tonic-gate * CDDL HEADER START 30Sstevel@tonic-gate * 40Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*6812Sraf * Common Development and Distribution License (the "License"). 6*6812Sraf * You may not use this file except in compliance with the License. 70Sstevel@tonic-gate * 80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 100Sstevel@tonic-gate * See the License for the specific language governing permissions 110Sstevel@tonic-gate * and limitations under the License. 120Sstevel@tonic-gate * 130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 180Sstevel@tonic-gate * 190Sstevel@tonic-gate * CDDL HEADER END 200Sstevel@tonic-gate */ 21*6812Sraf 22*6812Sraf /* 23*6812Sraf * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 24*6812Sraf * Use is subject to license terms. 25*6812Sraf */ 26*6812Sraf 270Sstevel@tonic-gate /* Copyright (c) 1988 AT&T */ 280Sstevel@tonic-gate /* All Rights Reserved */ 290Sstevel@tonic-gate 30*6812Sraf #pragma ident "%Z%%M% %I% %E% SMI" 310Sstevel@tonic-gate 320Sstevel@tonic-gate #include <stdlib.h> 330Sstevel@tonic-gate #include <errno.h> 340Sstevel@tonic-gate #include <libelf.h> 350Sstevel@tonic-gate #include "decl.h" 360Sstevel@tonic-gate #include "msg.h" 370Sstevel@tonic-gate 380Sstevel@tonic-gate 390Sstevel@tonic-gate /* 400Sstevel@tonic-gate * Convert archive symbol table to memory format 410Sstevel@tonic-gate * This takes a pointer to file's archive symbol table, 420Sstevel@tonic-gate * alignment unconstrained. Returns null terminated 430Sstevel@tonic-gate * vector of Elf_Arsym structures. 440Sstevel@tonic-gate * 450Sstevel@tonic-gate * Symbol table is the following: 460Sstevel@tonic-gate * # offsets 4-byte word 470Sstevel@tonic-gate * offset[0...] 4-byte word each 480Sstevel@tonic-gate * strings null-terminated, for offset[x] 490Sstevel@tonic-gate */ 500Sstevel@tonic-gate 510Sstevel@tonic-gate 520Sstevel@tonic-gate #define get4(p) ((((((p[0]<<8)+p[1])<<8)+p[2])<<8)+p[3]) 530Sstevel@tonic-gate 540Sstevel@tonic-gate 550Sstevel@tonic-gate static Elf_Void *arsym _((Byte *, size_t, size_t *)); 560Sstevel@tonic-gate 570Sstevel@tonic-gate 580Sstevel@tonic-gate Elf_Void * 59*6812Sraf arsym(Byte *off, size_t sz, size_t *e) 600Sstevel@tonic-gate { 610Sstevel@tonic-gate char *endstr = (char *)off + sz; 620Sstevel@tonic-gate register char *str; 630Sstevel@tonic-gate Byte *endoff; 640Sstevel@tonic-gate Elf_Void *oas; 650Sstevel@tonic-gate 660Sstevel@tonic-gate { 670Sstevel@tonic-gate register size_t n; 680Sstevel@tonic-gate 690Sstevel@tonic-gate if (sz < 4 || (sz - 4) / 4 < (n = get4(off))) { 700Sstevel@tonic-gate _elf_seterr(EFMT_ARSYMSZ, 0); 710Sstevel@tonic-gate return (0); 720Sstevel@tonic-gate } 730Sstevel@tonic-gate off += 4; 740Sstevel@tonic-gate endoff = off + n * 4; 750Sstevel@tonic-gate 760Sstevel@tonic-gate /* 770Sstevel@tonic-gate * string table must be present, null terminated 780Sstevel@tonic-gate */ 790Sstevel@tonic-gate 800Sstevel@tonic-gate if (((str = (char *)endoff) >= endstr) || 810Sstevel@tonic-gate (*(endstr - 1) != '\0')) { 820Sstevel@tonic-gate _elf_seterr(EFMT_ARSYM, 0); 830Sstevel@tonic-gate return (0); 840Sstevel@tonic-gate } 850Sstevel@tonic-gate 860Sstevel@tonic-gate /* 870Sstevel@tonic-gate * overflow can occur here, but not likely 880Sstevel@tonic-gate */ 890Sstevel@tonic-gate 900Sstevel@tonic-gate *e = n + 1; 910Sstevel@tonic-gate n = sizeof (Elf_Arsym) * (n + 1); 920Sstevel@tonic-gate if ((oas = malloc(n)) == 0) { 930Sstevel@tonic-gate _elf_seterr(EMEM_ARSYM, errno); 940Sstevel@tonic-gate return (0); 950Sstevel@tonic-gate } 960Sstevel@tonic-gate } 970Sstevel@tonic-gate { 980Sstevel@tonic-gate register Elf_Arsym *as = (Elf_Arsym *)oas; 990Sstevel@tonic-gate 1000Sstevel@tonic-gate while (off < endoff) { 1010Sstevel@tonic-gate if (str >= endstr) { 1020Sstevel@tonic-gate _elf_seterr(EFMT_ARSYMSTR, 0); 1030Sstevel@tonic-gate free(oas); 1040Sstevel@tonic-gate return (0); 1050Sstevel@tonic-gate } 1060Sstevel@tonic-gate as->as_off = get4(off); 1070Sstevel@tonic-gate as->as_name = str; 1080Sstevel@tonic-gate as->as_hash = elf_hash(str); 1090Sstevel@tonic-gate ++as; 1100Sstevel@tonic-gate off += 4; 1110Sstevel@tonic-gate while (*str++ != '\0') 1120Sstevel@tonic-gate /* LINTED */ 1130Sstevel@tonic-gate ; 1140Sstevel@tonic-gate } 1150Sstevel@tonic-gate as->as_name = 0; 1160Sstevel@tonic-gate as->as_off = 0; 1170Sstevel@tonic-gate as->as_hash = ~(unsigned long)0L; 1180Sstevel@tonic-gate } 1190Sstevel@tonic-gate return (oas); 1200Sstevel@tonic-gate } 1210Sstevel@tonic-gate 1220Sstevel@tonic-gate 1230Sstevel@tonic-gate Elf_Arsym * 124*6812Sraf elf_getarsym(Elf *elf, size_t *ptr) 1250Sstevel@tonic-gate { 126*6812Sraf Byte *as; 1270Sstevel@tonic-gate size_t sz; 128*6812Sraf Elf_Arsym *rc; 1290Sstevel@tonic-gate 1300Sstevel@tonic-gate if (ptr != 0) 1310Sstevel@tonic-gate *ptr = 0; 1320Sstevel@tonic-gate if (elf == 0) 1330Sstevel@tonic-gate return (0); 1340Sstevel@tonic-gate ELFRLOCK(elf); 1350Sstevel@tonic-gate if (elf->ed_kind != ELF_K_AR) { 1360Sstevel@tonic-gate ELFUNLOCK(elf); 1370Sstevel@tonic-gate _elf_seterr(EREQ_AR, 0); 1380Sstevel@tonic-gate return (0); 1390Sstevel@tonic-gate } 1400Sstevel@tonic-gate if ((as = (Byte *)elf->ed_arsym) == 0) { 1410Sstevel@tonic-gate ELFUNLOCK(elf); 1420Sstevel@tonic-gate return (0); 1430Sstevel@tonic-gate } 1440Sstevel@tonic-gate if (elf->ed_myflags & EDF_ASALLOC) { 1450Sstevel@tonic-gate if (ptr != 0) 1460Sstevel@tonic-gate *ptr = elf->ed_arsymsz; 1470Sstevel@tonic-gate ELFUNLOCK(elf); 1480Sstevel@tonic-gate /* LINTED */ 1490Sstevel@tonic-gate return ((Elf_Arsym *)as); 1500Sstevel@tonic-gate } 1510Sstevel@tonic-gate /* 1520Sstevel@tonic-gate * We're gonna need a write lock. 1530Sstevel@tonic-gate */ 1540Sstevel@tonic-gate ELFUNLOCK(elf) 1550Sstevel@tonic-gate ELFWLOCK(elf) 1560Sstevel@tonic-gate sz = elf->ed_arsymsz; 1570Sstevel@tonic-gate if (_elf_vm(elf, (size_t)(as - (Byte *)elf->ed_ident), sz) != 1580Sstevel@tonic-gate OK_YES) { 1590Sstevel@tonic-gate ELFUNLOCK(elf); 1600Sstevel@tonic-gate return (0); 1610Sstevel@tonic-gate } 1620Sstevel@tonic-gate if ((elf->ed_arsym = arsym(as, sz, &elf->ed_arsymsz)) == 0) { 1630Sstevel@tonic-gate ELFUNLOCK(elf); 1640Sstevel@tonic-gate return (0); 1650Sstevel@tonic-gate } 1660Sstevel@tonic-gate elf->ed_myflags |= EDF_ASALLOC; 1670Sstevel@tonic-gate if (ptr != 0) 1680Sstevel@tonic-gate *ptr = elf->ed_arsymsz; 1690Sstevel@tonic-gate rc = (Elf_Arsym *)elf->ed_arsym; 1700Sstevel@tonic-gate ELFUNLOCK(elf); 1710Sstevel@tonic-gate return (rc); 1720Sstevel@tonic-gate } 173