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