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