Coverage Report

Created: 2025-08-24 06:28

/src/elfutils/libelf/gelf_getphdr.c
Line
Count
Source (jump to first uncovered line)
1
/* Return program header table entry.
2
   Copyright (C) 1998-2010, 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 <string.h>
36
#include <stdbool.h>
37
38
#include "libelfP.h"
39
40
41
GElf_Phdr *
42
gelf_getphdr (Elf *elf, int ndx, GElf_Phdr *dst)
43
264M
{
44
264M
  GElf_Phdr *result = NULL;
45
46
264M
  if (elf == NULL)
47
0
    return NULL;
48
49
264M
  if (unlikely (elf->kind != ELF_K_ELF))
50
0
    {
51
0
      __libelf_seterrno (ELF_E_INVALID_HANDLE);
52
0
      return NULL;
53
0
    }
54
55
264M
  if (dst == NULL)
56
0
    {
57
0
      __libelf_seterrno (ELF_E_INVALID_OPERAND);
58
0
      return NULL;
59
0
    }
60
61
264M
  rwlock_rdlock (elf->lock);
62
63
264M
  if (elf->class == ELFCLASS32)
64
226M
    {
65
      /* Copy the elements one-by-one.  */
66
226M
      Elf32_Phdr *phdr = elf->state.elf32.phdr;
67
68
226M
      if (phdr == NULL)
69
11.4k
  {
70
11.4k
    rwlock_unlock (elf->lock);
71
11.4k
    phdr = INTUSE(elf32_getphdr) (elf);
72
11.4k
    if (phdr == NULL)
73
      /* The error number is already set.  */
74
66
      return NULL;
75
11.4k
    rwlock_rdlock (elf->lock);
76
11.4k
  }
77
78
      /* Test whether the index is ok.  */
79
226M
      size_t phnum;
80
226M
      if (__elf_getphdrnum_chk_rdlock (elf, &phnum) != 0
81
226M
    || (size_t) ndx >= phnum)
82
20.9k
  {
83
20.9k
    __libelf_seterrno (ELF_E_INVALID_INDEX);
84
20.9k
    goto out;
85
20.9k
  }
86
87
      /* We know the result now.  */
88
226M
      result = dst;
89
90
      /* Now correct the pointer to point to the correct element.  */
91
226M
      phdr += ndx;
92
93
1.80G
#define COPY(Name) result->Name = phdr->Name
94
226M
      COPY (p_type);
95
226M
      COPY (p_offset);
96
226M
      COPY (p_vaddr);
97
226M
      COPY (p_paddr);
98
226M
      COPY (p_filesz);
99
226M
      COPY (p_memsz);
100
226M
      COPY (p_flags);
101
226M
      COPY (p_align);
102
226M
    }
103
38.9M
  else
104
38.9M
    {
105
      /* Copy the elements one-by-one.  */
106
38.9M
      Elf64_Phdr *phdr = elf->state.elf64.phdr;
107
108
38.9M
      if (phdr == NULL)
109
10.3k
  {
110
10.3k
    rwlock_unlock (elf->lock);
111
10.3k
    phdr = INTUSE(elf64_getphdr) (elf);
112
10.3k
    if (phdr == NULL)
113
      /* The error number is already set.  */
114
71
      return NULL;
115
10.3k
    rwlock_rdlock (elf->lock);
116
10.3k
  }
117
118
      /* Test whether the index is ok.  */
119
38.9M
      size_t phnum;
120
38.9M
      if (__elf_getphdrnum_chk_rdlock (elf, &phnum) != 0
121
38.9M
    || (size_t) ndx >= phnum)
122
12.8k
  {
123
12.8k
    __libelf_seterrno (ELF_E_INVALID_INDEX);
124
12.8k
    goto out;
125
12.8k
  }
126
127
      /* We only have to copy the data.  */
128
38.9M
      result = memcpy (dst, phdr + ndx, sizeof (GElf_Phdr));
129
38.9M
    }
130
131
264M
 out:
132
264M
  rwlock_unlock (elf->lock);
133
134
264M
  return result;
135
264M
}