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 #pragma ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.6 */ 32 33 #pragma weak elf_strptr = _elf_strptr 34 35 36 #include "syn.h" 37 #include "libelf.h" 38 #include "decl.h" 39 #include "msg.h" 40 41 42 char * 43 elf_strptr(Elf * elf, size_t ndx, size_t off) 44 { 45 Elf_Scn * s; 46 Elf_Data * d; 47 char * rc; 48 49 if (elf == 0) 50 return (0); 51 if ((s = elf_getscn(elf, ndx)) == 0) { 52 _elf_seterr(EREQ_STRSCN, 0); 53 return (0); 54 } 55 READLOCKS(elf, s) 56 if (elf->ed_class == ELFCLASS32) { 57 Elf32_Shdr* sh = (Elf32_Shdr*)s->s_shdr; 58 59 if ((sh == 0) || (sh->sh_type != SHT_STRTAB)) { 60 _elf_seterr(EREQ_STRSCN, 0); 61 READUNLOCKS(elf, s) 62 return (0); 63 } 64 } else if (elf->ed_class == ELFCLASS64) { 65 Elf64_Shdr* sh = (Elf64_Shdr*)s->s_shdr; 66 67 if ((sh == 0) || (sh->sh_type != SHT_STRTAB)) { 68 _elf_seterr(EREQ_STRSCN, 0); 69 READUNLOCKS(elf, s) 70 return (0); 71 } 72 } else { 73 _elf_seterr(EREQ_STRSCN, 0); 74 READUNLOCKS(elf, s) 75 return (0); 76 } 77 78 79 /* 80 * If the layout bit is set, use the offsets and 81 * sizes in the data buffers. Otherwise, take 82 * data buffers in order. 83 */ 84 85 d = 0; 86 if (elf->ed_uflags & ELF_F_LAYOUT) { 87 while ((d = _elf_locked_getdata(s, d)) != 0) { 88 if (d->d_buf == 0) 89 continue; 90 if ((off >= d->d_off) && 91 (off < d->d_off + d->d_size)) { 92 rc = (char *)d->d_buf + off - d->d_off; 93 READUNLOCKS(elf, s) 94 return (rc); 95 } 96 } 97 } else { 98 size_t sz = 0, j; 99 while ((d = _elf_locked_getdata(s, d)) != 0) { 100 if (((j = d->d_align) > 1) && (sz % j != 0)) { 101 j -= sz % j; 102 sz += j; 103 if (off < j) 104 break; 105 off -= j; 106 } 107 if (d->d_buf != 0) { 108 if (off < d->d_size) { 109 rc = (char *)d->d_buf + off; 110 READUNLOCKS(elf, s) 111 return (rc); 112 } 113 } 114 sz += d->d_size; 115 if (off < d->d_size) 116 break; 117 off -= d->d_size; 118 } 119 } 120 _elf_seterr(EREQ_STROFF, 0); 121 READUNLOCKS(elf, s) 122 return (0); 123 } 124