1b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Get ELF program header table.
21ccdfb683ad6c7e59793136c3a657ddf131cafd1Mark Wielaard   Copyright (C) 1998-2010, 2014, 2015 Red Hat, Inc.
3de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard   This file is part of elfutils.
4b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
5b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
6de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard   This file is free software; you can redistribute it and/or modify
7de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard   it under the terms of either
8b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
9de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard     * the GNU Lesser General Public License as published by the Free
10de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard       Software Foundation; either version 3 of the License, or (at
11de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard       your option) any later version
12de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard
13de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard   or
14de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard
15de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard     * the GNU General Public License as published by the Free
16de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard       Software Foundation; either version 2 of the License, or (at
17de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard       your option) any later version
18de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard
19de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard   or both in parallel, as here.
20de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard
21de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard   elfutils is distributed in the hope that it will be useful, but
22361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   WITHOUT ANY WARRANTY; without even the implied warranty of
23361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
24361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   General Public License for more details.
25b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
26de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard   You should have received copies of the GNU General Public License and
27de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard   the GNU Lesser General Public License along with this program.  If
28de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard   not, see <http://www.gnu.org/licenses/>.  */
29b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
30b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#ifdef HAVE_CONFIG_H
31b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper# include <config.h>
32b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#endif
33b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
34fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper#include <errno.h>
35b4d6f0f8064f2b706ea9035ef0393d8299671390Roland McGrath#include <stdbool.h>
36b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <stdlib.h>
37b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <unistd.h>
38c373d850ec9ca342f4c71d5e287c8d8bf0723cd6Roland McGrath#include <assert.h>
39b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
40fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper#include <system.h>
41b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include "libelfP.h"
42b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include "common.h"
43b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
44b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#ifndef LIBELFBITS
45b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper# define LIBELFBITS 32
46b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#endif
47b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
48b08d5a8fb42f4586d756068065186b5af7e48daUlrich DrepperElfW2(LIBELFBITS,Phdr) *
491ccdfb683ad6c7e59793136c3a657ddf131cafd1Mark Wielaard__elfw2(LIBELFBITS,getphdr_wrlock) (Elf *elf)
50b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{
51b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  ElfW2(LIBELFBITS,Phdr) *result;
52b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
53b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* If the program header entry has already been filled in the code
54b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     below must already have been run.  So the class is set, too.  No
55b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     need to waste any more time here.  */
56b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  result = elf->state.ELFW(elf,LIBELFBITS).phdr;
57b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (likely (result != NULL))
58b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    return result;
59b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
60b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (elf->class == 0)
61b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    elf->class = ELFW(ELFCLASS,LIBELFBITS);
62b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  else if (elf->class != ELFW(ELFCLASS,LIBELFBITS))
63b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
64b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      __libelf_seterrno (ELF_E_INVALID_CLASS);
65b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      result = NULL;
66b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      goto out;
67b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
68b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
69b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (likely (result == NULL))
70b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
71b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      /* Read the section header table.  */
72b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      ElfW2(LIBELFBITS,Ehdr) *ehdr = elf->state.ELFW(elf,LIBELFBITS).ehdr;
73b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
74b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      /* If no program header exists return NULL.  */
756fd3cd104adf4107aa64e1c1e84028b4ea0b3296Roland McGrath      size_t phnum;
766fd3cd104adf4107aa64e1c1e84028b4ea0b3296Roland McGrath      if (__elf_getphdrnum_rdlock (elf, &phnum) != 0)
776fd3cd104adf4107aa64e1c1e84028b4ea0b3296Roland McGrath	goto out;
78436275edd015ab6a6f8e164ee2292f74f03d2413Mark Wielaard      if (phnum == 0 || ehdr->e_phoff == 0)
79b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	{
80b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  __libelf_seterrno (ELF_E_NO_PHDR);
81b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  goto out;
82b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	}
83b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
84436275edd015ab6a6f8e164ee2292f74f03d2413Mark Wielaard      /* Check this doesn't overflow.  */
85b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      size_t size = phnum * sizeof (ElfW2(LIBELFBITS,Phdr));
86b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
87436275edd015ab6a6f8e164ee2292f74f03d2413Mark Wielaard      if (phnum > SIZE_MAX / sizeof (ElfW2(LIBELFBITS,Phdr))
88436275edd015ab6a6f8e164ee2292f74f03d2413Mark Wielaard	  || ehdr->e_phoff > elf->maximum_size
89957072c18a906a43f0b428997d0c2b0da478213bRoland McGrath	  || elf->maximum_size - ehdr->e_phoff < size)
90957072c18a906a43f0b428997d0c2b0da478213bRoland McGrath	{
91957072c18a906a43f0b428997d0c2b0da478213bRoland McGrath	  __libelf_seterrno (ELF_E_INVALID_DATA);
92957072c18a906a43f0b428997d0c2b0da478213bRoland McGrath	  goto out;
93957072c18a906a43f0b428997d0c2b0da478213bRoland McGrath	}
94957072c18a906a43f0b428997d0c2b0da478213bRoland McGrath
95b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if (elf->map_address != NULL)
96b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	{
97720383c53b435de6647edd78060dd7d38ade25a5Jakub Jelinek	  /* First see whether the information in the ELF header is
98720383c53b435de6647edd78060dd7d38ade25a5Jakub Jelinek	     valid and it does not ask for too much.  */
99720383c53b435de6647edd78060dd7d38ade25a5Jakub Jelinek	  if (unlikely (ehdr->e_phoff >= elf->maximum_size)
100720383c53b435de6647edd78060dd7d38ade25a5Jakub Jelinek	      || unlikely (elf->maximum_size - ehdr->e_phoff < size))
101720383c53b435de6647edd78060dd7d38ade25a5Jakub Jelinek	    {
102720383c53b435de6647edd78060dd7d38ade25a5Jakub Jelinek	      /* Something is wrong.  */
103720383c53b435de6647edd78060dd7d38ade25a5Jakub Jelinek	      __libelf_seterrno (ELF_E_INVALID_PHDR);
104720383c53b435de6647edd78060dd7d38ade25a5Jakub Jelinek	      goto out;
105720383c53b435de6647edd78060dd7d38ade25a5Jakub Jelinek	    }
106720383c53b435de6647edd78060dd7d38ade25a5Jakub Jelinek
107b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  /* All the data is already mapped.  Use it.  */
108c373d850ec9ca342f4c71d5e287c8d8bf0723cd6Roland McGrath	  void *file_phdr = ((char *) elf->map_address
109c373d850ec9ca342f4c71d5e287c8d8bf0723cd6Roland McGrath			     + elf->start_offset + ehdr->e_phoff);
110b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  if (ehdr->e_ident[EI_DATA] == MY_ELFDATA
111b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      && (ALLOW_UNALIGNED
112c373d850ec9ca342f4c71d5e287c8d8bf0723cd6Roland McGrath		  || ((uintptr_t) file_phdr
113c373d850ec9ca342f4c71d5e287c8d8bf0723cd6Roland McGrath		      & (__alignof__ (ElfW2(LIBELFBITS,Phdr)) - 1)) == 0))
114b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    /* Simply use the mapped data.  */
115c373d850ec9ca342f4c71d5e287c8d8bf0723cd6Roland McGrath	    elf->state.ELFW(elf,LIBELFBITS).phdr = file_phdr;
116b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  else
117b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    {
118b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      ElfW2(LIBELFBITS,Phdr) *notcvt;
119b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      ElfW2(LIBELFBITS,Phdr) *phdr;
120b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
121b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      /* Allocate memory for the program headers.  We know the number
122b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		 of entries from the ELF header.  */
123b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      phdr = elf->state.ELFW(elf,LIBELFBITS).phdr =
124b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		(ElfW2(LIBELFBITS,Phdr) *) malloc (size);
125b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      if (elf->state.ELFW(elf,LIBELFBITS).phdr == NULL)
126b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		{
127b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		  __libelf_seterrno (ELF_E_NOMEM);
128b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		  goto out;
129b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		}
130b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      elf->state.ELFW(elf,LIBELFBITS).phdr_flags |=
131b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		ELF_F_MALLOCED | ELF_F_DIRTY;
132b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
133b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      /* Now copy the data and at the same time convert the
134b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		 byte order.  */
135c373d850ec9ca342f4c71d5e287c8d8bf0723cd6Roland McGrath
136c373d850ec9ca342f4c71d5e287c8d8bf0723cd6Roland McGrath	      if (ehdr->e_ident[EI_DATA] == MY_ELFDATA)
137b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		{
138c373d850ec9ca342f4c71d5e287c8d8bf0723cd6Roland McGrath		  assert (! ALLOW_UNALIGNED);
139c373d850ec9ca342f4c71d5e287c8d8bf0723cd6Roland McGrath		  memcpy (phdr, file_phdr, size);
140b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		}
141c373d850ec9ca342f4c71d5e287c8d8bf0723cd6Roland McGrath	      else
142b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		{
1432ec518247897bfa41327db2627e1e6112e5d59daMark Wielaard		  bool copy = ! (ALLOW_UNALIGNED
1442ec518247897bfa41327db2627e1e6112e5d59daMark Wielaard				 || ((uintptr_t) file_phdr
1452ec518247897bfa41327db2627e1e6112e5d59daMark Wielaard				     & (__alignof__ (ElfW2(LIBELFBITS,Phdr))
1462ec518247897bfa41327db2627e1e6112e5d59daMark Wielaard					- 1)) == 0);
1472ec518247897bfa41327db2627e1e6112e5d59daMark Wielaard		  if (! copy)
148c373d850ec9ca342f4c71d5e287c8d8bf0723cd6Roland McGrath		    notcvt = file_phdr;
149c373d850ec9ca342f4c71d5e287c8d8bf0723cd6Roland McGrath		  else
150c373d850ec9ca342f4c71d5e287c8d8bf0723cd6Roland McGrath		    {
1512ec518247897bfa41327db2627e1e6112e5d59daMark Wielaard		      notcvt = (ElfW2(LIBELFBITS,Phdr) *) malloc (size);
1522ec518247897bfa41327db2627e1e6112e5d59daMark Wielaard		      if (unlikely (notcvt == NULL))
1532ec518247897bfa41327db2627e1e6112e5d59daMark Wielaard			{
1542ec518247897bfa41327db2627e1e6112e5d59daMark Wielaard			  __libelf_seterrno (ELF_E_NOMEM);
1552ec518247897bfa41327db2627e1e6112e5d59daMark Wielaard			  goto out;
1562ec518247897bfa41327db2627e1e6112e5d59daMark Wielaard			}
157c373d850ec9ca342f4c71d5e287c8d8bf0723cd6Roland McGrath		      memcpy (notcvt, file_phdr, size);
158c373d850ec9ca342f4c71d5e287c8d8bf0723cd6Roland McGrath		    }
159c373d850ec9ca342f4c71d5e287c8d8bf0723cd6Roland McGrath
160c373d850ec9ca342f4c71d5e287c8d8bf0723cd6Roland McGrath		  for (size_t cnt = 0; cnt < phnum; ++cnt)
161c373d850ec9ca342f4c71d5e287c8d8bf0723cd6Roland McGrath		    {
162c373d850ec9ca342f4c71d5e287c8d8bf0723cd6Roland McGrath		      CONVERT_TO (phdr[cnt].p_type, notcvt[cnt].p_type);
163c373d850ec9ca342f4c71d5e287c8d8bf0723cd6Roland McGrath		      CONVERT_TO (phdr[cnt].p_offset, notcvt[cnt].p_offset);
164c373d850ec9ca342f4c71d5e287c8d8bf0723cd6Roland McGrath		      CONVERT_TO (phdr[cnt].p_vaddr, notcvt[cnt].p_vaddr);
165c373d850ec9ca342f4c71d5e287c8d8bf0723cd6Roland McGrath		      CONVERT_TO (phdr[cnt].p_paddr, notcvt[cnt].p_paddr);
166c373d850ec9ca342f4c71d5e287c8d8bf0723cd6Roland McGrath		      CONVERT_TO (phdr[cnt].p_filesz, notcvt[cnt].p_filesz);
167c373d850ec9ca342f4c71d5e287c8d8bf0723cd6Roland McGrath		      CONVERT_TO (phdr[cnt].p_memsz, notcvt[cnt].p_memsz);
168c373d850ec9ca342f4c71d5e287c8d8bf0723cd6Roland McGrath		      CONVERT_TO (phdr[cnt].p_flags, notcvt[cnt].p_flags);
169c373d850ec9ca342f4c71d5e287c8d8bf0723cd6Roland McGrath		      CONVERT_TO (phdr[cnt].p_align, notcvt[cnt].p_align);
170c373d850ec9ca342f4c71d5e287c8d8bf0723cd6Roland McGrath		    }
1712ec518247897bfa41327db2627e1e6112e5d59daMark Wielaard
1722ec518247897bfa41327db2627e1e6112e5d59daMark Wielaard		  if (copy)
1732ec518247897bfa41327db2627e1e6112e5d59daMark Wielaard		    free (notcvt);
174b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		}
175b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    }
176b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	}
177b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      else if (likely (elf->fildes != -1))
178b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	{
179b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  /* Allocate memory for the program headers.  We know the number
180b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	     of entries from the ELF header.  */
181b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  elf->state.ELFW(elf,LIBELFBITS).phdr =
182b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    (ElfW2(LIBELFBITS,Phdr) *) malloc (size);
183b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  if (elf->state.ELFW(elf,LIBELFBITS).phdr == NULL)
184b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    {
185b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      __libelf_seterrno (ELF_E_NOMEM);
186b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      goto out;
187b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    }
188b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  elf->state.ELFW(elf,LIBELFBITS).phdr_flags |= ELF_F_MALLOCED;
189b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
190b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  /* Read the header.  */
191fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper	  ssize_t n = pread_retry (elf->fildes,
192fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper				   elf->state.ELFW(elf,LIBELFBITS).phdr, size,
193fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper				   elf->start_offset + ehdr->e_phoff);
194fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper	  if (unlikely ((size_t) n != size))
195b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    {
196b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      /* Severe problems.  We cannot read the data.  */
197b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      __libelf_seterrno (ELF_E_READ_ERROR);
198b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      free (elf->state.ELFW(elf,LIBELFBITS).phdr);
199b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      elf->state.ELFW(elf,LIBELFBITS).phdr = NULL;
200b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      goto out;
201b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    }
202b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
203b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  /* If the byte order of the file is not the same as the one
204b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	     of the host convert the data now.  */
205b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  if (ehdr->e_ident[EI_DATA] != MY_ELFDATA)
206b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    {
207b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      ElfW2(LIBELFBITS,Phdr) *phdr
208b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		= elf->state.ELFW(elf,LIBELFBITS).phdr;
209b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
210b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      for (size_t cnt = 0; cnt < phnum; ++cnt)
211b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		{
212b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		  CONVERT (phdr[cnt].p_type);
213b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		  CONVERT (phdr[cnt].p_offset);
214b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		  CONVERT (phdr[cnt].p_vaddr);
215b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		  CONVERT (phdr[cnt].p_paddr);
216b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		  CONVERT (phdr[cnt].p_filesz);
217b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		  CONVERT (phdr[cnt].p_memsz);
218b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		  CONVERT (phdr[cnt].p_flags);
219b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		  CONVERT (phdr[cnt].p_align);
220b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		}
221b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    }
222b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	}
223b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      else
224b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	{
225b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  /* The file descriptor was already enabled and not all data was
226b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	     read.  */
227b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  __libelf_seterrno (ELF_E_FD_DISABLED);
228b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  goto out;
229b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	}
230b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
231b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      result = elf->state.ELFW(elf,LIBELFBITS).phdr;
232b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
233b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
234b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper out:
235b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  return result;
236b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper}
237d56e232fb8f8cd97a336ed612c89145ec121f785Ulrich Drepper
238d56e232fb8f8cd97a336ed612c89145ec121f785Ulrich DrepperElfW2(LIBELFBITS,Phdr) *
2391ccdfb683ad6c7e59793136c3a657ddf131cafd1Mark Wielaardelfw2(LIBELFBITS,getphdr) (Elf *elf)
240d56e232fb8f8cd97a336ed612c89145ec121f785Ulrich Drepper{
241b4d6f0f8064f2b706ea9035ef0393d8299671390Roland McGrath  ElfW2(LIBELFBITS,Phdr) *result;
242d56e232fb8f8cd97a336ed612c89145ec121f785Ulrich Drepper
243122f388b300a489b54829d80f5e5fffb3f743ab7Roland McGrath  if (elf == NULL)
244122f388b300a489b54829d80f5e5fffb3f743ab7Roland McGrath    return NULL;
245122f388b300a489b54829d80f5e5fffb3f743ab7Roland McGrath
246122f388b300a489b54829d80f5e5fffb3f743ab7Roland McGrath  if (unlikely (elf->kind != ELF_K_ELF))
247122f388b300a489b54829d80f5e5fffb3f743ab7Roland McGrath    {
248122f388b300a489b54829d80f5e5fffb3f743ab7Roland McGrath      __libelf_seterrno (ELF_E_INVALID_HANDLE);
249122f388b300a489b54829d80f5e5fffb3f743ab7Roland McGrath      return NULL;
250122f388b300a489b54829d80f5e5fffb3f743ab7Roland McGrath    }
251122f388b300a489b54829d80f5e5fffb3f743ab7Roland McGrath
252122f388b300a489b54829d80f5e5fffb3f743ab7Roland McGrath  /* If the program header entry has already been filled in the code
253122f388b300a489b54829d80f5e5fffb3f743ab7Roland McGrath   * in getphdr_wrlock must already have been run.  So the class is
254122f388b300a489b54829d80f5e5fffb3f743ab7Roland McGrath   * set, too.  No need to waste any more time here.  */
255122f388b300a489b54829d80f5e5fffb3f743ab7Roland McGrath  result = elf->state.ELFW(elf,LIBELFBITS).phdr;
256122f388b300a489b54829d80f5e5fffb3f743ab7Roland McGrath  if (likely (result != NULL))
257122f388b300a489b54829d80f5e5fffb3f743ab7Roland McGrath    return result;
258122f388b300a489b54829d80f5e5fffb3f743ab7Roland McGrath
259b4d6f0f8064f2b706ea9035ef0393d8299671390Roland McGrath  rwlock_wrlock (elf->lock);
260b4d6f0f8064f2b706ea9035ef0393d8299671390Roland McGrath  result = __elfw2(LIBELFBITS,getphdr_wrlock) (elf);
261b4d6f0f8064f2b706ea9035ef0393d8299671390Roland McGrath  rwlock_unlock (elf->lock);
262b4d6f0f8064f2b706ea9035ef0393d8299671390Roland McGrath
263b4d6f0f8064f2b706ea9035ef0393d8299671390Roland McGrath  return result;
264d56e232fb8f8cd97a336ed612c89145ec121f785Ulrich Drepper}
265b4d6f0f8064f2b706ea9035ef0393d8299671390Roland McGrathINTDEF(elfw2(LIBELFBITS,getphdr))
266