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 1852115 : __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 1852115 : 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 1851989 : Elf_Type t = shtype_map[TYPEIDX (sh_type)];
129 : /* Special case for GNU Property notes. */
130 1851989 : if (t == ELF_T_NHDR && align == 8)
131 8 : t = ELF_T_NHDR8;
132 1851989 : return t;
133 : }
134 : }
135 :
136 : /* Convert the data in the current section. */
137 : static void
138 1323488 : convert_data (Elf_Scn *scn, int eclass,
139 : int data, size_t size, Elf_Type type)
140 : {
141 1323488 : const size_t align = __libelf_type_align (eclass, type);
142 :
143 : /* Do we need to convert the data and/or adjust for alignment? */
144 1323488 : if (data == MY_ELFDATA || type == ELF_T_BYTE)
145 : {
146 1321319 : if (((((size_t) (char *) scn->rawdata_base)) & (align - 1)) == 0)
147 : /* No need to copy, we can use the raw data. */
148 1321077 : scn->data_base = scn->rawdata_base;
149 : else
150 : {
151 242 : scn->data_base = (char *) malloc (size);
152 242 : 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 242 : 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 1323488 : scn->data_list.data.d.d_buf = scn->data_base;
201 1323488 : scn->data_list.data.d.d_size = size;
202 1323488 : scn->data_list.data.d.d_type = type;
203 1323488 : scn->data_list.data.d.d_off = scn->rawdata.d.d_off;
204 1323488 : scn->data_list.data.d.d_align = scn->rawdata.d.d_align;
205 1323488 : scn->data_list.data.d.d_version = scn->rawdata.d.d_version;
206 :
207 1323488 : 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 1851894 : __libelf_set_rawdata_wrlock (Elf_Scn *scn)
215 : {
216 1851894 : Elf64_Off offset;
217 1851894 : Elf64_Xword size;
218 1851894 : Elf64_Xword align;
219 1851894 : Elf64_Xword flags;
220 1851894 : int type;
221 1851894 : Elf *elf = scn->elf;
222 :
223 1851894 : if (elf->class == ELFCLASS32)
224 : {
225 2025680 : Elf32_Shdr *shdr
226 1012840 : = scn->shdr.e32 ?: __elf32_getshdr_wrlock (scn);
227 :
228 1012840 : if (shdr == NULL)
229 : /* Something went terribly wrong. */
230 : return 1;
231 :
232 1012840 : offset = shdr->sh_offset;
233 1012840 : size = shdr->sh_size;
234 1012840 : type = shdr->sh_type;
235 1012840 : align = shdr->sh_addralign;
236 1012840 : flags = shdr->sh_flags;
237 : }
238 : else
239 : {
240 1678108 : Elf64_Shdr *shdr
241 839054 : = scn->shdr.e64 ?: __elf64_getshdr_wrlock (scn);
242 :
243 839054 : if (shdr == NULL)
244 : /* Something went terribly wrong. */
245 : return 1;
246 :
247 839054 : offset = shdr->sh_offset;
248 839054 : size = shdr->sh_size;
249 839054 : type = shdr->sh_type;
250 839054 : align = shdr->sh_addralign;
251 839054 : flags = shdr->sh_flags;
252 : }
253 :
254 : /* If the section has no data (for whatever reason), leave the `d_buf'
255 : pointer NULL. */
256 1851894 : if (size != 0 && type != SHT_NOBITS)
257 : {
258 : /* First a test whether the section is valid at all. */
259 1849966 : 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 1849966 : if ((flags & SHF_COMPRESSED) != 0)
266 : {
267 779 : entsize = 1;
268 779 : align = __libelf_type_align (elf->class, ELF_T_CHDR);
269 : }
270 1849187 : else if (type == SHT_HASH)
271 : {
272 254 : GElf_Ehdr ehdr_mem;
273 254 : GElf_Ehdr *ehdr = __gelf_getehdr_rdlock (elf, &ehdr_mem);
274 254 : if (unlikely (ehdr == NULL))
275 0 : return 1;
276 446 : entsize = SH_ENTSIZE_HASH (ehdr);
277 : }
278 : else
279 : {
280 1848933 : Elf_Type t = shtype_map[TYPEIDX (type)];
281 1848933 : if (t == ELF_T_NHDR && align == 8)
282 8 : t = ELF_T_NHDR8;
283 1848933 : if (t == ELF_T_VDEF || t == ELF_T_NHDR || t == ELF_T_NHDR8
284 1847721 : || (t == ELF_T_GNUHASH && elf->class == ELFCLASS64))
285 : entsize = 1;
286 : else
287 1847547 : entsize = __libelf_type_sizes[elf->class - 1][t];
288 : }
289 :
290 : /* We assume it is an array of bytes if it is none of the structured
291 : sections we know of. */
292 1847801 : if (entsize == 0)
293 0 : entsize = 1;
294 :
295 1849966 : if (unlikely (size % entsize != 0))
296 : {
297 0 : __libelf_seterrno (ELF_E_INVALID_DATA);
298 0 : return 1;
299 : }
300 :
301 : /* We can use the mapped or loaded data if available. */
302 1849966 : if (elf->map_address != NULL)
303 : {
304 : /* First see whether the information in the section header is
305 : valid and it does not ask for too much. Check for unsigned
306 : overflow. */
307 595181 : if (unlikely (offset > elf->maximum_size
308 : || elf->maximum_size - offset < size))
309 : {
310 : /* Something is wrong. */
311 0 : __libelf_seterrno (ELF_E_INVALID_SECTION_HEADER);
312 0 : return 1;
313 : }
314 :
315 1190362 : scn->rawdata_base = scn->rawdata.d.d_buf
316 595181 : = (char *) elf->map_address + elf->start_offset + offset;
317 : }
318 1254785 : else if (likely (elf->fildes != -1))
319 : {
320 : /* First see whether the information in the section header is
321 : valid and it does not ask for too much. Check for unsigned
322 : overflow. */
323 1254785 : if (unlikely (offset > elf->maximum_size
324 : || elf->maximum_size - offset < size))
325 : {
326 : /* Something is wrong. */
327 0 : __libelf_seterrno (ELF_E_INVALID_SECTION_HEADER);
328 0 : return 1;
329 : }
330 :
331 : /* We have to read the data from the file. Allocate the needed
332 : memory. */
333 2509570 : scn->rawdata_base = scn->rawdata.d.d_buf
334 1254785 : = (char *) malloc (size);
335 1254785 : if (scn->rawdata.d.d_buf == NULL)
336 : {
337 0 : __libelf_seterrno (ELF_E_NOMEM);
338 0 : return 1;
339 : }
340 :
341 3764355 : ssize_t n = pread_retry (elf->fildes, scn->rawdata.d.d_buf, size,
342 1254785 : elf->start_offset + offset);
343 1254785 : if (unlikely ((size_t) n != size))
344 : {
345 : /* Cannot read the data. */
346 0 : free (scn->rawdata.d.d_buf);
347 0 : scn->rawdata_base = scn->rawdata.d.d_buf = NULL;
348 0 : __libelf_seterrno (ELF_E_READ_ERROR);
349 0 : return 1;
350 : }
351 : }
352 : else
353 : {
354 : /* The file descriptor is already closed, we cannot get the data
355 : anymore. */
356 0 : __libelf_seterrno (ELF_E_FD_DISABLED);
357 0 : return 1;
358 : }
359 : }
360 :
361 1851894 : scn->rawdata.d.d_size = size;
362 :
363 : /* Compressed data always has type ELF_T_CHDR regardless of the
364 : section type. */
365 1851894 : if ((flags & SHF_COMPRESSED) != 0)
366 779 : scn->rawdata.d.d_type = ELF_T_CHDR;
367 : else
368 1851115 : scn->rawdata.d.d_type = __libelf_data_type (elf, type, align);
369 1851894 : scn->rawdata.d.d_off = 0;
370 :
371 : /* Make sure the alignment makes sense. d_align should be aligned both
372 : in the section (trivially true since d_off is zero) and in the file.
373 : Unfortunately we cannot be too strict because there are ELF files
374 : out there that fail this requirement. We will try to fix those up
375 : in elf_update when writing out the image. But for very large
376 : alignment values this can bloat the image considerably. So here
377 : just check and clamp the alignment value to not be bigger than the
378 : actual offset of the data in the file. Given that there is always
379 : at least an ehdr this will only trigger for alignment values > 64
380 : which should be uncommon. */
381 1851894 : align = align ?: 1;
382 1851894 : if (type != SHT_NOBITS && align > offset)
383 0 : align = offset;
384 1851894 : scn->rawdata.d.d_align = align;
385 1851894 : if (elf->class == ELFCLASS32
386 : || (offsetof (struct Elf, state.elf32.ehdr)
387 : == offsetof (struct Elf, state.elf64.ehdr)))
388 3703788 : scn->rawdata.d.d_version =
389 1851894 : elf->state.elf32.ehdr->e_ident[EI_VERSION];
390 : else
391 : scn->rawdata.d.d_version =
392 : elf->state.elf64.ehdr->e_ident[EI_VERSION];
393 :
394 1851894 : scn->rawdata.s = scn;
395 :
396 1851894 : scn->data_read = 1;
397 :
398 : /* We actually read data from the file. At least we tried. */
399 1851894 : scn->flags |= ELF_F_FILEDATA;
400 :
401 1851894 : return 0;
402 : }
403 :
404 : int
405 : internal_function
406 1122 : __libelf_set_rawdata (Elf_Scn *scn)
407 : {
408 1122 : int result;
409 :
410 1122 : if (scn == NULL)
411 : return 1;
412 :
413 1122 : rwlock_wrlock (scn->elf->lock);
414 1122 : result = __libelf_set_rawdata_wrlock (scn);
415 1122 : rwlock_unlock (scn->elf->lock);
416 :
417 1122 : return result;
418 : }
419 :
420 : void
421 : internal_function
422 1325325 : __libelf_set_data_list_rdlock (Elf_Scn *scn, int wrlocked)
423 : {
424 1325325 : if (scn->rawdata.d.d_buf != NULL && scn->rawdata.d.d_size > 0)
425 1323488 : {
426 1323488 : Elf *elf = scn->elf;
427 :
428 : /* Upgrade the lock to a write lock if necessary and check
429 : nobody else already did the work. */
430 1323488 : if (!wrlocked)
431 : {
432 1133 : rwlock_unlock (elf->lock);
433 1133 : rwlock_wrlock (elf->lock);
434 1133 : if (scn->data_list_rear != NULL)
435 : return;
436 : }
437 :
438 : /* Convert according to the version and the type. */
439 2646976 : convert_data (scn, elf->class,
440 : (elf->class == ELFCLASS32
441 : || (offsetof (struct Elf, state.elf32.ehdr)
442 : == offsetof (struct Elf, state.elf64.ehdr))
443 1323488 : ? elf->state.elf32.ehdr->e_ident[EI_DATA]
444 : : elf->state.elf64.ehdr->e_ident[EI_DATA]),
445 : scn->rawdata.d.d_size, scn->rawdata.d.d_type);
446 : }
447 : else
448 : {
449 : /* This is an empty or NOBITS section. There is no buffer but
450 : the size information etc is important. */
451 1837 : scn->data_list.data.d = scn->rawdata.d;
452 1837 : scn->data_list.data.s = scn;
453 : }
454 :
455 1325325 : scn->data_list_rear = &scn->data_list;
456 : }
457 :
458 : Elf_Data *
459 : internal_function
460 2490264 : __elf_getdata_rdlock (Elf_Scn *scn, Elf_Data *data)
461 : {
462 2490264 : Elf_Data *result = NULL;
463 2490264 : Elf *elf;
464 2490264 : int locked = 0;
465 :
466 2490264 : if (scn == NULL)
467 : return NULL;
468 :
469 2490264 : if (unlikely (scn->elf->kind != ELF_K_ELF))
470 : {
471 0 : __libelf_seterrno (ELF_E_INVALID_HANDLE);
472 0 : return NULL;
473 : }
474 :
475 : /* We will need this multiple times later on. */
476 2490264 : elf = scn->elf;
477 :
478 : /* If `data' is not NULL this means we are not addressing the initial
479 : data in the file. But this also means this data is already read
480 : (since otherwise it is not possible to have a valid `data' pointer)
481 : and all the data structures are initialized as well. In this case
482 : we can simply walk the list of data records. */
483 2490264 : if (data != NULL)
484 : {
485 1051187 : Elf_Data_List *runp;
486 :
487 : /* It is not possible that if DATA is not NULL the first entry is
488 : returned. But this also means that there must be a first data
489 : entry. */
490 1051187 : if (scn->data_list_rear == NULL
491 : /* The section the reference data is for must match the section
492 : parameter. */
493 1051187 : || unlikely (((Elf_Data_Scn *) data)->s != scn))
494 : {
495 0 : __libelf_seterrno (ELF_E_DATA_MISMATCH);
496 0 : goto out;
497 : }
498 :
499 : /* We start searching with the first entry. */
500 1051187 : runp = &scn->data_list;
501 :
502 1051199 : while (1)
503 : {
504 : /* If `data' does not match any known record punt. */
505 1051199 : if (runp == NULL)
506 : {
507 0 : __libelf_seterrno (ELF_E_DATA_MISMATCH);
508 0 : goto out;
509 : }
510 :
511 1051199 : if (&runp->data.d == data)
512 : /* Found the entry. */
513 : break;
514 :
515 12 : runp = runp->next;
516 : }
517 :
518 : /* Return the data for the next data record. */
519 1051187 : result = runp->next ? &runp->next->data.d : NULL;
520 1051187 : goto out;
521 : }
522 :
523 : /* If the data for this section was not yet initialized do it now. */
524 1439077 : if (scn->data_read == 0)
525 : {
526 : /* We cannot acquire a write lock while we are holding a read
527 : lock. Therefore give up the read lock and then get the write
528 : lock. But this means that the data could meanwhile be
529 : modified, therefore start the tests again. */
530 1322626 : rwlock_unlock (elf->lock);
531 1322626 : rwlock_wrlock (elf->lock);
532 1322626 : locked = 1;
533 :
534 : /* Read the data from the file. There is always a file (or
535 : memory region) associated with this descriptor since
536 : otherwise the `data_read' flag would be set. */
537 1322626 : if (scn->data_read == 0 && __libelf_set_rawdata_wrlock (scn) != 0)
538 : /* Something went wrong. The error value is already set. */
539 : goto out;
540 : }
541 :
542 : /* At this point we know the raw data is available. But it might be
543 : empty in case the section has size zero (for whatever reason).
544 : Now create the converted data in case this is necessary. */
545 1439077 : if (scn->data_list_rear == NULL)
546 1323790 : __libelf_set_data_list_rdlock (scn, locked);
547 :
548 : /* Return the first data element in the list. */
549 1439077 : result = &scn->data_list.data.d;
550 :
551 : out:
552 : return result;
553 : }
554 :
555 : Elf_Data *
556 2490197 : elf_getdata (Elf_Scn *scn, Elf_Data *data)
557 : {
558 2490197 : Elf_Data *result;
559 :
560 2490197 : if (scn == NULL)
561 : return NULL;
562 :
563 2490089 : rwlock_rdlock (scn->elf->lock);
564 2490089 : result = __elf_getdata_rdlock (scn, data);
565 2490089 : rwlock_unlock (scn->elf->lock);
566 :
567 2490089 : return result;
568 : }
569 : INTDEF(elf_getdata)
|