Coverage Report

Created: 2025-11-24 06:43

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