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.  */
53 static 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.  */
81 const 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.  */
112 static void
convert_data(Elf_Scn * scn,int version,int eclass,int data,size_t size,Elf_Type type)113 convert_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.  */
169 int
170 internal_function
__libelf_set_rawdata_wrlock(Elf_Scn * scn)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 
324 int
325 internal_function
__libelf_set_rawdata(Elf_Scn * scn)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 
340 Elf_Data *
341 internal_function
__elf_getdata_rdlock(scn,data)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 
471 Elf_Data *
elf_getdata(scn,data)472 elf_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 }
487 INTDEF(elf_getdata)
488