1 /* Return program header table entry. 2 Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. 3 Written by Ulrich Drepper <drepper (at) 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 28 GElf_Phdr * 29 gelf_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 } 118