Coverage Report

Created: 2026-02-24 06:49

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