Branch data Line data Source code
1 : : /* Return section index of section header string table.
2 : : Copyright (C) 2002, 2005, 2009 Red Hat, Inc.
3 : : This file is part of elfutils.
4 : : Written by Ulrich Drepper <drepper@redhat.com>, 2002.
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 <assert.h>
35 : : #include <errno.h>
36 : : #include <gelf.h>
37 : : #include <stddef.h>
38 : : #include <unistd.h>
39 : :
40 : : #include <system.h>
41 : : #include "libelfP.h"
42 : : #include "common.h"
43 : :
44 : :
45 : : int
46 : 89652 : elf_getshdrstrndx (elf, dst)
47 : : Elf *elf;
48 : : size_t *dst;
49 : : {
50 : 89652 : int result = 0;
51 : :
52 [ + - ]: 89652 : if (elf == NULL)
53 : : return -1;
54 : :
55 [ - + ]: 89652 : if (unlikely (elf->kind != ELF_K_ELF))
56 : : {
57 : 0 : __libelf_seterrno (ELF_E_INVALID_HANDLE);
58 : 0 : return -1;
59 : : }
60 : :
61 : : rwlock_rdlock (elf->lock);
62 : :
63 : : /* We rely here on the fact that the `elf' element is a common prefix
64 : : of `elf32' and `elf64'. */
65 : : assert (offsetof (struct Elf, state.elf.ehdr)
66 : : == offsetof (struct Elf, state.elf32.ehdr));
67 : : assert (sizeof (elf->state.elf.ehdr)
68 : : == sizeof (elf->state.elf32.ehdr));
69 : : assert (offsetof (struct Elf, state.elf.ehdr)
70 : : == offsetof (struct Elf, state.elf64.ehdr));
71 : : assert (sizeof (elf->state.elf.ehdr)
72 : : == sizeof (elf->state.elf64.ehdr));
73 : :
74 [ - + ]: 89652 : if (unlikely (elf->state.elf.ehdr == NULL))
75 : : {
76 : 0 : __libelf_seterrno (ELF_E_WRONG_ORDER_EHDR);
77 : 0 : result = -1;
78 : : }
79 : : else
80 : : {
81 : : Elf32_Word num;
82 : :
83 [ + + ]: 89652 : num = (elf->class == ELFCLASS32
84 : 115 : ? elf->state.elf32.ehdr->e_shstrndx
85 : 89537 : : elf->state.elf64.ehdr->e_shstrndx);
86 : :
87 : : /* Determine whether the index is too big to fit in the ELF
88 : : header. */
89 [ - + ]: 89652 : if (unlikely (num == SHN_XINDEX))
90 : : {
91 : : /* Yes. Search the zeroth section header. */
92 [ # # ]: 0 : if (elf->class == ELFCLASS32)
93 : : {
94 : : size_t offset;
95 : :
96 [ # # ]: 0 : if (elf->state.elf32.scns.data[0].shdr.e32 != NULL)
97 : : {
98 : 0 : num = elf->state.elf32.scns.data[0].shdr.e32->sh_link;
99 : 0 : goto success;
100 : : }
101 : :
102 : 0 : offset = elf->state.elf32.ehdr->e_shoff;
103 : :
104 [ # # ]: 0 : if (elf->map_address != NULL
105 : 0 : && elf->state.elf32.ehdr->e_ident[EI_DATA] == MY_ELFDATA
106 [ # # ]: 0 : && (ALLOW_UNALIGNED
107 : : || (((size_t) ((char *) elf->map_address + offset))
108 : : & (__alignof__ (Elf32_Shdr) - 1)) == 0))
109 : : /* We can directly access the memory. */
110 : 0 : num = ((Elf32_Shdr *) (elf->map_address + offset))->sh_link;
111 : : else
112 : : {
113 : : /* We avoid reading in all the section headers. Just read
114 : : the first one. */
115 : : Elf32_Shdr shdr_mem;
116 : :
117 [ # # ]: 0 : if (unlikely (pread_retry (elf->fildes, &shdr_mem,
118 : : sizeof (Elf32_Shdr), offset)
119 : : != sizeof (Elf32_Shdr)))
120 : : {
121 : : /* We must be able to read this ELF section header. */
122 : 0 : __libelf_seterrno (ELF_E_INVALID_FILE);
123 : 0 : result = -1;
124 : : goto out;
125 : : }
126 : :
127 [ # # ]: 0 : if (elf->state.elf32.ehdr->e_ident[EI_DATA] != MY_ELFDATA)
128 : 0 : CONVERT (shdr_mem.sh_link);
129 : 0 : num = shdr_mem.sh_link;
130 : : }
131 : : }
132 : : else
133 : : {
134 [ # # ]: 0 : if (elf->state.elf64.scns.data[0].shdr.e64 != NULL)
135 : : {
136 : 0 : num = elf->state.elf64.scns.data[0].shdr.e64->sh_link;
137 : 0 : goto success;
138 : : }
139 : :
140 : 0 : size_t offset = elf->state.elf64.ehdr->e_shoff;
141 : :
142 [ # # ]: 0 : if (elf->map_address != NULL
143 : 0 : && elf->state.elf64.ehdr->e_ident[EI_DATA] == MY_ELFDATA
144 [ # # ]: 0 : && (ALLOW_UNALIGNED
145 : : || (((size_t) ((char *) elf->map_address + offset))
146 : : & (__alignof__ (Elf64_Shdr) - 1)) == 0))
147 : : /* We can directly access the memory. */
148 : 0 : num = ((Elf64_Shdr *) (elf->map_address + offset))->sh_link;
149 : : else
150 : : {
151 : : /* We avoid reading in all the section headers. Just read
152 : : the first one. */
153 : : Elf64_Shdr shdr_mem;
154 : :
155 [ # # ]: 0 : if (unlikely (pread_retry (elf->fildes, &shdr_mem,
156 : : sizeof (Elf64_Shdr), offset)
157 : : != sizeof (Elf64_Shdr)))
158 : : {
159 : : /* We must be able to read this ELF section header. */
160 : 0 : __libelf_seterrno (ELF_E_INVALID_FILE);
161 : 0 : result = -1;
162 : : goto out;
163 : : }
164 : :
165 [ # # ]: 0 : if (elf->state.elf64.ehdr->e_ident[EI_DATA] != MY_ELFDATA)
166 : 0 : CONVERT (shdr_mem.sh_link);
167 : 0 : num = shdr_mem.sh_link;
168 : : }
169 : : }
170 : : }
171 : :
172 : : /* Store the result. */
173 : : success:
174 : 89652 : *dst = num;
175 : : }
176 : :
177 : : out:
178 : : rwlock_unlock (elf->lock);
179 : :
180 : 89652 : return result;
181 : : }
182 : : INTDEF(elf_getshdrstrndx)
183 : : /* Alias for the deprecated name. */
184 : : strong_alias (elf_getshdrstrndx, elf_getshstrndx)
|