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 (at) 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 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 * 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