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