1/* Return the next data element from the section after possibly converting it.
2   Copyright (C) 1998-2005, 2006, 2007 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_HALF] = __alignof__ (ElfW2(Bits,Half)),			      \
87      [ELF_T_WORD] = __alignof__ (ElfW2(Bits,Word)),			      \
88      [ELF_T_SYM] = __alignof__ (ElfW2(Bits,Sym)),			      \
89      [ELF_T_SYMINFO] = __alignof__ (ElfW2(Bits,Syminfo)),		      \
90      [ELF_T_REL] = __alignof__ (ElfW2(Bits,Rel)),			      \
91      [ELF_T_RELA] = __alignof__ (ElfW2(Bits,Rela)),			      \
92      [ELF_T_DYN] = __alignof__ (ElfW2(Bits,Dyn)),			      \
93      [ELF_T_VDEF] = __alignof__ (ElfW2(Bits,Verdef)),			      \
94      [ELF_T_VDAUX] = __alignof__ (ElfW2(Bits,Verdaux)),		      \
95      [ELF_T_VNEED] = __alignof__ (ElfW2(Bits,Verneed)),		      \
96      [ELF_T_VNAUX] = __alignof__ (ElfW2(Bits,Vernaux)),		      \
97      [ELF_T_MOVE] = __alignof__ (ElfW2(Bits,Move)),			      \
98      [ELF_T_LIB] = __alignof__ (ElfW2(Bits,Lib)),			      \
99      [ELF_T_NHDR] = __alignof__ (ElfW2(Bits,Nhdr)),			      \
100    }
101    [EV_CURRENT - 1] =
102    {
103      [ELFCLASS32 - 1] = TYPE_ALIGNS (32),
104      [ELFCLASS64 - 1] = TYPE_ALIGNS (64),
105    }
106# undef TYPE_ALIGNS
107  };
108#endif
109
110
111/* Convert the data in the current section.  */
112static void
113convert_data (Elf_Scn *scn, int version __attribute__ ((unused)), int eclass,
114	      int data, size_t size, Elf_Type type)
115{
116  const size_t align = __libelf_type_align (eclass, type);
117
118  if (data == MY_ELFDATA)
119    {
120      if (((((size_t) (char *) scn->rawdata_base)) & (align - 1)) == 0)
121	/* No need to copy, we can use the raw data.  */
122	scn->data_base = scn->rawdata_base;
123      else
124	{
125	  scn->data_base = (char *) malloc (size);
126	  if (scn->data_base == NULL)
127	    {
128	      __libelf_seterrno (ELF_E_NOMEM);
129	      return;
130	    }
131
132	  /* The copy will be appropriately aligned for direct access.  */
133	  memcpy (scn->data_base, scn->rawdata_base, size);
134	}
135    }
136  else
137    {
138      xfct_t fp;
139
140      scn->data_base = (char *) malloc (size);
141      if (scn->data_base == NULL)
142	{
143	  __libelf_seterrno (ELF_E_NOMEM);
144	  return;
145	}
146
147      /* Get the conversion function.  */
148#if EV_NUM != 2
149      fp = __elf_xfctstom[version - 1][__libelf_version - 1][eclass - 1][type];
150#else
151      fp = __elf_xfctstom[0][0][eclass - 1][type];
152#endif
153
154      fp (scn->data_base, scn->rawdata_base, size, 0);
155    }
156
157  scn->data_list.data.d.d_buf = scn->data_base;
158  scn->data_list.data.d.d_size = size;
159  scn->data_list.data.d.d_type = type;
160  scn->data_list.data.d.d_off = scn->rawdata.d.d_off;
161  scn->data_list.data.d.d_align = scn->rawdata.d.d_align;
162  scn->data_list.data.d.d_version = scn->rawdata.d.d_version;
163
164  scn->data_list.data.s = scn;
165}
166
167
168/* Store the information for the raw data in the `rawdata' element.  */
169int
170internal_function
171__libelf_set_rawdata_wrlock (Elf_Scn *scn)
172{
173  Elf64_Off offset;
174  Elf64_Xword size;
175  Elf64_Xword align;
176  int type;
177  Elf *elf = scn->elf;
178
179  if (elf->class == ELFCLASS32)
180    {
181      Elf32_Shdr *shdr
182	= scn->shdr.e32 ?: __elf32_getshdr_wrlock (scn);
183
184      if (shdr == NULL)
185	/* Something went terribly wrong.  */
186	return 1;
187
188      offset = shdr->sh_offset;
189      size = shdr->sh_size;
190      type = shdr->sh_type;
191      align = shdr->sh_addralign;
192    }
193  else
194    {
195      Elf64_Shdr *shdr
196	= scn->shdr.e64 ?: __elf64_getshdr_wrlock (scn);
197
198      if (shdr == NULL)
199	/* Something went terribly wrong.  */
200	return 1;
201
202      offset = shdr->sh_offset;
203      size = shdr->sh_size;
204      type = shdr->sh_type;
205      align = shdr->sh_addralign;
206    }
207
208  /* If the section has no data (for whatever reason), leave the `d_buf'
209     pointer NULL.  */
210  if (size != 0 && type != SHT_NOBITS)
211    {
212      /* First a test whether the section is valid at all.  */
213      size_t entsize;
214
215      if (type == SHT_HASH)
216	{
217	  GElf_Ehdr ehdr_mem;
218	  GElf_Ehdr *ehdr = __gelf_getehdr_rdlock (elf, &ehdr_mem);
219	  entsize = SH_ENTSIZE_HASH (ehdr);
220	}
221      else
222	{
223	  Elf_Type t = shtype_map[LIBELF_EV_IDX][TYPEIDX (type)];
224	  if (t == ELF_T_VDEF || t == ELF_T_NHDR
225	      || (t == ELF_T_GNUHASH && elf->class == ELFCLASS64))
226	    entsize = 1;
227	  else
228	    entsize = __libelf_type_sizes[LIBELF_EV_IDX][elf->class - 1][t];
229	}
230
231      /* We assume it is an array of bytes if it is none of the structured
232	 sections we know of.  */
233      if (entsize == 0)
234	entsize = 1;
235
236      if (unlikely (size % entsize != 0))
237	{
238	  __libelf_seterrno (ELF_E_INVALID_DATA);
239	  return 1;
240	}
241
242      /* We can use the mapped or loaded data if available.  */
243      if (elf->map_address != NULL)
244	{
245	  /* First see whether the information in the section header is
246	     valid and it does not ask for too much.  Check for unsigned
247	     overflow.  */
248	  if (unlikely (offset > elf->maximum_size
249	      || elf->maximum_size - offset < size))
250	    {
251	      /* Something is wrong.  */
252	      __libelf_seterrno (ELF_E_INVALID_SECTION_HEADER);
253	      return 1;
254	    }
255
256	  scn->rawdata_base = scn->rawdata.d.d_buf
257	    = (char *) elf->map_address + elf->start_offset + offset;
258	}
259      else if (likely (elf->fildes != -1))
260	{
261	  /* We have to read the data from the file.  Allocate the needed
262	     memory.  */
263	  scn->rawdata_base = scn->rawdata.d.d_buf
264	    = (char *) malloc (size);
265	  if (scn->rawdata.d.d_buf == NULL)
266	    {
267	      __libelf_seterrno (ELF_E_NOMEM);
268	      return 1;
269	    }
270
271	  ssize_t n = pread_retry (elf->fildes, scn->rawdata.d.d_buf, size,
272				   elf->start_offset + offset);
273	  if (unlikely ((size_t) n != size))
274	    {
275	      /* Cannot read the data.  */
276	      free (scn->rawdata.d.d_buf);
277	      scn->rawdata_base = scn->rawdata.d.d_buf = NULL;
278	      __libelf_seterrno (ELF_E_READ_ERROR);
279	      return 1;
280	    }
281	}
282      else
283	{
284	  /* The file descriptor is already closed, we cannot get the data
285	     anymore.  */
286	  __libelf_seterrno (ELF_E_FD_DISABLED);
287	  return 1;
288	}
289    }
290
291  scn->rawdata.d.d_size = size;
292  /* Some broken ELF ABI for 64-bit machines use the wrong hash table
293     entry size.  See elf-knowledge.h for more information.  */
294  if (type == SHT_HASH && elf->class == ELFCLASS64)
295    {
296      GElf_Ehdr ehdr_mem;
297      GElf_Ehdr *ehdr = __gelf_getehdr_rdlock (elf, &ehdr_mem);
298      scn->rawdata.d.d_type
299	= (SH_ENTSIZE_HASH (ehdr) == 4 ? ELF_T_WORD : ELF_T_XWORD);
300    }
301  else
302    scn->rawdata.d.d_type = shtype_map[LIBELF_EV_IDX][TYPEIDX (type)];
303  scn->rawdata.d.d_off = 0;
304  scn->rawdata.d.d_align = align;
305  if (elf->class == ELFCLASS32
306      || (offsetof (struct Elf, state.elf32.ehdr)
307	  == offsetof (struct Elf, state.elf64.ehdr)))
308    scn->rawdata.d.d_version =
309      elf->state.elf32.ehdr->e_ident[EI_VERSION];
310  else
311    scn->rawdata.d.d_version =
312      elf->state.elf64.ehdr->e_ident[EI_VERSION];
313
314  scn->rawdata.s = scn;
315
316  scn->data_read = 1;
317
318  /* We actually read data from the file.  At least we tried.  */
319  scn->flags |= ELF_F_FILEDATA;
320
321  return 0;
322}
323
324int
325internal_function
326__libelf_set_rawdata (Elf_Scn *scn)
327{
328  int result;
329
330  if (scn == NULL)
331    return 1;
332
333  rwlock_wrlock (scn->elf->lock);
334  result = __libelf_set_rawdata_wrlock (scn);
335  rwlock_unlock (scn->elf->lock);
336
337  return result;
338}
339
340Elf_Data *
341internal_function
342__elf_getdata_rdlock (scn, data)
343     Elf_Scn *scn;
344     Elf_Data *data;
345{
346  Elf_Data *result = NULL;
347  Elf *elf;
348  int locked = 0;
349
350  if (scn == NULL)
351    return NULL;
352
353  if (unlikely (scn->elf->kind != ELF_K_ELF))
354    {
355      __libelf_seterrno (ELF_E_INVALID_HANDLE);
356      return NULL;
357    }
358
359  /* We will need this multiple times later on.  */
360  elf = scn->elf;
361
362  /* If `data' is not NULL this means we are not addressing the initial
363     data in the file.  But this also means this data is already read
364     (since otherwise it is not possible to have a valid `data' pointer)
365     and all the data structures are initialized as well.  In this case
366     we can simply walk the list of data records.  */
367  if (data != NULL)
368    {
369      Elf_Data_List *runp;
370
371      /* It is not possible that if DATA is not NULL the first entry is
372	 returned.  But this also means that there must be a first data
373	 entry.  */
374      if (scn->data_list_rear == NULL
375	  /* The section the reference data is for must match the section
376	     parameter.  */
377	  || unlikely (((Elf_Data_Scn *) data)->s != scn))
378	{
379	  __libelf_seterrno (ELF_E_DATA_MISMATCH);
380	  goto out;
381	}
382
383      /* We start searching with the first entry.  */
384      runp = &scn->data_list;
385
386      while (1)
387	{
388	  /* If `data' does not match any known record punt.  */
389	  if (runp == NULL)
390	    {
391	      __libelf_seterrno (ELF_E_DATA_MISMATCH);
392	      goto out;
393	    }
394
395	  if (&runp->data.d == data)
396	    /* Found the entry.  */
397	    break;
398
399	  runp = runp->next;
400	}
401
402      /* Return the data for the next data record.  */
403      result = runp->next ? &runp->next->data.d : NULL;
404      goto out;
405    }
406
407  /* If the data for this section was not yet initialized do it now.  */
408  if (scn->data_read == 0)
409    {
410      /* We cannot acquire a write lock while we are holding a read
411         lock.  Therefore give up the read lock and then get the write
412         lock.  But this means that the data could meanwhile be
413         modified, therefore start the tests again.  */
414      rwlock_unlock (elf->lock);
415      rwlock_wrlock (elf->lock);
416      locked = 1;
417
418      /* Read the data from the file.  There is always a file (or
419	 memory region) associated with this descriptor since
420	 otherwise the `data_read' flag would be set.  */
421      if (scn->data_read == 0 && __libelf_set_rawdata_wrlock (scn) != 0)
422	/* Something went wrong.  The error value is already set.  */
423	goto out;
424    }
425
426  /* At this point we know the raw data is available.  But it might be
427     empty in case the section has size zero (for whatever reason).
428     Now create the converted data in case this is necessary.  */
429  if (scn->data_list_rear == NULL)
430    {
431      if (scn->rawdata.d.d_buf != NULL && scn->rawdata.d.d_size > 0)
432	{
433	  if (!locked)
434	    {
435	      rwlock_unlock (elf->lock);
436	      rwlock_wrlock (elf->lock);
437	      if (scn->data_list_rear != NULL)
438		goto pass;
439	    }
440
441	  /* Convert according to the version and the type.   */
442	  convert_data (scn, __libelf_version, elf->class,
443			(elf->class == ELFCLASS32
444			 || (offsetof (struct Elf, state.elf32.ehdr)
445			     == offsetof (struct Elf, state.elf64.ehdr))
446			 ? elf->state.elf32.ehdr->e_ident[EI_DATA]
447			 : elf->state.elf64.ehdr->e_ident[EI_DATA]),
448			scn->rawdata.d.d_size, scn->rawdata.d.d_type);
449	}
450      else
451	{
452	  /* This is an empty or NOBITS section.  There is no buffer but
453	     the size information etc is important.  */
454	  scn->data_list.data.d = scn->rawdata.d;
455	  scn->data_list.data.s = scn;
456	}
457
458      scn->data_list_rear = &scn->data_list;
459    }
460
461  /* If no data is present we cannot return any.  */
462  if (scn->data_list_rear != NULL)
463  pass:
464    /* Return the first data element in the list.  */
465    result = &scn->data_list.data.d;
466
467 out:
468  return result;
469}
470
471Elf_Data *
472elf_getdata (scn, data)
473     Elf_Scn *scn;
474     Elf_Data *data;
475{
476  Elf_Data *result;
477
478  if (scn == NULL)
479    return NULL;
480
481  rwlock_rdlock (scn->elf->lock);
482  result = __elf_getdata_rdlock (scn, data);
483  rwlock_unlock (scn->elf->lock);
484
485  return result;
486}
487INTDEF(elf_getdata)
488