• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Return the next data element from the section after possibly converting it.
2    Copyright (C) 1998-2005, 2006, 2007, 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 <errno.h>
35 #include <stddef.h>
36 #include <string.h>
37 #include <unistd.h>
38 
39 #include "libelfP.h"
40 #include <system.h>
41 #include "common.h"
42 #include "elf-knowledge.h"
43 
44 
45 #define TYPEIDX(Sh_Type) \
46   (Sh_Type >= SHT_NULL && Sh_Type < SHT_NUM				      \
47    ? Sh_Type								      \
48    : (Sh_Type >= SHT_GNU_HASH && Sh_Type <= SHT_HISUNW			      \
49       ? SHT_NUM + Sh_Type - SHT_GNU_HASH				      \
50       : 0))
51 
52 /* Associate section types with libelf types.  */
53 static const Elf_Type shtype_map[TYPEIDX (SHT_HISUNW) + 1] =
54   {
55       [SHT_SYMTAB] = ELF_T_SYM,
56       [SHT_RELA] = ELF_T_RELA,
57       [SHT_HASH] = ELF_T_WORD,
58       [SHT_DYNAMIC] = ELF_T_DYN,
59       [SHT_REL] = ELF_T_REL,
60       [SHT_DYNSYM] = ELF_T_SYM,
61       [SHT_INIT_ARRAY] = ELF_T_ADDR,
62       [SHT_FINI_ARRAY] = ELF_T_ADDR,
63       [SHT_PREINIT_ARRAY] = ELF_T_ADDR,
64       [SHT_GROUP] = ELF_T_WORD,
65       [SHT_SYMTAB_SHNDX] = ELF_T_WORD,
66       [SHT_NOTE] = ELF_T_NHDR, /* Need alignment to guess ELF_T_NHDR8.  */
67       [TYPEIDX (SHT_GNU_verdef)] = ELF_T_VDEF,
68       [TYPEIDX (SHT_GNU_verneed)] = ELF_T_VNEED,
69       [TYPEIDX (SHT_GNU_versym)] = ELF_T_HALF,
70       [TYPEIDX (SHT_SUNW_syminfo)] = ELF_T_SYMINFO,
71       [TYPEIDX (SHT_SUNW_move)] = ELF_T_MOVE,
72       [TYPEIDX (SHT_GNU_LIBLIST)] = ELF_T_LIB,
73       [TYPEIDX (SHT_GNU_HASH)] = ELF_T_GNUHASH,
74   };
75 
76 /* Associate libelf types with their internal alignment requirements.  */
77 const uint_fast8_t __libelf_type_aligns[ELFCLASSNUM - 1][ELF_T_NUM] =
78   {
79 # define TYPE_ALIGNS(Bits)						      \
80     {									      \
81       [ELF_T_ADDR] = __alignof__ (ElfW2(Bits,Addr)),			      \
82       [ELF_T_EHDR] = __alignof__ (ElfW2(Bits,Ehdr)),			      \
83       [ELF_T_HALF] = __alignof__ (ElfW2(Bits,Half)),			      \
84       [ELF_T_OFF] = __alignof__ (ElfW2(Bits,Off)),			      \
85       [ELF_T_PHDR] = __alignof__ (ElfW2(Bits,Phdr)),			      \
86       [ELF_T_SHDR] = __alignof__ (ElfW2(Bits,Shdr)),			      \
87       [ELF_T_SWORD] = __alignof__ (ElfW2(Bits,Sword)),			      \
88       [ELF_T_WORD] = __alignof__ (ElfW2(Bits,Word)),			      \
89       [ELF_T_XWORD] = __alignof__ (ElfW2(Bits,Xword)),			      \
90       [ELF_T_SXWORD] = __alignof__ (ElfW2(Bits,Sxword)),		      \
91       [ELF_T_SYM] = __alignof__ (ElfW2(Bits,Sym)),			      \
92       [ELF_T_SYMINFO] = __alignof__ (ElfW2(Bits,Syminfo)),		      \
93       [ELF_T_REL] = __alignof__ (ElfW2(Bits,Rel)),			      \
94       [ELF_T_RELA] = __alignof__ (ElfW2(Bits,Rela)),			      \
95       [ELF_T_DYN] = __alignof__ (ElfW2(Bits,Dyn)),			      \
96       [ELF_T_VDEF] = __alignof__ (ElfW2(Bits,Verdef)),			      \
97       [ELF_T_VDAUX] = __alignof__ (ElfW2(Bits,Verdaux)),		      \
98       [ELF_T_VNEED] = __alignof__ (ElfW2(Bits,Verneed)),		      \
99       [ELF_T_VNAUX] = __alignof__ (ElfW2(Bits,Vernaux)),		      \
100       [ELF_T_MOVE] = __alignof__ (ElfW2(Bits,Move)),			      \
101       [ELF_T_LIB] = __alignof__ (ElfW2(Bits,Lib)),			      \
102       [ELF_T_NHDR] = __alignof__ (ElfW2(Bits,Nhdr)),			      \
103       [ELF_T_GNUHASH] = __alignof__ (Elf32_Word),			      \
104       [ELF_T_AUXV] = __alignof__ (ElfW2(Bits,auxv_t)),			      \
105       [ELF_T_CHDR] = __alignof__ (ElfW2(Bits,Chdr)),			      \
106       [ELF_T_NHDR8] = 8 /* Special case for GNU Property note.  */	      \
107     }
108       [ELFCLASS32 - 1] = TYPE_ALIGNS (32),
109       [ELFCLASS64 - 1] = TYPE_ALIGNS (64),
110 # undef TYPE_ALIGNS
111   };
112 
113 
114 Elf_Type
115 internal_function
__libelf_data_type(GElf_Ehdr * ehdr,int sh_type,GElf_Xword align)116 __libelf_data_type (GElf_Ehdr *ehdr, int sh_type, GElf_Xword align)
117 {
118   /* Some broken ELF ABI for 64-bit machines use the wrong hash table
119      entry size.  See elf-knowledge.h for more information.  */
120   if (sh_type == SHT_HASH && ehdr->e_ident[EI_CLASS] == ELFCLASS64)
121     {
122       return (SH_ENTSIZE_HASH (ehdr) == 4 ? ELF_T_WORD : ELF_T_XWORD);
123     }
124   else
125     {
126       Elf_Type t = shtype_map[TYPEIDX (sh_type)];
127       /* Special case for GNU Property notes.  */
128       if (t == ELF_T_NHDR && align == 8)
129 	t = ELF_T_NHDR8;
130       return t;
131     }
132 }
133 
134 /* Convert the data in the current section.  */
135 static void
convert_data(Elf_Scn * scn,int eclass,int data,size_t size,Elf_Type type)136 convert_data (Elf_Scn *scn, int eclass,
137 	      int data, size_t size, Elf_Type type)
138 {
139   const size_t align = __libelf_type_align (eclass, type);
140 
141   /* Do we need to convert the data and/or adjust for alignment?  */
142   if (data == MY_ELFDATA || type == ELF_T_BYTE)
143     {
144       if (((((size_t) (char *) scn->rawdata_base)) & (align - 1)) == 0)
145 	/* No need to copy, we can use the raw data.  */
146 	scn->data_base = scn->rawdata_base;
147       else
148 	{
149 	  scn->data_base = (char *) malloc (size);
150 	  if (scn->data_base == NULL)
151 	    {
152 	      __libelf_seterrno (ELF_E_NOMEM);
153 	      return;
154 	    }
155 
156 	  /* The copy will be appropriately aligned for direct access.  */
157 	  memcpy (scn->data_base, scn->rawdata_base, size);
158 	}
159     }
160   else
161     {
162       xfct_t fp;
163 
164       scn->data_base = (char *) malloc (size);
165       if (scn->data_base == NULL)
166 	{
167 	  __libelf_seterrno (ELF_E_NOMEM);
168 	  return;
169 	}
170 
171       /* Make sure the source is correctly aligned for the conversion
172 	 function to directly access the data elements.  */
173       char *rawdata_source;
174       if (((((size_t) (char *) scn->rawdata_base)) & (align - 1)) == 0)
175 	rawdata_source = scn->rawdata_base;
176       else
177 	{
178 	  rawdata_source = (char *) malloc (size);
179 	  if (rawdata_source == NULL)
180 	    {
181 	      __libelf_seterrno (ELF_E_NOMEM);
182 	      return;
183 	    }
184 
185 	  /* The copy will be appropriately aligned for direct access.  */
186 	  memcpy (rawdata_source, scn->rawdata_base, size);
187 	}
188 
189       /* Get the conversion function.  */
190       fp = __elf_xfctstom[eclass - 1][type];
191 
192       fp (scn->data_base, rawdata_source, size, 0);
193 
194       if (rawdata_source != scn->rawdata_base)
195 	free (rawdata_source);
196     }
197 
198   scn->data_list.data.d.d_buf = scn->data_base;
199   scn->data_list.data.d.d_size = size;
200   scn->data_list.data.d.d_type = type;
201   scn->data_list.data.d.d_off = scn->rawdata.d.d_off;
202   scn->data_list.data.d.d_align = scn->rawdata.d.d_align;
203   scn->data_list.data.d.d_version = scn->rawdata.d.d_version;
204 
205   scn->data_list.data.s = scn;
206 }
207 
208 
209 /* Store the information for the raw data in the `rawdata' element.  */
210 int
211 internal_function
__libelf_set_rawdata_wrlock(Elf_Scn * scn)212 __libelf_set_rawdata_wrlock (Elf_Scn *scn)
213 {
214   Elf64_Off offset;
215   Elf64_Xword size;
216   Elf64_Xword align;
217   Elf64_Xword flags;
218   int type;
219   Elf *elf = scn->elf;
220 
221   if (elf->class == ELFCLASS32)
222     {
223       Elf32_Shdr *shdr
224 	= scn->shdr.e32 ?: __elf32_getshdr_wrlock (scn);
225 
226       if (shdr == NULL)
227 	/* Something went terribly wrong.  */
228 	return 1;
229 
230       offset = shdr->sh_offset;
231       size = shdr->sh_size;
232       type = shdr->sh_type;
233       align = shdr->sh_addralign;
234       flags = shdr->sh_flags;
235     }
236   else
237     {
238       Elf64_Shdr *shdr
239 	= scn->shdr.e64 ?: __elf64_getshdr_wrlock (scn);
240 
241       if (shdr == NULL)
242 	/* Something went terribly wrong.  */
243 	return 1;
244 
245       offset = shdr->sh_offset;
246       size = shdr->sh_size;
247       type = shdr->sh_type;
248       align = shdr->sh_addralign;
249       flags = shdr->sh_flags;
250     }
251 
252   /* If the section has no data (for whatever reason), leave the `d_buf'
253      pointer NULL.  */
254   if (size != 0 && type != SHT_NOBITS)
255     {
256       /* First a test whether the section is valid at all.  */
257       size_t entsize;
258 
259       /* Compressed data has a header, but then compressed data.
260 	 Make sure to set the alignment of the header explicitly,
261 	 don't trust the file alignment for the section, it is
262 	 often wrong.  */
263       if ((flags & SHF_COMPRESSED) != 0)
264 	{
265 	  entsize = 1;
266 	  align = __libelf_type_align (elf->class, ELF_T_CHDR);
267 	}
268       else if (type == SHT_HASH)
269 	{
270 	  GElf_Ehdr ehdr_mem;
271 	  GElf_Ehdr *ehdr = __gelf_getehdr_rdlock (elf, &ehdr_mem);
272 	  if (unlikely (ehdr == NULL))
273 	    return 1;
274 	  entsize = SH_ENTSIZE_HASH (ehdr);
275 	}
276       else
277 	{
278 	  Elf_Type t = shtype_map[TYPEIDX (type)];
279 	  if (t == ELF_T_NHDR && align == 8)
280 	    t = ELF_T_NHDR8;
281 	  if (t == ELF_T_VDEF || t == ELF_T_NHDR || t == ELF_T_NHDR8
282 	      || (t == ELF_T_GNUHASH && elf->class == ELFCLASS64))
283 	    entsize = 1;
284 	  else
285 	    entsize = __libelf_type_sizes[elf->class - 1][t];
286 	}
287 
288       /* We assume it is an array of bytes if it is none of the structured
289 	 sections we know of.  */
290       if (entsize == 0)
291 	entsize = 1;
292 
293       if (unlikely (size % entsize != 0))
294 	{
295 	  __libelf_seterrno (ELF_E_INVALID_DATA);
296 	  return 1;
297 	}
298 
299       /* We can use the mapped or loaded data if available.  */
300       if (elf->map_address != NULL)
301 	{
302 	  /* First see whether the information in the section header is
303 	     valid and it does not ask for too much.  Check for unsigned
304 	     overflow.  */
305 	  if (unlikely (offset > elf->maximum_size
306 	      || elf->maximum_size - offset < size))
307 	    {
308 	      /* Something is wrong.  */
309 	      __libelf_seterrno (ELF_E_INVALID_SECTION_HEADER);
310 	      return 1;
311 	    }
312 
313 	  scn->rawdata_base = scn->rawdata.d.d_buf
314 	    = (char *) elf->map_address + elf->start_offset + offset;
315 	}
316       else if (likely (elf->fildes != -1))
317 	{
318 	  /* First see whether the information in the section header is
319 	     valid and it does not ask for too much.  Check for unsigned
320 	     overflow.  */
321 	  if (unlikely (offset > elf->maximum_size
322 			|| elf->maximum_size - offset < size))
323 	    {
324 	      /* Something is wrong.  */
325 	      __libelf_seterrno (ELF_E_INVALID_SECTION_HEADER);
326 	      return 1;
327 	    }
328 
329 	  /* We have to read the data from the file.  Allocate the needed
330 	     memory.  */
331 	  scn->rawdata_base = scn->rawdata.d.d_buf
332 	    = (char *) malloc (size);
333 	  if (scn->rawdata.d.d_buf == NULL)
334 	    {
335 	      __libelf_seterrno (ELF_E_NOMEM);
336 	      return 1;
337 	    }
338 
339 	  ssize_t n = pread_retry (elf->fildes, scn->rawdata.d.d_buf, size,
340 				   elf->start_offset + offset);
341 	  if (unlikely ((size_t) n != size))
342 	    {
343 	      /* Cannot read the data.  */
344 	      free (scn->rawdata.d.d_buf);
345 	      scn->rawdata_base = scn->rawdata.d.d_buf = NULL;
346 	      __libelf_seterrno (ELF_E_READ_ERROR);
347 	      return 1;
348 	    }
349 	}
350       else
351 	{
352 	  /* The file descriptor is already closed, we cannot get the data
353 	     anymore.  */
354 	  __libelf_seterrno (ELF_E_FD_DISABLED);
355 	  return 1;
356 	}
357     }
358 
359   scn->rawdata.d.d_size = size;
360 
361   /* Compressed data always has type ELF_T_CHDR regardless of the
362      section type.  */
363   if ((flags & SHF_COMPRESSED) != 0)
364     scn->rawdata.d.d_type = ELF_T_CHDR;
365   else
366     {
367       GElf_Ehdr ehdr_mem;
368       GElf_Ehdr *ehdr = __gelf_getehdr_rdlock (elf, &ehdr_mem);
369       if (unlikely (ehdr == NULL))
370 	return 1;
371       scn->rawdata.d.d_type = __libelf_data_type (ehdr, type, align);
372     }
373   scn->rawdata.d.d_off = 0;
374 
375   /* Make sure the alignment makes sense.  d_align should be aligned both
376      in the section (trivially true since d_off is zero) and in the file.
377      Unfortunately we cannot be too strict because there are ELF files
378      out there that fail this requirement.  We will try to fix those up
379      in elf_update when writing out the image.  But for very large
380      alignment values this can bloat the image considerably.  So here
381      just check and clamp the alignment value to not be bigger than the
382      actual offset of the data in the file.  Given that there is always
383      at least an ehdr this will only trigger for alignment values > 64
384      which should be uncommon.  */
385   align = align ?: 1;
386   if (type != SHT_NOBITS && align > offset)
387     align = offset;
388   scn->rawdata.d.d_align = align;
389   if (elf->class == ELFCLASS32
390       || (offsetof (struct Elf, state.elf32.ehdr)
391 	  == offsetof (struct Elf, state.elf64.ehdr)))
392     scn->rawdata.d.d_version =
393       elf->state.elf32.ehdr->e_ident[EI_VERSION];
394   else
395     scn->rawdata.d.d_version =
396       elf->state.elf64.ehdr->e_ident[EI_VERSION];
397 
398   scn->rawdata.s = scn;
399 
400   scn->data_read = 1;
401 
402   /* We actually read data from the file.  At least we tried.  */
403   scn->flags |= ELF_F_FILEDATA;
404 
405   return 0;
406 }
407 
408 int
409 internal_function
__libelf_set_rawdata(Elf_Scn * scn)410 __libelf_set_rawdata (Elf_Scn *scn)
411 {
412   int result;
413 
414   if (scn == NULL)
415     return 1;
416 
417   rwlock_wrlock (scn->elf->lock);
418   result = __libelf_set_rawdata_wrlock (scn);
419   rwlock_unlock (scn->elf->lock);
420 
421   return result;
422 }
423 
424 void
425 internal_function
__libelf_set_data_list_rdlock(Elf_Scn * scn,int wrlocked)426 __libelf_set_data_list_rdlock (Elf_Scn *scn, int wrlocked)
427 {
428   if (scn->rawdata.d.d_buf != NULL && scn->rawdata.d.d_size > 0)
429     {
430       Elf *elf = scn->elf;
431 
432       /* Upgrade the lock to a write lock if necessary and check
433 	 nobody else already did the work.  */
434       if (!wrlocked)
435 	{
436 	  rwlock_unlock (elf->lock);
437 	  rwlock_wrlock (elf->lock);
438 	  if (scn->data_list_rear != NULL)
439 	    return;
440 	}
441 
442       /* Convert according to the version and the type.   */
443       convert_data (scn, elf->class,
444 		    (elf->class == ELFCLASS32
445 		     || (offsetof (struct Elf, state.elf32.ehdr)
446 			 == offsetof (struct Elf, state.elf64.ehdr))
447 		     ? elf->state.elf32.ehdr->e_ident[EI_DATA]
448 		     : elf->state.elf64.ehdr->e_ident[EI_DATA]),
449 		    scn->rawdata.d.d_size, scn->rawdata.d.d_type);
450     }
451   else
452     {
453       /* This is an empty or NOBITS section.  There is no buffer but
454 	 the size information etc is important.  */
455       scn->data_list.data.d = scn->rawdata.d;
456       scn->data_list.data.s = scn;
457     }
458 
459   scn->data_list_rear = &scn->data_list;
460 }
461 
462 Elf_Data *
463 internal_function
__elf_getdata_rdlock(Elf_Scn * scn,Elf_Data * data)464 __elf_getdata_rdlock (Elf_Scn *scn, Elf_Data *data)
465 {
466   Elf_Data *result = NULL;
467   Elf *elf;
468   int locked = 0;
469 
470   if (scn == NULL)
471     return NULL;
472 
473   if (unlikely (scn->elf->kind != ELF_K_ELF))
474     {
475       __libelf_seterrno (ELF_E_INVALID_HANDLE);
476       return NULL;
477     }
478 
479   /* We will need this multiple times later on.  */
480   elf = scn->elf;
481 
482   /* If `data' is not NULL this means we are not addressing the initial
483      data in the file.  But this also means this data is already read
484      (since otherwise it is not possible to have a valid `data' pointer)
485      and all the data structures are initialized as well.  In this case
486      we can simply walk the list of data records.  */
487   if (data != NULL)
488     {
489       Elf_Data_List *runp;
490 
491       /* It is not possible that if DATA is not NULL the first entry is
492 	 returned.  But this also means that there must be a first data
493 	 entry.  */
494       if (scn->data_list_rear == NULL
495 	  /* The section the reference data is for must match the section
496 	     parameter.  */
497 	  || unlikely (((Elf_Data_Scn *) data)->s != scn))
498 	{
499 	  __libelf_seterrno (ELF_E_DATA_MISMATCH);
500 	  goto out;
501 	}
502 
503       /* We start searching with the first entry.  */
504       runp = &scn->data_list;
505 
506       while (1)
507 	{
508 	  /* If `data' does not match any known record punt.  */
509 	  if (runp == NULL)
510 	    {
511 	      __libelf_seterrno (ELF_E_DATA_MISMATCH);
512 	      goto out;
513 	    }
514 
515 	  if (&runp->data.d == data)
516 	    /* Found the entry.  */
517 	    break;
518 
519 	  runp = runp->next;
520 	}
521 
522       /* Return the data for the next data record.  */
523       result = runp->next ? &runp->next->data.d : NULL;
524       goto out;
525     }
526 
527   /* If the data for this section was not yet initialized do it now.  */
528   if (scn->data_read == 0)
529     {
530       /* We cannot acquire a write lock while we are holding a read
531          lock.  Therefore give up the read lock and then get the write
532          lock.  But this means that the data could meanwhile be
533          modified, therefore start the tests again.  */
534       rwlock_unlock (elf->lock);
535       rwlock_wrlock (elf->lock);
536       locked = 1;
537 
538       /* Read the data from the file.  There is always a file (or
539 	 memory region) associated with this descriptor since
540 	 otherwise the `data_read' flag would be set.  */
541       if (scn->data_read == 0 && __libelf_set_rawdata_wrlock (scn) != 0)
542 	/* Something went wrong.  The error value is already set.  */
543 	goto out;
544     }
545 
546   /* At this point we know the raw data is available.  But it might be
547      empty in case the section has size zero (for whatever reason).
548      Now create the converted data in case this is necessary.  */
549   if (scn->data_list_rear == NULL)
550     __libelf_set_data_list_rdlock (scn, locked);
551 
552   /* Return the first data element in the list.  */
553   result = &scn->data_list.data.d;
554 
555  out:
556   return result;
557 }
558 
559 Elf_Data *
elf_getdata(Elf_Scn * scn,Elf_Data * data)560 elf_getdata (Elf_Scn *scn, Elf_Data *data)
561 {
562   Elf_Data *result;
563 
564   if (scn == NULL)
565     return NULL;
566 
567   rwlock_rdlock (scn->elf->lock);
568   result = __elf_getdata_rdlock (scn, data);
569   rwlock_unlock (scn->elf->lock);
570 
571   return result;
572 }
573 INTDEF(elf_getdata)
574