Branch data Line data Source code
1 : : /* Return string pointer from string section.
2 : : Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2008, 2009 Red Hat, Inc.
3 : : This file is part of elfutils.
4 : : Contributed by Ulrich Drepper <drepper@redhat.com>, 1998.
5 : :
6 : : This file is free software; you can redistribute it and/or modify
7 : : it under the terms of either
8 : :
9 : : * the GNU Lesser General Public License as published by the Free
10 : : Software Foundation; either version 3 of the License, or (at
11 : : your option) any later version
12 : :
13 : : or
14 : :
15 : : * the GNU General Public License as published by the Free
16 : : Software Foundation; either version 2 of the License, or (at
17 : : your option) any later version
18 : :
19 : : or both in parallel, as here.
20 : :
21 : : elfutils is distributed in the hope that it will be useful, but
22 : : WITHOUT ANY WARRANTY; without even the implied warranty of
23 : : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24 : : General Public License for more details.
25 : :
26 : : You should have received copies of the GNU General Public License and
27 : : the GNU Lesser General Public License along with this program. If
28 : : not, see <http://www.gnu.org/licenses/>. */
29 : :
30 : : #ifdef HAVE_CONFIG_H
31 : : # include <config.h>
32 : : #endif
33 : :
34 : : #include <libelf.h>
35 : : #include <stddef.h>
36 : :
37 : : #include "libelfP.h"
38 : :
39 : :
40 : : char *
41 : 1294165 : elf_strptr (elf, idx, offset)
42 : : Elf *elf;
43 : : size_t idx;
44 : : size_t offset;
45 : : {
46 [ + - ]: 1294165 : if (elf == NULL)
47 : : return NULL;
48 : :
49 [ - + ]: 1294165 : if (elf->kind != ELF_K_ELF)
50 : : {
51 : 0 : __libelf_seterrno (ELF_E_INVALID_HANDLE);
52 : 0 : return NULL;
53 : : }
54 : :
55 : : rwlock_rdlock (elf->lock);
56 : :
57 : 1294165 : char *result = NULL;
58 : : Elf_Scn *strscn;
59 : :
60 : : /* Find the section in the list. */
61 : 1294165 : Elf_ScnList *runp = (elf->class == ELFCLASS32
62 : : || (offsetof (struct Elf, state.elf32.scns)
63 : : == offsetof (struct Elf, state.elf64.scns))
64 : : ? &elf->state.elf32.scns : &elf->state.elf64.scns);
65 : : while (1)
66 : : {
67 [ + + ]: 1294203 : if (idx < runp->max)
68 : : {
69 [ + - ]: 1294165 : if (idx < runp->cnt)
70 : 1294165 : strscn = &runp->data[idx];
71 : : else
72 : : {
73 : 0 : __libelf_seterrno (ELF_E_INVALID_INDEX);
74 : 0 : goto out;
75 : : }
76 : : break;
77 : : }
78 : :
79 : 38 : idx -= runp->max;
80 : :
81 : 38 : runp = runp->next;
82 [ + - ]: 38 : if (runp == NULL)
83 : : {
84 : 0 : __libelf_seterrno (ELF_E_INVALID_INDEX);
85 : 0 : goto out;
86 : : }
87 : : }
88 : :
89 [ + + ]: 1294165 : if (elf->class == ELFCLASS32)
90 : : {
91 [ + + ]: 510354 : if (unlikely (strscn->shdr.e32->sh_type != SHT_STRTAB))
92 : : {
93 : : /* This is no string section. */
94 : 5 : __libelf_seterrno (ELF_E_INVALID_SECTION);
95 : 5 : goto out;
96 : : }
97 : :
98 [ - + ]: 510349 : if (unlikely (offset >= strscn->shdr.e32->sh_size))
99 : : {
100 : : /* The given offset is too big, it is beyond this section. */
101 : 0 : __libelf_seterrno (ELF_E_OFFSET_RANGE);
102 : 0 : goto out;
103 : : }
104 : : }
105 : : else
106 : : {
107 [ - + ]: 783811 : if (unlikely (strscn->shdr.e64->sh_type != SHT_STRTAB))
108 : : {
109 : : /* This is no string section. */
110 : 0 : __libelf_seterrno (ELF_E_INVALID_SECTION);
111 : 0 : goto out;
112 : : }
113 : :
114 [ - + ]: 783811 : if (unlikely (offset >= strscn->shdr.e64->sh_size))
115 : : {
116 : : /* The given offset is too big, it is beyond this section. */
117 : 0 : __libelf_seterrno (ELF_E_OFFSET_RANGE);
118 : 0 : goto out;
119 : : }
120 : : }
121 : :
122 [ + + ][ + + ]: 1294160 : if (strscn->rawdata_base == NULL && ! strscn->data_read)
123 : : {
124 : : rwlock_unlock (elf->lock);
125 : : rwlock_wrlock (elf->lock);
126 [ + - ][ + - ]: 5938 : if (strscn->rawdata_base == NULL && ! strscn->data_read
127 : : /* Read the section data. */
128 [ + - ]: 5938 : && __libelf_set_rawdata_wrlock (strscn) != 0)
129 : : goto out;
130 : : }
131 : :
132 [ + + ]: 1294160 : if (likely (strscn->rawdata_base != NULL))
133 : : // XXX Is this correct if a file is read and then new data is added
134 : : // XXX to the string section? Likely needs to check offset against
135 : : // XXX size of rawdata_base buffer and then iterate over rest of the
136 : : // XXX list.
137 : 1294133 : result = &strscn->rawdata_base[offset];
138 : : else
139 : : {
140 : : /* This is a file which is currently created. Use the list of
141 : : data blocks. */
142 : 27 : struct Elf_Data_List *dl = &strscn->data_list;
143 [ + - ]: 27 : while (dl != NULL)
144 : : {
145 [ + - ]: 27 : if (offset >= (size_t) dl->data.d.d_off
146 [ + - ]: 27 : && offset < dl->data.d.d_off + dl->data.d.d_size)
147 : : {
148 : 27 : result = (char *) dl->data.d.d_buf + (offset - dl->data.d.d_off);
149 : 27 : break;
150 : : }
151 : :
152 : 0 : dl = dl->next;
153 : : }
154 : : }
155 : :
156 : : out:
157 : : rwlock_unlock (elf->lock);
158 : :
159 : 1294165 : return result;
160 : : }
161 : : INTDEF(elf_strptr)
|