1 /* Read all of the file associated with the descriptor.
2 Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
3 Contributed by Ulrich Drepper <drepper@redhat.com>, 1998.
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, version 2.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software Foundation,
16 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
17
18 #ifdef HAVE_CONFIG_H
19 # include <config.h>
20 #endif
21
22 #include <unistd.h>
23
24 #include "libelfP.h"
25 #include "common.h"
26
27
28 static void
set_address(Elf * elf,size_t offset)29 set_address (Elf *elf, size_t offset)
30 {
31 if (elf->kind == ELF_K_AR)
32 {
33 Elf *child = elf->state.ar.children;
34
35 while (child != NULL)
36 {
37 if (child->map_address == NULL)
38 {
39 child->map_address = elf->map_address;
40 child->start_offset -= offset;
41 if (child->kind == ELF_K_AR)
42 child->state.ar.offset -= offset;
43
44 set_address (child, offset);
45 }
46
47 child = child->next;
48 }
49 }
50 }
51
52
53 char *
__libelf_readall(elf)54 __libelf_readall (elf)
55 Elf *elf;
56 {
57 /* Get the file. */
58 rwlock_wrlock (elf->lock);
59
60 if (elf->map_address == NULL && unlikely (elf->fildes == -1))
61 {
62 __libelf_seterrno (ELF_E_INVALID_HANDLE);
63 rwlock_unlock (elf->lock);
64 return NULL;
65 }
66
67 /* If the file is not mmap'ed and not previously loaded, do it now. */
68 if (elf->map_address == NULL)
69 {
70 char *mem;
71
72 /* If this is an archive and we have derived descriptors get the
73 locks for all of them. */
74 libelf_acquire_all (elf);
75
76 /* Allocate all the memory we need. */
77 mem = (char *) malloc (elf->maximum_size);
78 if (mem != NULL)
79 {
80 /* Read the file content. */
81 if ((size_t) pread (elf->fildes, mem, elf->maximum_size,
82 elf->start_offset) != elf->maximum_size)
83 {
84 /* Something went wrong. */
85 __libelf_seterrno (ELF_E_READ_ERROR);
86 free (mem);
87 }
88 else
89 {
90 /* Remember the address. */
91 elf->map_address = mem;
92
93 /* Also remember that we allocated the memory. */
94 elf->flags |= ELF_F_MALLOCED;
95
96 /* Propagate the information down to all children and
97 their children. */
98 set_address (elf, elf->start_offset);
99
100 /* Correct the own offsets. */
101 if (elf->kind == ELF_K_AR)
102 elf->state.ar.offset -= elf->start_offset;
103 elf->start_offset = 0;
104 }
105 }
106 else
107 __libelf_seterrno (ELF_E_NOMEM);
108
109 /* Free the locks on the children. */
110 libelf_release_all (elf);
111 }
112
113 rwlock_unlock (elf->lock);
114
115 return (char *) elf->map_address;
116 }
117