• 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(Elf * elf,int sh_type,GElf_Xword align)116 __libelf_data_type (Elf *elf, 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 && elf->class == ELFCLASS64)
121     {
122       GElf_Ehdr ehdr_mem;
123       GElf_Ehdr *ehdr = __gelf_getehdr_rdlock (elf, &ehdr_mem);
124       return (SH_ENTSIZE_HASH (ehdr) == 4 ? ELF_T_WORD : ELF_T_XWORD);
125     }
126   else
127     {
128       Elf_Type t = shtype_map[TYPEIDX (sh_type)];
129       /* Special case for GNU Property notes.  */
130       if (t == ELF_T_NHDR && align == 8)
131 	t = ELF_T_NHDR8;
132       return t;
133     }
134 }
135 
136 /* Convert the data in the current section.  */
137 static void
convert_data(Elf_Scn * scn,int eclass,int data,size_t size,Elf_Type type)138 convert_data (Elf_Scn *scn, int eclass,
139 	      int data, size_t size, Elf_Type type)
140 {
141   const size_t align = __libelf_type_align (eclass, type);
142 
143   /* Do we need to convert the data and/or adjust for alignment?  */
144   if (data == MY_ELFDATA || type == ELF_T_BYTE)
145     {
146       if (((((size_t) (char *) scn->rawdata_base)) & (align - 1)) == 0)
147 	/* No need to copy, we can use the raw data.  */
148 	scn->data_base = scn->rawdata_base;
149       else
150 	{
151 	  scn->data_base = (char *) malloc (size);
152 	  if (scn->data_base == NULL)
153 	    {
154 	      __libelf_seterrno (ELF_E_NOMEM);
155 	      return;
156 	    }
157 
158 	  /* The copy will be appropriately aligned for direct access.  */
159 	  memcpy (scn->data_base, scn->rawdata_base, size);
160 	}
161     }
162   else
163     {
164       xfct_t fp;
165 
166       scn->data_base = (char *) malloc (size);
167       if (scn->data_base == NULL)
168 	{
169 	  __libelf_seterrno (ELF_E_NOMEM);
170 	  return;
171 	}
172 
173       /* Make sure the source is correctly aligned for the conversion
174 	 function to directly access the data elements.  */
175       char *rawdata_source;
176       if (((((size_t) (char *) scn->rawdata_base)) & (align - 1)) == 0)
177 	rawdata_source = scn->rawdata_base;
178       else
179 	{
180 	  rawdata_source = (char *) malloc (size);
181 	  if (rawdata_source == NULL)
182 	    {
183 	      __libelf_seterrno (ELF_E_NOMEM);
184 	      return;
185 	    }
186 
187 	  /* The copy will be appropriately aligned for direct access.  */
188 	  memcpy (rawdata_source, scn->rawdata_base, size);
189 	}
190 
191       /* Get the conversion function.  */
192       fp = __elf_xfctstom[eclass - 1][type];
193 
194       fp (scn->data_base, rawdata_source, size, 0);
195 
196       if (rawdata_source != scn->rawdata_base)
197 	free (rawdata_source);
198     }
199 
200   scn->data_list.data.d.d_buf = scn->data_base;
201   scn->data_list.data.d.d_size = size;
202   scn->data_list.data.d.d_type = type;
203   scn->data_list.data.d.d_off = scn->rawdata.d.d_off;
204   scn->data_list.data.d.d_align = scn->rawdata.d.d_align;
205   scn->data_list.data.d.d_version = scn->rawdata.d.d_version;
206 
207   scn->data_list.data.s = scn;
208 }
209 
210 
211 /* Store the information for the raw data in the `rawdata' element.  */
212 int
213 internal_function
__libelf_set_rawdata_wrlock(Elf_Scn * scn)214 __libelf_set_rawdata_wrlock (Elf_Scn *scn)
215 {
216   Elf64_Off offset;
217   Elf64_Xword size;
218   Elf64_Xword align;
219   Elf64_Xword flags;
220   int type;
221   Elf *elf = scn->elf;
222 
223   if (elf->class == ELFCLASS32)
224     {
225       Elf32_Shdr *shdr
226 	= scn->shdr.e32 ?: __elf32_getshdr_wrlock (scn);
227 
228       if (shdr == NULL)
229 	/* Something went terribly wrong.  */
230 	return 1;
231 
232       offset = shdr->sh_offset;
233       size = shdr->sh_size;
234       type = shdr->sh_type;
235       align = shdr->sh_addralign;
236       flags = shdr->sh_flags;
237     }
238   else
239     {
240       Elf64_Shdr *shdr
241 	= scn->shdr.e64 ?: __elf64_getshdr_wrlock (scn);
242 
243       if (shdr == NULL)
244 	/* Something went terribly wrong.  */
245 	return 1;
246 
247       offset = shdr->sh_offset;
248       size = shdr->sh_size;
249       type = shdr->sh_type;
250       align = shdr->sh_addralign;
251       flags = shdr->sh_flags;
252     }
253 
254   /* If the section has no data (for whatever reason), leave the `d_buf'
255      pointer NULL.  */
256   if (size != 0 && type != SHT_NOBITS)
257     {
258       /* First a test whether the section is valid at all.  */
259       size_t entsize;
260 
261       /* Compressed data has a header, but then compressed data.
262 	 Make sure to set the alignment of the header explicitly,
263 	 don't trust the file alignment for the section, it is
264 	 often wrong.  */
265       if ((flags & SHF_COMPRESSED) != 0)
266 	{
267 	  entsize = 1;
268 	  align = __libelf_type_align (elf->class, ELF_T_CHDR);
269 	}
270       else if (type == SHT_HASH)
271 	{
272 	  GElf_Ehdr ehdr_mem;
273 	  GElf_Ehdr *ehdr = __gelf_getehdr_rdlock (elf, &ehdr_mem);
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     scn->rawdata.d.d_type = __libelf_data_type (elf, type, align);
367   scn->rawdata.d.d_off = 0;
368 
369   /* Make sure the alignment makes sense.  d_align should be aligned both
370      in the section (trivially true since d_off is zero) and in the file.
371      Unfortunately we cannot be too strict because there are ELF files
372      out there that fail this requirement.  We will try to fix those up
373      in elf_update when writing out the image.  But for very large
374      alignment values this can bloat the image considerably.  So here
375      just check and clamp the alignment value to not be bigger than the
376      actual offset of the data in the file.  Given that there is always
377      at least an ehdr this will only trigger for alignment values > 64
378      which should be uncommon.  */
379   align = align ?: 1;
380   if (type != SHT_NOBITS && align > offset)
381     align = offset;
382   scn->rawdata.d.d_align = align;
383   if (elf->class == ELFCLASS32
384       || (offsetof (struct Elf, state.elf32.ehdr)
385 	  == offsetof (struct Elf, state.elf64.ehdr)))
386     scn->rawdata.d.d_version =
387       elf->state.elf32.ehdr->e_ident[EI_VERSION];
388   else
389     scn->rawdata.d.d_version =
390       elf->state.elf64.ehdr->e_ident[EI_VERSION];
391 
392   scn->rawdata.s = scn;
393 
394   scn->data_read = 1;
395 
396   /* We actually read data from the file.  At least we tried.  */
397   scn->flags |= ELF_F_FILEDATA;
398 
399   return 0;
400 }
401 
402 int
403 internal_function
__libelf_set_rawdata(Elf_Scn * scn)404 __libelf_set_rawdata (Elf_Scn *scn)
405 {
406   int result;
407 
408   if (scn == NULL)
409     return 1;
410 
411   rwlock_wrlock (scn->elf->lock);
412   result = __libelf_set_rawdata_wrlock (scn);
413   rwlock_unlock (scn->elf->lock);
414 
415   return result;
416 }
417 
418 void
419 internal_function
__libelf_set_data_list_rdlock(Elf_Scn * scn,int wrlocked)420 __libelf_set_data_list_rdlock (Elf_Scn *scn, int wrlocked)
421 {
422   if (scn->rawdata.d.d_buf != NULL && scn->rawdata.d.d_size > 0)
423     {
424       Elf *elf = scn->elf;
425 
426       /* Upgrade the lock to a write lock if necessary and check
427 	 nobody else already did the work.  */
428       if (!wrlocked)
429 	{
430 	  rwlock_unlock (elf->lock);
431 	  rwlock_wrlock (elf->lock);
432 	  if (scn->data_list_rear != NULL)
433 	    return;
434 	}
435 
436       /* Convert according to the version and the type.   */
437       convert_data (scn, elf->class,
438 		    (elf->class == ELFCLASS32
439 		     || (offsetof (struct Elf, state.elf32.ehdr)
440 			 == offsetof (struct Elf, state.elf64.ehdr))
441 		     ? elf->state.elf32.ehdr->e_ident[EI_DATA]
442 		     : elf->state.elf64.ehdr->e_ident[EI_DATA]),
443 		    scn->rawdata.d.d_size, scn->rawdata.d.d_type);
444     }
445   else
446     {
447       /* This is an empty or NOBITS section.  There is no buffer but
448 	 the size information etc is important.  */
449       scn->data_list.data.d = scn->rawdata.d;
450       scn->data_list.data.s = scn;
451     }
452 
453   scn->data_list_rear = &scn->data_list;
454 }
455 
456 Elf_Data *
457 internal_function
__elf_getdata_rdlock(Elf_Scn * scn,Elf_Data * data)458 __elf_getdata_rdlock (Elf_Scn *scn, Elf_Data *data)
459 {
460   Elf_Data *result = NULL;
461   Elf *elf;
462   int locked = 0;
463 
464   if (scn == NULL)
465     return NULL;
466 
467   if (unlikely (scn->elf->kind != ELF_K_ELF))
468     {
469       __libelf_seterrno (ELF_E_INVALID_HANDLE);
470       return NULL;
471     }
472 
473   /* We will need this multiple times later on.  */
474   elf = scn->elf;
475 
476   /* If `data' is not NULL this means we are not addressing the initial
477      data in the file.  But this also means this data is already read
478      (since otherwise it is not possible to have a valid `data' pointer)
479      and all the data structures are initialized as well.  In this case
480      we can simply walk the list of data records.  */
481   if (data != NULL)
482     {
483       Elf_Data_List *runp;
484 
485       /* It is not possible that if DATA is not NULL the first entry is
486 	 returned.  But this also means that there must be a first data
487 	 entry.  */
488       if (scn->data_list_rear == NULL
489 	  /* The section the reference data is for must match the section
490 	     parameter.  */
491 	  || unlikely (((Elf_Data_Scn *) data)->s != scn))
492 	{
493 	  __libelf_seterrno (ELF_E_DATA_MISMATCH);
494 	  goto out;
495 	}
496 
497       /* We start searching with the first entry.  */
498       runp = &scn->data_list;
499 
500       while (1)
501 	{
502 	  /* If `data' does not match any known record punt.  */
503 	  if (runp == NULL)
504 	    {
505 	      __libelf_seterrno (ELF_E_DATA_MISMATCH);
506 	      goto out;
507 	    }
508 
509 	  if (&runp->data.d == data)
510 	    /* Found the entry.  */
511 	    break;
512 
513 	  runp = runp->next;
514 	}
515 
516       /* Return the data for the next data record.  */
517       result = runp->next ? &runp->next->data.d : NULL;
518       goto out;
519     }
520 
521   /* If the data for this section was not yet initialized do it now.  */
522   if (scn->data_read == 0)
523     {
524       /* We cannot acquire a write lock while we are holding a read
525          lock.  Therefore give up the read lock and then get the write
526          lock.  But this means that the data could meanwhile be
527          modified, therefore start the tests again.  */
528       rwlock_unlock (elf->lock);
529       rwlock_wrlock (elf->lock);
530       locked = 1;
531 
532       /* Read the data from the file.  There is always a file (or
533 	 memory region) associated with this descriptor since
534 	 otherwise the `data_read' flag would be set.  */
535       if (scn->data_read == 0 && __libelf_set_rawdata_wrlock (scn) != 0)
536 	/* Something went wrong.  The error value is already set.  */
537 	goto out;
538     }
539 
540   /* At this point we know the raw data is available.  But it might be
541      empty in case the section has size zero (for whatever reason).
542      Now create the converted data in case this is necessary.  */
543   if (scn->data_list_rear == NULL)
544     __libelf_set_data_list_rdlock (scn, locked);
545 
546   /* Return the first data element in the list.  */
547   result = &scn->data_list.data.d;
548 
549  out:
550   return result;
551 }
552 
553 Elf_Data *
elf_getdata(Elf_Scn * scn,Elf_Data * data)554 elf_getdata (Elf_Scn *scn, Elf_Data *data)
555 {
556   Elf_Data *result;
557 
558   if (scn == NULL)
559     return NULL;
560 
561   rwlock_rdlock (scn->elf->lock);
562   result = __elf_getdata_rdlock (scn, data);
563   rwlock_unlock (scn->elf->lock);
564 
565   return result;
566 }
567 INTDEF(elf_getdata)
568