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