1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* Copyright (c) 1988 AT&T */ 23 /* All Rights Reserved */ 24 25 26 /* 27 * Copyright (c) 1998 by Sun Microsystems, Inc. 28 * All rights reserved. 29 */ 30 31 32 #pragma ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.6 */ 33 34 #pragma weak elf_getarsym = _elf_getarsym 35 36 37 #include "syn.h" 38 #include <stdlib.h> 39 #include <errno.h> 40 #include <libelf.h> 41 #include "decl.h" 42 #include "msg.h" 43 44 45 /* 46 * Convert archive symbol table to memory format 47 * This takes a pointer to file's archive symbol table, 48 * alignment unconstrained. Returns null terminated 49 * vector of Elf_Arsym structures. 50 * 51 * Symbol table is the following: 52 * # offsets 4-byte word 53 * offset[0...] 4-byte word each 54 * strings null-terminated, for offset[x] 55 */ 56 57 58 #define get4(p) ((((((p[0]<<8)+p[1])<<8)+p[2])<<8)+p[3]) 59 60 61 static Elf_Void *arsym _((Byte *, size_t, size_t *)); 62 63 64 Elf_Void * 65 arsym(Byte * off, size_t sz, size_t * e) 66 { 67 char *endstr = (char *)off + sz; 68 register char *str; 69 Byte *endoff; 70 Elf_Void *oas; 71 72 { 73 register size_t n; 74 75 if (sz < 4 || (sz - 4) / 4 < (n = get4(off))) { 76 _elf_seterr(EFMT_ARSYMSZ, 0); 77 return (0); 78 } 79 off += 4; 80 endoff = off + n * 4; 81 82 /* 83 * string table must be present, null terminated 84 */ 85 86 if (((str = (char *)endoff) >= endstr) || 87 (*(endstr - 1) != '\0')) { 88 _elf_seterr(EFMT_ARSYM, 0); 89 return (0); 90 } 91 92 /* 93 * overflow can occur here, but not likely 94 */ 95 96 *e = n + 1; 97 n = sizeof (Elf_Arsym) * (n + 1); 98 if ((oas = malloc(n)) == 0) { 99 _elf_seterr(EMEM_ARSYM, errno); 100 return (0); 101 } 102 } 103 { 104 register Elf_Arsym *as = (Elf_Arsym *)oas; 105 106 while (off < endoff) { 107 if (str >= endstr) { 108 _elf_seterr(EFMT_ARSYMSTR, 0); 109 free(oas); 110 return (0); 111 } 112 as->as_off = get4(off); 113 as->as_name = str; 114 as->as_hash = elf_hash(str); 115 ++as; 116 off += 4; 117 while (*str++ != '\0') 118 /* LINTED */ 119 ; 120 } 121 as->as_name = 0; 122 as->as_off = 0; 123 as->as_hash = ~(unsigned long)0L; 124 } 125 return (oas); 126 } 127 128 129 Elf_Arsym * 130 elf_getarsym(Elf * elf, size_t * ptr) 131 { 132 Byte * as; 133 size_t sz; 134 Elf_Arsym * rc; 135 136 if (ptr != 0) 137 *ptr = 0; 138 if (elf == 0) 139 return (0); 140 ELFRLOCK(elf); 141 if (elf->ed_kind != ELF_K_AR) { 142 ELFUNLOCK(elf); 143 _elf_seterr(EREQ_AR, 0); 144 return (0); 145 } 146 if ((as = (Byte *)elf->ed_arsym) == 0) { 147 ELFUNLOCK(elf); 148 return (0); 149 } 150 if (elf->ed_myflags & EDF_ASALLOC) { 151 if (ptr != 0) 152 *ptr = elf->ed_arsymsz; 153 ELFUNLOCK(elf); 154 /* LINTED */ 155 return ((Elf_Arsym *)as); 156 } 157 /* 158 * We're gonna need a write lock. 159 */ 160 ELFUNLOCK(elf) 161 ELFWLOCK(elf) 162 sz = elf->ed_arsymsz; 163 if (_elf_vm(elf, (size_t)(as - (Byte *)elf->ed_ident), sz) != 164 OK_YES) { 165 ELFUNLOCK(elf); 166 return (0); 167 } 168 if ((elf->ed_arsym = arsym(as, sz, &elf->ed_arsymsz)) == 0) { 169 ELFUNLOCK(elf); 170 return (0); 171 } 172 elf->ed_myflags |= EDF_ASALLOC; 173 if (ptr != 0) 174 *ptr = elf->ed_arsymsz; 175 rc = (Elf_Arsym *)elf->ed_arsym; 176 ELFUNLOCK(elf); 177 return (rc); 178 } 179