Coverage Report

Created: 2025-11-24 06:43

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/elfutils/libelf/elf_readall.c
Line
Count
Source
1
/* Read all of the file associated with the descriptor.
2
   Copyright (C) 1998-2009, 2015 Red Hat, Inc.
3
   This file is part of elfutils.
4
   Contributed 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 <errno.h>
35
#include <sys/stat.h>
36
37
#include "libelfP.h"
38
#include "common.h"
39
40
41
static void
42
set_address (Elf *elf, size_t offset)
43
6.11k
{
44
6.11k
  if (elf->kind == ELF_K_AR)
45
1
    {
46
1
      Elf *child = elf->state.ar.children;
47
48
1
      while (child != NULL)
49
0
  {
50
0
    if (child->map_address == NULL)
51
0
      {
52
0
        child->map_address = elf->map_address;
53
0
        child->start_offset -= offset;
54
0
        if (child->kind == ELF_K_AR)
55
0
    child->state.ar.offset -= offset;
56
57
0
        set_address (child, offset);
58
0
      }
59
60
0
    child = child->next;
61
0
  }
62
1
    }
63
6.11k
}
64
65
66
char *
67
internal_function
68
__libelf_readall (Elf *elf)
69
6.11k
{
70
  /* Get the file.  */
71
6.11k
  rwlock_wrlock (elf->lock);
72
73
6.11k
  if (elf->map_address == NULL && unlikely (elf->fildes == -1))
74
0
    {
75
0
      __libelf_seterrno (ELF_E_INVALID_HANDLE);
76
0
      rwlock_unlock (elf->lock);
77
0
      return NULL;
78
0
    }
79
80
  /* If the file is not mmap'ed and not previously loaded, do it now.  */
81
6.11k
  if (elf->map_address == NULL)
82
6.11k
    {
83
6.11k
      char *mem = NULL;
84
85
      /* If this is an archive and we have derived descriptors get the
86
   locks for all of them.  */
87
6.11k
      libelf_acquire_all_children (elf);
88
89
6.11k
      if (elf->maximum_size == ~((size_t) 0))
90
0
  {
91
    /* We don't yet know how large the file is.   Determine that now.  */
92
0
    struct stat st;
93
94
0
    if (fstat (elf->fildes, &st) < 0)
95
0
      goto read_error;
96
97
0
    if (sizeof (size_t) >= sizeof (st.st_size)
98
0
        || st.st_size <= ~((size_t) 0))
99
0
      elf->maximum_size = (size_t) st.st_size;
100
0
    else
101
0
      {
102
0
        errno = EOVERFLOW;
103
0
        goto read_error;
104
0
      }
105
0
  }
106
107
      /* Allocate all the memory we need.  */
108
6.11k
      mem = malloc (elf->maximum_size);
109
6.11k
      if (mem != NULL)
110
6.11k
  {
111
    /* Read the file content.  */
112
6.11k
    if (unlikely ((size_t) pread_retry (elf->fildes, mem,
113
6.11k
                elf->maximum_size,
114
6.11k
                elf->start_offset)
115
6.11k
      != elf->maximum_size))
116
0
      {
117
        /* Something went wrong.  */
118
0
      read_error:
119
0
        __libelf_seterrno (ELF_E_READ_ERROR);
120
0
        free (mem);
121
0
      }
122
6.11k
    else
123
6.11k
      {
124
        /* Remember the address.  */
125
6.11k
        elf->map_address = mem;
126
127
        /* Also remember that we allocated the memory.  */
128
6.11k
        elf->flags |= ELF_F_MALLOCED;
129
130
        /* Propagate the information down to all children and
131
     their children.  */
132
6.11k
        set_address (elf, elf->start_offset);
133
134
        /* Correct the own offsets.  */
135
6.11k
        if (elf->kind == ELF_K_AR)
136
1
    elf->state.ar.offset -= elf->start_offset;
137
6.11k
        elf->start_offset = 0;
138
6.11k
      }
139
6.11k
  }
140
0
      else
141
0
  __libelf_seterrno (ELF_E_NOMEM);
142
143
      /* Free the locks on the children.  */
144
6.11k
      libelf_release_all_children (elf);
145
6.11k
    }
146
147
6.11k
  rwlock_unlock (elf->lock);
148
149
6.11k
  return (char *) elf->map_address;
150
6.11k
}