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