Coverage Report

Created: 2025-11-13 06:36

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