blob: fd033e562ae383a4f1a4bcf7cdb5cda1d3f50505 [file] [log] [blame]
Ulrich Drepperb08d5a82005-07-26 05:00:05 +00001/* Return program header table entry.
2 Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
3 Written by Ulrich Drepper <drepper@redhat.com>, 1998.
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, version 2.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software Foundation,
16 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
17
18#ifdef HAVE_CONFIG_H
19# include <config.h>
20#endif
21
22#include <gelf.h>
23#include <string.h>
24
25#include "libelfP.h"
26
27
28GElf_Phdr *
29gelf_getphdr (elf, ndx, dst)
30 Elf *elf;
31 int ndx;
32 GElf_Phdr *dst;
33{
34 GElf_Phdr *result = NULL;
35
36 if (elf == NULL)
37 return NULL;
38
39 if (unlikely (elf->kind != ELF_K_ELF))
40 {
41 __libelf_seterrno (ELF_E_INVALID_HANDLE);
42 return NULL;
43 }
44
45 if (dst == NULL)
46 {
47 __libelf_seterrno (ELF_E_INVALID_OPERAND);
48 return NULL;
49 }
50
51 rwlock_rdlock (elf->lock);
52
53 if (elf->class == ELFCLASS32)
54 {
55 /* Copy the elements one-by-one. */
56 Elf32_Phdr *phdr = elf->state.elf32.phdr;
57
58 if (phdr == NULL)
59 {
60 phdr = INTUSE(elf32_getphdr) (elf);
61 if (phdr == NULL)
62 /* The error number is already set. */
63 goto out;
64 }
65
66 /* Test whether the index is ok. */
67 if (ndx >= elf->state.elf32.ehdr->e_phnum)
68 {
69 __libelf_seterrno (ELF_E_INVALID_INDEX);
70 goto out;
71 }
72
73 /* We know the result now. */
74 result = dst;
75
76 /* Now correct the pointer to point to the correct element. */
77 phdr += ndx;
78
79#define COPY(Name) result->Name = phdr->Name
80 COPY (p_type);
81 COPY (p_offset);
82 COPY (p_vaddr);
83 COPY (p_paddr);
84 COPY (p_filesz);
85 COPY (p_memsz);
86 COPY (p_flags);
87 COPY (p_align);
88 }
89 else
90 {
91 /* Copy the elements one-by-one. */
92 Elf64_Phdr *phdr = elf->state.elf64.phdr;
93
94 if (phdr == NULL)
95 {
96 phdr = INTUSE(elf64_getphdr) (elf);
97 if (phdr == NULL)
98 /* The error number is already set. */
99 goto out;
100 }
101
102 /* Test whether the index is ok. */
103 if (ndx >= elf->state.elf64.ehdr->e_phnum)
104 {
105 __libelf_seterrno (ELF_E_INVALID_INDEX);
106 goto out;
107 }
108
109 /* We only have to copy the data. */
110 result = memcpy (dst, phdr + ndx, sizeof (GElf_Phdr));
111 }
112
113 out:
114 rwlock_unlock (elf->lock);
115
116 return result;
117}