Coverage Report

Created: 2026-02-26 06:47

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/elfutils/libelf/elf32_getshdr.c
Line
Count
Source
1
/* Return section header.
2
   Copyright (C) 1998-2002, 2005, 2007, 2009, 2012, 2014, 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 <assert.h>
35
#include <errno.h>
36
#include <stdbool.h>
37
38
#include "libelfP.h"
39
#include "common.h"
40
41
#ifndef LIBELFBITS
42
# define LIBELFBITS 32
43
#endif
44
45
46
static ElfW2(LIBELFBITS,Shdr) *
47
load_shdr_wrlock (Elf_Scn *scn)
48
2.25k
{
49
2.25k
  ElfW2(LIBELFBITS,Shdr) *result;
50
51
  /* Read the section header table.  */
52
2.25k
  Elf *elf = scn->elf;
53
2.25k
  ElfW2(LIBELFBITS,Ehdr) *ehdr = elf->state.ELFW(elf,LIBELFBITS).ehdr;
54
55
  /* Try again, maybe the data is there now.  */
56
2.25k
  result = scn->shdr.ELFW(e,LIBELFBITS);
57
2.25k
  if (result != NULL)
58
0
    goto out;
59
60
2.25k
  size_t shnum;
61
2.25k
  if (__elf_getshdrnum_rdlock (elf, &shnum) != 0
62
2.25k
      || shnum > SIZE_MAX / sizeof (ElfW2(LIBELFBITS,Shdr)))
63
0
    goto out;
64
2.25k
  size_t size = shnum * sizeof (ElfW2(LIBELFBITS,Shdr));
65
66
  /* Allocate memory for the section headers.  We know the number
67
     of entries from the ELF header.  */
68
2.25k
  ElfW2(LIBELFBITS,Shdr) *shdr = elf->state.ELFW(elf,LIBELFBITS).shdr =
69
2.25k
    (ElfW2(LIBELFBITS,Shdr) *) malloc (size);
70
2.25k
  if (elf->state.ELFW(elf,LIBELFBITS).shdr == NULL)
71
0
    {
72
0
      __libelf_seterrno (ELF_E_NOMEM);
73
0
      goto out;
74
0
    }
75
2.25k
  elf->state.ELFW(elf,LIBELFBITS).shdr_malloced = 1;
76
77
2.25k
  if (elf->map_address != NULL)
78
2.25k
    {
79
      /* First see whether the information in the ELF header is
80
   valid and it does not ask for too much.  */
81
2.25k
      if (unlikely (ehdr->e_shoff >= elf->maximum_size)
82
2.25k
    || unlikely (elf->maximum_size - ehdr->e_shoff < size))
83
0
  {
84
    /* Something is wrong.  */
85
0
    __libelf_seterrno (ELF_E_INVALID_SECTION_HEADER);
86
0
    goto free_and_out;
87
0
  }
88
89
2.25k
      ElfW2(LIBELFBITS,Shdr) *notcvt;
90
91
      /* All the data is already mapped.  If we could use it
92
   directly this would already have happened.  Unless
93
   we allocated the memory ourselves and the ELF_F_MALLOCED
94
   flag is set.  */
95
2.25k
      void *file_shdr = ((char *) elf->map_address
96
2.25k
       + elf->start_offset + ehdr->e_shoff);
97
98
2.25k
      assert ((elf->flags & ELF_F_MALLOCED)
99
2.25k
        || ehdr->e_ident[EI_DATA] != MY_ELFDATA
100
2.25k
        || elf->cmd == ELF_C_READ_MMAP
101
2.25k
        || (! ALLOW_UNALIGNED
102
2.25k
      && ((uintptr_t) file_shdr
103
2.25k
          & (__alignof__ (ElfW2(LIBELFBITS,Shdr)) - 1)) != 0));
104
105
      /* Now copy the data and at the same time convert the byte order.  */
106
2.25k
      if (ehdr->e_ident[EI_DATA] == MY_ELFDATA)
107
0
  {
108
0
    assert ((elf->flags & ELF_F_MALLOCED)
109
0
      || elf->cmd == ELF_C_READ_MMAP
110
0
      || ! ALLOW_UNALIGNED);
111
0
    memcpy (shdr, file_shdr, size);
112
0
  }
113
2.25k
      else
114
2.25k
  {
115
2.25k
    bool copy = ! (ALLOW_UNALIGNED
116
0
       || ((uintptr_t) file_shdr
117
0
           & (__alignof__ (ElfW2(LIBELFBITS,Shdr)) - 1))
118
0
           == 0);
119
2.25k
    if (! copy)
120
2.25k
      notcvt = (ElfW2(LIBELFBITS,Shdr) *)
121
2.25k
        ((char *) elf->map_address
122
2.25k
         + elf->start_offset + ehdr->e_shoff);
123
0
    else
124
0
      {
125
0
        notcvt = (ElfW2(LIBELFBITS,Shdr) *) malloc (size);
126
0
        if (unlikely (notcvt == NULL))
127
0
    {
128
0
      __libelf_seterrno (ELF_E_NOMEM);
129
0
      goto free_and_out;
130
0
    }
131
0
        memcpy (notcvt, ((char *) elf->map_address
132
0
             + elf->start_offset + ehdr->e_shoff),
133
0
          size);
134
0
      }
135
136
1.90M
    for (size_t cnt = 0; cnt < shnum; ++cnt)
137
1.89M
      {
138
1.89M
        CONVERT_TO (shdr[cnt].sh_name, notcvt[cnt].sh_name);
139
1.89M
        CONVERT_TO (shdr[cnt].sh_type, notcvt[cnt].sh_type);
140
1.89M
        CONVERT_TO (shdr[cnt].sh_flags, notcvt[cnt].sh_flags);
141
1.89M
        CONVERT_TO (shdr[cnt].sh_addr, notcvt[cnt].sh_addr);
142
1.89M
        CONVERT_TO (shdr[cnt].sh_offset, notcvt[cnt].sh_offset);
143
1.89M
        CONVERT_TO (shdr[cnt].sh_size, notcvt[cnt].sh_size);
144
1.89M
        CONVERT_TO (shdr[cnt].sh_link, notcvt[cnt].sh_link);
145
1.89M
        CONVERT_TO (shdr[cnt].sh_info, notcvt[cnt].sh_info);
146
1.89M
        CONVERT_TO (shdr[cnt].sh_addralign,
147
1.89M
        notcvt[cnt].sh_addralign);
148
1.89M
        CONVERT_TO (shdr[cnt].sh_entsize, notcvt[cnt].sh_entsize);
149
1.89M
      }
150
151
2.25k
    if (copy)
152
0
      free (notcvt);
153
2.25k
  }
154
2.25k
    }
155
0
  else if (likely (elf->fildes != -1))
156
0
    {
157
      /* Read the header.  */
158
0
      ssize_t n = pread_retry (elf->fildes,
159
0
             elf->state.ELFW(elf,LIBELFBITS).shdr, size,
160
0
             elf->start_offset + ehdr->e_shoff);
161
0
      if (unlikely ((size_t) n != size))
162
0
  {
163
    /* Severe problems.  We cannot read the data.  */
164
0
    __libelf_seterrno (ELF_E_READ_ERROR);
165
0
    goto free_and_out;
166
0
  }
167
168
      /* If the byte order of the file is not the same as the one
169
   of the host convert the data now.  */
170
0
      if (ehdr->e_ident[EI_DATA] != MY_ELFDATA)
171
0
  for (size_t cnt = 0; cnt < shnum; ++cnt)
172
0
    {
173
0
      CONVERT (shdr[cnt].sh_name);
174
0
      CONVERT (shdr[cnt].sh_type);
175
0
      CONVERT (shdr[cnt].sh_flags);
176
0
      CONVERT (shdr[cnt].sh_addr);
177
0
      CONVERT (shdr[cnt].sh_offset);
178
0
      CONVERT (shdr[cnt].sh_size);
179
0
      CONVERT (shdr[cnt].sh_link);
180
0
      CONVERT (shdr[cnt].sh_info);
181
0
      CONVERT (shdr[cnt].sh_addralign);
182
0
      CONVERT (shdr[cnt].sh_entsize);
183
0
    }
184
0
    }
185
0
  else
186
0
    {
187
      /* The file descriptor was already enabled and not all data was
188
   read.  Undo the allocation.  */
189
0
      __libelf_seterrno (ELF_E_FD_DISABLED);
190
191
0
    free_and_out:
192
0
      free (shdr);
193
0
      elf->state.ELFW(elf,LIBELFBITS).shdr = NULL;
194
0
      elf->state.ELFW(elf,LIBELFBITS).shdr_malloced = 0;
195
196
0
      goto out;
197
0
    }
198
199
  /* Set the pointers in the `scn's.  */
200
1.90M
  for (size_t cnt = 0; cnt < shnum; ++cnt)
201
1.89M
    elf->state.ELFW(elf,LIBELFBITS).scns.data[cnt].shdr.ELFW(e,LIBELFBITS)
202
1.89M
      = &elf->state.ELFW(elf,LIBELFBITS).shdr[cnt];
203
204
2.25k
  result = scn->shdr.ELFW(e,LIBELFBITS);
205
2.25k
  assert (result != NULL);
206
207
2.25k
out:
208
2.25k
  return result;
209
2.25k
}
elf32_getshdr.c:load_shdr_wrlock
Line
Count
Source
48
1.10k
{
49
1.10k
  ElfW2(LIBELFBITS,Shdr) *result;
50
51
  /* Read the section header table.  */
52
1.10k
  Elf *elf = scn->elf;
53
1.10k
  ElfW2(LIBELFBITS,Ehdr) *ehdr = elf->state.ELFW(elf,LIBELFBITS).ehdr;
54
55
  /* Try again, maybe the data is there now.  */
56
1.10k
  result = scn->shdr.ELFW(e,LIBELFBITS);
57
1.10k
  if (result != NULL)
58
0
    goto out;
59
60
1.10k
  size_t shnum;
61
1.10k
  if (__elf_getshdrnum_rdlock (elf, &shnum) != 0
62
1.10k
      || shnum > SIZE_MAX / sizeof (ElfW2(LIBELFBITS,Shdr)))
63
0
    goto out;
64
1.10k
  size_t size = shnum * sizeof (ElfW2(LIBELFBITS,Shdr));
65
66
  /* Allocate memory for the section headers.  We know the number
67
     of entries from the ELF header.  */
68
1.10k
  ElfW2(LIBELFBITS,Shdr) *shdr = elf->state.ELFW(elf,LIBELFBITS).shdr =
69
1.10k
    (ElfW2(LIBELFBITS,Shdr) *) malloc (size);
70
1.10k
  if (elf->state.ELFW(elf,LIBELFBITS).shdr == NULL)
71
0
    {
72
0
      __libelf_seterrno (ELF_E_NOMEM);
73
0
      goto out;
74
0
    }
75
1.10k
  elf->state.ELFW(elf,LIBELFBITS).shdr_malloced = 1;
76
77
1.10k
  if (elf->map_address != NULL)
78
1.10k
    {
79
      /* First see whether the information in the ELF header is
80
   valid and it does not ask for too much.  */
81
1.10k
      if (unlikely (ehdr->e_shoff >= elf->maximum_size)
82
1.10k
    || unlikely (elf->maximum_size - ehdr->e_shoff < size))
83
0
  {
84
    /* Something is wrong.  */
85
0
    __libelf_seterrno (ELF_E_INVALID_SECTION_HEADER);
86
0
    goto free_and_out;
87
0
  }
88
89
1.10k
      ElfW2(LIBELFBITS,Shdr) *notcvt;
90
91
      /* All the data is already mapped.  If we could use it
92
   directly this would already have happened.  Unless
93
   we allocated the memory ourselves and the ELF_F_MALLOCED
94
   flag is set.  */
95
1.10k
      void *file_shdr = ((char *) elf->map_address
96
1.10k
       + elf->start_offset + ehdr->e_shoff);
97
98
1.10k
      assert ((elf->flags & ELF_F_MALLOCED)
99
1.10k
        || ehdr->e_ident[EI_DATA] != MY_ELFDATA
100
1.10k
        || elf->cmd == ELF_C_READ_MMAP
101
1.10k
        || (! ALLOW_UNALIGNED
102
1.10k
      && ((uintptr_t) file_shdr
103
1.10k
          & (__alignof__ (ElfW2(LIBELFBITS,Shdr)) - 1)) != 0));
104
105
      /* Now copy the data and at the same time convert the byte order.  */
106
1.10k
      if (ehdr->e_ident[EI_DATA] == MY_ELFDATA)
107
0
  {
108
0
    assert ((elf->flags & ELF_F_MALLOCED)
109
0
      || elf->cmd == ELF_C_READ_MMAP
110
0
      || ! ALLOW_UNALIGNED);
111
0
    memcpy (shdr, file_shdr, size);
112
0
  }
113
1.10k
      else
114
1.10k
  {
115
1.10k
    bool copy = ! (ALLOW_UNALIGNED
116
0
       || ((uintptr_t) file_shdr
117
0
           & (__alignof__ (ElfW2(LIBELFBITS,Shdr)) - 1))
118
0
           == 0);
119
1.10k
    if (! copy)
120
1.10k
      notcvt = (ElfW2(LIBELFBITS,Shdr) *)
121
1.10k
        ((char *) elf->map_address
122
1.10k
         + elf->start_offset + ehdr->e_shoff);
123
0
    else
124
0
      {
125
0
        notcvt = (ElfW2(LIBELFBITS,Shdr) *) malloc (size);
126
0
        if (unlikely (notcvt == NULL))
127
0
    {
128
0
      __libelf_seterrno (ELF_E_NOMEM);
129
0
      goto free_and_out;
130
0
    }
131
0
        memcpy (notcvt, ((char *) elf->map_address
132
0
             + elf->start_offset + ehdr->e_shoff),
133
0
          size);
134
0
      }
135
136
520k
    for (size_t cnt = 0; cnt < shnum; ++cnt)
137
519k
      {
138
519k
        CONVERT_TO (shdr[cnt].sh_name, notcvt[cnt].sh_name);
139
519k
        CONVERT_TO (shdr[cnt].sh_type, notcvt[cnt].sh_type);
140
519k
        CONVERT_TO (shdr[cnt].sh_flags, notcvt[cnt].sh_flags);
141
519k
        CONVERT_TO (shdr[cnt].sh_addr, notcvt[cnt].sh_addr);
142
519k
        CONVERT_TO (shdr[cnt].sh_offset, notcvt[cnt].sh_offset);
143
519k
        CONVERT_TO (shdr[cnt].sh_size, notcvt[cnt].sh_size);
144
519k
        CONVERT_TO (shdr[cnt].sh_link, notcvt[cnt].sh_link);
145
519k
        CONVERT_TO (shdr[cnt].sh_info, notcvt[cnt].sh_info);
146
519k
        CONVERT_TO (shdr[cnt].sh_addralign,
147
519k
        notcvt[cnt].sh_addralign);
148
519k
        CONVERT_TO (shdr[cnt].sh_entsize, notcvt[cnt].sh_entsize);
149
519k
      }
150
151
1.10k
    if (copy)
152
0
      free (notcvt);
153
1.10k
  }
154
1.10k
    }
155
0
  else if (likely (elf->fildes != -1))
156
0
    {
157
      /* Read the header.  */
158
0
      ssize_t n = pread_retry (elf->fildes,
159
0
             elf->state.ELFW(elf,LIBELFBITS).shdr, size,
160
0
             elf->start_offset + ehdr->e_shoff);
161
0
      if (unlikely ((size_t) n != size))
162
0
  {
163
    /* Severe problems.  We cannot read the data.  */
164
0
    __libelf_seterrno (ELF_E_READ_ERROR);
165
0
    goto free_and_out;
166
0
  }
167
168
      /* If the byte order of the file is not the same as the one
169
   of the host convert the data now.  */
170
0
      if (ehdr->e_ident[EI_DATA] != MY_ELFDATA)
171
0
  for (size_t cnt = 0; cnt < shnum; ++cnt)
172
0
    {
173
0
      CONVERT (shdr[cnt].sh_name);
174
0
      CONVERT (shdr[cnt].sh_type);
175
0
      CONVERT (shdr[cnt].sh_flags);
176
0
      CONVERT (shdr[cnt].sh_addr);
177
0
      CONVERT (shdr[cnt].sh_offset);
178
0
      CONVERT (shdr[cnt].sh_size);
179
0
      CONVERT (shdr[cnt].sh_link);
180
0
      CONVERT (shdr[cnt].sh_info);
181
0
      CONVERT (shdr[cnt].sh_addralign);
182
0
      CONVERT (shdr[cnt].sh_entsize);
183
0
    }
184
0
    }
185
0
  else
186
0
    {
187
      /* The file descriptor was already enabled and not all data was
188
   read.  Undo the allocation.  */
189
0
      __libelf_seterrno (ELF_E_FD_DISABLED);
190
191
0
    free_and_out:
192
0
      free (shdr);
193
0
      elf->state.ELFW(elf,LIBELFBITS).shdr = NULL;
194
0
      elf->state.ELFW(elf,LIBELFBITS).shdr_malloced = 0;
195
196
0
      goto out;
197
0
    }
198
199
  /* Set the pointers in the `scn's.  */
200
520k
  for (size_t cnt = 0; cnt < shnum; ++cnt)
201
519k
    elf->state.ELFW(elf,LIBELFBITS).scns.data[cnt].shdr.ELFW(e,LIBELFBITS)
202
519k
      = &elf->state.ELFW(elf,LIBELFBITS).shdr[cnt];
203
204
1.10k
  result = scn->shdr.ELFW(e,LIBELFBITS);
205
1.10k
  assert (result != NULL);
206
207
1.10k
out:
208
1.10k
  return result;
209
1.10k
}
elf64_getshdr.c:load_shdr_wrlock
Line
Count
Source
48
1.14k
{
49
1.14k
  ElfW2(LIBELFBITS,Shdr) *result;
50
51
  /* Read the section header table.  */
52
1.14k
  Elf *elf = scn->elf;
53
1.14k
  ElfW2(LIBELFBITS,Ehdr) *ehdr = elf->state.ELFW(elf,LIBELFBITS).ehdr;
54
55
  /* Try again, maybe the data is there now.  */
56
1.14k
  result = scn->shdr.ELFW(e,LIBELFBITS);
57
1.14k
  if (result != NULL)
58
0
    goto out;
59
60
1.14k
  size_t shnum;
61
1.14k
  if (__elf_getshdrnum_rdlock (elf, &shnum) != 0
62
1.14k
      || shnum > SIZE_MAX / sizeof (ElfW2(LIBELFBITS,Shdr)))
63
0
    goto out;
64
1.14k
  size_t size = shnum * sizeof (ElfW2(LIBELFBITS,Shdr));
65
66
  /* Allocate memory for the section headers.  We know the number
67
     of entries from the ELF header.  */
68
1.14k
  ElfW2(LIBELFBITS,Shdr) *shdr = elf->state.ELFW(elf,LIBELFBITS).shdr =
69
1.14k
    (ElfW2(LIBELFBITS,Shdr) *) malloc (size);
70
1.14k
  if (elf->state.ELFW(elf,LIBELFBITS).shdr == NULL)
71
0
    {
72
0
      __libelf_seterrno (ELF_E_NOMEM);
73
0
      goto out;
74
0
    }
75
1.14k
  elf->state.ELFW(elf,LIBELFBITS).shdr_malloced = 1;
76
77
1.14k
  if (elf->map_address != NULL)
78
1.14k
    {
79
      /* First see whether the information in the ELF header is
80
   valid and it does not ask for too much.  */
81
1.14k
      if (unlikely (ehdr->e_shoff >= elf->maximum_size)
82
1.14k
    || unlikely (elf->maximum_size - ehdr->e_shoff < size))
83
0
  {
84
    /* Something is wrong.  */
85
0
    __libelf_seterrno (ELF_E_INVALID_SECTION_HEADER);
86
0
    goto free_and_out;
87
0
  }
88
89
1.14k
      ElfW2(LIBELFBITS,Shdr) *notcvt;
90
91
      /* All the data is already mapped.  If we could use it
92
   directly this would already have happened.  Unless
93
   we allocated the memory ourselves and the ELF_F_MALLOCED
94
   flag is set.  */
95
1.14k
      void *file_shdr = ((char *) elf->map_address
96
1.14k
       + elf->start_offset + ehdr->e_shoff);
97
98
1.14k
      assert ((elf->flags & ELF_F_MALLOCED)
99
1.14k
        || ehdr->e_ident[EI_DATA] != MY_ELFDATA
100
1.14k
        || elf->cmd == ELF_C_READ_MMAP
101
1.14k
        || (! ALLOW_UNALIGNED
102
1.14k
      && ((uintptr_t) file_shdr
103
1.14k
          & (__alignof__ (ElfW2(LIBELFBITS,Shdr)) - 1)) != 0));
104
105
      /* Now copy the data and at the same time convert the byte order.  */
106
1.14k
      if (ehdr->e_ident[EI_DATA] == MY_ELFDATA)
107
0
  {
108
0
    assert ((elf->flags & ELF_F_MALLOCED)
109
0
      || elf->cmd == ELF_C_READ_MMAP
110
0
      || ! ALLOW_UNALIGNED);
111
0
    memcpy (shdr, file_shdr, size);
112
0
  }
113
1.14k
      else
114
1.14k
  {
115
1.14k
    bool copy = ! (ALLOW_UNALIGNED
116
0
       || ((uintptr_t) file_shdr
117
0
           & (__alignof__ (ElfW2(LIBELFBITS,Shdr)) - 1))
118
0
           == 0);
119
1.14k
    if (! copy)
120
1.14k
      notcvt = (ElfW2(LIBELFBITS,Shdr) *)
121
1.14k
        ((char *) elf->map_address
122
1.14k
         + elf->start_offset + ehdr->e_shoff);
123
0
    else
124
0
      {
125
0
        notcvt = (ElfW2(LIBELFBITS,Shdr) *) malloc (size);
126
0
        if (unlikely (notcvt == NULL))
127
0
    {
128
0
      __libelf_seterrno (ELF_E_NOMEM);
129
0
      goto free_and_out;
130
0
    }
131
0
        memcpy (notcvt, ((char *) elf->map_address
132
0
             + elf->start_offset + ehdr->e_shoff),
133
0
          size);
134
0
      }
135
136
1.38M
    for (size_t cnt = 0; cnt < shnum; ++cnt)
137
1.37M
      {
138
1.37M
        CONVERT_TO (shdr[cnt].sh_name, notcvt[cnt].sh_name);
139
1.37M
        CONVERT_TO (shdr[cnt].sh_type, notcvt[cnt].sh_type);
140
1.37M
        CONVERT_TO (shdr[cnt].sh_flags, notcvt[cnt].sh_flags);
141
1.37M
        CONVERT_TO (shdr[cnt].sh_addr, notcvt[cnt].sh_addr);
142
1.37M
        CONVERT_TO (shdr[cnt].sh_offset, notcvt[cnt].sh_offset);
143
1.37M
        CONVERT_TO (shdr[cnt].sh_size, notcvt[cnt].sh_size);
144
1.37M
        CONVERT_TO (shdr[cnt].sh_link, notcvt[cnt].sh_link);
145
1.37M
        CONVERT_TO (shdr[cnt].sh_info, notcvt[cnt].sh_info);
146
1.37M
        CONVERT_TO (shdr[cnt].sh_addralign,
147
1.37M
        notcvt[cnt].sh_addralign);
148
1.37M
        CONVERT_TO (shdr[cnt].sh_entsize, notcvt[cnt].sh_entsize);
149
1.37M
      }
150
151
1.14k
    if (copy)
152
0
      free (notcvt);
153
1.14k
  }
154
1.14k
    }
155
0
  else if (likely (elf->fildes != -1))
156
0
    {
157
      /* Read the header.  */
158
0
      ssize_t n = pread_retry (elf->fildes,
159
0
             elf->state.ELFW(elf,LIBELFBITS).shdr, size,
160
0
             elf->start_offset + ehdr->e_shoff);
161
0
      if (unlikely ((size_t) n != size))
162
0
  {
163
    /* Severe problems.  We cannot read the data.  */
164
0
    __libelf_seterrno (ELF_E_READ_ERROR);
165
0
    goto free_and_out;
166
0
  }
167
168
      /* If the byte order of the file is not the same as the one
169
   of the host convert the data now.  */
170
0
      if (ehdr->e_ident[EI_DATA] != MY_ELFDATA)
171
0
  for (size_t cnt = 0; cnt < shnum; ++cnt)
172
0
    {
173
0
      CONVERT (shdr[cnt].sh_name);
174
0
      CONVERT (shdr[cnt].sh_type);
175
0
      CONVERT (shdr[cnt].sh_flags);
176
0
      CONVERT (shdr[cnt].sh_addr);
177
0
      CONVERT (shdr[cnt].sh_offset);
178
0
      CONVERT (shdr[cnt].sh_size);
179
0
      CONVERT (shdr[cnt].sh_link);
180
0
      CONVERT (shdr[cnt].sh_info);
181
0
      CONVERT (shdr[cnt].sh_addralign);
182
0
      CONVERT (shdr[cnt].sh_entsize);
183
0
    }
184
0
    }
185
0
  else
186
0
    {
187
      /* The file descriptor was already enabled and not all data was
188
   read.  Undo the allocation.  */
189
0
      __libelf_seterrno (ELF_E_FD_DISABLED);
190
191
0
    free_and_out:
192
0
      free (shdr);
193
0
      elf->state.ELFW(elf,LIBELFBITS).shdr = NULL;
194
0
      elf->state.ELFW(elf,LIBELFBITS).shdr_malloced = 0;
195
196
0
      goto out;
197
0
    }
198
199
  /* Set the pointers in the `scn's.  */
200
1.38M
  for (size_t cnt = 0; cnt < shnum; ++cnt)
201
1.37M
    elf->state.ELFW(elf,LIBELFBITS).scns.data[cnt].shdr.ELFW(e,LIBELFBITS)
202
1.37M
      = &elf->state.ELFW(elf,LIBELFBITS).shdr[cnt];
203
204
1.14k
  result = scn->shdr.ELFW(e,LIBELFBITS);
205
1.14k
  assert (result != NULL);
206
207
1.14k
out:
208
1.14k
  return result;
209
1.14k
}
210
211
static bool
212
scn_valid (Elf_Scn *scn)
213
843k
{
214
843k
  if (scn == NULL)
215
0
    return false;
216
217
843k
  if (unlikely (scn->elf->state.elf.ehdr == NULL))
218
0
    {
219
0
      __libelf_seterrno (ELF_E_WRONG_ORDER_EHDR);
220
0
      return false;
221
0
    }
222
223
843k
  if (unlikely (scn->elf->class != ELFW(ELFCLASS,LIBELFBITS)))
224
0
    {
225
0
      __libelf_seterrno (ELF_E_INVALID_CLASS);
226
0
      return false;
227
0
    }
228
229
843k
  return true;
230
843k
}
elf32_getshdr.c:scn_valid
Line
Count
Source
213
678k
{
214
678k
  if (scn == NULL)
215
0
    return false;
216
217
678k
  if (unlikely (scn->elf->state.elf.ehdr == NULL))
218
0
    {
219
0
      __libelf_seterrno (ELF_E_WRONG_ORDER_EHDR);
220
0
      return false;
221
0
    }
222
223
678k
  if (unlikely (scn->elf->class != ELFW(ELFCLASS,LIBELFBITS)))
224
0
    {
225
0
      __libelf_seterrno (ELF_E_INVALID_CLASS);
226
0
      return false;
227
0
    }
228
229
678k
  return true;
230
678k
}
elf64_getshdr.c:scn_valid
Line
Count
Source
213
164k
{
214
164k
  if (scn == NULL)
215
0
    return false;
216
217
164k
  if (unlikely (scn->elf->state.elf.ehdr == NULL))
218
0
    {
219
0
      __libelf_seterrno (ELF_E_WRONG_ORDER_EHDR);
220
0
      return false;
221
0
    }
222
223
164k
  if (unlikely (scn->elf->class != ELFW(ELFCLASS,LIBELFBITS)))
224
0
    {
225
0
      __libelf_seterrno (ELF_E_INVALID_CLASS);
226
0
      return false;
227
0
    }
228
229
164k
  return true;
230
164k
}
231
232
ElfW2(LIBELFBITS,Shdr) *
233
internal_function
234
__elfw2(LIBELFBITS,getshdr_rdlock) (Elf_Scn *scn)
235
422k
{
236
422k
  ElfW2(LIBELFBITS,Shdr) *result;
237
238
422k
  if (!scn_valid (scn))
239
0
    return NULL;
240
241
422k
  result = scn->shdr.ELFW(e,LIBELFBITS);
242
422k
  if (result == NULL)
243
2.25k
    {
244
2.25k
      rwlock_unlock (scn->elf->lock);
245
2.25k
      rwlock_wrlock (scn->elf->lock);
246
2.25k
      result = scn->shdr.ELFW(e,LIBELFBITS);
247
2.25k
      if (result == NULL)
248
2.25k
  result = load_shdr_wrlock (scn);
249
2.25k
    }
250
251
422k
  return result;
252
422k
}
__elf32_getshdr_rdlock
Line
Count
Source
235
340k
{
236
340k
  ElfW2(LIBELFBITS,Shdr) *result;
237
238
340k
  if (!scn_valid (scn))
239
0
    return NULL;
240
241
340k
  result = scn->shdr.ELFW(e,LIBELFBITS);
242
340k
  if (result == NULL)
243
1.10k
    {
244
1.10k
      rwlock_unlock (scn->elf->lock);
245
1.10k
      rwlock_wrlock (scn->elf->lock);
246
1.10k
      result = scn->shdr.ELFW(e,LIBELFBITS);
247
1.10k
      if (result == NULL)
248
1.10k
  result = load_shdr_wrlock (scn);
249
1.10k
    }
250
251
340k
  return result;
252
340k
}
__elf64_getshdr_rdlock
Line
Count
Source
235
82.9k
{
236
82.9k
  ElfW2(LIBELFBITS,Shdr) *result;
237
238
82.9k
  if (!scn_valid (scn))
239
0
    return NULL;
240
241
82.9k
  result = scn->shdr.ELFW(e,LIBELFBITS);
242
82.9k
  if (result == NULL)
243
1.14k
    {
244
1.14k
      rwlock_unlock (scn->elf->lock);
245
1.14k
      rwlock_wrlock (scn->elf->lock);
246
1.14k
      result = scn->shdr.ELFW(e,LIBELFBITS);
247
1.14k
      if (result == NULL)
248
1.14k
  result = load_shdr_wrlock (scn);
249
1.14k
    }
250
251
82.9k
  return result;
252
82.9k
}
253
254
ElfW2(LIBELFBITS,Shdr) *
255
internal_function
256
__elfw2(LIBELFBITS,getshdr_wrlock) (Elf_Scn *scn)
257
0
{
258
0
  ElfW2(LIBELFBITS,Shdr) *result;
259
260
0
  if (!scn_valid (scn))
261
0
    return NULL;
262
263
0
  result = scn->shdr.ELFW(e,LIBELFBITS);
264
0
  if (result == NULL)
265
0
    result = load_shdr_wrlock (scn);
266
267
0
  return result;
268
0
}
Unexecuted instantiation: __elf32_getshdr_wrlock
Unexecuted instantiation: __elf64_getshdr_wrlock
269
270
ElfW2(LIBELFBITS,Shdr) *
271
elfw2(LIBELFBITS,getshdr) (Elf_Scn *scn)
272
420k
{
273
420k
  ElfW2(LIBELFBITS,Shdr) *result;
274
275
420k
  if (!scn_valid (scn))
276
0
    return NULL;
277
278
420k
  rwlock_rdlock (scn->elf->lock);
279
420k
  result = __elfw2(LIBELFBITS,getshdr_rdlock) (scn);
280
420k
  rwlock_unlock (scn->elf->lock);
281
282
420k
  return result;
283
420k
}
elf32_getshdr
Line
Count
Source
272
338k
{
273
338k
  ElfW2(LIBELFBITS,Shdr) *result;
274
275
338k
  if (!scn_valid (scn))
276
0
    return NULL;
277
278
338k
  rwlock_rdlock (scn->elf->lock);
279
338k
  result = __elfw2(LIBELFBITS,getshdr_rdlock) (scn);
280
338k
  rwlock_unlock (scn->elf->lock);
281
282
338k
  return result;
283
338k
}
elf64_getshdr
Line
Count
Source
272
81.8k
{
273
81.8k
  ElfW2(LIBELFBITS,Shdr) *result;
274
275
81.8k
  if (!scn_valid (scn))
276
0
    return NULL;
277
278
81.8k
  rwlock_rdlock (scn->elf->lock);
279
81.8k
  result = __elfw2(LIBELFBITS,getshdr_rdlock) (scn);
280
81.8k
  rwlock_unlock (scn->elf->lock);
281
282
81.8k
  return result;
283
81.8k
}