Branch data Line data Source code
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 : 2 : set_address (Elf *elf, size_t offset)
43 : : {
44 [ - + ]: 2 : if (elf->kind == ELF_K_AR)
45 : : {
46 : 0 : Elf *child = elf->state.ar.children;
47 : :
48 [ # # ]: 0 : while (child != NULL)
49 : : {
50 [ # # ]: 0 : if (child->map_address == NULL)
51 : : {
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 : : }
59 : :
60 : 0 : child = child->next;
61 : : }
62 : : }
63 : 2 : }
64 : :
65 : :
66 : : char *
67 : : internal_function
68 : 1418 : __libelf_readall (Elf *elf)
69 : : {
70 : : /* Get the file. */
71 : 1418 : rwlock_wrlock (elf->lock);
72 : :
73 [ + + - + ]: 1418 : if (elf->map_address == NULL && unlikely (elf->fildes == -1))
74 : : {
75 : 0 : __libelf_seterrno (ELF_E_INVALID_HANDLE);
76 : 0 : rwlock_unlock (elf->lock);
77 : 0 : return NULL;
78 : : }
79 : :
80 : : /* If the file is not mmap'ed and not previously loaded, do it now. */
81 [ + + ]: 1418 : if (elf->map_address == NULL)
82 : : {
83 : 2 : char *mem = NULL;
84 : :
85 : : /* If this is an archive and we have derived descriptors get the
86 : : locks for all of them. */
87 : 2 : libelf_acquire_all_children (elf);
88 : :
89 [ - + ]: 2 : if (elf->maximum_size == ~((size_t) 0))
90 : : {
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 : : || st.st_size <= ~((size_t) 0))
99 : 0 : elf->maximum_size = (size_t) st.st_size;
100 : : else
101 : : {
102 : : errno = EOVERFLOW;
103 : : goto read_error;
104 : : }
105 : : }
106 : :
107 : : /* Allocate all the memory we need. */
108 : 2 : mem = malloc (elf->maximum_size);
109 [ + - ]: 2 : if (mem != NULL)
110 : : {
111 : : /* Read the file content. */
112 [ - + ]: 2 : if (unlikely ((size_t) pread_retry (elf->fildes, mem,
113 : : elf->maximum_size,
114 : : elf->start_offset)
115 : : != elf->maximum_size))
116 : : {
117 : : /* Something went wrong. */
118 : 0 : read_error:
119 : 0 : __libelf_seterrno (ELF_E_READ_ERROR);
120 : 0 : free (mem);
121 : : }
122 : : else
123 : : {
124 : : /* Remember the address. */
125 : 2 : elf->map_address = mem;
126 : :
127 : : /* Also remember that we allocated the memory. */
128 : 2 : elf->flags |= ELF_F_MALLOCED;
129 : :
130 : : /* Propagate the information down to all children and
131 : : their children. */
132 : 2 : set_address (elf, elf->start_offset);
133 : :
134 : : /* Correct the own offsets. */
135 [ - + ]: 2 : if (elf->kind == ELF_K_AR)
136 : 0 : elf->state.ar.offset -= elf->start_offset;
137 : 2 : elf->start_offset = 0;
138 : : }
139 : : }
140 : : else
141 : 0 : __libelf_seterrno (ELF_E_NOMEM);
142 : :
143 : : /* Free the locks on the children. */
144 : 2 : libelf_release_all_children (elf);
145 : : }
146 : :
147 : 1418 : rwlock_unlock (elf->lock);
148 : :
149 : 1418 : return (char *) elf->map_address;
150 : : }
|