1 /* Return the next data element from the section after possibly converting it.
2 Copyright (C) 1998-2005, 2006, 2007 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_HALF] = __alignof__ (ElfW2(Bits,Half)), \
87 [ELF_T_WORD] = __alignof__ (ElfW2(Bits,Word)), \
88 [ELF_T_SYM] = __alignof__ (ElfW2(Bits,Sym)), \
89 [ELF_T_SYMINFO] = __alignof__ (ElfW2(Bits,Syminfo)), \
90 [ELF_T_REL] = __alignof__ (ElfW2(Bits,Rel)), \
91 [ELF_T_RELA] = __alignof__ (ElfW2(Bits,Rela)), \
92 [ELF_T_DYN] = __alignof__ (ElfW2(Bits,Dyn)), \
93 [ELF_T_VDEF] = __alignof__ (ElfW2(Bits,Verdef)), \
94 [ELF_T_VDAUX] = __alignof__ (ElfW2(Bits,Verdaux)), \
95 [ELF_T_VNEED] = __alignof__ (ElfW2(Bits,Verneed)), \
96 [ELF_T_VNAUX] = __alignof__ (ElfW2(Bits,Vernaux)), \
97 [ELF_T_MOVE] = __alignof__ (ElfW2(Bits,Move)), \
98 [ELF_T_LIB] = __alignof__ (ElfW2(Bits,Lib)), \
99 [ELF_T_NHDR] = __alignof__ (ElfW2(Bits,Nhdr)), \
100 }
101 [EV_CURRENT - 1] =
102 {
103 [ELFCLASS32 - 1] = TYPE_ALIGNS (32),
104 [ELFCLASS64 - 1] = TYPE_ALIGNS (64),
105 }
106 # undef TYPE_ALIGNS
107 };
108 #endif
109
110
111 /* Convert the data in the current section. */
112 static void
convert_data(Elf_Scn * scn,int version,int eclass,int data,size_t size,Elf_Type type)113 convert_data (Elf_Scn *scn, int version __attribute__ ((unused)), int eclass,
114 int data, size_t size, Elf_Type type)
115 {
116 const size_t align = __libelf_type_align (eclass, type);
117
118 if (data == MY_ELFDATA)
119 {
120 if (((((size_t) (char *) scn->rawdata_base)) & (align - 1)) == 0)
121 /* No need to copy, we can use the raw data. */
122 scn->data_base = scn->rawdata_base;
123 else
124 {
125 scn->data_base = (char *) malloc (size);
126 if (scn->data_base == NULL)
127 {
128 __libelf_seterrno (ELF_E_NOMEM);
129 return;
130 }
131
132 /* The copy will be appropriately aligned for direct access. */
133 memcpy (scn->data_base, scn->rawdata_base, size);
134 }
135 }
136 else
137 {
138 xfct_t fp;
139
140 scn->data_base = (char *) malloc (size);
141 if (scn->data_base == NULL)
142 {
143 __libelf_seterrno (ELF_E_NOMEM);
144 return;
145 }
146
147 /* Get the conversion function. */
148 #if EV_NUM != 2
149 fp = __elf_xfctstom[version - 1][__libelf_version - 1][eclass - 1][type];
150 #else
151 fp = __elf_xfctstom[0][0][eclass - 1][type];
152 #endif
153
154 fp (scn->data_base, scn->rawdata_base, size, 0);
155 }
156
157 scn->data_list.data.d.d_buf = scn->data_base;
158 scn->data_list.data.d.d_size = size;
159 scn->data_list.data.d.d_type = type;
160 scn->data_list.data.d.d_off = scn->rawdata.d.d_off;
161 scn->data_list.data.d.d_align = scn->rawdata.d.d_align;
162 scn->data_list.data.d.d_version = scn->rawdata.d.d_version;
163
164 scn->data_list.data.s = scn;
165 }
166
167
168 /* Store the information for the raw data in the `rawdata' element. */
169 int
170 internal_function
__libelf_set_rawdata_wrlock(Elf_Scn * scn)171 __libelf_set_rawdata_wrlock (Elf_Scn *scn)
172 {
173 Elf64_Off offset;
174 Elf64_Xword size;
175 Elf64_Xword align;
176 int type;
177 Elf *elf = scn->elf;
178
179 if (elf->class == ELFCLASS32)
180 {
181 Elf32_Shdr *shdr
182 = scn->shdr.e32 ?: __elf32_getshdr_wrlock (scn);
183
184 if (shdr == NULL)
185 /* Something went terribly wrong. */
186 return 1;
187
188 offset = shdr->sh_offset;
189 size = shdr->sh_size;
190 type = shdr->sh_type;
191 align = shdr->sh_addralign;
192 }
193 else
194 {
195 Elf64_Shdr *shdr
196 = scn->shdr.e64 ?: __elf64_getshdr_wrlock (scn);
197
198 if (shdr == NULL)
199 /* Something went terribly wrong. */
200 return 1;
201
202 offset = shdr->sh_offset;
203 size = shdr->sh_size;
204 type = shdr->sh_type;
205 align = shdr->sh_addralign;
206 }
207
208 /* If the section has no data (for whatever reason), leave the `d_buf'
209 pointer NULL. */
210 if (size != 0 && type != SHT_NOBITS)
211 {
212 /* First a test whether the section is valid at all. */
213 size_t entsize;
214
215 if (type == SHT_HASH)
216 {
217 GElf_Ehdr ehdr_mem;
218 GElf_Ehdr *ehdr = __gelf_getehdr_rdlock (elf, &ehdr_mem);
219 entsize = SH_ENTSIZE_HASH (ehdr);
220 }
221 else
222 {
223 Elf_Type t = shtype_map[LIBELF_EV_IDX][TYPEIDX (type)];
224 if (t == ELF_T_VDEF || t == ELF_T_NHDR
225 || (t == ELF_T_GNUHASH && elf->class == ELFCLASS64))
226 entsize = 1;
227 else
228 entsize = __libelf_type_sizes[LIBELF_EV_IDX][elf->class - 1][t];
229 }
230
231 /* We assume it is an array of bytes if it is none of the structured
232 sections we know of. */
233 if (entsize == 0)
234 entsize = 1;
235
236 if (unlikely (size % entsize != 0))
237 {
238 __libelf_seterrno (ELF_E_INVALID_DATA);
239 return 1;
240 }
241
242 /* We can use the mapped or loaded data if available. */
243 if (elf->map_address != NULL)
244 {
245 /* First see whether the information in the section header is
246 valid and it does not ask for too much. Check for unsigned
247 overflow. */
248 if (unlikely (offset > elf->maximum_size
249 || elf->maximum_size - offset < size))
250 {
251 /* Something is wrong. */
252 __libelf_seterrno (ELF_E_INVALID_SECTION_HEADER);
253 return 1;
254 }
255
256 scn->rawdata_base = scn->rawdata.d.d_buf
257 = (char *) elf->map_address + elf->start_offset + offset;
258 }
259 else if (likely (elf->fildes != -1))
260 {
261 /* We have to read the data from the file. Allocate the needed
262 memory. */
263 scn->rawdata_base = scn->rawdata.d.d_buf
264 = (char *) malloc (size);
265 if (scn->rawdata.d.d_buf == NULL)
266 {
267 __libelf_seterrno (ELF_E_NOMEM);
268 return 1;
269 }
270
271 ssize_t n = pread_retry (elf->fildes, scn->rawdata.d.d_buf, size,
272 elf->start_offset + offset);
273 if (unlikely ((size_t) n != size))
274 {
275 /* Cannot read the data. */
276 free (scn->rawdata.d.d_buf);
277 scn->rawdata_base = scn->rawdata.d.d_buf = NULL;
278 __libelf_seterrno (ELF_E_READ_ERROR);
279 return 1;
280 }
281 }
282 else
283 {
284 /* The file descriptor is already closed, we cannot get the data
285 anymore. */
286 __libelf_seterrno (ELF_E_FD_DISABLED);
287 return 1;
288 }
289 }
290
291 scn->rawdata.d.d_size = size;
292 /* Some broken ELF ABI for 64-bit machines use the wrong hash table
293 entry size. See elf-knowledge.h for more information. */
294 if (type == SHT_HASH && elf->class == ELFCLASS64)
295 {
296 GElf_Ehdr ehdr_mem;
297 GElf_Ehdr *ehdr = __gelf_getehdr_rdlock (elf, &ehdr_mem);
298 scn->rawdata.d.d_type
299 = (SH_ENTSIZE_HASH (ehdr) == 4 ? ELF_T_WORD : ELF_T_XWORD);
300 }
301 else
302 scn->rawdata.d.d_type = shtype_map[LIBELF_EV_IDX][TYPEIDX (type)];
303 scn->rawdata.d.d_off = 0;
304 scn->rawdata.d.d_align = align;
305 if (elf->class == ELFCLASS32
306 || (offsetof (struct Elf, state.elf32.ehdr)
307 == offsetof (struct Elf, state.elf64.ehdr)))
308 scn->rawdata.d.d_version =
309 elf->state.elf32.ehdr->e_ident[EI_VERSION];
310 else
311 scn->rawdata.d.d_version =
312 elf->state.elf64.ehdr->e_ident[EI_VERSION];
313
314 scn->rawdata.s = scn;
315
316 scn->data_read = 1;
317
318 /* We actually read data from the file. At least we tried. */
319 scn->flags |= ELF_F_FILEDATA;
320
321 return 0;
322 }
323
324 int
325 internal_function
__libelf_set_rawdata(Elf_Scn * scn)326 __libelf_set_rawdata (Elf_Scn *scn)
327 {
328 int result;
329
330 if (scn == NULL)
331 return 1;
332
333 rwlock_wrlock (scn->elf->lock);
334 result = __libelf_set_rawdata_wrlock (scn);
335 rwlock_unlock (scn->elf->lock);
336
337 return result;
338 }
339
340 Elf_Data *
341 internal_function
__elf_getdata_rdlock(scn,data)342 __elf_getdata_rdlock (scn, data)
343 Elf_Scn *scn;
344 Elf_Data *data;
345 {
346 Elf_Data *result = NULL;
347 Elf *elf;
348 int locked = 0;
349
350 if (scn == NULL)
351 return NULL;
352
353 if (unlikely (scn->elf->kind != ELF_K_ELF))
354 {
355 __libelf_seterrno (ELF_E_INVALID_HANDLE);
356 return NULL;
357 }
358
359 /* We will need this multiple times later on. */
360 elf = scn->elf;
361
362 /* If `data' is not NULL this means we are not addressing the initial
363 data in the file. But this also means this data is already read
364 (since otherwise it is not possible to have a valid `data' pointer)
365 and all the data structures are initialized as well. In this case
366 we can simply walk the list of data records. */
367 if (data != NULL)
368 {
369 Elf_Data_List *runp;
370
371 /* It is not possible that if DATA is not NULL the first entry is
372 returned. But this also means that there must be a first data
373 entry. */
374 if (scn->data_list_rear == NULL
375 /* The section the reference data is for must match the section
376 parameter. */
377 || unlikely (((Elf_Data_Scn *) data)->s != scn))
378 {
379 __libelf_seterrno (ELF_E_DATA_MISMATCH);
380 goto out;
381 }
382
383 /* We start searching with the first entry. */
384 runp = &scn->data_list;
385
386 while (1)
387 {
388 /* If `data' does not match any known record punt. */
389 if (runp == NULL)
390 {
391 __libelf_seterrno (ELF_E_DATA_MISMATCH);
392 goto out;
393 }
394
395 if (&runp->data.d == data)
396 /* Found the entry. */
397 break;
398
399 runp = runp->next;
400 }
401
402 /* Return the data for the next data record. */
403 result = runp->next ? &runp->next->data.d : NULL;
404 goto out;
405 }
406
407 /* If the data for this section was not yet initialized do it now. */
408 if (scn->data_read == 0)
409 {
410 /* We cannot acquire a write lock while we are holding a read
411 lock. Therefore give up the read lock and then get the write
412 lock. But this means that the data could meanwhile be
413 modified, therefore start the tests again. */
414 rwlock_unlock (elf->lock);
415 rwlock_wrlock (elf->lock);
416 locked = 1;
417
418 /* Read the data from the file. There is always a file (or
419 memory region) associated with this descriptor since
420 otherwise the `data_read' flag would be set. */
421 if (scn->data_read == 0 && __libelf_set_rawdata_wrlock (scn) != 0)
422 /* Something went wrong. The error value is already set. */
423 goto out;
424 }
425
426 /* At this point we know the raw data is available. But it might be
427 empty in case the section has size zero (for whatever reason).
428 Now create the converted data in case this is necessary. */
429 if (scn->data_list_rear == NULL)
430 {
431 if (scn->rawdata.d.d_buf != NULL && scn->rawdata.d.d_size > 0)
432 {
433 if (!locked)
434 {
435 rwlock_unlock (elf->lock);
436 rwlock_wrlock (elf->lock);
437 if (scn->data_list_rear != NULL)
438 goto pass;
439 }
440
441 /* Convert according to the version and the type. */
442 convert_data (scn, __libelf_version, elf->class,
443 (elf->class == ELFCLASS32
444 || (offsetof (struct Elf, state.elf32.ehdr)
445 == offsetof (struct Elf, state.elf64.ehdr))
446 ? elf->state.elf32.ehdr->e_ident[EI_DATA]
447 : elf->state.elf64.ehdr->e_ident[EI_DATA]),
448 scn->rawdata.d.d_size, scn->rawdata.d.d_type);
449 }
450 else
451 {
452 /* This is an empty or NOBITS section. There is no buffer but
453 the size information etc is important. */
454 scn->data_list.data.d = scn->rawdata.d;
455 scn->data_list.data.s = scn;
456 }
457
458 scn->data_list_rear = &scn->data_list;
459 }
460
461 /* If no data is present we cannot return any. */
462 if (scn->data_list_rear != NULL)
463 pass:
464 /* Return the first data element in the list. */
465 result = &scn->data_list.data.d;
466
467 out:
468 return result;
469 }
470
471 Elf_Data *
elf_getdata(scn,data)472 elf_getdata (scn, data)
473 Elf_Scn *scn;
474 Elf_Data *data;
475 {
476 Elf_Data *result;
477
478 if (scn == NULL)
479 return NULL;
480
481 rwlock_rdlock (scn->elf->lock);
482 result = __elf_getdata_rdlock (scn, data);
483 rwlock_unlock (scn->elf->lock);
484
485 return result;
486 }
487 INTDEF(elf_getdata)
488