Branch data Line data Source code
1 : : /* Create descriptor for processing file.
2 : : Copyright (C) 1998-2010, 2012, 2014, 2015, 2016 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 <assert.h>
35 : : #include <ctype.h>
36 : : #include <errno.h>
37 : : #include <fcntl.h>
38 : : #include <stdbool.h>
39 : : #include <stddef.h>
40 : : #include <string.h>
41 : : #include <unistd.h>
42 : : #include <sys/mman.h>
43 : : #include <sys/stat.h>
44 : :
45 : : #include <system.h>
46 : : #include "libelfP.h"
47 : : #include "common.h"
48 : :
49 : :
50 : : /* Create descriptor for archive in memory. */
51 : : static inline Elf *
52 : : file_read_ar (int fildes, void *map_address, off_t offset, size_t maxsize,
53 : : Elf_Cmd cmd, Elf *parent)
54 : : {
55 : 137 : Elf *elf;
56 : :
57 : : /* Create a descriptor. */
58 : 274 : elf = allocate_elf (fildes, map_address, offset, maxsize, cmd, parent,
59 : : ELF_K_AR, 0);
60 [ + - + - ]: 137 : if (elf != NULL)
61 : : {
62 : : /* We don't read all the symbol tables in advance. All this will
63 : : happen on demand. */
64 : 137 : elf->state.ar.offset = offset + SARMAG;
65 : :
66 : 137 : elf->state.ar.elf_ar_hdr.ar_rawname = elf->state.ar.raw_name;
67 : : }
68 : :
69 : : return elf;
70 : : }
71 : :
72 : :
73 : : static size_t
74 : 14917 : get_shnum (void *map_address, unsigned char *e_ident, int fildes,
75 : : int64_t offset, size_t maxsize)
76 : : {
77 : 14917 : size_t result;
78 : 14917 : union
79 : : {
80 : : Elf32_Ehdr *e32;
81 : : Elf64_Ehdr *e64;
82 : : void *p;
83 : : } ehdr;
84 : 14917 : union
85 : : {
86 : : Elf32_Ehdr e32;
87 : : Elf64_Ehdr e64;
88 : : } ehdr_mem;
89 : 14917 : bool is32 = e_ident[EI_CLASS] == ELFCLASS32;
90 : :
91 [ + - ]: 14917 : if ((is32 && maxsize < sizeof (Elf32_Ehdr))
92 [ - + ]: 14917 : || (!is32 && maxsize < sizeof (Elf64_Ehdr)))
93 : : {
94 : 0 : __libelf_seterrno (ELF_E_INVALID_ELF);
95 : 0 : return (size_t) -1l;
96 : : }
97 : :
98 : : /* Make the ELF header available. */
99 [ + + ]: 14917 : if (e_ident[EI_DATA] == MY_ELFDATA
100 : : && (ALLOW_UNALIGNED
101 : : || (((size_t) e_ident
102 : : & ((is32 ? __alignof__ (Elf32_Ehdr) : __alignof__ (Elf64_Ehdr))
103 : : - 1)) == 0)))
104 : : ehdr.p = e_ident;
105 : : else
106 : : {
107 : : /* We already read the ELF header. We have to copy the header
108 : : since we possibly modify the data here and the caller
109 : : expects the memory it passes in to be preserved. */
110 : 684 : ehdr.p = &ehdr_mem;
111 : :
112 [ + + ]: 684 : if (is32)
113 : : {
114 : 313 : if (ALLOW_UNALIGNED)
115 : : {
116 : 313 : ehdr_mem.e32.e_shnum = ((Elf32_Ehdr *) e_ident)->e_shnum;
117 : 313 : ehdr_mem.e32.e_shoff = ((Elf32_Ehdr *) e_ident)->e_shoff;
118 : : }
119 : : else
120 : : memcpy (&ehdr_mem, e_ident, sizeof (Elf32_Ehdr));
121 : :
122 : 313 : if (e_ident[EI_DATA] != MY_ELFDATA)
123 : : {
124 : 313 : CONVERT (ehdr_mem.e32.e_shnum);
125 : 626 : CONVERT (ehdr_mem.e32.e_shoff);
126 : : }
127 : : }
128 : : else
129 : : {
130 : 371 : if (ALLOW_UNALIGNED)
131 : : {
132 : 371 : ehdr_mem.e64.e_shnum = ((Elf64_Ehdr *) e_ident)->e_shnum;
133 : 371 : ehdr_mem.e64.e_shoff = ((Elf64_Ehdr *) e_ident)->e_shoff;
134 : : }
135 : : else
136 : : memcpy (&ehdr_mem, e_ident, sizeof (Elf64_Ehdr));
137 : :
138 : 371 : if (e_ident[EI_DATA] != MY_ELFDATA)
139 : : {
140 : 371 : CONVERT (ehdr_mem.e64.e_shnum);
141 : 742 : CONVERT (ehdr_mem.e64.e_shoff);
142 : : }
143 : : }
144 : : }
145 : :
146 [ + + ]: 14917 : if (is32)
147 : : {
148 : : /* Get the number of sections from the ELF header. */
149 : 893 : result = ehdr.e32->e_shnum;
150 : :
151 [ + + ][ + + ]: 893 : if (unlikely (result == 0) && ehdr.e32->e_shoff != 0)
152 : : {
153 [ + - ]: 52 : if (unlikely (ehdr.e32->e_shoff >= maxsize)
154 [ + - ]: 52 : || unlikely (maxsize - ehdr.e32->e_shoff < sizeof (Elf32_Shdr)))
155 : : /* Cannot read the first section header. */
156 : : return 0;
157 : :
158 [ + + ]: 52 : if (likely (map_address != NULL) && e_ident[EI_DATA] == MY_ELFDATA
159 [ + + ]: 40 : && (ALLOW_UNALIGNED
160 : : || (((size_t) ((char *) map_address + ehdr.e32->e_shoff))
161 : : & (__alignof__ (Elf32_Shdr) - 1)) == 0))
162 : : /* We can directly access the memory. */
163 : 72 : result = ((Elf32_Shdr *) ((char *) map_address + ehdr.e32->e_shoff
164 : 24 : + offset))->sh_size;
165 : : else
166 : : {
167 : 28 : Elf32_Word size;
168 : 28 : ssize_t r;
169 : :
170 [ + + ]: 28 : if (likely (map_address != NULL))
171 : : /* gcc will optimize the memcpy to a simple memory
172 : : access while taking care of alignment issues. */
173 : 32 : memcpy (&size, &((Elf32_Shdr *) ((char *) map_address
174 : : + ehdr.e32->e_shoff
175 : 16 : + offset))->sh_size,
176 : : sizeof (Elf32_Word));
177 : : else
178 [ - + ]: 12 : if (unlikely ((r = pread_retry (fildes, &size,
179 : : sizeof (Elf32_Word),
180 : : offset + ehdr.e32->e_shoff
181 : : + offsetof (Elf32_Shdr,
182 : : sh_size)))
183 : : != sizeof (Elf32_Word)))
184 : : {
185 [ # # ]: 0 : if (r < 0)
186 : 0 : __libelf_seterrno (ELF_E_INVALID_FILE);
187 : : else
188 : 0 : __libelf_seterrno (ELF_E_INVALID_ELF);
189 : 0 : return (size_t) -1l;
190 : : }
191 : :
192 [ + + ]: 28 : if (e_ident[EI_DATA] != MY_ELFDATA)
193 : 40 : CONVERT (size);
194 : :
195 : 28 : result = size;
196 : : }
197 : : }
198 : :
199 : : /* If the section headers were truncated, pretend none were there. */
200 [ + - ]: 893 : if (ehdr.e32->e_shoff > maxsize
201 [ - + ]: 893 : || maxsize - ehdr.e32->e_shoff < sizeof (Elf32_Shdr) * result)
202 : 0 : result = 0;
203 : : }
204 : : else
205 : : {
206 : : /* Get the number of sections from the ELF header. */
207 : 14024 : result = ehdr.e64->e_shnum;
208 : :
209 [ + + ][ + + ]: 14024 : if (unlikely (result == 0) && ehdr.e64->e_shoff != 0)
210 : : {
211 [ + - ]: 41 : if (unlikely (ehdr.e64->e_shoff >= maxsize)
212 [ + - ]: 41 : || unlikely (ehdr.e64->e_shoff + sizeof (Elf64_Shdr) > maxsize))
213 : : /* Cannot read the first section header. */
214 : 0 : return 0;
215 : :
216 : 41 : Elf64_Xword size;
217 [ + + ]: 41 : if (likely (map_address != NULL) && e_ident[EI_DATA] == MY_ELFDATA
218 [ + + ]: 33 : && (ALLOW_UNALIGNED
219 : : || (((size_t) ((char *) map_address + ehdr.e64->e_shoff))
220 : : & (__alignof__ (Elf64_Shdr) - 1)) == 0))
221 : : /* We can directly access the memory. */
222 : 51 : size = ((Elf64_Shdr *) ((char *) map_address + ehdr.e64->e_shoff
223 : 17 : + offset))->sh_size;
224 : : else
225 : : {
226 : 24 : ssize_t r;
227 [ + + ]: 24 : if (likely (map_address != NULL))
228 : : /* gcc will optimize the memcpy to a simple memory
229 : : access while taking care of alignment issues. */
230 : 32 : memcpy (&size, &((Elf64_Shdr *) ((char *) map_address
231 : : + ehdr.e64->e_shoff
232 : 16 : + offset))->sh_size,
233 : : sizeof (Elf64_Xword));
234 : : else
235 [ - + ]: 8 : if (unlikely ((r = pread_retry (fildes, &size,
236 : : sizeof (Elf64_Xword),
237 : : offset + ehdr.e64->e_shoff
238 : : + offsetof (Elf64_Shdr,
239 : : sh_size)))
240 : : != sizeof (Elf64_Xword)))
241 : : {
242 [ # # ]: 0 : if (r < 0)
243 : 0 : __libelf_seterrno (ELF_E_INVALID_FILE);
244 : : else
245 : 0 : __libelf_seterrno (ELF_E_INVALID_ELF);
246 : 0 : return (size_t) -1l;
247 : : }
248 : :
249 [ + + ]: 24 : if (e_ident[EI_DATA] != MY_ELFDATA)
250 : 40 : CONVERT (size);
251 : : }
252 : :
253 : : /* Although sh_size is an Elf64_Xword and can contain a 64bit
254 : : value, we only expect an 32bit value max. GElf_Word is
255 : : 32bit unsigned. */
256 [ - + ]: 41 : if (size > ~((GElf_Word) 0))
257 : : {
258 : : /* Invalid value, it is too large. */
259 : 0 : __libelf_seterrno (ELF_E_INVALID_ELF);
260 : 0 : return (size_t) -1l;
261 : : }
262 : :
263 : 41 : result = size;
264 : : }
265 : :
266 : : /* If the section headers were truncated, pretend none were there. */
267 [ + + ]: 14024 : if (ehdr.e64->e_shoff > maxsize
268 [ - + ]: 14022 : || maxsize - ehdr.e64->e_shoff < sizeof (Elf64_Shdr) * result)
269 : 2 : result = 0;
270 : : }
271 : :
272 : : return result;
273 : : }
274 : :
275 : :
276 : : /* Create descriptor for ELF file in memory. */
277 : : static Elf *
278 : 14917 : file_read_elf (int fildes, void *map_address, unsigned char *e_ident,
279 : : int64_t offset, size_t maxsize, Elf_Cmd cmd, Elf *parent)
280 : : {
281 : : /* Verify the binary is of the class we can handle. */
282 [ + - ][ - + ]: 14917 : if (unlikely ((e_ident[EI_CLASS] != ELFCLASS32
283 : : && e_ident[EI_CLASS] != ELFCLASS64)
284 : : /* We also can only handle two encodings. */
285 : : || (e_ident[EI_DATA] != ELFDATA2LSB
286 : : && e_ident[EI_DATA] != ELFDATA2MSB)))
287 : : {
288 : : /* Cannot handle this. */
289 : 0 : __libelf_seterrno (ELF_E_INVALID_ELF);
290 : 0 : return NULL;
291 : : }
292 : :
293 : : /* Determine the number of sections. Returns -1 and sets libelf errno
294 : : if the file handle or elf file is invalid. Returns zero if there
295 : : are no section headers (or they cannot be read). */
296 : 14917 : size_t scncnt = get_shnum (map_address, e_ident, fildes, offset, maxsize);
297 [ + - ]: 14917 : if (scncnt == (size_t) -1l)
298 : : /* Could not determine the number of sections. */
299 : : return NULL;
300 : :
301 : : /* Check for too many sections. */
302 [ + + ]: 14917 : if (e_ident[EI_CLASS] == ELFCLASS32)
303 : : {
304 [ - + ]: 893 : if (scncnt > SIZE_MAX / (sizeof (Elf_Scn) + sizeof (Elf32_Shdr)))
305 : : {
306 : 0 : __libelf_seterrno (ELF_E_INVALID_ELF);
307 : 0 : return NULL;
308 : : }
309 : : }
310 [ - + ]: 14024 : else if (scncnt > SIZE_MAX / (sizeof (Elf_Scn) + sizeof (Elf64_Shdr)))
311 : : {
312 : 0 : __libelf_seterrno (ELF_E_INVALID_ELF);
313 : 0 : return NULL;
314 : : }
315 : :
316 : : /* We can now allocate the memory. Even if there are no section headers,
317 : : we allocate space for a zeroth section in case we need it later. */
318 [ + + ]: 14917 : const size_t scnmax = (scncnt ?: (cmd == ELF_C_RDWR || cmd == ELF_C_RDWR_MMAP)
319 : 191 : ? 1 : 0);
320 : 14917 : Elf *elf = allocate_elf (fildes, map_address, offset, maxsize, cmd, parent,
321 : : ELF_K_ELF, scnmax * sizeof (Elf_Scn));
322 [ + - ]: 14917 : if (elf == NULL)
323 : : /* Not enough memory. allocate_elf will have set libelf errno. */
324 : : return NULL;
325 : :
326 [ - + ]: 14917 : assert ((unsigned int) scncnt == scncnt);
327 : 14917 : assert (offsetof (struct Elf, state.elf32.scns)
328 : : == offsetof (struct Elf, state.elf64.scns));
329 : 14917 : elf->state.elf32.scns.cnt = scncnt;
330 : 14917 : elf->state.elf32.scns.max = scnmax;
331 : :
332 : : /* Some more or less arbitrary value. */
333 : 14917 : elf->state.elf.scnincr = 10;
334 : :
335 : : /* Make the class easily available. */
336 : 14917 : elf->class = e_ident[EI_CLASS];
337 : :
338 [ + + ]: 14917 : if (e_ident[EI_CLASS] == ELFCLASS32)
339 : : {
340 : : /* This pointer might not be directly usable if the alignment is
341 : : not sufficient for the architecture. */
342 : 893 : Elf32_Ehdr *ehdr = (Elf32_Ehdr *) ((char *) map_address + offset);
343 : :
344 : : /* This is a 32-bit binary. */
345 [ + + ]: 893 : if (map_address != NULL && e_ident[EI_DATA] == MY_ELFDATA
346 [ + + ]: 486 : && (ALLOW_UNALIGNED
347 : : || (((uintptr_t) ehdr) & (__alignof__ (Elf32_Ehdr) - 1)) == 0))
348 : : {
349 : : /* We can use the mmapped memory. */
350 : 322 : elf->state.elf32.ehdr = ehdr;
351 : : }
352 : : else
353 : : {
354 : : /* Copy the ELF header. */
355 [ + + ]: 571 : elf->state.elf32.ehdr = memcpy (&elf->state.elf32.ehdr_mem, e_ident,
356 : : sizeof (Elf32_Ehdr));
357 : :
358 [ + + ]: 571 : if (e_ident[EI_DATA] != MY_ELFDATA)
359 : : {
360 : 313 : CONVERT (elf->state.elf32.ehdr_mem.e_type);
361 : 313 : CONVERT (elf->state.elf32.ehdr_mem.e_machine);
362 : 313 : CONVERT (elf->state.elf32.ehdr_mem.e_version);
363 : 313 : CONVERT (elf->state.elf32.ehdr_mem.e_entry);
364 : 313 : CONVERT (elf->state.elf32.ehdr_mem.e_phoff);
365 : 313 : CONVERT (elf->state.elf32.ehdr_mem.e_shoff);
366 : 313 : CONVERT (elf->state.elf32.ehdr_mem.e_flags);
367 : 313 : CONVERT (elf->state.elf32.ehdr_mem.e_ehsize);
368 : 313 : CONVERT (elf->state.elf32.ehdr_mem.e_phentsize);
369 : 313 : CONVERT (elf->state.elf32.ehdr_mem.e_phnum);
370 : 313 : CONVERT (elf->state.elf32.ehdr_mem.e_shentsize);
371 : 313 : CONVERT (elf->state.elf32.ehdr_mem.e_shnum);
372 : 626 : CONVERT (elf->state.elf32.ehdr_mem.e_shstrndx);
373 : : }
374 : : }
375 : :
376 : : /* Don't precache the phdr pointer here.
377 : : elf32_getphdr will validate it against the size when asked. */
378 : :
379 : 893 : Elf32_Off e_shoff = elf->state.elf32.ehdr->e_shoff;
380 [ + + ][ + + ]: 893 : if (map_address != NULL && e_ident[EI_DATA] == MY_ELFDATA
381 : : && cmd != ELF_C_READ_MMAP /* We need a copy to be able to write. */
382 [ + + ]: 322 : && (ALLOW_UNALIGNED
383 : : || (((uintptr_t) ((char *) ehdr + e_shoff)
384 : : & (__alignof__ (Elf32_Shdr) - 1)) == 0)))
385 : : {
386 [ + + ][ - + ]: 175 : if (unlikely (scncnt > 0 && e_shoff >= maxsize)
387 [ - + ]: 175 : || unlikely (maxsize - e_shoff
388 : : < scncnt * sizeof (Elf32_Shdr)))
389 : : {
390 : 0 : free_and_out:
391 : 0 : free (elf);
392 : 0 : __libelf_seterrno (ELF_E_INVALID_ELF);
393 : 0 : return NULL;
394 : : }
395 : 175 : elf->state.elf32.shdr
396 : 175 : = (Elf32_Shdr *) ((char *) ehdr + e_shoff);
397 : :
398 [ + + ]: 594561 : for (size_t cnt = 0; cnt < scncnt; ++cnt)
399 : : {
400 : 594386 : elf->state.elf32.scns.data[cnt].index = cnt;
401 : 594386 : elf->state.elf32.scns.data[cnt].elf = elf;
402 : 1188772 : elf->state.elf32.scns.data[cnt].shdr.e32 =
403 : 594386 : &elf->state.elf32.shdr[cnt];
404 [ + + ]: 594386 : if (likely (elf->state.elf32.shdr[cnt].sh_offset < maxsize)
405 [ + + ]: 594384 : && likely (elf->state.elf32.shdr[cnt].sh_size
406 : : <= maxsize - elf->state.elf32.shdr[cnt].sh_offset))
407 : 1188752 : elf->state.elf32.scns.data[cnt].rawdata_base =
408 : 594376 : elf->state.elf32.scns.data[cnt].data_base =
409 : : ((char *) map_address + offset
410 : 594376 : + elf->state.elf32.shdr[cnt].sh_offset);
411 : 594386 : elf->state.elf32.scns.data[cnt].list = &elf->state.elf32.scns;
412 : :
413 : : /* If this is a section with an extended index add a
414 : : reference in the section which uses the extended
415 : : index. */
416 [ - + ]: 594386 : if (elf->state.elf32.shdr[cnt].sh_type == SHT_SYMTAB_SHNDX
417 [ # # ]: 0 : && elf->state.elf32.shdr[cnt].sh_link < scncnt)
418 : 0 : elf->state.elf32.scns.data[elf->state.elf32.shdr[cnt].sh_link].shndx_index
419 : 0 : = cnt;
420 : :
421 : : /* Set the own shndx_index field in case it has not yet
422 : : been set. */
423 [ + - ]: 594386 : if (elf->state.elf32.scns.data[cnt].shndx_index == 0)
424 : 594386 : elf->state.elf32.scns.data[cnt].shndx_index = -1;
425 : : }
426 : : }
427 : : else
428 : : {
429 [ + + ]: 3228990 : for (size_t cnt = 0; cnt < scncnt; ++cnt)
430 : : {
431 : 3228272 : elf->state.elf32.scns.data[cnt].index = cnt;
432 : 3228272 : elf->state.elf32.scns.data[cnt].elf = elf;
433 : 3228272 : elf->state.elf32.scns.data[cnt].list = &elf->state.elf32.scns;
434 : : }
435 : : }
436 : :
437 : : /* So far only one block with sections. */
438 : 893 : elf->state.elf32.scns_last = &elf->state.elf32.scns;
439 : : }
440 : : else
441 : : {
442 : : /* This pointer might not be directly usable if the alignment is
443 : : not sufficient for the architecture. */
444 : 14024 : Elf64_Ehdr *ehdr = (Elf64_Ehdr *) ((char *) map_address + offset);
445 : :
446 : : /* This is a 64-bit binary. */
447 [ + + ]: 14024 : if (map_address != NULL && e_ident[EI_DATA] == MY_ELFDATA
448 [ + + ]: 6372 : && (ALLOW_UNALIGNED
449 : : || (((uintptr_t) ehdr) & (__alignof__ (Elf64_Ehdr) - 1)) == 0))
450 : : {
451 : : /* We can use the mmapped memory. */
452 : 6162 : elf->state.elf64.ehdr = ehdr;
453 : : }
454 : : else
455 : : {
456 : : /* Copy the ELF header. */
457 [ + + ]: 7862 : elf->state.elf64.ehdr = memcpy (&elf->state.elf64.ehdr_mem, e_ident,
458 : : sizeof (Elf64_Ehdr));
459 : :
460 [ + + ]: 7862 : if (e_ident[EI_DATA] != MY_ELFDATA)
461 : : {
462 : 371 : CONVERT (elf->state.elf64.ehdr_mem.e_type);
463 : 371 : CONVERT (elf->state.elf64.ehdr_mem.e_machine);
464 : 371 : CONVERT (elf->state.elf64.ehdr_mem.e_version);
465 : 371 : CONVERT (elf->state.elf64.ehdr_mem.e_entry);
466 : 371 : CONVERT (elf->state.elf64.ehdr_mem.e_phoff);
467 : 371 : CONVERT (elf->state.elf64.ehdr_mem.e_shoff);
468 : 371 : CONVERT (elf->state.elf64.ehdr_mem.e_flags);
469 : 371 : CONVERT (elf->state.elf64.ehdr_mem.e_ehsize);
470 : 371 : CONVERT (elf->state.elf64.ehdr_mem.e_phentsize);
471 : 371 : CONVERT (elf->state.elf64.ehdr_mem.e_phnum);
472 : 371 : CONVERT (elf->state.elf64.ehdr_mem.e_shentsize);
473 : 371 : CONVERT (elf->state.elf64.ehdr_mem.e_shnum);
474 : 742 : CONVERT (elf->state.elf64.ehdr_mem.e_shstrndx);
475 : : }
476 : : }
477 : :
478 : : /* Don't precache the phdr pointer here.
479 : : elf64_getphdr will validate it against the size when asked. */
480 : :
481 : 14024 : Elf64_Off e_shoff = elf->state.elf64.ehdr->e_shoff;
482 [ + + ][ + + ]: 14024 : if (map_address != NULL && e_ident[EI_DATA] == MY_ELFDATA
483 : : && cmd != ELF_C_READ_MMAP /* We need a copy to be able to write. */
484 [ + + ]: 6162 : && (ALLOW_UNALIGNED
485 : : || (((uintptr_t) ((char *) ehdr + e_shoff)
486 : : & (__alignof__ (Elf64_Shdr) - 1)) == 0)))
487 : : {
488 [ - + ]: 5560 : if (unlikely (scncnt > 0 && e_shoff >= maxsize)
489 [ - + ]: 5560 : || unlikely (maxsize - e_shoff
490 : : < scncnt * sizeof (Elf64_Shdr)))
491 : : goto free_and_out;
492 : 5560 : elf->state.elf64.shdr
493 : 5560 : = (Elf64_Shdr *) ((char *) ehdr + e_shoff);
494 : :
495 [ + + ]: 811597 : for (size_t cnt = 0; cnt < scncnt; ++cnt)
496 : : {
497 : 806037 : elf->state.elf64.scns.data[cnt].index = cnt;
498 : 806037 : elf->state.elf64.scns.data[cnt].elf = elf;
499 : 1612074 : elf->state.elf64.scns.data[cnt].shdr.e64 =
500 : 806037 : &elf->state.elf64.shdr[cnt];
501 [ + + ]: 806037 : if (likely (elf->state.elf64.shdr[cnt].sh_offset < maxsize)
502 [ + + ]: 806007 : && likely (elf->state.elf64.shdr[cnt].sh_size
503 : : <= maxsize - elf->state.elf64.shdr[cnt].sh_offset))
504 : 1611962 : elf->state.elf64.scns.data[cnt].rawdata_base =
505 : 805981 : elf->state.elf64.scns.data[cnt].data_base =
506 : : ((char *) map_address + offset
507 : 805981 : + elf->state.elf64.shdr[cnt].sh_offset);
508 : 806037 : elf->state.elf64.scns.data[cnt].list = &elf->state.elf64.scns;
509 : :
510 : : /* If this is a section with an extended index add a
511 : : reference in the section which uses the extended
512 : : index. */
513 [ - + ]: 806037 : if (elf->state.elf64.shdr[cnt].sh_type == SHT_SYMTAB_SHNDX
514 [ # # ]: 0 : && elf->state.elf64.shdr[cnt].sh_link < scncnt)
515 : 0 : elf->state.elf64.scns.data[elf->state.elf64.shdr[cnt].sh_link].shndx_index
516 : 0 : = cnt;
517 : :
518 : : /* Set the own shndx_index field in case it has not yet
519 : : been set. */
520 [ + - ]: 806037 : if (elf->state.elf64.scns.data[cnt].shndx_index == 0)
521 : 806037 : elf->state.elf64.scns.data[cnt].shndx_index = -1;
522 : : }
523 : : }
524 : : else
525 : : {
526 [ + + ]: 2782822 : for (size_t cnt = 0; cnt < scncnt; ++cnt)
527 : : {
528 : 2774358 : elf->state.elf64.scns.data[cnt].index = cnt;
529 : 2774358 : elf->state.elf64.scns.data[cnt].elf = elf;
530 : 2774358 : elf->state.elf64.scns.data[cnt].list = &elf->state.elf64.scns;
531 : : }
532 : : }
533 : :
534 : : /* So far only one block with sections. */
535 : 14024 : elf->state.elf64.scns_last = &elf->state.elf64.scns;
536 : : }
537 : :
538 : : return elf;
539 : : }
540 : :
541 : :
542 : : Elf *
543 : : internal_function
544 : 6943 : __libelf_read_mmaped_file (int fildes, void *map_address, int64_t offset,
545 : : size_t maxsize, Elf_Cmd cmd, Elf *parent)
546 : : {
547 : : /* We have to find out what kind of file this is. We handle ELF
548 : : files and archives. To find out what we have we must look at the
549 : : header. The header for an ELF file is EI_NIDENT bytes in size,
550 : : the header for an archive file SARMAG bytes long. */
551 : 6943 : unsigned char *e_ident = (unsigned char *) map_address + offset;
552 : :
553 : : /* See what kind of object we have here. */
554 : 6943 : Elf_Kind kind = determine_kind (e_ident, maxsize);
555 : :
556 [ + + + ]: 6943 : switch (kind)
557 : : {
558 : 6858 : case ELF_K_ELF:
559 : 6858 : return file_read_elf (fildes, map_address, e_ident, offset, maxsize,
560 : : cmd, parent);
561 : :
562 : : case ELF_K_AR:
563 : 10 : return file_read_ar (fildes, map_address, offset, maxsize, cmd, parent);
564 : :
565 : : default:
566 : 75 : break;
567 : : }
568 : :
569 : : /* This case is easy. Since we cannot do anything with this file
570 : : create a dummy descriptor. */
571 : 75 : return allocate_elf (fildes, map_address, offset, maxsize, cmd, parent,
572 : : ELF_K_NONE, 0);
573 : : }
574 : :
575 : :
576 : : static Elf *
577 : 8418 : read_unmmaped_file (int fildes, int64_t offset, size_t maxsize, Elf_Cmd cmd,
578 : : Elf *parent)
579 : : {
580 : : /* We have to find out what kind of file this is. We handle ELF
581 : : files and archives. To find out what we have we must read the
582 : : header. The identification header for an ELF file is EI_NIDENT
583 : : bytes in size, but we read the whole ELF header since we will
584 : : need it anyway later. For archives the header in SARMAG bytes
585 : : long. Read the maximum of these numbers.
586 : :
587 : : XXX We have to change this for the extended `ar' format some day.
588 : :
589 : : Use a union to ensure alignment. We might later access the
590 : : memory as a ElfXX_Ehdr. */
591 : 8418 : union
592 : : {
593 : : Elf64_Ehdr ehdr;
594 : : unsigned char header[MAX (sizeof (Elf64_Ehdr), SARMAG)];
595 : : } mem;
596 : :
597 : : /* Read the head of the file. */
598 : 25254 : ssize_t nread = pread_retry (fildes, mem.header,
599 : 8418 : MIN (MAX (sizeof (Elf64_Ehdr), SARMAG),
600 : : maxsize),
601 : : offset);
602 [ - + ]: 8418 : if (unlikely (nread == -1))
603 : : {
604 : : /* We cannot even read the head of the file. Maybe FILDES is associated
605 : : with an unseekable device. This is nothing we can handle. */
606 : 0 : __libelf_seterrno (ELF_E_INVALID_FILE);
607 : 0 : return NULL;
608 : : }
609 : :
610 : : /* See what kind of object we have here. */
611 : 8418 : Elf_Kind kind = determine_kind (mem.header, nread);
612 : :
613 [ + + + ]: 8418 : switch (kind)
614 : : {
615 : : case ELF_K_AR:
616 : 127 : return file_read_ar (fildes, NULL, offset, maxsize, cmd, parent);
617 : :
618 : 8059 : case ELF_K_ELF:
619 : : /* Make sure at least the ELF header is contained in the file. */
620 [ + - ]: 8059 : if ((size_t) nread >= (mem.header[EI_CLASS] == ELFCLASS32
621 [ + + ]: 8059 : ? sizeof (Elf32_Ehdr) : sizeof (Elf64_Ehdr)))
622 : 8059 : return file_read_elf (fildes, NULL, mem.header, offset, maxsize, cmd,
623 : : parent);
624 : 232 : FALLTHROUGH;
625 : :
626 : : default:
627 : 232 : break;
628 : : }
629 : :
630 : : /* This case is easy. Since we cannot do anything with this file
631 : : create a dummy descriptor. */
632 : 232 : return allocate_elf (fildes, NULL, offset, maxsize, cmd, parent,
633 : : ELF_K_NONE, 0);
634 : : }
635 : :
636 : :
637 : : /* Open a file for reading. If possible we will try to mmap() the file. */
638 : : static struct Elf *
639 : 15290 : read_file (int fildes, int64_t offset, size_t maxsize,
640 : : Elf_Cmd cmd, Elf *parent)
641 : : {
642 : 15290 : void *map_address = NULL;
643 : 30580 : int use_mmap = (cmd == ELF_C_READ_MMAP || cmd == ELF_C_RDWR_MMAP
644 : : || cmd == ELF_C_WRITE_MMAP
645 : 15290 : || cmd == ELF_C_READ_MMAP_PRIVATE);
646 : :
647 [ + + ]: 15290 : if (parent == NULL)
648 : : {
649 [ + - ]: 8060 : if (maxsize == ~((size_t) 0))
650 : : {
651 : : /* We don't know in the moment how large the file is.
652 : : Determine it now. */
653 : 8060 : struct stat st;
654 : :
655 [ + - ]: 8060 : if (fstat (fildes, &st) == 0
656 : : && (sizeof (size_t) >= sizeof (st.st_size)
657 : : || st.st_size <= ~((size_t) 0)))
658 : 8060 : maxsize = (size_t) st.st_size;
659 : : }
660 : : }
661 : : else
662 : : {
663 : : /* The parent is already loaded. Use it. */
664 [ - + ]: 7230 : assert (maxsize != ~((size_t) 0));
665 : : }
666 : :
667 [ + + ]: 15290 : if (use_mmap)
668 : : {
669 [ + + ]: 6878 : if (parent == NULL)
670 : : {
671 : : /* We try to map the file ourself. */
672 [ + + ]: 12707 : map_address = mmap (NULL, maxsize, (cmd == ELF_C_READ_MMAP
673 : : ? PROT_READ
674 : : : PROT_READ|PROT_WRITE),
675 : 6815 : cmd == ELF_C_READ_MMAP_PRIVATE
676 [ + + ]: 6815 : || cmd == ELF_C_READ_MMAP
677 : : ? MAP_PRIVATE : MAP_SHARED,
678 : : fildes, offset);
679 : :
680 [ + + ]: 6815 : if (map_address == MAP_FAILED)
681 : : map_address = NULL;
682 : : }
683 : : else
684 : : {
685 : 63 : map_address = parent->map_address;
686 : : }
687 : : }
688 : :
689 : : /* If we have the file in memory optimize the access. */
690 [ + - ]: 6872 : if (map_address != NULL)
691 : : {
692 [ - + ]: 6872 : assert (map_address != MAP_FAILED);
693 : :
694 : 6872 : struct Elf *result = __libelf_read_mmaped_file (fildes, map_address,
695 : : offset, maxsize, cmd,
696 : : parent);
697 : :
698 : : /* If something went wrong during the initialization unmap the
699 : : memory if we mmaped here. */
700 [ - + ]: 6872 : if (result == NULL
701 [ # # ]: 0 : && (parent == NULL
702 [ # # ]: 0 : || parent->map_address != map_address))
703 : 0 : munmap (map_address, maxsize);
704 [ + + ]: 6872 : else if (parent == NULL)
705 : : /* Remember that we mmap()ed the memory. */
706 : 6809 : result->flags |= ELF_F_MMAPPED;
707 : :
708 : 6872 : return result;
709 : : }
710 : :
711 : : /* Otherwise we have to do it the hard way. We read as much as necessary
712 : : from the file whenever we need information which is not available. */
713 : 8418 : return read_unmmaped_file (fildes, offset, maxsize, cmd, parent);
714 : : }
715 : :
716 : :
717 : : /* Find the entry with the long names for the content of this archive. */
718 : : static const char *
719 : 102 : read_long_names (Elf *elf)
720 : : {
721 : 102 : off_t offset = SARMAG; /* This is the first entry. */
722 : 204 : struct ar_hdr hdrm;
723 : 204 : struct ar_hdr *hdr;
724 : 204 : char *newp;
725 : 204 : size_t len;
726 : :
727 : 204 : while (1)
728 : 102 : {
729 [ - + ]: 204 : if (elf->map_address != NULL)
730 : : {
731 [ # # ]: 0 : if ((size_t) offset > elf->maximum_size
732 [ # # ]: 0 : || elf->maximum_size - offset < sizeof (struct ar_hdr))
733 : 0 : return NULL;
734 : :
735 : : /* The data is mapped. */
736 : 0 : hdr = (struct ar_hdr *) (elf->map_address + offset);
737 : : }
738 : : else
739 : : {
740 : : /* Read the header from the file. */
741 [ + - ]: 204 : if (unlikely (pread_retry (elf->fildes, &hdrm, sizeof (hdrm),
742 : : elf->start_offset + offset)
743 : : != sizeof (hdrm)))
744 : : return NULL;
745 : :
746 : : hdr = &hdrm;
747 : : }
748 : :
749 : : /* The ar_size is given as a fixed size decimal string, right
750 : : padded with spaces. Make sure we read it properly even if
751 : : there is no terminating space. */
752 : 204 : char buf[sizeof (hdr->ar_size) + 1];
753 : 204 : const char *string = hdr->ar_size;
754 [ - + ]: 204 : if (hdr->ar_size[sizeof (hdr->ar_size) - 1] != ' ')
755 : : {
756 : 0 : *((char *) mempcpy (buf, hdr->ar_size, sizeof (hdr->ar_size))) = '\0';
757 : 0 : string = buf;
758 : : }
759 : 204 : len = atol (string);
760 : :
761 [ + + ]: 204 : if (memcmp (hdr->ar_name, "// ", 16) == 0)
762 : : break;
763 : :
764 : 102 : offset += sizeof (struct ar_hdr) + ((len + 1) & ~1l);
765 : : }
766 : :
767 : : /* Sanity check len early if we can. */
768 [ - + ]: 102 : if (elf->map_address != NULL)
769 : : {
770 [ # # ]: 0 : if (len > elf->maximum_size - offset - sizeof (struct ar_hdr))
771 : : return NULL;
772 : : }
773 : :
774 : : /* Due to the stupid format of the long name table entry (which are not
775 : : NUL terminted) we have to provide an appropriate representation anyhow.
776 : : Therefore we always make a copy which has the appropriate form. */
777 : 102 : newp = (char *) malloc (len);
778 [ + - ]: 102 : if (newp != NULL)
779 : : {
780 : 102 : char *runp;
781 : :
782 [ - + ]: 102 : if (elf->map_address != NULL)
783 : : {
784 : : /* Simply copy it over. */
785 : 0 : elf->state.ar.long_names = (char *) memcpy (newp,
786 : : elf->map_address + offset
787 : 0 : + sizeof (struct ar_hdr),
788 : : len);
789 : : }
790 : : else
791 : : {
792 [ - + ]: 102 : if (unlikely ((size_t) pread_retry (elf->fildes, newp, len,
793 : : elf->start_offset + offset
794 : : + sizeof (struct ar_hdr))
795 : : != len))
796 : : {
797 : : /* We were not able to read all data. */
798 : 0 : free (newp);
799 : 0 : elf->state.ar.long_names = NULL;
800 : 0 : return NULL;
801 : : }
802 : 102 : elf->state.ar.long_names = newp;
803 : : }
804 : :
805 : 102 : elf->state.ar.long_names_len = len;
806 : :
807 : : /* Now NUL-terminate the strings. */
808 : 102 : runp = newp;
809 : 4182 : while (1)
810 : : {
811 : 4182 : char *startp = runp;
812 : 4182 : runp = (char *) memchr (runp, '/', newp + len - runp);
813 [ + + ]: 4182 : if (runp == NULL)
814 : : {
815 : : /* This was the last entry. Clear any left overs. */
816 : 102 : memset (startp, '\0', newp + len - startp);
817 : : break;
818 : : }
819 : :
820 : : /* NUL-terminate the string. */
821 : 4080 : *runp++ = '\0';
822 : :
823 : : /* A sanity check. Somebody might have generated invalid
824 : : archive. */
825 [ + - ]: 4080 : if (runp >= newp + len)
826 : : break;
827 : : }
828 : : }
829 : :
830 : : return newp;
831 : : }
832 : :
833 : :
834 : : /* Read the next archive header. */
835 : : int
836 : : internal_function
837 : 7238 : __libelf_next_arhdr_wrlock (Elf *elf)
838 : : {
839 : 7238 : struct ar_hdr *ar_hdr;
840 : 7238 : Elf_Arhdr *elf_ar_hdr;
841 : :
842 [ + + ]: 7238 : if (elf->map_address != NULL)
843 : : {
844 : : /* See whether this entry is in the file. */
845 [ + - ][ + + ]: 71 : if (unlikely ((size_t) elf->state.ar.offset
846 : : > elf->start_offset + elf->maximum_size
847 : : || (elf->start_offset + elf->maximum_size
848 : : - elf->state.ar.offset) < sizeof (struct ar_hdr)))
849 : : {
850 : : /* This record is not anymore in the file. */
851 : 8 : __libelf_seterrno (ELF_E_RANGE);
852 : 8 : return -1;
853 : : }
854 : 63 : ar_hdr = (struct ar_hdr *) (elf->map_address + elf->state.ar.offset);
855 : : }
856 : : else
857 : : {
858 : 7167 : ar_hdr = &elf->state.ar.ar_hdr;
859 : :
860 [ - + ]: 7167 : if (unlikely (pread_retry (elf->fildes, ar_hdr, sizeof (struct ar_hdr),
861 : : elf->state.ar.offset)
862 : : != sizeof (struct ar_hdr)))
863 : : {
864 : : /* Something went wrong while reading the file. */
865 : 0 : __libelf_seterrno (ELF_E_RANGE);
866 : 0 : return -1;
867 : : }
868 : : }
869 : :
870 : : /* One little consistency check. */
871 [ - + ]: 7230 : if (unlikely (memcmp (ar_hdr->ar_fmag, ARFMAG, 2) != 0))
872 : : {
873 : : /* This is no valid archive. */
874 : 0 : __libelf_seterrno (ELF_E_ARCHIVE_FMAG);
875 : 0 : return -1;
876 : : }
877 : :
878 : : /* Copy the raw name over to a NUL terminated buffer. */
879 [ + + ]: 7230 : *((char *) mempcpy (elf->state.ar.raw_name, ar_hdr->ar_name, 16)) = '\0';
880 : :
881 : 7230 : elf_ar_hdr = &elf->state.ar.elf_ar_hdr;
882 : :
883 : : /* Now convert the `struct ar_hdr' into `Elf_Arhdr'.
884 : : Determine whether this is a special entry. */
885 [ + + ]: 7230 : if (ar_hdr->ar_name[0] == '/')
886 : : {
887 [ + + ]: 2077 : if (ar_hdr->ar_name[1] == ' '
888 [ + - ]: 120 : && memcmp (ar_hdr->ar_name, "/ ", 16) == 0)
889 : : /* This is the index. */
890 : 240 : elf_ar_hdr->ar_name = memcpy (elf->state.ar.ar_name, "/", 2);
891 [ + + ]: 1957 : else if (ar_hdr->ar_name[1] == 'S'
892 [ + - ]: 1 : && memcmp (ar_hdr->ar_name, "/SYM64/ ", 16) == 0)
893 : : /* 64-bit index. */
894 : 2 : elf_ar_hdr->ar_name = memcpy (elf->state.ar.ar_name, "/SYM64/", 8);
895 [ + + ]: 1956 : else if (ar_hdr->ar_name[1] == '/'
896 [ + - ]: 116 : && memcmp (ar_hdr->ar_name, "// ", 16) == 0)
897 : : /* This is the array with the long names. */
898 : 232 : elf_ar_hdr->ar_name = memcpy (elf->state.ar.ar_name, "//", 3);
899 [ + - ]: 1840 : else if (likely (isdigit (ar_hdr->ar_name[1])))
900 : : {
901 : 1840 : size_t offset;
902 : :
903 : : /* This is a long name. First we have to read the long name
904 : : table, if this hasn't happened already. */
905 [ + + ][ - + ]: 1840 : if (unlikely (elf->state.ar.long_names == NULL
906 : : && read_long_names (elf) == NULL))
907 : : {
908 : : /* No long name table although it is reference. The archive is
909 : : broken. */
910 : 0 : __libelf_seterrno (ELF_E_INVALID_ARCHIVE);
911 : 0 : return -1;
912 : : }
913 : :
914 : 1840 : offset = atol (ar_hdr->ar_name + 1);
915 [ - + ]: 1840 : if (unlikely (offset >= elf->state.ar.long_names_len))
916 : : {
917 : : /* The index in the long name table is larger than the table. */
918 : 0 : __libelf_seterrno (ELF_E_INVALID_ARCHIVE);
919 : 0 : return -1;
920 : : }
921 : 1840 : elf_ar_hdr->ar_name = elf->state.ar.long_names + offset;
922 : : }
923 : : else
924 : : {
925 : : /* This is none of the known special entries. */
926 : 0 : __libelf_seterrno (ELF_E_INVALID_ARCHIVE);
927 : 0 : return -1;
928 : : }
929 : : }
930 : : else
931 : : {
932 : 5153 : char *endp;
933 : :
934 : : /* It is a normal entry. Copy over the name. */
935 : 5153 : endp = (char *) memccpy (elf->state.ar.ar_name, ar_hdr->ar_name,
936 : : '/', 16);
937 [ + - ]: 5153 : if (endp != NULL)
938 : 5153 : endp[-1] = '\0';
939 : : else
940 : : {
941 : : /* In the old BSD style of archive, there is no / terminator.
942 : : Instead, there is space padding at the end of the name. */
943 : : size_t i = 15;
944 : 0 : do
945 : 0 : elf->state.ar.ar_name[i] = '\0';
946 [ # # # # ]: 0 : while (i > 0 && elf->state.ar.ar_name[--i] == ' ');
947 : : }
948 : :
949 : 5153 : elf_ar_hdr->ar_name = elf->state.ar.ar_name;
950 : : }
951 : :
952 [ - + ]: 7230 : if (unlikely (ar_hdr->ar_size[0] == ' '))
953 : : /* Something is really wrong. We cannot live without a size for
954 : : the member since it will not be possible to find the next
955 : : archive member. */
956 : : {
957 : 0 : __libelf_seterrno (ELF_E_INVALID_ARCHIVE);
958 : 0 : return -1;
959 : : }
960 : :
961 : : /* Since there are no specialized functions to convert ASCII to
962 : : time_t, uid_t, gid_t, mode_t, and off_t we use either atol or
963 : : atoll depending on the size of the types. We are also prepared
964 : : for the case where the whole field in the `struct ar_hdr' is
965 : : filled in which case we cannot simply use atol/l but instead have
966 : : to create a temporary copy. */
967 : :
968 : : #define INT_FIELD(FIELD) \
969 : : do \
970 : : { \
971 : : char buf[sizeof (ar_hdr->FIELD) + 1]; \
972 : : const char *string = ar_hdr->FIELD; \
973 : : if (ar_hdr->FIELD[sizeof (ar_hdr->FIELD) - 1] != ' ') \
974 : : { \
975 : : *((char *) mempcpy (buf, ar_hdr->FIELD, sizeof (ar_hdr->FIELD))) \
976 : : = '\0'; \
977 : : string = buf; \
978 : : } \
979 : : if (sizeof (elf_ar_hdr->FIELD) <= sizeof (long int)) \
980 : : elf_ar_hdr->FIELD = (__typeof (elf_ar_hdr->FIELD)) atol (string); \
981 : : else \
982 : : elf_ar_hdr->FIELD = (__typeof (elf_ar_hdr->FIELD)) atoll (string); \
983 : : } \
984 : : while (0)
985 : :
986 [ - + ]: 7230 : INT_FIELD (ar_date);
987 [ - + ]: 7230 : INT_FIELD (ar_uid);
988 [ - + ]: 7230 : INT_FIELD (ar_gid);
989 [ - + ]: 7230 : INT_FIELD (ar_mode);
990 [ - + ]: 7230 : INT_FIELD (ar_size);
991 : :
992 [ - + ]: 7230 : if (elf_ar_hdr->ar_size < 0)
993 : : {
994 : 0 : __libelf_seterrno (ELF_E_INVALID_ARCHIVE);
995 : 0 : return -1;
996 : : }
997 : :
998 : : /* Truncated file? */
999 : 7230 : size_t maxsize;
1000 : 14460 : maxsize = (elf->start_offset + elf->maximum_size
1001 : 7230 : - elf->state.ar.offset - sizeof (struct ar_hdr));
1002 [ - + ]: 7230 : if ((size_t) elf_ar_hdr->ar_size > maxsize)
1003 : 0 : elf_ar_hdr->ar_size = maxsize;
1004 : :
1005 : : return 0;
1006 : : }
1007 : :
1008 : :
1009 : : /* We were asked to return a clone of an existing descriptor. This
1010 : : function must be called with the lock on the parent descriptor
1011 : : being held. */
1012 : : static Elf *
1013 : 7231 : dup_elf (int fildes, Elf_Cmd cmd, Elf *ref)
1014 : : {
1015 : 7231 : struct Elf *result;
1016 : :
1017 [ + + ]: 7231 : if (fildes == -1)
1018 : : /* Allow the user to pass -1 as the file descriptor for the new file. */
1019 : 6 : fildes = ref->fildes;
1020 : : /* The file descriptor better should be the same. If it was disconnected
1021 : : already (using `elf_cntl') we do not test it. */
1022 [ + - ][ - + ]: 7225 : else if (unlikely (ref->fildes != -1 && fildes != ref->fildes))
1023 : : {
1024 : 0 : __libelf_seterrno (ELF_E_FD_MISMATCH);
1025 : 0 : return NULL;
1026 : : }
1027 : :
1028 : : /* The mode must allow reading. I.e., a descriptor creating with a
1029 : : command different then ELF_C_READ, ELF_C_WRITE and ELF_C_RDWR is
1030 : : not allowed. */
1031 [ - + # # : 7231 : if (unlikely (ref->cmd != ELF_C_READ && ref->cmd != ELF_C_READ_MMAP
# # # # #
# # # ]
1032 : : && ref->cmd != ELF_C_WRITE && ref->cmd != ELF_C_WRITE_MMAP
1033 : : && ref->cmd != ELF_C_RDWR && ref->cmd != ELF_C_RDWR_MMAP
1034 : : && ref->cmd != ELF_C_READ_MMAP_PRIVATE))
1035 : : {
1036 : 0 : __libelf_seterrno (ELF_E_INVALID_OP);
1037 : 0 : return NULL;
1038 : : }
1039 : :
1040 : : /* Now it is time to distinguish between reading normal files and
1041 : : archives. Normal files can easily be handled be incrementing the
1042 : : reference counter and return the same descriptor. */
1043 [ - + ]: 7231 : if (ref->kind != ELF_K_AR)
1044 : : {
1045 : 0 : ++ref->ref_count;
1046 : 0 : return ref;
1047 : : }
1048 : :
1049 : : /* This is an archive. We must create a descriptor for the archive
1050 : : member the internal pointer of the archive file descriptor is
1051 : : pointing to. First read the header of the next member if this
1052 : : has not happened already. */
1053 [ + + ]: 7231 : if (ref->state.ar.elf_ar_hdr.ar_name == NULL
1054 [ + + ]: 124 : && __libelf_next_arhdr_wrlock (ref) != 0)
1055 : : /* Something went wrong. Maybe there is no member left. */
1056 : : return NULL;
1057 : :
1058 : : /* We have all the information we need about the next archive member.
1059 : : Now create a descriptor for it. */
1060 : 21690 : result = read_file (fildes, ref->state.ar.offset + sizeof (struct ar_hdr),
1061 : 7230 : ref->state.ar.elf_ar_hdr.ar_size, cmd, ref);
1062 : :
1063 : : /* Enlist this new descriptor in the list of children. */
1064 [ + - ]: 7230 : if (result != NULL)
1065 : : {
1066 : 7230 : result->next = ref->state.ar.children;
1067 : 7230 : ref->state.ar.children = result;
1068 : : }
1069 : :
1070 : : return result;
1071 : : }
1072 : :
1073 : :
1074 : : /* Return descriptor for empty file ready for writing. */
1075 : : static struct Elf *
1076 : 439 : write_file (int fd, Elf_Cmd cmd)
1077 : : {
1078 : : /* We simply create an empty `Elf' structure. */
1079 : : #define NSCNSALLOC 10
1080 : 439 : Elf *result = allocate_elf (fd, NULL, 0, 0, cmd, NULL, ELF_K_ELF,
1081 : : NSCNSALLOC * sizeof (Elf_Scn));
1082 : :
1083 [ + - ]: 439 : if (result != NULL)
1084 : : {
1085 : : /* We have to write to the file in any case. */
1086 : 439 : result->flags = ELF_F_DIRTY;
1087 : :
1088 : : /* Some more or less arbitrary value. */
1089 : 439 : result->state.elf.scnincr = NSCNSALLOC;
1090 : :
1091 : : /* We have allocated room for some sections. */
1092 : 439 : assert (offsetof (struct Elf, state.elf32.scns)
1093 : : == offsetof (struct Elf, state.elf64.scns));
1094 : 439 : result->state.elf.scns_last = &result->state.elf32.scns;
1095 : 439 : result->state.elf32.scns.max = NSCNSALLOC;
1096 : : }
1097 : :
1098 : 439 : return result;
1099 : : }
1100 : :
1101 : : /* Lock if necessary before dup an archive. */
1102 : : static inline Elf *
1103 : : lock_dup_elf (int fildes, Elf_Cmd cmd, Elf *ref)
1104 : : {
1105 : : /* We need wrlock to dup an archive. */
1106 : 7231 : if (ref->kind == ELF_K_AR)
1107 : : {
1108 : 7231 : rwlock_unlock (ref->lock);
1109 : 7231 : rwlock_wrlock (ref->lock);
1110 : : }
1111 : : /* Duplicate the descriptor. */
1112 : 7231 : return dup_elf (fildes, cmd, ref);
1113 : : }
1114 : :
1115 : : /* Return a descriptor for the file belonging to FILDES. */
1116 : : Elf *
1117 : 15737 : elf_begin (int fildes, Elf_Cmd cmd, Elf *ref)
1118 : : {
1119 : 15737 : Elf *retval;
1120 : :
1121 [ - + ]: 15737 : if (unlikely (__libelf_version != EV_CURRENT))
1122 : : {
1123 : : /* Version wasn't set so far. */
1124 : 0 : __libelf_seterrno (ELF_E_NO_VERSION);
1125 : 0 : return NULL;
1126 : : }
1127 : :
1128 [ + + ]: 15737 : if (ref != NULL)
1129 : : /* Make sure the descriptor is not suddenly going away. */
1130 : : rwlock_rdlock (ref->lock);
1131 [ - + # # ]: 8499 : else if (unlikely (fcntl (fildes, F_GETFD) == -1 && errno == EBADF))
1132 : : {
1133 : : /* We cannot do anything productive without a file descriptor. */
1134 : 0 : __libelf_seterrno (ELF_E_INVALID_FILE);
1135 : 0 : return NULL;
1136 : : }
1137 : :
1138 [ + + + + : 15737 : switch (cmd)
- + ]
1139 : : {
1140 : : case ELF_C_NULL:
1141 : : /* We simply return a NULL pointer. */
1142 : : retval = NULL;
1143 : : break;
1144 : :
1145 : 5870 : case ELF_C_READ_MMAP_PRIVATE:
1146 : : /* If we have a reference it must also be opened this way. */
1147 [ - + # # ]: 5870 : if (unlikely (ref != NULL && ref->cmd != ELF_C_READ_MMAP_PRIVATE))
1148 : : {
1149 : 0 : __libelf_seterrno (ELF_E_INVALID_CMD);
1150 : 0 : retval = NULL;
1151 : 0 : break;
1152 : : }
1153 : 15175 : FALLTHROUGH;
1154 : :
1155 : : case ELF_C_READ:
1156 : : case ELF_C_READ_MMAP:
1157 [ + + ]: 15175 : if (ref != NULL)
1158 : 7231 : retval = lock_dup_elf (fildes, cmd, ref);
1159 : : else
1160 : : /* Create descriptor for existing file. */
1161 : 7944 : retval = read_file (fildes, 0, ~((size_t) 0), cmd, NULL);
1162 : : break;
1163 : :
1164 : 116 : case ELF_C_RDWR:
1165 : : case ELF_C_RDWR_MMAP:
1166 : : /* If we have a REF object it must also be opened using this
1167 : : command. */
1168 [ - + ]: 116 : if (ref != NULL)
1169 : : {
1170 [ # # # # : 0 : if (unlikely (ref->cmd != ELF_C_RDWR && ref->cmd != ELF_C_RDWR_MMAP
# # ]
1171 : : && ref->cmd != ELF_C_WRITE
1172 : : && ref->cmd != ELF_C_WRITE_MMAP))
1173 : : {
1174 : : /* This is not ok. REF must also be opened for writing. */
1175 : 0 : __libelf_seterrno (ELF_E_INVALID_CMD);
1176 : 0 : retval = NULL;
1177 : : }
1178 : : else
1179 : 0 : retval = lock_dup_elf (fildes, cmd, ref);
1180 : : }
1181 : : else
1182 : : /* Create descriptor for existing file. */
1183 : 116 : retval = read_file (fildes, 0, ~((size_t) 0), cmd, NULL);
1184 : : break;
1185 : :
1186 : 439 : case ELF_C_WRITE:
1187 : : case ELF_C_WRITE_MMAP:
1188 : : /* We ignore REF and prepare a descriptor to write a new file. */
1189 : 439 : retval = write_file (fildes, cmd);
1190 : 439 : break;
1191 : :
1192 : 0 : default:
1193 : 0 : __libelf_seterrno (ELF_E_INVALID_CMD);
1194 : 0 : retval = NULL;
1195 : 0 : break;
1196 : : }
1197 : :
1198 : : /* Release the lock. */
1199 : : if (ref != NULL)
1200 : : rwlock_unlock (ref->lock);
1201 : :
1202 : : return retval;
1203 : : }
1204 : : INTDEF(elf_begin)
|