blob: d135deab15052d80a747a0320ed5cdfce3af8655 [file] [log] [blame]
Ulrich Drepperb08d5a82005-07-26 05:00:05 +00001/* Create descriptor for processing file.
Jakub Jelinek720383c2014-01-17 19:36:16 +01002 Copyright (C) 1998-2010, 2012, 2014 Red Hat, Inc.
Mark Wielaardde2ed972012-06-05 17:15:16 +02003 This file is part of elfutils.
Ulrich Drepperb08d5a82005-07-26 05:00:05 +00004 Written by Ulrich Drepper <drepper@redhat.com>, 1998.
5
Mark Wielaardde2ed972012-06-05 17:15:16 +02006 This file is free software; you can redistribute it and/or modify
7 it under the terms of either
Ulrich Drepperb08d5a82005-07-26 05:00:05 +00008
Mark Wielaardde2ed972012-06-05 17:15:16 +02009 * 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
Ulrich Drepper361df7d2006-04-04 21:38:57 +000022 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.
Ulrich Drepperb08d5a82005-07-26 05:00:05 +000025
Mark Wielaardde2ed972012-06-05 17:15:16 +020026 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/>. */
Ulrich Drepperb08d5a82005-07-26 05:00:05 +000029
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/param.h>
44#include <sys/stat.h>
45
Ulrich Drepperfbe998a2005-08-29 16:27:10 +000046#include <system.h>
Ulrich Drepperb08d5a82005-07-26 05:00:05 +000047#include "libelfP.h"
48#include "common.h"
49
50
51/* Create descriptor for archive in memory. */
52static inline Elf *
53file_read_ar (int fildes, void *map_address, off_t offset, size_t maxsize,
54 Elf_Cmd cmd, Elf *parent)
55{
56 Elf *elf;
57
58 /* Create a descriptor. */
59 elf = allocate_elf (fildes, map_address, offset, maxsize, cmd, parent,
60 ELF_K_AR, 0);
61 if (elf != NULL)
62 {
63 /* We don't read all the symbol tables in advance. All this will
64 happen on demand. */
65 elf->state.ar.offset = offset + SARMAG;
66
67 elf->state.ar.elf_ar_hdr.ar_rawname = elf->state.ar.raw_name;
68 }
69
70 return elf;
71}
72
73
74static size_t
75get_shnum (void *map_address, unsigned char *e_ident, int fildes, off_t offset,
76 size_t maxsize)
77{
78 size_t result;
79 union
80 {
81 Elf32_Ehdr *e32;
82 Elf64_Ehdr *e64;
83 void *p;
84 } ehdr;
Ulrich Drepper0f6abbb2005-08-13 22:35:15 +000085 union
86 {
87 Elf32_Ehdr e32;
88 Elf64_Ehdr e64;
89 } ehdr_mem;
Ulrich Drepperb08d5a82005-07-26 05:00:05 +000090 bool is32 = e_ident[EI_CLASS] == ELFCLASS32;
91
92 /* Make the ELF header available. */
Roland McGrath9cf28e42008-09-30 06:35:35 +000093 if (e_ident[EI_DATA] == MY_ELFDATA
94 && (ALLOW_UNALIGNED
95 || (((size_t) e_ident
96 & ((is32 ? __alignof__ (Elf32_Ehdr) : __alignof__ (Elf64_Ehdr))
97 - 1)) == 0)))
Ulrich Drepperfbe998a2005-08-29 16:27:10 +000098 ehdr.p = e_ident;
Ulrich Drepperb08d5a82005-07-26 05:00:05 +000099 else
100 {
Ulrich Drepperfbe998a2005-08-29 16:27:10 +0000101 /* We already read the ELF header. We have to copy the header
102 since we possibly modify the data here and the caller
103 expects the memory it passes in to be preserved. */
104 ehdr.p = &ehdr_mem;
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000105
Ulrich Drepperfbe998a2005-08-29 16:27:10 +0000106 if (is32)
Ulrich Drepper0f6abbb2005-08-13 22:35:15 +0000107 {
Ulrich Drepperfbe998a2005-08-29 16:27:10 +0000108 if (ALLOW_UNALIGNED)
Ulrich Drepper969bda42005-08-28 08:30:08 +0000109 {
Ulrich Drepperfbe998a2005-08-29 16:27:10 +0000110 ehdr_mem.e32.e_shnum = ((Elf32_Ehdr *) e_ident)->e_shnum;
111 ehdr_mem.e32.e_shoff = ((Elf32_Ehdr *) e_ident)->e_shoff;
Ulrich Drepper969bda42005-08-28 08:30:08 +0000112 }
113 else
Ulrich Drepperfbe998a2005-08-29 16:27:10 +0000114 memcpy (&ehdr_mem, e_ident, sizeof (Elf32_Ehdr));
115
Roland McGrath9cf28e42008-09-30 06:35:35 +0000116 if (e_ident[EI_DATA] != MY_ELFDATA)
117 {
118 CONVERT (ehdr_mem.e32.e_shnum);
119 CONVERT (ehdr_mem.e32.e_shoff);
120 }
Ulrich Drepperfbe998a2005-08-29 16:27:10 +0000121 }
122 else
123 {
124 if (ALLOW_UNALIGNED)
Roland McGrath4c305da2005-08-25 01:49:35 +0000125 {
Ulrich Drepperfbe998a2005-08-29 16:27:10 +0000126 ehdr_mem.e64.e_shnum = ((Elf64_Ehdr *) e_ident)->e_shnum;
127 ehdr_mem.e64.e_shoff = ((Elf64_Ehdr *) e_ident)->e_shoff;
Roland McGrath4c305da2005-08-25 01:49:35 +0000128 }
Ulrich Drepperfbe998a2005-08-29 16:27:10 +0000129 else
130 memcpy (&ehdr_mem, e_ident, sizeof (Elf64_Ehdr));
131
Roland McGrath9cf28e42008-09-30 06:35:35 +0000132 if (e_ident[EI_DATA] != MY_ELFDATA)
133 {
134 CONVERT (ehdr_mem.e64.e_shnum);
135 CONVERT (ehdr_mem.e64.e_shoff);
136 }
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000137 }
138 }
139
140 if (is32)
141 {
142 /* Get the number of sections from the ELF header. */
143 result = ehdr.e32->e_shnum;
144
145 if (unlikely (result == 0) && ehdr.e32->e_shoff != 0)
146 {
Jakub Jelinek720383c2014-01-17 19:36:16 +0100147 if (unlikely (ehdr.e32->e_shoff >= maxsize)
148 || unlikely (maxsize - ehdr.e32->e_shoff < sizeof (Elf32_Shdr)))
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000149 /* Cannot read the first section header. */
Ulrich Drepperc07fbb32007-03-30 19:14:59 +0000150 return 0;
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000151
152 if (likely (map_address != NULL) && e_ident[EI_DATA] == MY_ELFDATA
153 && (ALLOW_UNALIGNED
154 || (((size_t) ((char *) map_address + offset))
155 & (__alignof__ (Elf32_Ehdr) - 1)) == 0))
156 /* We can directly access the memory. */
Ulrich Drepper0f6abbb2005-08-13 22:35:15 +0000157 result = ((Elf32_Shdr *) ((char *) map_address + ehdr.e32->e_shoff
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000158 + offset))->sh_size;
159 else
160 {
161 Elf32_Word size;
162
Ulrich Drepper0f6abbb2005-08-13 22:35:15 +0000163 if (likely (map_address != NULL))
164 /* gcc will optimize the memcpy to a simple memory
165 access while taking care of alignment issues. */
166 memcpy (&size, &((Elf32_Shdr *) ((char *) map_address
167 + ehdr.e32->e_shoff
168 + offset))->sh_size,
169 sizeof (Elf32_Word));
170 else
Ulrich Drepperfbe998a2005-08-29 16:27:10 +0000171 if (unlikely (pread_retry (fildes, &size, sizeof (Elf32_Word),
172 offset + ehdr.e32->e_shoff
173 + offsetof (Elf32_Shdr, sh_size))
174 != sizeof (Elf32_Word)))
Ulrich Drepper0f6abbb2005-08-13 22:35:15 +0000175 return (size_t) -1l;
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000176
177 if (e_ident[EI_DATA] != MY_ELFDATA)
178 CONVERT (size);
179
180 result = size;
181 }
182 }
Ulrich Drepperc07fbb32007-03-30 19:14:59 +0000183
184 /* If the section headers were truncated, pretend none were there. */
185 if (ehdr.e32->e_shoff > maxsize
186 || maxsize - ehdr.e32->e_shoff < sizeof (Elf32_Shdr) * result)
187 result = 0;
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000188 }
189 else
190 {
191 /* Get the number of sections from the ELF header. */
192 result = ehdr.e64->e_shnum;
193
194 if (unlikely (result == 0) && ehdr.e64->e_shoff != 0)
195 {
Jakub Jelinek720383c2014-01-17 19:36:16 +0100196 if (unlikely (ehdr.e64->e_shoff >= maxsize)
197 || unlikely (ehdr.e64->e_shoff + sizeof (Elf64_Shdr) > maxsize))
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000198 /* Cannot read the first section header. */
Ulrich Drepperc07fbb32007-03-30 19:14:59 +0000199 return 0;
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000200
Ulrich Drepper0f6abbb2005-08-13 22:35:15 +0000201 Elf64_Xword size;
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000202 if (likely (map_address != NULL) && e_ident[EI_DATA] == MY_ELFDATA
203 && (ALLOW_UNALIGNED
204 || (((size_t) ((char *) map_address + offset))
205 & (__alignof__ (Elf64_Ehdr) - 1)) == 0))
206 /* We can directly access the memory. */
Ulrich Drepper0f6abbb2005-08-13 22:35:15 +0000207 size = ((Elf64_Shdr *) ((char *) map_address + ehdr.e64->e_shoff
208 + offset))->sh_size;
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000209 else
210 {
Ulrich Drepper0f6abbb2005-08-13 22:35:15 +0000211 if (likely (map_address != NULL))
212 /* gcc will optimize the memcpy to a simple memory
213 access while taking care of alignment issues. */
214 memcpy (&size, &((Elf64_Shdr *) ((char *) map_address
215 + ehdr.e64->e_shoff
216 + offset))->sh_size,
217 sizeof (Elf64_Xword));
218 else
Ulrich Drepperfbe998a2005-08-29 16:27:10 +0000219 if (unlikely (pread_retry (fildes, &size, sizeof (Elf64_Word),
220 offset + ehdr.e64->e_shoff
221 + offsetof (Elf64_Shdr, sh_size))
222 != sizeof (Elf64_Xword)))
Ulrich Drepper0f6abbb2005-08-13 22:35:15 +0000223 return (size_t) -1l;
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000224
225 if (e_ident[EI_DATA] != MY_ELFDATA)
226 CONVERT (size);
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000227 }
Ulrich Drepper0f6abbb2005-08-13 22:35:15 +0000228
229 if (size > ~((GElf_Word) 0))
230 /* Invalid value, it is too large. */
231 return (size_t) -1l;
232
233 result = size;
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000234 }
Ulrich Drepperc07fbb32007-03-30 19:14:59 +0000235
236 /* If the section headers were truncated, pretend none were there. */
237 if (ehdr.e64->e_shoff > maxsize
238 || maxsize - ehdr.e64->e_shoff < sizeof (Elf64_Shdr) * result)
239 result = 0;
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000240 }
241
242 return result;
243}
244
245
246/* Create descriptor for ELF file in memory. */
247static Elf *
Ulrich Drepperfbe998a2005-08-29 16:27:10 +0000248file_read_elf (int fildes, void *map_address, unsigned char *e_ident,
249 off_t offset, size_t maxsize, Elf_Cmd cmd, Elf *parent)
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000250{
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000251 /* Verify the binary is of the class we can handle. */
Ulrich Drepperfbe998a2005-08-29 16:27:10 +0000252 if (unlikely ((e_ident[EI_CLASS] != ELFCLASS32
253 && e_ident[EI_CLASS] != ELFCLASS64)
254 /* We also can only handle two encodings. */
255 || (e_ident[EI_DATA] != ELFDATA2LSB
256 && e_ident[EI_DATA] != ELFDATA2MSB)))
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000257 {
258 /* Cannot handle this. */
259 __libelf_seterrno (ELF_E_INVALID_FILE);
260 return NULL;
261 }
262
263 /* Determine the number of sections. */
Ulrich Drepperfbe998a2005-08-29 16:27:10 +0000264 size_t scncnt = get_shnum (map_address, e_ident, fildes, offset, maxsize);
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000265 if (scncnt == (size_t) -1l)
266 /* Could not determine the number of sections. */
267 return NULL;
268
Jakub Jelinek720383c2014-01-17 19:36:16 +0100269 /* Check for too many sections. */
270 if (e_ident[EI_CLASS] == ELFCLASS32)
271 {
272 if (scncnt > SIZE_MAX / (sizeof (Elf_Scn) + sizeof (Elf32_Shdr)))
273 return NULL;
274 }
275 else if (scncnt > SIZE_MAX / (sizeof (Elf_Scn) + sizeof (Elf64_Shdr)))
276 return NULL;
277
Roland McGrath6fd3cd12010-01-07 19:41:04 -0800278 /* We can now allocate the memory. Even if there are no section headers,
279 we allocate space for a zeroth section in case we need it later. */
280 const size_t scnmax = (scncnt ?: (cmd == ELF_C_RDWR || cmd == ELF_C_RDWR_MMAP)
281 ? 1 : 0);
Ulrich Drepperfbe998a2005-08-29 16:27:10 +0000282 Elf *elf = allocate_elf (fildes, map_address, offset, maxsize, cmd, parent,
Roland McGrath6fd3cd12010-01-07 19:41:04 -0800283 ELF_K_ELF, scnmax * sizeof (Elf_Scn));
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000284 if (elf == NULL)
285 /* Not enough memory. */
286 return NULL;
287
Roland McGrath6fd3cd12010-01-07 19:41:04 -0800288 assert ((unsigned int) scncnt == scncnt);
289 assert (offsetof (struct Elf, state.elf32.scns)
290 == offsetof (struct Elf, state.elf64.scns));
291 elf->state.elf32.scns.cnt = scncnt;
292 elf->state.elf32.scns.max = scnmax;
293
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000294 /* Some more or less arbitrary value. */
295 elf->state.elf.scnincr = 10;
296
Ulrich Drepperfbe998a2005-08-29 16:27:10 +0000297 /* Make the class easily available. */
298 elf->class = e_ident[EI_CLASS];
299
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000300 if (e_ident[EI_CLASS] == ELFCLASS32)
301 {
302 /* This pointer might not be directly usable if the alignment is
303 not sufficient for the architecture. */
304 Elf32_Ehdr *ehdr = (Elf32_Ehdr *) ((char *) map_address + offset);
305
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000306 /* This is a 32-bit binary. */
307 if (map_address != NULL && e_ident[EI_DATA] == MY_ELFDATA
308 && (ALLOW_UNALIGNED
309 || ((((uintptr_t) ehdr) & (__alignof__ (Elf32_Ehdr) - 1)) == 0
310 && ((uintptr_t) ((char *) ehdr + ehdr->e_shoff)
311 & (__alignof__ (Elf32_Shdr) - 1)) == 0
312 && ((uintptr_t) ((char *) ehdr + ehdr->e_phoff)
313 & (__alignof__ (Elf32_Phdr) - 1)) == 0)))
314 {
315 /* We can use the mmapped memory. */
Ulrich Drepperfbe998a2005-08-29 16:27:10 +0000316 elf->state.elf32.ehdr = ehdr;
Jakub Jelinek720383c2014-01-17 19:36:16 +0100317
318 if (unlikely (ehdr->e_shoff >= maxsize)
319 || unlikely (maxsize - ehdr->e_shoff
320 < scncnt * sizeof (Elf32_Shdr)))
321 {
322 free_and_out:
323 free (elf);
324 __libelf_seterrno (ELF_E_INVALID_FILE);
325 return NULL;
326 }
Ulrich Drepperfbe998a2005-08-29 16:27:10 +0000327 elf->state.elf32.shdr
328 = (Elf32_Shdr *) ((char *) ehdr + ehdr->e_shoff);
Roland McGrath957072c2010-04-14 11:24:15 -0700329
330 /* Don't precache the phdr pointer here.
331 elf32_getphdr will validate it against the size when asked. */
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000332
333 for (size_t cnt = 0; cnt < scncnt; ++cnt)
334 {
335 elf->state.elf32.scns.data[cnt].index = cnt;
336 elf->state.elf32.scns.data[cnt].elf = elf;
337 elf->state.elf32.scns.data[cnt].shdr.e32 =
338 &elf->state.elf32.shdr[cnt];
Roland McGrath429502f2010-02-17 00:49:46 -0800339 if (likely (elf->state.elf32.shdr[cnt].sh_offset < maxsize)
Mark Wielaardb635b8d2014-11-07 12:47:16 +0100340 && likely (elf->state.elf32.shdr[cnt].sh_size
341 <= maxsize - elf->state.elf32.shdr[cnt].sh_offset))
Roland McGrath429502f2010-02-17 00:49:46 -0800342 elf->state.elf32.scns.data[cnt].rawdata_base =
343 elf->state.elf32.scns.data[cnt].data_base =
344 ((char *) map_address + offset
345 + elf->state.elf32.shdr[cnt].sh_offset);
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000346 elf->state.elf32.scns.data[cnt].list = &elf->state.elf32.scns;
Ulrich Drepper3cbdd382008-01-02 17:44:39 +0000347
348 /* If this is a section with an extended index add a
349 reference in the section which uses the extended
350 index. */
351 if (elf->state.elf32.shdr[cnt].sh_type == SHT_SYMTAB_SHNDX
352 && elf->state.elf32.shdr[cnt].sh_link < scncnt)
353 elf->state.elf32.scns.data[elf->state.elf32.shdr[cnt].sh_link].shndx_index
354 = cnt;
355
356 /* Set the own shndx_index field in case it has not yet
357 been set. */
358 if (elf->state.elf32.scns.data[cnt].shndx_index == 0)
359 elf->state.elf32.scns.data[cnt].shndx_index = -1;
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000360 }
361 }
362 else
363 {
Ulrich Drepperfbe998a2005-08-29 16:27:10 +0000364 /* Copy the ELF header. */
365 elf->state.elf32.ehdr = memcpy (&elf->state.elf32.ehdr_mem, e_ident,
366 sizeof (Elf32_Ehdr));
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000367
368 if (e_ident[EI_DATA] != MY_ELFDATA)
369 {
370 CONVERT (elf->state.elf32.ehdr_mem.e_type);
371 CONVERT (elf->state.elf32.ehdr_mem.e_machine);
372 CONVERT (elf->state.elf32.ehdr_mem.e_version);
373 CONVERT (elf->state.elf32.ehdr_mem.e_entry);
374 CONVERT (elf->state.elf32.ehdr_mem.e_phoff);
375 CONVERT (elf->state.elf32.ehdr_mem.e_shoff);
376 CONVERT (elf->state.elf32.ehdr_mem.e_flags);
377 CONVERT (elf->state.elf32.ehdr_mem.e_ehsize);
378 CONVERT (elf->state.elf32.ehdr_mem.e_phentsize);
379 CONVERT (elf->state.elf32.ehdr_mem.e_phnum);
380 CONVERT (elf->state.elf32.ehdr_mem.e_shentsize);
381 CONVERT (elf->state.elf32.ehdr_mem.e_shnum);
382 CONVERT (elf->state.elf32.ehdr_mem.e_shstrndx);
383 }
384
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000385 for (size_t cnt = 0; cnt < scncnt; ++cnt)
386 {
387 elf->state.elf32.scns.data[cnt].index = cnt;
388 elf->state.elf32.scns.data[cnt].elf = elf;
389 elf->state.elf32.scns.data[cnt].list = &elf->state.elf32.scns;
390 }
391 }
392
393 /* So far only one block with sections. */
394 elf->state.elf32.scns_last = &elf->state.elf32.scns;
395 }
396 else
397 {
398 /* This pointer might not be directly usable if the alignment is
399 not sufficient for the architecture. */
400 Elf64_Ehdr *ehdr = (Elf64_Ehdr *) ((char *) map_address + offset);
401
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000402 /* This is a 64-bit binary. */
403 if (map_address != NULL && e_ident[EI_DATA] == MY_ELFDATA
404 && (ALLOW_UNALIGNED
405 || ((((uintptr_t) ehdr) & (__alignof__ (Elf64_Ehdr) - 1)) == 0
406 && ((uintptr_t) ((char *) ehdr + ehdr->e_shoff)
407 & (__alignof__ (Elf64_Shdr) - 1)) == 0
408 && ((uintptr_t) ((char *) ehdr + ehdr->e_phoff)
409 & (__alignof__ (Elf64_Phdr) - 1)) == 0)))
410 {
411 /* We can use the mmapped memory. */
Ulrich Drepperfbe998a2005-08-29 16:27:10 +0000412 elf->state.elf64.ehdr = ehdr;
Jakub Jelinek720383c2014-01-17 19:36:16 +0100413
414 if (unlikely (ehdr->e_shoff >= maxsize)
415 || unlikely (ehdr->e_shoff
416 + scncnt * sizeof (Elf32_Shdr) > maxsize))
417 goto free_and_out;
Ulrich Drepperfbe998a2005-08-29 16:27:10 +0000418 elf->state.elf64.shdr
419 = (Elf64_Shdr *) ((char *) ehdr + ehdr->e_shoff);
Roland McGrath957072c2010-04-14 11:24:15 -0700420
421 /* Don't precache the phdr pointer here.
422 elf64_getphdr will validate it against the size when asked. */
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000423
424 for (size_t cnt = 0; cnt < scncnt; ++cnt)
425 {
426 elf->state.elf64.scns.data[cnt].index = cnt;
427 elf->state.elf64.scns.data[cnt].elf = elf;
428 elf->state.elf64.scns.data[cnt].shdr.e64 =
429 &elf->state.elf64.shdr[cnt];
Roland McGrath429502f2010-02-17 00:49:46 -0800430 if (likely (elf->state.elf64.shdr[cnt].sh_offset < maxsize)
Mark Wielaardb635b8d2014-11-07 12:47:16 +0100431 && likely (elf->state.elf64.shdr[cnt].sh_size
432 <= maxsize - elf->state.elf64.shdr[cnt].sh_offset))
Roland McGrath429502f2010-02-17 00:49:46 -0800433 elf->state.elf64.scns.data[cnt].rawdata_base =
434 elf->state.elf64.scns.data[cnt].data_base =
435 ((char *) map_address + offset
436 + elf->state.elf64.shdr[cnt].sh_offset);
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000437 elf->state.elf64.scns.data[cnt].list = &elf->state.elf64.scns;
Ulrich Drepper3cbdd382008-01-02 17:44:39 +0000438
439 /* If this is a section with an extended index add a
440 reference in the section which uses the extended
441 index. */
442 if (elf->state.elf64.shdr[cnt].sh_type == SHT_SYMTAB_SHNDX
443 && elf->state.elf64.shdr[cnt].sh_link < scncnt)
444 elf->state.elf64.scns.data[elf->state.elf64.shdr[cnt].sh_link].shndx_index
445 = cnt;
446
447 /* Set the own shndx_index field in case it has not yet
448 been set. */
449 if (elf->state.elf64.scns.data[cnt].shndx_index == 0)
450 elf->state.elf64.scns.data[cnt].shndx_index = -1;
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000451 }
452 }
453 else
454 {
Ulrich Drepperfbe998a2005-08-29 16:27:10 +0000455 /* Copy the ELF header. */
456 elf->state.elf64.ehdr = memcpy (&elf->state.elf64.ehdr_mem, e_ident,
457 sizeof (Elf64_Ehdr));
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000458
459 if (e_ident[EI_DATA] != MY_ELFDATA)
460 {
461 CONVERT (elf->state.elf64.ehdr_mem.e_type);
462 CONVERT (elf->state.elf64.ehdr_mem.e_machine);
463 CONVERT (elf->state.elf64.ehdr_mem.e_version);
464 CONVERT (elf->state.elf64.ehdr_mem.e_entry);
465 CONVERT (elf->state.elf64.ehdr_mem.e_phoff);
466 CONVERT (elf->state.elf64.ehdr_mem.e_shoff);
467 CONVERT (elf->state.elf64.ehdr_mem.e_flags);
468 CONVERT (elf->state.elf64.ehdr_mem.e_ehsize);
469 CONVERT (elf->state.elf64.ehdr_mem.e_phentsize);
470 CONVERT (elf->state.elf64.ehdr_mem.e_phnum);
471 CONVERT (elf->state.elf64.ehdr_mem.e_shentsize);
472 CONVERT (elf->state.elf64.ehdr_mem.e_shnum);
473 CONVERT (elf->state.elf64.ehdr_mem.e_shstrndx);
474 }
475
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000476 for (size_t cnt = 0; cnt < scncnt; ++cnt)
477 {
478 elf->state.elf64.scns.data[cnt].index = cnt;
479 elf->state.elf64.scns.data[cnt].elf = elf;
480 elf->state.elf64.scns.data[cnt].list = &elf->state.elf64.scns;
481 }
482 }
483
484 /* So far only one block with sections. */
485 elf->state.elf64.scns_last = &elf->state.elf64.scns;
486 }
487
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000488 return elf;
489}
490
491
492Elf *
Ulrich Drepper077c65f2006-07-12 19:54:51 +0000493internal_function
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000494__libelf_read_mmaped_file (int fildes, void *map_address, off_t offset,
495 size_t maxsize, Elf_Cmd cmd, Elf *parent)
496{
497 /* We have to find out what kind of file this is. We handle ELF
498 files and archives. To find out what we have we must look at the
499 header. The header for an ELF file is EI_NIDENT bytes in size,
500 the header for an archive file SARMAG bytes long. */
Ulrich Drepperfbe998a2005-08-29 16:27:10 +0000501 unsigned char *e_ident = (unsigned char *) map_address + offset;
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000502
503 /* See what kind of object we have here. */
Ulrich Drepperfbe998a2005-08-29 16:27:10 +0000504 Elf_Kind kind = determine_kind (e_ident, maxsize);
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000505
506 switch (kind)
507 {
508 case ELF_K_ELF:
Ulrich Drepperfbe998a2005-08-29 16:27:10 +0000509 return file_read_elf (fildes, map_address, e_ident, offset, maxsize,
510 cmd, parent);
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000511
512 case ELF_K_AR:
513 return file_read_ar (fildes, map_address, offset, maxsize, cmd, parent);
514
515 default:
516 break;
517 }
518
519 /* This case is easy. Since we cannot do anything with this file
520 create a dummy descriptor. */
521 return allocate_elf (fildes, map_address, offset, maxsize, cmd, parent,
522 ELF_K_NONE, 0);
523}
524
525
526static Elf *
527read_unmmaped_file (int fildes, off_t offset, size_t maxsize, Elf_Cmd cmd,
528 Elf *parent)
529{
530 /* We have to find out what kind of file this is. We handle ELF
531 files and archives. To find out what we have we must read the
Ulrich Drepperfbe998a2005-08-29 16:27:10 +0000532 header. The identification header for an ELF file is EI_NIDENT
533 bytes in size, but we read the whole ELF header since we will
534 need it anyway later. For archives the header in SARMAG bytes
535 long. Read the maximum of these numbers.
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000536
Ulrich Drepperfbe998a2005-08-29 16:27:10 +0000537 XXX We have to change this for the extended `ar' format some day.
538
539 Use a union to ensure alignment. We might later access the
540 memory as a ElfXX_Ehdr. */
541 union
542 {
543 Elf64_Ehdr ehdr;
544 unsigned char header[MAX (sizeof (Elf64_Ehdr), SARMAG)];
545 } mem;
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000546
547 /* Read the head of the file. */
Ulrich Drepperfbe998a2005-08-29 16:27:10 +0000548 ssize_t nread = pread_retry (fildes, mem.header,
549 MIN (MAX (sizeof (Elf64_Ehdr), SARMAG),
550 maxsize),
551 offset);
552 if (unlikely (nread == -1))
Petr Machata237188e2014-09-10 22:25:35 +0200553 {
554 /* We cannot even read the head of the file. Maybe FILDES is associated
555 with an unseekable device. This is nothing we can handle. */
556 __libelf_seterrno (ELF_E_INVALID_FILE);
557 return NULL;
558 }
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000559
560 /* See what kind of object we have here. */
Ulrich Drepperfbe998a2005-08-29 16:27:10 +0000561 Elf_Kind kind = determine_kind (mem.header, nread);
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000562
563 switch (kind)
564 {
565 case ELF_K_AR:
566 return file_read_ar (fildes, NULL, offset, maxsize, cmd, parent);
567
568 case ELF_K_ELF:
569 /* Make sure at least the ELF header is contained in the file. */
Ulrich Drepperfbe998a2005-08-29 16:27:10 +0000570 if ((size_t) nread >= (mem.header[EI_CLASS] == ELFCLASS32
571 ? sizeof (Elf32_Ehdr) : sizeof (Elf64_Ehdr)))
572 return file_read_elf (fildes, NULL, mem.header, offset, maxsize, cmd,
573 parent);
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000574 /* FALLTHROUGH */
575
576 default:
577 break;
578 }
579
580 /* This case is easy. Since we cannot do anything with this file
581 create a dummy descriptor. */
582 return allocate_elf (fildes, NULL, offset, maxsize, cmd, parent,
583 ELF_K_NONE, 0);
584}
585
586
587/* Open a file for reading. If possible we will try to mmap() the file. */
588static struct Elf *
589read_file (int fildes, off_t offset, size_t maxsize,
590 Elf_Cmd cmd, Elf *parent)
591{
592 void *map_address = NULL;
593 int use_mmap = (cmd == ELF_C_READ_MMAP || cmd == ELF_C_RDWR_MMAP
594 || cmd == ELF_C_WRITE_MMAP
595 || cmd == ELF_C_READ_MMAP_PRIVATE);
596
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000597 if (use_mmap)
598 {
599 if (parent == NULL)
600 {
601 if (maxsize == ~((size_t) 0))
602 {
603 /* We don't know in the moment how large the file is.
604 Determine it now. */
605 struct stat st;
606
607 if (fstat (fildes, &st) == 0
608 && (sizeof (size_t) >= sizeof (st.st_size)
609 || st.st_size <= ~((size_t) 0)))
610 maxsize = (size_t) st.st_size;
611 }
612
613 /* We try to map the file ourself. */
614 map_address = mmap (NULL, maxsize, (cmd == ELF_C_READ_MMAP
615 ? PROT_READ
616 : PROT_READ|PROT_WRITE),
617 cmd == ELF_C_READ_MMAP_PRIVATE
Ulrich Drepperce0bdb62007-02-05 07:13:52 +0000618 || cmd == ELF_C_READ_MMAP
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000619 ? MAP_PRIVATE : MAP_SHARED,
620 fildes, offset);
621
622 if (map_address == MAP_FAILED)
623 map_address = NULL;
624 }
625 else
626 {
627 /* The parent is already loaded. Use it. */
628 assert (maxsize != ~((size_t) 0));
629
630 map_address = parent->map_address;
631 }
632 }
633
634 /* If we have the file in memory optimize the access. */
635 if (map_address != NULL)
636 {
Ulrich Drepperfbe998a2005-08-29 16:27:10 +0000637 assert (map_address != MAP_FAILED);
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000638
Ulrich Drepperfbe998a2005-08-29 16:27:10 +0000639 struct Elf *result = __libelf_read_mmaped_file (fildes, map_address,
640 offset, maxsize, cmd,
641 parent);
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000642
643 /* If something went wrong during the initialization unmap the
644 memory if we mmaped here. */
645 if (result == NULL
646 && (parent == NULL
647 || parent->map_address != map_address))
648 munmap (map_address, maxsize);
649 else if (parent == NULL)
650 /* Remember that we mmap()ed the memory. */
651 result->flags |= ELF_F_MMAPPED;
652
653 return result;
654 }
655
656 /* Otherwise we have to do it the hard way. We read as much as necessary
657 from the file whenever we need information which is not available. */
658 return read_unmmaped_file (fildes, offset, maxsize, cmd, parent);
659}
660
661
662/* Find the entry with the long names for the content of this archive. */
663static const char *
664read_long_names (Elf *elf)
665{
666 off_t offset = SARMAG; /* This is the first entry. */
667 struct ar_hdr hdrm;
668 struct ar_hdr *hdr;
669 char *newp;
670 size_t len;
671
672 while (1)
673 {
674 if (elf->map_address != NULL)
675 {
676 if (offset + sizeof (struct ar_hdr) > elf->maximum_size)
677 return NULL;
678
679 /* The data is mapped. */
680 hdr = (struct ar_hdr *) (elf->map_address + offset);
681 }
682 else
683 {
684 /* Read the header from the file. */
Ulrich Drepperfbe998a2005-08-29 16:27:10 +0000685 if (unlikely (pread_retry (elf->fildes, &hdrm, sizeof (hdrm),
686 elf->start_offset + offset)
687 != sizeof (hdrm)))
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000688 return NULL;
689
690 hdr = &hdrm;
691 }
692
693 len = atol (hdr->ar_size);
694
695 if (memcmp (hdr->ar_name, "// ", 16) == 0)
696 break;
697
698 offset += sizeof (struct ar_hdr) + ((len + 1) & ~1l);
699 }
700
701 /* Due to the stupid format of the long name table entry (which are not
702 NUL terminted) we have to provide an appropriate representation anyhow.
703 Therefore we always make a copy which has the appropriate form. */
704 newp = (char *) malloc (len);
705 if (newp != NULL)
706 {
707 char *runp;
708
709 if (elf->map_address != NULL)
710 /* Simply copy it over. */
711 elf->state.ar.long_names = (char *) memcpy (newp,
712 elf->map_address + offset
713 + sizeof (struct ar_hdr),
714 len);
715 else
716 {
Ulrich Drepperfbe998a2005-08-29 16:27:10 +0000717 if (unlikely ((size_t) pread_retry (elf->fildes, newp, len,
718 elf->start_offset + offset
719 + sizeof (struct ar_hdr))
720 != len))
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000721 {
722 /* We were not able to read all data. */
723 free (newp);
724 elf->state.ar.long_names = NULL;
725 return NULL;
726 }
727 elf->state.ar.long_names = newp;
728 }
729
730 elf->state.ar.long_names_len = len;
731
732 /* Now NUL-terminate the strings. */
733 runp = newp;
734 while (1)
735 {
736 runp = (char *) memchr (runp, '/', newp + len - runp);
737 if (runp == NULL)
738 /* This was the last entry. */
739 break;
740
741 /* NUL-terminate the string. */
742 *runp = '\0';
743
Ulrich Drepperce0bdb62007-02-05 07:13:52 +0000744 /* Skip the NUL byte and the \012. */
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000745 runp += 2;
746
747 /* A sanity check. Somebody might have generated invalid
748 archive. */
749 if (runp >= newp + len)
750 break;
751 }
752 }
753
754 return newp;
755}
756
757
758/* Read the next archive header. */
759int
Ulrich Drepper077c65f2006-07-12 19:54:51 +0000760internal_function
Ulrich Drepper02f66452008-12-04 05:58:16 +0000761__libelf_next_arhdr_wrlock (elf)
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000762 Elf *elf;
763{
764 struct ar_hdr *ar_hdr;
765 Elf_Arhdr *elf_ar_hdr;
766
767 if (elf->map_address != NULL)
768 {
769 /* See whether this entry is in the file. */
Ulrich Drepperfbe998a2005-08-29 16:27:10 +0000770 if (unlikely (elf->state.ar.offset + sizeof (struct ar_hdr)
771 > elf->start_offset + elf->maximum_size))
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000772 {
773 /* This record is not anymore in the file. */
774 __libelf_seterrno (ELF_E_RANGE);
775 return -1;
776 }
777 ar_hdr = (struct ar_hdr *) (elf->map_address + elf->state.ar.offset);
778 }
779 else
780 {
781 ar_hdr = &elf->state.ar.ar_hdr;
782
Ulrich Drepperfbe998a2005-08-29 16:27:10 +0000783 if (unlikely (pread_retry (elf->fildes, ar_hdr, sizeof (struct ar_hdr),
784 elf->state.ar.offset)
785 != sizeof (struct ar_hdr)))
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000786 {
787 /* Something went wrong while reading the file. */
788 __libelf_seterrno (ELF_E_RANGE);
789 return -1;
790 }
791 }
792
793 /* One little consistency check. */
Ulrich Drepperfbe998a2005-08-29 16:27:10 +0000794 if (unlikely (memcmp (ar_hdr->ar_fmag, ARFMAG, 2) != 0))
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000795 {
796 /* This is no valid archive. */
797 __libelf_seterrno (ELF_E_ARCHIVE_FMAG);
798 return -1;
799 }
800
801 /* Copy the raw name over to a NUL terminated buffer. */
Mark Wielaardbabd5b62014-11-08 16:18:34 +0100802 *((char *) mempcpy (elf->state.ar.raw_name, ar_hdr->ar_name, 16)) = '\0';
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000803
804 elf_ar_hdr = &elf->state.ar.elf_ar_hdr;
805
806 /* Now convert the `struct ar_hdr' into `Elf_Arhdr'.
807 Determine whether this is a special entry. */
808 if (ar_hdr->ar_name[0] == '/')
809 {
810 if (ar_hdr->ar_name[1] == ' '
811 && memcmp (ar_hdr->ar_name, "/ ", 16) == 0)
812 /* This is the index. */
813 elf_ar_hdr->ar_name = memcpy (elf->state.ar.ar_name, "/", 2);
Petr Machatae1873142012-08-01 21:37:52 +0200814 else if (ar_hdr->ar_name[1] == 'S'
815 && memcmp (ar_hdr->ar_name, "/SYM64/ ", 16) == 0)
816 /* 64-bit index. */
817 elf_ar_hdr->ar_name = memcpy (elf->state.ar.ar_name, "/SYM64/", 8);
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000818 else if (ar_hdr->ar_name[1] == '/'
819 && memcmp (ar_hdr->ar_name, "// ", 16) == 0)
820 /* This is the array with the long names. */
821 elf_ar_hdr->ar_name = memcpy (elf->state.ar.ar_name, "//", 3);
Ulrich Drepperfbe998a2005-08-29 16:27:10 +0000822 else if (likely (isdigit (ar_hdr->ar_name[1])))
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000823 {
824 size_t offset;
825
826 /* This is a long name. First we have to read the long name
827 table, if this hasn't happened already. */
Ulrich Drepperfbe998a2005-08-29 16:27:10 +0000828 if (unlikely (elf->state.ar.long_names == NULL
829 && read_long_names (elf) == NULL))
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000830 {
831 /* No long name table although it is reference. The archive is
832 broken. */
833 __libelf_seterrno (ELF_E_INVALID_ARCHIVE);
834 return -1;
835 }
836
837 offset = atol (ar_hdr->ar_name + 1);
Ulrich Drepperfbe998a2005-08-29 16:27:10 +0000838 if (unlikely (offset >= elf->state.ar.long_names_len))
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000839 {
840 /* The index in the long name table is larger than the table. */
841 __libelf_seterrno (ELF_E_INVALID_ARCHIVE);
842 return -1;
843 }
844 elf_ar_hdr->ar_name = elf->state.ar.long_names + offset;
845 }
846 else
847 {
848 /* This is none of the known special entries. */
849 __libelf_seterrno (ELF_E_INVALID_ARCHIVE);
850 return -1;
851 }
852 }
853 else
854 {
855 char *endp;
856
857 /* It is a normal entry. Copy over the name. */
858 endp = (char *) memccpy (elf->state.ar.ar_name, ar_hdr->ar_name,
859 '/', 16);
860 if (endp != NULL)
861 endp[-1] = '\0';
862 else
Ulrich Drepperb597dfa2007-10-16 05:21:27 +0000863 {
864 /* In the old BSD style of archive, there is no / terminator.
865 Instead, there is space padding at the end of the name. */
866 size_t i = 15;
867 do
868 elf->state.ar.ar_name[i] = '\0';
869 while (i > 0 && elf->state.ar.ar_name[--i] == ' ');
870 }
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000871
872 elf_ar_hdr->ar_name = elf->state.ar.ar_name;
873 }
874
Roland McGrath059c83e2008-02-21 06:19:39 +0000875 if (unlikely (ar_hdr->ar_size[0] == ' '))
876 /* Something is really wrong. We cannot live without a size for
877 the member since it will not be possible to find the next
878 archive member. */
879 {
880 __libelf_seterrno (ELF_E_INVALID_ARCHIVE);
881 return -1;
882 }
883
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000884 /* Since there are no specialized functions to convert ASCII to
885 time_t, uid_t, gid_t, mode_t, and off_t we use either atol or
886 atoll depending on the size of the types. We are also prepared
887 for the case where the whole field in the `struct ar_hdr' is
888 filled in which case we cannot simply use atol/l but instead have
889 to create a temporary copy. */
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000890
Roland McGrath059c83e2008-02-21 06:19:39 +0000891#define INT_FIELD(FIELD) \
892 do \
893 { \
894 char buf[sizeof (ar_hdr->FIELD) + 1]; \
895 const char *string = ar_hdr->FIELD; \
896 if (ar_hdr->FIELD[sizeof (ar_hdr->FIELD) - 1] != ' ') \
897 { \
Mark Wielaardbabd5b62014-11-08 16:18:34 +0100898 *((char *) mempcpy (buf, ar_hdr->FIELD, sizeof (ar_hdr->FIELD))) \
Roland McGrath059c83e2008-02-21 06:19:39 +0000899 = '\0'; \
900 string = buf; \
901 } \
902 if (sizeof (elf_ar_hdr->FIELD) <= sizeof (long int)) \
903 elf_ar_hdr->FIELD = (__typeof (elf_ar_hdr->FIELD)) atol (string); \
904 else \
905 elf_ar_hdr->FIELD = (__typeof (elf_ar_hdr->FIELD)) atoll (string); \
906 } \
907 while (0)
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000908
Roland McGrath059c83e2008-02-21 06:19:39 +0000909 INT_FIELD (ar_date);
910 INT_FIELD (ar_uid);
911 INT_FIELD (ar_gid);
912 INT_FIELD (ar_mode);
913 INT_FIELD (ar_size);
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000914
915 return 0;
916}
917
918
919/* We were asked to return a clone of an existing descriptor. This
920 function must be called with the lock on the parent descriptor
921 being held. */
922static Elf *
923dup_elf (int fildes, Elf_Cmd cmd, Elf *ref)
924{
925 struct Elf *result;
926
927 if (fildes == -1)
928 /* Allow the user to pass -1 as the file descriptor for the new file. */
929 fildes = ref->fildes;
930 /* The file descriptor better should be the same. If it was disconnected
931 already (using `elf_cntl') we do not test it. */
Ulrich Drepperfbe998a2005-08-29 16:27:10 +0000932 else if (unlikely (ref->fildes != -1 && fildes != ref->fildes))
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000933 {
934 __libelf_seterrno (ELF_E_FD_MISMATCH);
935 return NULL;
936 }
937
938 /* The mode must allow reading. I.e., a descriptor creating with a
939 command different then ELF_C_READ, ELF_C_WRITE and ELF_C_RDWR is
940 not allowed. */
Ulrich Drepperfbe998a2005-08-29 16:27:10 +0000941 if (unlikely (ref->cmd != ELF_C_READ && ref->cmd != ELF_C_READ_MMAP
942 && ref->cmd != ELF_C_WRITE && ref->cmd != ELF_C_WRITE_MMAP
943 && ref->cmd != ELF_C_RDWR && ref->cmd != ELF_C_RDWR_MMAP
944 && ref->cmd != ELF_C_READ_MMAP_PRIVATE))
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000945 {
946 __libelf_seterrno (ELF_E_INVALID_OP);
947 return NULL;
948 }
949
950 /* Now it is time to distinguish between reading normal files and
951 archives. Normal files can easily be handled be incrementing the
952 reference counter and return the same descriptor. */
953 if (ref->kind != ELF_K_AR)
954 {
955 ++ref->ref_count;
956 return ref;
957 }
958
959 /* This is an archive. We must create a descriptor for the archive
960 member the internal pointer of the archive file desriptor is
961 pointing to. First read the header of the next member if this
962 has not happened already. */
963 if (ref->state.ar.elf_ar_hdr.ar_name == NULL
Ulrich Drepper02f66452008-12-04 05:58:16 +0000964 && __libelf_next_arhdr_wrlock (ref) != 0)
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000965 /* Something went wrong. Maybe there is no member left. */
966 return NULL;
967
968 /* We have all the information we need about the next archive member.
969 Now create a descriptor for it. */
970 result = read_file (fildes, ref->state.ar.offset + sizeof (struct ar_hdr),
971 ref->state.ar.elf_ar_hdr.ar_size, cmd, ref);
972
973 /* Enlist this new descriptor in the list of children. */
974 if (result != NULL)
975 {
976 result->next = ref->state.ar.children;
977 ref->state.ar.children = result;
978 }
979
980 return result;
981}
982
983
984/* Return desriptor for empty file ready for writing. */
985static struct Elf *
986write_file (int fd, Elf_Cmd cmd)
987{
988 /* We simply create an empty `Elf' structure. */
989#define NSCNSALLOC 10
990 Elf *result = allocate_elf (fd, NULL, 0, 0, cmd, NULL, ELF_K_ELF,
991 NSCNSALLOC * sizeof (Elf_Scn));
992
993 if (result != NULL)
994 {
995 /* We have to write to the file in any case. */
996 result->flags = ELF_F_DIRTY;
997
998 /* Some more or less arbitrary value. */
999 result->state.elf.scnincr = NSCNSALLOC;
1000
1001 /* We have allocated room for some sections. */
1002 assert (offsetof (struct Elf, state.elf32.scns)
1003 == offsetof (struct Elf, state.elf64.scns));
1004 result->state.elf.scns_last = &result->state.elf32.scns;
1005 result->state.elf32.scns.max = NSCNSALLOC;
1006 }
1007
1008 return result;
1009}
1010
1011
1012/* Return a descriptor for the file belonging to FILDES. */
1013Elf *
1014elf_begin (fildes, cmd, ref)
1015 int fildes;
1016 Elf_Cmd cmd;
1017 Elf *ref;
1018{
1019 Elf *retval;
1020
Ulrich Drepperfbe998a2005-08-29 16:27:10 +00001021 if (unlikely (! __libelf_version_initialized))
Ulrich Drepperb08d5a82005-07-26 05:00:05 +00001022 {
1023 /* Version wasn't set so far. */
1024 __libelf_seterrno (ELF_E_NO_VERSION);
1025 return NULL;
1026 }
1027
1028 if (ref != NULL)
1029 /* Make sure the descriptor is not suddenly going away. */
Roland McGrathb4d6f0f2008-08-25 22:55:17 +00001030 rwlock_rdlock (ref->lock);
Ulrich Drepperfbe998a2005-08-29 16:27:10 +00001031 else if (unlikely (fcntl (fildes, F_GETFL) == -1 && errno == EBADF))
Ulrich Drepperb08d5a82005-07-26 05:00:05 +00001032 {
1033 /* We cannot do anything productive without a file descriptor. */
1034 __libelf_seterrno (ELF_E_INVALID_FILE);
1035 return NULL;
1036 }
1037
Ulrich Drepper02f66452008-12-04 05:58:16 +00001038 Elf *lock_dup_elf ()
1039 {
1040 /* We need wrlock to dup an archive. */
1041 if (ref->kind == ELF_K_AR)
1042 {
1043 rwlock_unlock (ref->lock);
1044 rwlock_wrlock (ref->lock);
1045 }
1046
1047 /* Duplicate the descriptor. */
1048 return dup_elf (fildes, cmd, ref);
1049 }
1050
Ulrich Drepperb08d5a82005-07-26 05:00:05 +00001051 switch (cmd)
1052 {
1053 case ELF_C_NULL:
1054 /* We simply return a NULL pointer. */
1055 retval = NULL;
1056 break;
1057
1058 case ELF_C_READ_MMAP_PRIVATE:
1059 /* If we have a reference it must also be opened this way. */
Ulrich Drepperfbe998a2005-08-29 16:27:10 +00001060 if (unlikely (ref != NULL && ref->cmd != ELF_C_READ_MMAP_PRIVATE))
Ulrich Drepperb08d5a82005-07-26 05:00:05 +00001061 {
1062 __libelf_seterrno (ELF_E_INVALID_CMD);
1063 retval = NULL;
1064 break;
1065 }
1066 /* FALLTHROUGH */
1067
1068 case ELF_C_READ:
1069 case ELF_C_READ_MMAP:
1070 if (ref != NULL)
Ulrich Drepper02f66452008-12-04 05:58:16 +00001071 retval = lock_dup_elf ();
Ulrich Drepperb08d5a82005-07-26 05:00:05 +00001072 else
1073 /* Create descriptor for existing file. */
1074 retval = read_file (fildes, 0, ~((size_t) 0), cmd, NULL);
1075 break;
1076
1077 case ELF_C_RDWR:
1078 case ELF_C_RDWR_MMAP:
1079 /* If we have a REF object it must also be opened using this
1080 command. */
1081 if (ref != NULL)
1082 {
Ulrich Drepperfbe998a2005-08-29 16:27:10 +00001083 if (unlikely (ref->cmd != ELF_C_RDWR && ref->cmd != ELF_C_RDWR_MMAP
1084 && ref->cmd != ELF_C_WRITE
1085 && ref->cmd != ELF_C_WRITE_MMAP))
Ulrich Drepperb08d5a82005-07-26 05:00:05 +00001086 {
1087 /* This is not ok. REF must also be opened for writing. */
1088 __libelf_seterrno (ELF_E_INVALID_CMD);
1089 retval = NULL;
1090 }
1091 else
Ulrich Drepper02f66452008-12-04 05:58:16 +00001092 retval = lock_dup_elf ();
Ulrich Drepperb08d5a82005-07-26 05:00:05 +00001093 }
1094 else
1095 /* Create descriptor for existing file. */
1096 retval = read_file (fildes, 0, ~((size_t) 0), cmd, NULL);
1097 break;
1098
1099 case ELF_C_WRITE:
1100 case ELF_C_WRITE_MMAP:
1101 /* We ignore REF and prepare a descriptor to write a new file. */
1102 retval = write_file (fildes, cmd);
1103 break;
1104
1105 default:
1106 __libelf_seterrno (ELF_E_INVALID_CMD);
1107 retval = NULL;
1108 break;
1109 }
1110
1111 /* Release the lock. */
1112 if (ref != NULL)
Roland McGrathb4d6f0f2008-08-25 22:55:17 +00001113 rwlock_unlock (ref->lock);
Ulrich Drepperb08d5a82005-07-26 05:00:05 +00001114
1115 return retval;
1116}
1117INTDEF(elf_begin)