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 : 1 : set_address (Elf *elf, size_t offset) 43 : : { 44 [ - + ]: 1 : 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 : 1 : } 64 : : 65 : : 66 : : char * 67 : : internal_function 68 : 1 : __libelf_readall (Elf *elf) 69 : : { 70 : : /* Get the file. */ 71 : 1 : rwlock_wrlock (elf->lock); 72 : : 73 [ + - - + ]: 1 : 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 [ + - ]: 1 : if (elf->map_address == NULL) 82 : : { 83 : 1 : char *mem = NULL; 84 : : 85 : : /* If this is an archive and we have derived descriptors get the 86 : : locks for all of them. */ 87 : 1 : libelf_acquire_all (elf); 88 : : 89 [ - + ]: 1 : 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 : 1 : mem = malloc (elf->maximum_size); 109 [ + - ]: 1 : if (mem != NULL) 110 : : { 111 : : /* Read the file content. */ 112 [ - + ]: 1 : 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 : 1 : elf->map_address = mem; 126 : : 127 : : /* Also remember that we allocated the memory. */ 128 : 1 : elf->flags |= ELF_F_MALLOCED; 129 : : 130 : : /* Propagate the information down to all children and 131 : : their children. */ 132 : 1 : set_address (elf, elf->start_offset); 133 : : 134 : : /* Correct the own offsets. */ 135 [ - + ]: 1 : if (elf->kind == ELF_K_AR) 136 : 0 : elf->state.ar.offset -= elf->start_offset; 137 : 1 : elf->start_offset = 0; 138 : : } 139 : : } 140 : : else 141 : 0 : __libelf_seterrno (ELF_E_NOMEM); 142 : : 143 : : /* Free the locks on the children. */ 144 : 1 : libelf_release_all (elf); 145 : : } 146 : : 147 : 1 : rwlock_unlock (elf->lock); 148 : : 149 : 1 : return (char *) elf->map_address; 150 : : }