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