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