1 /* Get ELF program header table.
2 Copyright (C) 1998-2010, 2014, 2015 Red Hat, Inc.
3 This file is part of elfutils.
4 Written 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 <errno.h>
35 #include <stdbool.h>
36 #include <stdlib.h>
37 #include <assert.h>
38
39 #include "libelfP.h"
40 #include "common.h"
41
42 #ifndef LIBELFBITS
43 # define LIBELFBITS 32
44 #endif
45
ElfW2(LIBELFBITS,Phdr)46 ElfW2(LIBELFBITS,Phdr) *
47 __elfw2(LIBELFBITS,getphdr_wrlock) (Elf *elf)
48 {
49 ElfW2(LIBELFBITS,Phdr) *result;
50
51 /* If the program header entry has already been filled in the code
52 below must already have been run. So the class is set, too. No
53 need to waste any more time here. */
54 result = elf->state.ELFW(elf,LIBELFBITS).phdr;
55 if (likely (result != NULL))
56 return result;
57
58 if (elf->class == 0)
59 elf->class = ELFW(ELFCLASS,LIBELFBITS);
60 else if (elf->class != ELFW(ELFCLASS,LIBELFBITS))
61 {
62 __libelf_seterrno (ELF_E_INVALID_CLASS);
63 result = NULL;
64 goto out;
65 }
66
67 if (likely (result == NULL))
68 {
69 /* Read the section header table. */
70 ElfW2(LIBELFBITS,Ehdr) *ehdr = elf->state.ELFW(elf,LIBELFBITS).ehdr;
71
72 /* If no program header exists return NULL. */
73 size_t phnum;
74 if (__elf_getphdrnum_rdlock (elf, &phnum) != 0)
75 goto out;
76 if (phnum == 0 || ehdr->e_phoff == 0)
77 {
78 __libelf_seterrno (ELF_E_NO_PHDR);
79 goto out;
80 }
81
82 /* Check this doesn't overflow. */
83 size_t size = phnum * sizeof (ElfW2(LIBELFBITS,Phdr));
84
85 if (phnum > SIZE_MAX / sizeof (ElfW2(LIBELFBITS,Phdr))
86 || ehdr->e_phoff > elf->maximum_size
87 || elf->maximum_size - ehdr->e_phoff < size)
88 {
89 __libelf_seterrno (ELF_E_INVALID_DATA);
90 goto out;
91 }
92
93 if (elf->map_address != NULL)
94 {
95 /* First see whether the information in the ELF header is
96 valid and it does not ask for too much. */
97 if (unlikely (ehdr->e_phoff >= elf->maximum_size)
98 || unlikely (elf->maximum_size - ehdr->e_phoff < size))
99 {
100 /* Something is wrong. */
101 __libelf_seterrno (ELF_E_INVALID_PHDR);
102 goto out;
103 }
104
105 /* All the data is already mapped. Use it. */
106 void *file_phdr = ((char *) elf->map_address
107 + elf->start_offset + ehdr->e_phoff);
108 if (ehdr->e_ident[EI_DATA] == MY_ELFDATA
109 && (ALLOW_UNALIGNED
110 || ((uintptr_t) file_phdr
111 & (__alignof__ (ElfW2(LIBELFBITS,Phdr)) - 1)) == 0))
112 /* Simply use the mapped data. */
113 elf->state.ELFW(elf,LIBELFBITS).phdr = file_phdr;
114 else
115 {
116 ElfW2(LIBELFBITS,Phdr) *notcvt;
117 ElfW2(LIBELFBITS,Phdr) *phdr;
118
119 /* Allocate memory for the program headers. We know the number
120 of entries from the ELF header. */
121 phdr = elf->state.ELFW(elf,LIBELFBITS).phdr =
122 (ElfW2(LIBELFBITS,Phdr) *) malloc (size);
123 if (elf->state.ELFW(elf,LIBELFBITS).phdr == NULL)
124 {
125 __libelf_seterrno (ELF_E_NOMEM);
126 goto out;
127 }
128 elf->state.ELFW(elf,LIBELFBITS).phdr_flags |=
129 ELF_F_MALLOCED | ELF_F_DIRTY;
130
131 /* Now copy the data and at the same time convert the
132 byte order. */
133
134 if (ehdr->e_ident[EI_DATA] == MY_ELFDATA)
135 {
136 assert (! ALLOW_UNALIGNED);
137 memcpy (phdr, file_phdr, size);
138 }
139 else
140 {
141 bool copy = ! (ALLOW_UNALIGNED
142 || ((uintptr_t) file_phdr
143 & (__alignof__ (ElfW2(LIBELFBITS,Phdr))
144 - 1)) == 0);
145 if (! copy)
146 notcvt = file_phdr;
147 else
148 {
149 notcvt = (ElfW2(LIBELFBITS,Phdr) *) malloc (size);
150 if (unlikely (notcvt == NULL))
151 {
152 __libelf_seterrno (ELF_E_NOMEM);
153 goto out;
154 }
155 memcpy (notcvt, file_phdr, size);
156 }
157
158 for (size_t cnt = 0; cnt < phnum; ++cnt)
159 {
160 CONVERT_TO (phdr[cnt].p_type, notcvt[cnt].p_type);
161 CONVERT_TO (phdr[cnt].p_offset, notcvt[cnt].p_offset);
162 CONVERT_TO (phdr[cnt].p_vaddr, notcvt[cnt].p_vaddr);
163 CONVERT_TO (phdr[cnt].p_paddr, notcvt[cnt].p_paddr);
164 CONVERT_TO (phdr[cnt].p_filesz, notcvt[cnt].p_filesz);
165 CONVERT_TO (phdr[cnt].p_memsz, notcvt[cnt].p_memsz);
166 CONVERT_TO (phdr[cnt].p_flags, notcvt[cnt].p_flags);
167 CONVERT_TO (phdr[cnt].p_align, notcvt[cnt].p_align);
168 }
169
170 if (copy)
171 free (notcvt);
172 }
173 }
174 }
175 else if (likely (elf->fildes != -1))
176 {
177 /* Allocate memory for the program headers. We know the number
178 of entries from the ELF header. */
179 elf->state.ELFW(elf,LIBELFBITS).phdr =
180 (ElfW2(LIBELFBITS,Phdr) *) malloc (size);
181 if (elf->state.ELFW(elf,LIBELFBITS).phdr == NULL)
182 {
183 __libelf_seterrno (ELF_E_NOMEM);
184 goto out;
185 }
186 elf->state.ELFW(elf,LIBELFBITS).phdr_flags |= ELF_F_MALLOCED;
187
188 /* Read the header. */
189 ssize_t n = pread_retry (elf->fildes,
190 elf->state.ELFW(elf,LIBELFBITS).phdr, size,
191 elf->start_offset + ehdr->e_phoff);
192 if (unlikely ((size_t) n != size))
193 {
194 /* Severe problems. We cannot read the data. */
195 __libelf_seterrno (ELF_E_READ_ERROR);
196 free (elf->state.ELFW(elf,LIBELFBITS).phdr);
197 elf->state.ELFW(elf,LIBELFBITS).phdr = NULL;
198 goto out;
199 }
200
201 /* If the byte order of the file is not the same as the one
202 of the host convert the data now. */
203 if (ehdr->e_ident[EI_DATA] != MY_ELFDATA)
204 {
205 ElfW2(LIBELFBITS,Phdr) *phdr
206 = elf->state.ELFW(elf,LIBELFBITS).phdr;
207
208 for (size_t cnt = 0; cnt < phnum; ++cnt)
209 {
210 CONVERT (phdr[cnt].p_type);
211 CONVERT (phdr[cnt].p_offset);
212 CONVERT (phdr[cnt].p_vaddr);
213 CONVERT (phdr[cnt].p_paddr);
214 CONVERT (phdr[cnt].p_filesz);
215 CONVERT (phdr[cnt].p_memsz);
216 CONVERT (phdr[cnt].p_flags);
217 CONVERT (phdr[cnt].p_align);
218 }
219 }
220 }
221 else
222 {
223 /* The file descriptor was already enabled and not all data was
224 read. */
225 __libelf_seterrno (ELF_E_FD_DISABLED);
226 goto out;
227 }
228
229 result = elf->state.ELFW(elf,LIBELFBITS).phdr;
230 }
231
232 out:
233 return result;
234 }
235
ElfW2(LIBELFBITS,Phdr)236 ElfW2(LIBELFBITS,Phdr) *
237 elfw2(LIBELFBITS,getphdr) (Elf *elf)
238 {
239 ElfW2(LIBELFBITS,Phdr) *result;
240
241 if (elf == NULL)
242 return NULL;
243
244 if (unlikely (elf->kind != ELF_K_ELF))
245 {
246 __libelf_seterrno (ELF_E_INVALID_HANDLE);
247 return NULL;
248 }
249
250 /* If the program header entry has already been filled in the code
251 * in getphdr_wrlock must already have been run. So the class is
252 * set, too. No need to waste any more time here. */
253 result = elf->state.ELFW(elf,LIBELFBITS).phdr;
254 if (likely (result != NULL))
255 return result;
256
257 rwlock_wrlock (elf->lock);
258 result = __elfw2(LIBELFBITS,getphdr_wrlock) (elf);
259 rwlock_unlock (elf->lock);
260
261 return result;
262 }
263 INTDEF(elfw2(LIBELFBITS,getphdr))
264