Coverage Report

Created: 2025-10-13 07:18

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/elfutils/libelf/gelf_getphdr.c
Line
Count
Source
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
270M
{
44
270M
  GElf_Phdr *result = NULL;
45
46
270M
  if (elf == NULL)
47
0
    return NULL;
48
49
270M
  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
270M
  if (dst == NULL)
56
0
    {
57
0
      __libelf_seterrno (ELF_E_INVALID_OPERAND);
58
0
      return NULL;
59
0
    }
60
61
270M
  rwlock_rdlock (elf->lock);
62
63
270M
  if (elf->class == ELFCLASS32)
64
203M
    {
65
      /* Copy the elements one-by-one.  */
66
203M
      Elf32_Phdr *phdr = elf->state.elf32.phdr;
67
68
203M
      if (phdr == NULL)
69
9.16k
  {
70
9.16k
    rwlock_unlock (elf->lock);
71
9.16k
    phdr = INTUSE(elf32_getphdr) (elf);
72
9.16k
    if (phdr == NULL)
73
      /* The error number is already set.  */
74
74
      return NULL;
75
9.09k
    rwlock_rdlock (elf->lock);
76
9.09k
  }
77
78
      /* Test whether the index is ok.  */
79
203M
      size_t phnum;
80
203M
      if (__elf_getphdrnum_chk_rdlock (elf, &phnum) != 0
81
203M
    || (size_t) ndx >= phnum)
82
16.1k
  {
83
16.1k
    __libelf_seterrno (ELF_E_INVALID_INDEX);
84
16.1k
    goto out;
85
16.1k
  }
86
87
      /* We know the result now.  */
88
203M
      result = dst;
89
90
      /* Now correct the pointer to point to the correct element.  */
91
203M
      phdr += ndx;
92
93
1.62G
#define COPY(Name) result->Name = phdr->Name
94
203M
      COPY (p_type);
95
203M
      COPY (p_offset);
96
203M
      COPY (p_vaddr);
97
203M
      COPY (p_paddr);
98
203M
      COPY (p_filesz);
99
203M
      COPY (p_memsz);
100
203M
      COPY (p_flags);
101
203M
      COPY (p_align);
102
203M
    }
103
67.2M
  else
104
67.2M
    {
105
      /* Copy the elements one-by-one.  */
106
67.2M
      Elf64_Phdr *phdr = elf->state.elf64.phdr;
107
108
67.2M
      if (phdr == NULL)
109
10.8k
  {
110
10.8k
    rwlock_unlock (elf->lock);
111
10.8k
    phdr = INTUSE(elf64_getphdr) (elf);
112
10.8k
    if (phdr == NULL)
113
      /* The error number is already set.  */
114
70
      return NULL;
115
10.7k
    rwlock_rdlock (elf->lock);
116
10.7k
  }
117
118
      /* Test whether the index is ok.  */
119
67.2M
      size_t phnum;
120
67.2M
      if (__elf_getphdrnum_chk_rdlock (elf, &phnum) != 0
121
67.2M
    || (size_t) ndx >= phnum)
122
21.0k
  {
123
21.0k
    __libelf_seterrno (ELF_E_INVALID_INDEX);
124
21.0k
    goto out;
125
21.0k
  }
126
127
      /* We only have to copy the data.  */
128
67.2M
      result = memcpy (dst, phdr + ndx, sizeof (GElf_Phdr));
129
67.2M
    }
130
131
270M
 out:
132
270M
  rwlock_unlock (elf->lock);
133
134
270M
  return result;
135
270M
}