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 (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* Copyright (c) 1988 AT&T */ 28 /* All Rights Reserved */ 29 30 #include "libelf.h" 31 #include "decl.h" 32 #include "msg.h" 33 34 35 char * 36 elf_strptr(Elf * elf, size_t ndx, size_t off) 37 { 38 Elf_Scn *s; 39 Elf_Data *d; 40 char *rc; 41 42 if (elf == 0) 43 return (0); 44 if ((s = elf_getscn(elf, ndx)) == 0) { 45 _elf_seterr(EREQ_STRSCN, 0); 46 return (0); 47 } 48 READLOCKS(elf, s) 49 if (elf->ed_class == ELFCLASS32) { 50 Elf32_Shdr* sh = (Elf32_Shdr*)s->s_shdr; 51 52 if ((sh == 0) || (sh->sh_type != SHT_STRTAB)) { 53 _elf_seterr(EREQ_STRSCN, 0); 54 READUNLOCKS(elf, s) 55 return (0); 56 } 57 } else if (elf->ed_class == ELFCLASS64) { 58 Elf64_Shdr* sh = (Elf64_Shdr*)s->s_shdr; 59 60 if ((sh == 0) || (sh->sh_type != SHT_STRTAB)) { 61 _elf_seterr(EREQ_STRSCN, 0); 62 READUNLOCKS(elf, s) 63 return (0); 64 } 65 } else { 66 _elf_seterr(EREQ_STRSCN, 0); 67 READUNLOCKS(elf, s) 68 return (0); 69 } 70 71 72 /* 73 * If the layout bit is set, use the offsets and 74 * sizes in the data buffers. Otherwise, take 75 * data buffers in order. 76 */ 77 78 d = 0; 79 if (elf->ed_uflags & ELF_F_LAYOUT) { 80 while ((d = _elf_locked_getdata(s, d)) != 0) { 81 if (d->d_buf == 0) 82 continue; 83 if ((off >= d->d_off) && 84 (off < d->d_off + d->d_size)) { 85 rc = (char *)d->d_buf + off - d->d_off; 86 READUNLOCKS(elf, s) 87 return (rc); 88 } 89 } 90 } else { 91 size_t sz = 0, j; 92 while ((d = _elf_locked_getdata(s, d)) != 0) { 93 if (((j = d->d_align) > 1) && (sz % j != 0)) { 94 j -= sz % j; 95 sz += j; 96 if (off < j) 97 break; 98 off -= j; 99 } 100 if (d->d_buf != 0) { 101 if (off < d->d_size) { 102 rc = (char *)d->d_buf + off; 103 READUNLOCKS(elf, s) 104 return (rc); 105 } 106 } 107 sz += d->d_size; 108 if (off < d->d_size) 109 break; 110 off -= d->d_size; 111 } 112 } 113 _elf_seterr(EREQ_STROFF, 0); 114 READUNLOCKS(elf, s) 115 return (0); 116 } 117