1 /* Get ELF program header table.
2 Copyright (C) 1998-2010 Red Hat, Inc.
3 This file is part of elfutils.
4 Written by Ulrich Drepper <drepper@redhat.com>, 1998.
6 This file is free software; you can redistribute it and/or modify
7 it under the terms of either
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
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
19 or both in parallel, as here.
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.
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/>. */
45 # define LIBELFBITS 32
48 ElfW2(LIBELFBITS,Phdr) *
49 __elfw2(LIBELFBITS,getphdr_wrlock) (elf)
52 ElfW2(LIBELFBITS,Phdr) *result;
54 /* If the program header entry has already been filled in the code
55 below must already have been run. So the class is set, too. No
56 need to waste any more time here. */
57 result = elf->state.ELFW(elf,LIBELFBITS).phdr;
58 if (likely (result != NULL))
62 elf->class = ELFW(ELFCLASS,LIBELFBITS);
63 else if (elf->class != ELFW(ELFCLASS,LIBELFBITS))
65 __libelf_seterrno (ELF_E_INVALID_CLASS);
70 if (likely (result == NULL))
72 /* Read the section header table. */
73 ElfW2(LIBELFBITS,Ehdr) *ehdr = elf->state.ELFW(elf,LIBELFBITS).ehdr;
75 /* If no program header exists return NULL. */
77 if (__elf_getphdrnum_rdlock (elf, &phnum) != 0)
81 __libelf_seterrno (ELF_E_NO_PHDR);
85 size_t size = phnum * sizeof (ElfW2(LIBELFBITS,Phdr));
87 if (ehdr->e_phoff > elf->maximum_size
88 || elf->maximum_size - ehdr->e_phoff < size)
90 __libelf_seterrno (ELF_E_INVALID_DATA);
94 if (elf->map_address != NULL)
96 /* All the data is already mapped. Use it. */
97 void *file_phdr = ((char *) elf->map_address
98 + elf->start_offset + ehdr->e_phoff);
99 if (ehdr->e_ident[EI_DATA] == MY_ELFDATA
101 || ((uintptr_t) file_phdr
102 & (__alignof__ (ElfW2(LIBELFBITS,Phdr)) - 1)) == 0))
103 /* Simply use the mapped data. */
104 elf->state.ELFW(elf,LIBELFBITS).phdr = file_phdr;
107 ElfW2(LIBELFBITS,Phdr) *notcvt;
108 ElfW2(LIBELFBITS,Phdr) *phdr;
110 /* Allocate memory for the program headers. We know the number
111 of entries from the ELF header. */
112 phdr = elf->state.ELFW(elf,LIBELFBITS).phdr =
113 (ElfW2(LIBELFBITS,Phdr) *) malloc (size);
114 if (elf->state.ELFW(elf,LIBELFBITS).phdr == NULL)
116 __libelf_seterrno (ELF_E_NOMEM);
119 elf->state.ELFW(elf,LIBELFBITS).phdr_flags |=
120 ELF_F_MALLOCED | ELF_F_DIRTY;
122 /* Now copy the data and at the same time convert the
125 if (ehdr->e_ident[EI_DATA] == MY_ELFDATA)
127 assert (! ALLOW_UNALIGNED);
128 memcpy (phdr, file_phdr, size);
133 || ((uintptr_t) file_phdr
134 & (__alignof__ (ElfW2(LIBELFBITS,Phdr)) - 1)) == 0)
138 notcvt = (ElfW2(LIBELFBITS,Phdr) *) alloca (size);
139 memcpy (notcvt, file_phdr, size);
142 for (size_t cnt = 0; cnt < phnum; ++cnt)
144 CONVERT_TO (phdr[cnt].p_type, notcvt[cnt].p_type);
145 CONVERT_TO (phdr[cnt].p_offset, notcvt[cnt].p_offset);
146 CONVERT_TO (phdr[cnt].p_vaddr, notcvt[cnt].p_vaddr);
147 CONVERT_TO (phdr[cnt].p_paddr, notcvt[cnt].p_paddr);
148 CONVERT_TO (phdr[cnt].p_filesz, notcvt[cnt].p_filesz);
149 CONVERT_TO (phdr[cnt].p_memsz, notcvt[cnt].p_memsz);
150 CONVERT_TO (phdr[cnt].p_flags, notcvt[cnt].p_flags);
151 CONVERT_TO (phdr[cnt].p_align, notcvt[cnt].p_align);
156 else if (likely (elf->fildes != -1))
158 /* Allocate memory for the program headers. We know the number
159 of entries from the ELF header. */
160 elf->state.ELFW(elf,LIBELFBITS).phdr =
161 (ElfW2(LIBELFBITS,Phdr) *) malloc (size);
162 if (elf->state.ELFW(elf,LIBELFBITS).phdr == NULL)
164 __libelf_seterrno (ELF_E_NOMEM);
167 elf->state.ELFW(elf,LIBELFBITS).phdr_flags |= ELF_F_MALLOCED;
169 /* Read the header. */
170 ssize_t n = pread_retry (elf->fildes,
171 elf->state.ELFW(elf,LIBELFBITS).phdr, size,
172 elf->start_offset + ehdr->e_phoff);
173 if (unlikely ((size_t) n != size))
175 /* Severe problems. We cannot read the data. */
176 __libelf_seterrno (ELF_E_READ_ERROR);
177 free (elf->state.ELFW(elf,LIBELFBITS).phdr);
178 elf->state.ELFW(elf,LIBELFBITS).phdr = NULL;
182 /* If the byte order of the file is not the same as the one
183 of the host convert the data now. */
184 if (ehdr->e_ident[EI_DATA] != MY_ELFDATA)
186 ElfW2(LIBELFBITS,Phdr) *phdr
187 = elf->state.ELFW(elf,LIBELFBITS).phdr;
189 for (size_t cnt = 0; cnt < phnum; ++cnt)
191 CONVERT (phdr[cnt].p_type);
192 CONVERT (phdr[cnt].p_offset);
193 CONVERT (phdr[cnt].p_vaddr);
194 CONVERT (phdr[cnt].p_paddr);
195 CONVERT (phdr[cnt].p_filesz);
196 CONVERT (phdr[cnt].p_memsz);
197 CONVERT (phdr[cnt].p_flags);
198 CONVERT (phdr[cnt].p_align);
204 /* The file descriptor was already enabled and not all data was
206 __libelf_seterrno (ELF_E_FD_DISABLED);
210 result = elf->state.ELFW(elf,LIBELFBITS).phdr;
217 ElfW2(LIBELFBITS,Phdr) *
218 elfw2(LIBELFBITS,getphdr) (elf)
221 ElfW2(LIBELFBITS,Phdr) *result;
226 if (unlikely (elf->kind != ELF_K_ELF))
228 __libelf_seterrno (ELF_E_INVALID_HANDLE);
232 /* If the program header entry has already been filled in the code
233 * in getphdr_wrlock must already have been run. So the class is
234 * set, too. No need to waste any more time here. */
235 result = elf->state.ELFW(elf,LIBELFBITS).phdr;
236 if (likely (result != NULL))
239 rwlock_wrlock (elf->lock);
240 result = __elfw2(LIBELFBITS,getphdr_wrlock) (elf);
241 rwlock_unlock (elf->lock);
245 INTDEF(elfw2(LIBELFBITS,getphdr))