Coverage Report

Created: 2026-09-03 06:53

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