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