blob: d36da270ffc1f5fce4ae54de1d707731b228bca0 [file] [log] [blame]
Ulrich Drepperb08d5a82005-07-26 05:00:05 +00001/* 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
28static void
29set_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
53char *
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}