/src/elfutils/libelf/gelf_getehdr.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* Get ELF header. |
2 | | Copyright (C) 1998, 1999, 2000, 2001, 2002, 2005, 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 <gelf.h> |
35 | | #include <stddef.h> |
36 | | #include <stdlib.h> |
37 | | #include <string.h> |
38 | | |
39 | | #include "libelfP.h" |
40 | | |
41 | | |
42 | | GElf_Ehdr * |
43 | | internal_function |
44 | | __gelf_getehdr_rdlock (Elf *elf, GElf_Ehdr *dest) |
45 | 1.18M | { |
46 | 1.18M | GElf_Ehdr *result = NULL; |
47 | | |
48 | 1.18M | if (elf == NULL) |
49 | 0 | return NULL; |
50 | | |
51 | 1.18M | if (unlikely (elf->kind != ELF_K_ELF)) |
52 | 0 | { |
53 | 0 | __libelf_seterrno (ELF_E_INVALID_HANDLE); |
54 | 0 | return NULL; |
55 | 0 | } |
56 | | |
57 | | /* The following is an optimization: the ehdr element is at the same |
58 | | position in both the elf32 and elf64 structure. */ |
59 | 1.18M | if (offsetof (struct Elf, state.elf32.ehdr) |
60 | 1.18M | != offsetof (struct Elf, state.elf64.ehdr)) |
61 | 0 | abort (); |
62 | | /* Just pick one of the values. */ |
63 | 1.18M | if (unlikely (elf->state.elf64.ehdr == NULL)) |
64 | | /* Maybe no ELF header was created yet. */ |
65 | 0 | __libelf_seterrno (ELF_E_WRONG_ORDER_EHDR); |
66 | 1.18M | else if (elf->class == ELFCLASS32) |
67 | 1.08M | { |
68 | 1.08M | Elf32_Ehdr *ehdr = elf->state.elf32.ehdr; |
69 | | |
70 | | /* Convert the 32-bit struct to an 64-bit one. */ |
71 | 1.08M | memcpy (dest->e_ident, ehdr->e_ident, EI_NIDENT); |
72 | 1.08M | #define COPY(name) \ |
73 | 14.0M | dest->name = ehdr->name |
74 | 1.08M | COPY (e_type); |
75 | 1.08M | COPY (e_machine); |
76 | 1.08M | COPY (e_version); |
77 | 1.08M | COPY (e_entry); |
78 | 1.08M | COPY (e_phoff); |
79 | 1.08M | COPY (e_shoff); |
80 | 1.08M | COPY (e_flags); |
81 | 1.08M | COPY (e_ehsize); |
82 | 1.08M | COPY (e_phentsize); |
83 | 1.08M | COPY (e_phnum); |
84 | 1.08M | COPY (e_shentsize); |
85 | 1.08M | COPY (e_shnum); |
86 | 1.08M | COPY (e_shstrndx); |
87 | | |
88 | 1.08M | result = dest; |
89 | 1.08M | } |
90 | 100k | else |
91 | 100k | result = memcpy (dest, elf->state.elf64.ehdr, sizeof (*dest)); |
92 | | |
93 | 1.18M | return result; |
94 | 1.18M | } |
95 | | |
96 | | GElf_Ehdr * |
97 | | gelf_getehdr (Elf *elf, GElf_Ehdr *dest) |
98 | 1.12M | { |
99 | 1.12M | GElf_Ehdr *result; |
100 | 1.12M | if (elf == NULL) |
101 | 0 | return NULL; |
102 | | |
103 | 1.12M | rwlock_rdlock (elf->lock); |
104 | 1.12M | result = __gelf_getehdr_rdlock (elf, dest); |
105 | 1.12M | rwlock_unlock (elf->lock); |
106 | | |
107 | 1.12M | return result; |
108 | 1.12M | } |