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