Line data Source code
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
116 1852014 : __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 1852014 : if (sh_type == SHT_HASH && elf->class == ELFCLASS64)
121 : {
122 126 : GElf_Ehdr ehdr_mem;
123 126 : GElf_Ehdr *ehdr = __gelf_getehdr_rdlock (elf, &ehdr_mem);
124 126 : return (SH_ENTSIZE_HASH (ehdr) == 4 ? ELF_T_WORD : ELF_T_XWORD);
125 : }
126 : else
127 : {
128 1851888 : Elf_Type t = shtype_map[TYPEIDX (sh_type)];
129 : /* Special case for GNU Property notes. */
130 1851888 : if (t == ELF_T_NHDR && align == 8)
131 5 : t = ELF_T_NHDR8;
132 1851888 : return t;
133 : }
134 : }
135 :
136 : /* Convert the data in the current section. */
137 : static void
138 1323505 : convert_data (Elf_Scn *scn, int eclass,
139 : int data, size_t size, Elf_Type type)
140 : {
141 1323505 : const size_t align = __libelf_type_align (eclass, type);
142 :
143 : /* Do we need to convert the data and/or adjust for alignment? */
144 1323505 : if (data == MY_ELFDATA || type == ELF_T_BYTE)
145 : {
146 1321336 : if (((((size_t) (char *) scn->rawdata_base)) & (align - 1)) == 0)
147 : /* No need to copy, we can use the raw data. */
148 1321100 : scn->data_base = scn->rawdata_base;
149 : else
150 : {
151 236 : scn->data_base = (char *) malloc (size);
152 236 : if (scn->data_base == NULL)
153 : {
154 0 : __libelf_seterrno (ELF_E_NOMEM);
155 0 : return;
156 : }
157 :
158 : /* The copy will be appropriately aligned for direct access. */
159 236 : memcpy (scn->data_base, scn->rawdata_base, size);
160 : }
161 : }
162 : else
163 : {
164 2169 : xfct_t fp;
165 :
166 2169 : scn->data_base = (char *) malloc (size);
167 2169 : if (scn->data_base == NULL)
168 : {
169 0 : __libelf_seterrno (ELF_E_NOMEM);
170 0 : return;
171 : }
172 :
173 : /* Make sure the source is correctly aligned for the conversion
174 : function to directly access the data elements. */
175 2169 : char *rawdata_source;
176 2169 : if (((((size_t) (char *) scn->rawdata_base)) & (align - 1)) == 0)
177 : rawdata_source = scn->rawdata_base;
178 : else
179 : {
180 17 : rawdata_source = (char *) malloc (size);
181 17 : if (rawdata_source == NULL)
182 : {
183 0 : __libelf_seterrno (ELF_E_NOMEM);
184 0 : return;
185 : }
186 :
187 : /* The copy will be appropriately aligned for direct access. */
188 17 : memcpy (rawdata_source, scn->rawdata_base, size);
189 : }
190 :
191 : /* Get the conversion function. */
192 2169 : fp = __elf_xfctstom[eclass - 1][type];
193 :
194 2169 : fp (scn->data_base, rawdata_source, size, 0);
195 :
196 2169 : if (rawdata_source != scn->rawdata_base)
197 17 : free (rawdata_source);
198 : }
199 :
200 1323505 : scn->data_list.data.d.d_buf = scn->data_base;
201 1323505 : scn->data_list.data.d.d_size = size;
202 1323505 : scn->data_list.data.d.d_type = type;
203 1323505 : scn->data_list.data.d.d_off = scn->rawdata.d.d_off;
204 1323505 : scn->data_list.data.d.d_align = scn->rawdata.d.d_align;
205 1323505 : scn->data_list.data.d.d_version = scn->rawdata.d.d_version;
206 :
207 1323505 : 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
214 1851807 : __libelf_set_rawdata_wrlock (Elf_Scn *scn)
215 : {
216 1851807 : Elf64_Off offset;
217 1851807 : Elf64_Xword size;
218 1851807 : Elf64_Xword align;
219 1851807 : Elf64_Xword flags;
220 1851807 : int type;
221 1851807 : Elf *elf = scn->elf;
222 :
223 1851807 : if (elf->class == ELFCLASS32)
224 : {
225 2025272 : Elf32_Shdr *shdr
226 1012636 : = scn->shdr.e32 ?: __elf32_getshdr_wrlock (scn);
227 :
228 1012636 : if (shdr == NULL)
229 : /* Something went terribly wrong. */
230 : return 1;
231 :
232 1012636 : offset = shdr->sh_offset;
233 1012636 : size = shdr->sh_size;
234 1012636 : type = shdr->sh_type;
235 1012636 : align = shdr->sh_addralign;
236 1012636 : flags = shdr->sh_flags;
237 : }
238 : else
239 : {
240 1678342 : Elf64_Shdr *shdr
241 839171 : = scn->shdr.e64 ?: __elf64_getshdr_wrlock (scn);
242 :
243 839171 : if (shdr == NULL)
244 : /* Something went terribly wrong. */
245 : return 1;
246 :
247 839171 : offset = shdr->sh_offset;
248 839171 : size = shdr->sh_size;
249 839171 : type = shdr->sh_type;
250 839171 : align = shdr->sh_addralign;
251 839171 : flags = shdr->sh_flags;
252 : }
253 :
254 : /* If the section has no data (for whatever reason), leave the `d_buf'
255 : pointer NULL. */
256 1851807 : if (size != 0 && type != SHT_NOBITS)
257 : {
258 : /* First a test whether the section is valid at all. */
259 1849865 : 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 1849865 : if ((flags & SHF_COMPRESSED) != 0)
266 : {
267 811 : entsize = 1;
268 811 : align = __libelf_type_align (elf->class, ELF_T_CHDR);
269 : }
270 1849054 : else if (type == SHT_HASH)
271 : {
272 254 : GElf_Ehdr ehdr_mem;
273 254 : GElf_Ehdr *ehdr = __gelf_getehdr_rdlock (elf, &ehdr_mem);
274 446 : entsize = SH_ENTSIZE_HASH (ehdr);
275 : }
276 : else
277 : {
278 1848800 : Elf_Type t = shtype_map[TYPEIDX (type)];
279 1848800 : if (t == ELF_T_NHDR && align == 8)
280 5 : t = ELF_T_NHDR8;
281 1848800 : if (t == ELF_T_VDEF || t == ELF_T_NHDR || t == ELF_T_NHDR8
282 1847672 : || (t == ELF_T_GNUHASH && elf->class == ELFCLASS64))
283 : entsize = 1;
284 : else
285 1847487 : 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 1847741 : if (entsize == 0)
291 0 : entsize = 1;
292 :
293 1849865 : if (unlikely (size % entsize != 0))
294 : {
295 0 : __libelf_seterrno (ELF_E_INVALID_DATA);
296 0 : return 1;
297 : }
298 :
299 : /* We can use the mapped or loaded data if available. */
300 1849865 : 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 594838 : if (unlikely (offset > elf->maximum_size
306 : || elf->maximum_size - offset < size))
307 : {
308 : /* Something is wrong. */
309 0 : __libelf_seterrno (ELF_E_INVALID_SECTION_HEADER);
310 0 : return 1;
311 : }
312 :
313 1189676 : scn->rawdata_base = scn->rawdata.d.d_buf
314 594838 : = (char *) elf->map_address + elf->start_offset + offset;
315 : }
316 1255027 : 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 1255027 : if (unlikely (offset > elf->maximum_size
322 : || elf->maximum_size - offset < size))
323 : {
324 : /* Something is wrong. */
325 0 : __libelf_seterrno (ELF_E_INVALID_SECTION_HEADER);
326 0 : return 1;
327 : }
328 :
329 : /* We have to read the data from the file. Allocate the needed
330 : memory. */
331 2510054 : scn->rawdata_base = scn->rawdata.d.d_buf
332 1255027 : = (char *) malloc (size);
333 1255027 : if (scn->rawdata.d.d_buf == NULL)
334 : {
335 0 : __libelf_seterrno (ELF_E_NOMEM);
336 0 : return 1;
337 : }
338 :
339 3765081 : ssize_t n = pread_retry (elf->fildes, scn->rawdata.d.d_buf, size,
340 1255027 : elf->start_offset + offset);
341 1255027 : if (unlikely ((size_t) n != size))
342 : {
343 : /* Cannot read the data. */
344 0 : free (scn->rawdata.d.d_buf);
345 0 : scn->rawdata_base = scn->rawdata.d.d_buf = NULL;
346 0 : __libelf_seterrno (ELF_E_READ_ERROR);
347 0 : return 1;
348 : }
349 : }
350 : else
351 : {
352 : /* The file descriptor is already closed, we cannot get the data
353 : anymore. */
354 0 : __libelf_seterrno (ELF_E_FD_DISABLED);
355 0 : return 1;
356 : }
357 : }
358 :
359 1851807 : scn->rawdata.d.d_size = size;
360 :
361 : /* Compressed data always has type ELF_T_CHDR regardless of the
362 : section type. */
363 1851807 : if ((flags & SHF_COMPRESSED) != 0)
364 811 : scn->rawdata.d.d_type = ELF_T_CHDR;
365 : else
366 1850996 : scn->rawdata.d.d_type = __libelf_data_type (elf, type, align);
367 1851807 : 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 1851807 : align = align ?: 1;
380 1851807 : if (type != SHT_NOBITS && align > offset)
381 0 : align = offset;
382 1851807 : scn->rawdata.d.d_align = align;
383 1851807 : if (elf->class == ELFCLASS32
384 : || (offsetof (struct Elf, state.elf32.ehdr)
385 : == offsetof (struct Elf, state.elf64.ehdr)))
386 3703614 : scn->rawdata.d.d_version =
387 1851807 : 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 1851807 : scn->rawdata.s = scn;
393 :
394 1851807 : scn->data_read = 1;
395 :
396 : /* We actually read data from the file. At least we tried. */
397 1851807 : scn->flags |= ELF_F_FILEDATA;
398 :
399 1851807 : return 0;
400 : }
401 :
402 : int
403 : internal_function
404 1019 : __libelf_set_rawdata (Elf_Scn *scn)
405 : {
406 1019 : int result;
407 :
408 1019 : if (scn == NULL)
409 : return 1;
410 :
411 1019 : rwlock_wrlock (scn->elf->lock);
412 1019 : result = __libelf_set_rawdata_wrlock (scn);
413 1019 : rwlock_unlock (scn->elf->lock);
414 :
415 1019 : return result;
416 : }
417 :
418 : void
419 : internal_function
420 1325354 : __libelf_set_data_list_rdlock (Elf_Scn *scn, int wrlocked)
421 : {
422 1325354 : if (scn->rawdata.d.d_buf != NULL && scn->rawdata.d.d_size > 0)
423 1323505 : {
424 1323505 : 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 1323505 : if (!wrlocked)
429 : {
430 839 : rwlock_unlock (elf->lock);
431 839 : rwlock_wrlock (elf->lock);
432 839 : if (scn->data_list_rear != NULL)
433 : return;
434 : }
435 :
436 : /* Convert according to the version and the type. */
437 2647010 : convert_data (scn, elf->class,
438 : (elf->class == ELFCLASS32
439 : || (offsetof (struct Elf, state.elf32.ehdr)
440 : == offsetof (struct Elf, state.elf64.ehdr))
441 1323505 : ? 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 1849 : scn->data_list.data.d = scn->rawdata.d;
450 1849 : scn->data_list.data.s = scn;
451 : }
452 :
453 1325354 : scn->data_list_rear = &scn->data_list;
454 : }
455 :
456 : Elf_Data *
457 : internal_function
458 2490314 : __elf_getdata_rdlock (Elf_Scn *scn, Elf_Data *data)
459 : {
460 2490314 : Elf_Data *result = NULL;
461 2490314 : Elf *elf;
462 2490314 : int locked = 0;
463 :
464 2490314 : if (scn == NULL)
465 : return NULL;
466 :
467 2490314 : if (unlikely (scn->elf->kind != ELF_K_ELF))
468 : {
469 0 : __libelf_seterrno (ELF_E_INVALID_HANDLE);
470 0 : return NULL;
471 : }
472 :
473 : /* We will need this multiple times later on. */
474 2490314 : 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 2490314 : if (data != NULL)
482 : {
483 1051289 : 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 1051289 : if (scn->data_list_rear == NULL
489 : /* The section the reference data is for must match the section
490 : parameter. */
491 1051289 : || unlikely (((Elf_Data_Scn *) data)->s != scn))
492 : {
493 0 : __libelf_seterrno (ELF_E_DATA_MISMATCH);
494 0 : goto out;
495 : }
496 :
497 : /* We start searching with the first entry. */
498 1051289 : runp = &scn->data_list;
499 :
500 1051301 : while (1)
501 : {
502 : /* If `data' does not match any known record punt. */
503 1051301 : if (runp == NULL)
504 : {
505 0 : __libelf_seterrno (ELF_E_DATA_MISMATCH);
506 0 : goto out;
507 : }
508 :
509 1051301 : if (&runp->data.d == data)
510 : /* Found the entry. */
511 : break;
512 :
513 12 : runp = runp->next;
514 : }
515 :
516 : /* Return the data for the next data record. */
517 1051289 : result = runp->next ? &runp->next->data.d : NULL;
518 1051289 : goto out;
519 : }
520 :
521 : /* If the data for this section was not yet initialized do it now. */
522 1439025 : 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 1322927 : rwlock_unlock (elf->lock);
529 1322927 : rwlock_wrlock (elf->lock);
530 1322927 : 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 1322927 : 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 1439025 : if (scn->data_list_rear == NULL)
544 1323783 : __libelf_set_data_list_rdlock (scn, locked);
545 :
546 : /* Return the first data element in the list. */
547 1439025 : result = &scn->data_list.data.d;
548 :
549 : out:
550 : return result;
551 : }
552 :
553 : Elf_Data *
554 2490241 : elf_getdata (Elf_Scn *scn, Elf_Data *data)
555 : {
556 2490241 : Elf_Data *result;
557 :
558 2490241 : if (scn == NULL)
559 : return NULL;
560 :
561 2490139 : rwlock_rdlock (scn->elf->lock);
562 2490139 : result = __elf_getdata_rdlock (scn, data);
563 2490139 : rwlock_unlock (scn->elf->lock);
564 :
565 2490139 : return result;
566 : }
567 : INTDEF(elf_getdata)
|