blob: 97c503b534a78eee98e7160e3596a919baf38d96 [file] [log] [blame]
Brian Silverman86497922018-02-10 19:28:39 -05001/* 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. */
53static 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. */
81const 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
121Elf_Type
122internal_function
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. */
138static void
139convert_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. */
217int
218internal_function
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 /* First see whether the information in the section header is
316 valid and it does not ask for too much. Check for unsigned
317 overflow. */
318 if (unlikely (offset > elf->maximum_size
319 || elf->maximum_size - offset < size))
320 {
321 /* Something is wrong. */
322 __libelf_seterrno (ELF_E_INVALID_SECTION_HEADER);
323 return 1;
324 }
325
326 /* We have to read the data from the file. Allocate the needed
327 memory. */
328 scn->rawdata_base = scn->rawdata.d.d_buf
329 = (char *) malloc (size);
330 if (scn->rawdata.d.d_buf == NULL)
331 {
332 __libelf_seterrno (ELF_E_NOMEM);
333 return 1;
334 }
335
336 ssize_t n = pread_retry (elf->fildes, scn->rawdata.d.d_buf, size,
337 elf->start_offset + offset);
338 if (unlikely ((size_t) n != size))
339 {
340 /* Cannot read the data. */
341 free (scn->rawdata.d.d_buf);
342 scn->rawdata_base = scn->rawdata.d.d_buf = NULL;
343 __libelf_seterrno (ELF_E_READ_ERROR);
344 return 1;
345 }
346 }
347 else
348 {
349 /* The file descriptor is already closed, we cannot get the data
350 anymore. */
351 __libelf_seterrno (ELF_E_FD_DISABLED);
352 return 1;
353 }
354 }
355
356 scn->rawdata.d.d_size = size;
357
358 /* Compressed data always has type ELF_T_CHDR regardless of the
359 section type. */
360 if ((flags & SHF_COMPRESSED) != 0)
361 scn->rawdata.d.d_type = ELF_T_CHDR;
362 else
363 scn->rawdata.d.d_type = __libelf_data_type (elf, type);
364 scn->rawdata.d.d_off = 0;
365
366 /* Make sure the alignment makes sense. d_align should be aligned both
367 in the section (trivially true since d_off is zero) and in the file.
368 Unfortunately we cannot be too strict because there are ELF files
369 out there that fail this requirement. We will try to fix those up
370 in elf_update when writing out the image. But for very large
371 alignment values this can bloat the image considerably. So here
372 just check and clamp the alignment value to not be bigger than the
373 actual offset of the data in the file. Given that there is always
374 at least an ehdr this will only trigger for alignment values > 64
375 which should be uncommon. */
376 align = align ?: 1;
377 if (type != SHT_NOBITS && align > offset)
378 align = offset;
379 scn->rawdata.d.d_align = align;
380 if (elf->class == ELFCLASS32
381 || (offsetof (struct Elf, state.elf32.ehdr)
382 == offsetof (struct Elf, state.elf64.ehdr)))
383 scn->rawdata.d.d_version =
384 elf->state.elf32.ehdr->e_ident[EI_VERSION];
385 else
386 scn->rawdata.d.d_version =
387 elf->state.elf64.ehdr->e_ident[EI_VERSION];
388
389 scn->rawdata.s = scn;
390
391 scn->data_read = 1;
392
393 /* We actually read data from the file. At least we tried. */
394 scn->flags |= ELF_F_FILEDATA;
395
396 return 0;
397}
398
399int
400internal_function
401__libelf_set_rawdata (Elf_Scn *scn)
402{
403 int result;
404
405 if (scn == NULL)
406 return 1;
407
408 rwlock_wrlock (scn->elf->lock);
409 result = __libelf_set_rawdata_wrlock (scn);
410 rwlock_unlock (scn->elf->lock);
411
412 return result;
413}
414
415void
416internal_function
417__libelf_set_data_list_rdlock (Elf_Scn *scn, int wrlocked)
418{
419 if (scn->rawdata.d.d_buf != NULL && scn->rawdata.d.d_size > 0)
420 {
421 Elf *elf = scn->elf;
422
423 /* Upgrade the lock to a write lock if necessary and check
424 nobody else already did the work. */
425 if (!wrlocked)
426 {
427 rwlock_unlock (elf->lock);
428 rwlock_wrlock (elf->lock);
429 if (scn->data_list_rear != NULL)
430 return;
431 }
432
433 /* Convert according to the version and the type. */
434 convert_data (scn, __libelf_version, elf->class,
435 (elf->class == ELFCLASS32
436 || (offsetof (struct Elf, state.elf32.ehdr)
437 == offsetof (struct Elf, state.elf64.ehdr))
438 ? elf->state.elf32.ehdr->e_ident[EI_DATA]
439 : elf->state.elf64.ehdr->e_ident[EI_DATA]),
440 scn->rawdata.d.d_size, scn->rawdata.d.d_type);
441 }
442 else
443 {
444 /* This is an empty or NOBITS section. There is no buffer but
445 the size information etc is important. */
446 scn->data_list.data.d = scn->rawdata.d;
447 scn->data_list.data.s = scn;
448 }
449
450 scn->data_list_rear = &scn->data_list;
451}
452
453Elf_Data *
454internal_function
455__elf_getdata_rdlock (Elf_Scn *scn, Elf_Data *data)
456{
457 Elf_Data *result = NULL;
458 Elf *elf;
459 int locked = 0;
460
461 if (scn == NULL)
462 return NULL;
463
464 if (unlikely (scn->elf->kind != ELF_K_ELF))
465 {
466 __libelf_seterrno (ELF_E_INVALID_HANDLE);
467 return NULL;
468 }
469
470 /* We will need this multiple times later on. */
471 elf = scn->elf;
472
473 /* If `data' is not NULL this means we are not addressing the initial
474 data in the file. But this also means this data is already read
475 (since otherwise it is not possible to have a valid `data' pointer)
476 and all the data structures are initialized as well. In this case
477 we can simply walk the list of data records. */
478 if (data != NULL)
479 {
480 Elf_Data_List *runp;
481
482 /* It is not possible that if DATA is not NULL the first entry is
483 returned. But this also means that there must be a first data
484 entry. */
485 if (scn->data_list_rear == NULL
486 /* The section the reference data is for must match the section
487 parameter. */
488 || unlikely (((Elf_Data_Scn *) data)->s != scn))
489 {
490 __libelf_seterrno (ELF_E_DATA_MISMATCH);
491 goto out;
492 }
493
494 /* We start searching with the first entry. */
495 runp = &scn->data_list;
496
497 while (1)
498 {
499 /* If `data' does not match any known record punt. */
500 if (runp == NULL)
501 {
502 __libelf_seterrno (ELF_E_DATA_MISMATCH);
503 goto out;
504 }
505
506 if (&runp->data.d == data)
507 /* Found the entry. */
508 break;
509
510 runp = runp->next;
511 }
512
513 /* Return the data for the next data record. */
514 result = runp->next ? &runp->next->data.d : NULL;
515 goto out;
516 }
517
518 /* If the data for this section was not yet initialized do it now. */
519 if (scn->data_read == 0)
520 {
521 /* We cannot acquire a write lock while we are holding a read
522 lock. Therefore give up the read lock and then get the write
523 lock. But this means that the data could meanwhile be
524 modified, therefore start the tests again. */
525 rwlock_unlock (elf->lock);
526 rwlock_wrlock (elf->lock);
527 locked = 1;
528
529 /* Read the data from the file. There is always a file (or
530 memory region) associated with this descriptor since
531 otherwise the `data_read' flag would be set. */
532 if (scn->data_read == 0 && __libelf_set_rawdata_wrlock (scn) != 0)
533 /* Something went wrong. The error value is already set. */
534 goto out;
535 }
536
537 /* At this point we know the raw data is available. But it might be
538 empty in case the section has size zero (for whatever reason).
539 Now create the converted data in case this is necessary. */
540 if (scn->data_list_rear == NULL)
541 __libelf_set_data_list_rdlock (scn, locked);
542
543 /* Return the first data element in the list. */
544 result = &scn->data_list.data.d;
545
546 out:
547 return result;
548}
549
550Elf_Data *
551elf_getdata (Elf_Scn *scn, Elf_Data *data)
552{
553 Elf_Data *result;
554
555 if (scn == NULL)
556 return NULL;
557
558 rwlock_rdlock (scn->elf->lock);
559 result = __elf_getdata_rdlock (scn, data);
560 rwlock_unlock (scn->elf->lock);
561
562 return result;
563}
564INTDEF(elf_getdata)