elf_begin.c revision 237188e4d764598300a577e08fd872339812fb2c
1b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Create descriptor for processing file. 2720383c53b435de6647edd78060dd7d38ade25a5Jakub Jelinek Copyright (C) 1998-2010, 2012, 2014 Red Hat, Inc. 3de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard This file is part of elfutils. 4b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Written by Ulrich Drepper <drepper@redhat.com>, 1998. 5b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 6de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard This file is free software; you can redistribute it and/or modify 7de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard it under the terms of either 8b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 9de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard * the GNU Lesser General Public License as published by the Free 10de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard Software Foundation; either version 3 of the License, or (at 11de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard your option) any later version 12de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard 13de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard or 14de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard 15de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard * the GNU General Public License as published by the Free 16de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard Software Foundation; either version 2 of the License, or (at 17de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard your option) any later version 18de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard 19de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard or both in parallel, as here. 20de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard 21de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard elfutils is distributed in the hope that it will be useful, but 22361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper WITHOUT ANY WARRANTY; without even the implied warranty of 23361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 24361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper General Public License for more details. 25b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 26de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard You should have received copies of the GNU General Public License and 27de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard the GNU Lesser General Public License along with this program. If 28de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard not, see <http://www.gnu.org/licenses/>. */ 29b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 30b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#ifdef HAVE_CONFIG_H 31b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper# include <config.h> 32b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#endif 33b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 34b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <assert.h> 35b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <ctype.h> 36b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <errno.h> 37b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <fcntl.h> 38b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <stdbool.h> 39b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <stddef.h> 40b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <string.h> 41b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <unistd.h> 42b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <sys/mman.h> 43b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <sys/param.h> 44b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <sys/stat.h> 45b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 46fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper#include <system.h> 47b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include "libelfP.h" 48b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include "common.h" 49b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 50b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 51b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Create descriptor for archive in memory. */ 52b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic inline Elf * 53b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperfile_read_ar (int fildes, void *map_address, off_t offset, size_t maxsize, 54b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf_Cmd cmd, Elf *parent) 55b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 56b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf *elf; 57b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 58b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Create a descriptor. */ 59b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper elf = allocate_elf (fildes, map_address, offset, maxsize, cmd, parent, 60b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ELF_K_AR, 0); 61b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (elf != NULL) 62b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 63b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* We don't read all the symbol tables in advance. All this will 64b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper happen on demand. */ 65b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper elf->state.ar.offset = offset + SARMAG; 66b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 67b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper elf->state.ar.elf_ar_hdr.ar_rawname = elf->state.ar.raw_name; 68b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 69b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 70b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return elf; 71b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 72b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 73b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 74b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic size_t 75b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperget_shnum (void *map_address, unsigned char *e_ident, int fildes, off_t offset, 76b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size_t maxsize) 77b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 78b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size_t result; 79b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper union 80b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 81b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf32_Ehdr *e32; 82b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf64_Ehdr *e64; 83b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper void *p; 84b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } ehdr; 850f6abbbc08ee259a1a702e7dd3be3e2c6b82305eUlrich Drepper union 860f6abbbc08ee259a1a702e7dd3be3e2c6b82305eUlrich Drepper { 870f6abbbc08ee259a1a702e7dd3be3e2c6b82305eUlrich Drepper Elf32_Ehdr e32; 880f6abbbc08ee259a1a702e7dd3be3e2c6b82305eUlrich Drepper Elf64_Ehdr e64; 890f6abbbc08ee259a1a702e7dd3be3e2c6b82305eUlrich Drepper } ehdr_mem; 90b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper bool is32 = e_ident[EI_CLASS] == ELFCLASS32; 91b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 92b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Make the ELF header available. */ 939cf28e4f899f97ecdc983a0af8e2be62f3d69058Roland McGrath if (e_ident[EI_DATA] == MY_ELFDATA 949cf28e4f899f97ecdc983a0af8e2be62f3d69058Roland McGrath && (ALLOW_UNALIGNED 959cf28e4f899f97ecdc983a0af8e2be62f3d69058Roland McGrath || (((size_t) e_ident 969cf28e4f899f97ecdc983a0af8e2be62f3d69058Roland McGrath & ((is32 ? __alignof__ (Elf32_Ehdr) : __alignof__ (Elf64_Ehdr)) 979cf28e4f899f97ecdc983a0af8e2be62f3d69058Roland McGrath - 1)) == 0))) 98fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper ehdr.p = e_ident; 99b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 100b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 101fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper /* We already read the ELF header. We have to copy the header 102fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper since we possibly modify the data here and the caller 103fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper expects the memory it passes in to be preserved. */ 104fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper ehdr.p = &ehdr_mem; 105b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 106fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper if (is32) 107b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 108fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper if (ALLOW_UNALIGNED) 109969bda4a47575b33af814c62ea876b0bbf8c5713Ulrich Drepper { 110fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper ehdr_mem.e32.e_shnum = ((Elf32_Ehdr *) e_ident)->e_shnum; 111fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper ehdr_mem.e32.e_shoff = ((Elf32_Ehdr *) e_ident)->e_shoff; 112969bda4a47575b33af814c62ea876b0bbf8c5713Ulrich Drepper } 113969bda4a47575b33af814c62ea876b0bbf8c5713Ulrich Drepper else 114fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper memcpy (&ehdr_mem, e_ident, sizeof (Elf32_Ehdr)); 115fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper 1169cf28e4f899f97ecdc983a0af8e2be62f3d69058Roland McGrath if (e_ident[EI_DATA] != MY_ELFDATA) 1179cf28e4f899f97ecdc983a0af8e2be62f3d69058Roland McGrath { 1189cf28e4f899f97ecdc983a0af8e2be62f3d69058Roland McGrath CONVERT (ehdr_mem.e32.e_shnum); 1199cf28e4f899f97ecdc983a0af8e2be62f3d69058Roland McGrath CONVERT (ehdr_mem.e32.e_shoff); 1209cf28e4f899f97ecdc983a0af8e2be62f3d69058Roland McGrath } 121fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper } 122fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper else 123fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper { 124fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper if (ALLOW_UNALIGNED) 1254c305da9de0ecfe9af64cb6787b2b4b8a6aa8dd5Roland McGrath { 126fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper ehdr_mem.e64.e_shnum = ((Elf64_Ehdr *) e_ident)->e_shnum; 127fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper ehdr_mem.e64.e_shoff = ((Elf64_Ehdr *) e_ident)->e_shoff; 1284c305da9de0ecfe9af64cb6787b2b4b8a6aa8dd5Roland McGrath } 129fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper else 130fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper memcpy (&ehdr_mem, e_ident, sizeof (Elf64_Ehdr)); 131fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper 1329cf28e4f899f97ecdc983a0af8e2be62f3d69058Roland McGrath if (e_ident[EI_DATA] != MY_ELFDATA) 1339cf28e4f899f97ecdc983a0af8e2be62f3d69058Roland McGrath { 1349cf28e4f899f97ecdc983a0af8e2be62f3d69058Roland McGrath CONVERT (ehdr_mem.e64.e_shnum); 1359cf28e4f899f97ecdc983a0af8e2be62f3d69058Roland McGrath CONVERT (ehdr_mem.e64.e_shoff); 1369cf28e4f899f97ecdc983a0af8e2be62f3d69058Roland McGrath } 137b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 138b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 139b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 140b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (is32) 141b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 142b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Get the number of sections from the ELF header. */ 143b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper result = ehdr.e32->e_shnum; 144b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 145b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (unlikely (result == 0) && ehdr.e32->e_shoff != 0) 146b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 147720383c53b435de6647edd78060dd7d38ade25a5Jakub Jelinek if (unlikely (ehdr.e32->e_shoff >= maxsize) 148720383c53b435de6647edd78060dd7d38ade25a5Jakub Jelinek || unlikely (maxsize - ehdr.e32->e_shoff < sizeof (Elf32_Shdr))) 149b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Cannot read the first section header. */ 150c07fbb3ff74a8c7b4916ff8155060a35f4b08aaaUlrich Drepper return 0; 151b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 152b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (likely (map_address != NULL) && e_ident[EI_DATA] == MY_ELFDATA 153b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && (ALLOW_UNALIGNED 154b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper || (((size_t) ((char *) map_address + offset)) 155b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper & (__alignof__ (Elf32_Ehdr) - 1)) == 0)) 156b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* We can directly access the memory. */ 1570f6abbbc08ee259a1a702e7dd3be3e2c6b82305eUlrich Drepper result = ((Elf32_Shdr *) ((char *) map_address + ehdr.e32->e_shoff 158b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper + offset))->sh_size; 159b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 160b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 161b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf32_Word size; 162b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1630f6abbbc08ee259a1a702e7dd3be3e2c6b82305eUlrich Drepper if (likely (map_address != NULL)) 1640f6abbbc08ee259a1a702e7dd3be3e2c6b82305eUlrich Drepper /* gcc will optimize the memcpy to a simple memory 1650f6abbbc08ee259a1a702e7dd3be3e2c6b82305eUlrich Drepper access while taking care of alignment issues. */ 1660f6abbbc08ee259a1a702e7dd3be3e2c6b82305eUlrich Drepper memcpy (&size, &((Elf32_Shdr *) ((char *) map_address 1670f6abbbc08ee259a1a702e7dd3be3e2c6b82305eUlrich Drepper + ehdr.e32->e_shoff 1680f6abbbc08ee259a1a702e7dd3be3e2c6b82305eUlrich Drepper + offset))->sh_size, 1690f6abbbc08ee259a1a702e7dd3be3e2c6b82305eUlrich Drepper sizeof (Elf32_Word)); 1700f6abbbc08ee259a1a702e7dd3be3e2c6b82305eUlrich Drepper else 171fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper if (unlikely (pread_retry (fildes, &size, sizeof (Elf32_Word), 172fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper offset + ehdr.e32->e_shoff 173fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper + offsetof (Elf32_Shdr, sh_size)) 174fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper != sizeof (Elf32_Word))) 1750f6abbbc08ee259a1a702e7dd3be3e2c6b82305eUlrich Drepper return (size_t) -1l; 176b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 177b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (e_ident[EI_DATA] != MY_ELFDATA) 178b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper CONVERT (size); 179b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 180b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper result = size; 181b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 182b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 183c07fbb3ff74a8c7b4916ff8155060a35f4b08aaaUlrich Drepper 184c07fbb3ff74a8c7b4916ff8155060a35f4b08aaaUlrich Drepper /* If the section headers were truncated, pretend none were there. */ 185c07fbb3ff74a8c7b4916ff8155060a35f4b08aaaUlrich Drepper if (ehdr.e32->e_shoff > maxsize 186c07fbb3ff74a8c7b4916ff8155060a35f4b08aaaUlrich Drepper || maxsize - ehdr.e32->e_shoff < sizeof (Elf32_Shdr) * result) 187c07fbb3ff74a8c7b4916ff8155060a35f4b08aaaUlrich Drepper result = 0; 188b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 189b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 190b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 191b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Get the number of sections from the ELF header. */ 192b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper result = ehdr.e64->e_shnum; 193b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 194b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (unlikely (result == 0) && ehdr.e64->e_shoff != 0) 195b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 196720383c53b435de6647edd78060dd7d38ade25a5Jakub Jelinek if (unlikely (ehdr.e64->e_shoff >= maxsize) 197720383c53b435de6647edd78060dd7d38ade25a5Jakub Jelinek || unlikely (ehdr.e64->e_shoff + sizeof (Elf64_Shdr) > maxsize)) 198b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Cannot read the first section header. */ 199c07fbb3ff74a8c7b4916ff8155060a35f4b08aaaUlrich Drepper return 0; 200b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2010f6abbbc08ee259a1a702e7dd3be3e2c6b82305eUlrich Drepper Elf64_Xword size; 202b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (likely (map_address != NULL) && e_ident[EI_DATA] == MY_ELFDATA 203b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && (ALLOW_UNALIGNED 204b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper || (((size_t) ((char *) map_address + offset)) 205b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper & (__alignof__ (Elf64_Ehdr) - 1)) == 0)) 206b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* We can directly access the memory. */ 2070f6abbbc08ee259a1a702e7dd3be3e2c6b82305eUlrich Drepper size = ((Elf64_Shdr *) ((char *) map_address + ehdr.e64->e_shoff 2080f6abbbc08ee259a1a702e7dd3be3e2c6b82305eUlrich Drepper + offset))->sh_size; 209b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 210b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 2110f6abbbc08ee259a1a702e7dd3be3e2c6b82305eUlrich Drepper if (likely (map_address != NULL)) 2120f6abbbc08ee259a1a702e7dd3be3e2c6b82305eUlrich Drepper /* gcc will optimize the memcpy to a simple memory 2130f6abbbc08ee259a1a702e7dd3be3e2c6b82305eUlrich Drepper access while taking care of alignment issues. */ 2140f6abbbc08ee259a1a702e7dd3be3e2c6b82305eUlrich Drepper memcpy (&size, &((Elf64_Shdr *) ((char *) map_address 2150f6abbbc08ee259a1a702e7dd3be3e2c6b82305eUlrich Drepper + ehdr.e64->e_shoff 2160f6abbbc08ee259a1a702e7dd3be3e2c6b82305eUlrich Drepper + offset))->sh_size, 2170f6abbbc08ee259a1a702e7dd3be3e2c6b82305eUlrich Drepper sizeof (Elf64_Xword)); 2180f6abbbc08ee259a1a702e7dd3be3e2c6b82305eUlrich Drepper else 219fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper if (unlikely (pread_retry (fildes, &size, sizeof (Elf64_Word), 220fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper offset + ehdr.e64->e_shoff 221fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper + offsetof (Elf64_Shdr, sh_size)) 222fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper != sizeof (Elf64_Xword))) 2230f6abbbc08ee259a1a702e7dd3be3e2c6b82305eUlrich Drepper return (size_t) -1l; 224b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 225b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (e_ident[EI_DATA] != MY_ELFDATA) 226b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper CONVERT (size); 227e53d04af5fbf8486933821c81c8fe6637a546f48Roland McGrath } 2280f6abbbc08ee259a1a702e7dd3be3e2c6b82305eUlrich Drepper 2290f6abbbc08ee259a1a702e7dd3be3e2c6b82305eUlrich Drepper if (size > ~((GElf_Word) 0)) 2300f6abbbc08ee259a1a702e7dd3be3e2c6b82305eUlrich Drepper /* Invalid value, it is too large. */ 2310f6abbbc08ee259a1a702e7dd3be3e2c6b82305eUlrich Drepper return (size_t) -1l; 2320f6abbbc08ee259a1a702e7dd3be3e2c6b82305eUlrich Drepper 2330f6abbbc08ee259a1a702e7dd3be3e2c6b82305eUlrich Drepper result = size; 234b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 235c07fbb3ff74a8c7b4916ff8155060a35f4b08aaaUlrich Drepper 236c07fbb3ff74a8c7b4916ff8155060a35f4b08aaaUlrich Drepper /* If the section headers were truncated, pretend none were there. */ 237c07fbb3ff74a8c7b4916ff8155060a35f4b08aaaUlrich Drepper if (ehdr.e64->e_shoff > maxsize 238c07fbb3ff74a8c7b4916ff8155060a35f4b08aaaUlrich Drepper || maxsize - ehdr.e64->e_shoff < sizeof (Elf64_Shdr) * result) 239c07fbb3ff74a8c7b4916ff8155060a35f4b08aaaUlrich Drepper result = 0; 240b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 241b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 242b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return result; 243b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 244b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 245b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 246b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Create descriptor for ELF file in memory. */ 247b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic Elf * 248fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepperfile_read_elf (int fildes, void *map_address, unsigned char *e_ident, 249fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper off_t offset, size_t maxsize, Elf_Cmd cmd, Elf *parent) 250b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 251b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Verify the binary is of the class we can handle. */ 252fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper if (unlikely ((e_ident[EI_CLASS] != ELFCLASS32 253fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper && e_ident[EI_CLASS] != ELFCLASS64) 254fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper /* We also can only handle two encodings. */ 255fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper || (e_ident[EI_DATA] != ELFDATA2LSB 256fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper && e_ident[EI_DATA] != ELFDATA2MSB))) 257b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 258b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Cannot handle this. */ 259b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper __libelf_seterrno (ELF_E_INVALID_FILE); 260b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return NULL; 261b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 262b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 263b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Determine the number of sections. */ 264fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper size_t scncnt = get_shnum (map_address, e_ident, fildes, offset, maxsize); 265b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (scncnt == (size_t) -1l) 266b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Could not determine the number of sections. */ 267b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return NULL; 268b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 269720383c53b435de6647edd78060dd7d38ade25a5Jakub Jelinek /* Check for too many sections. */ 270720383c53b435de6647edd78060dd7d38ade25a5Jakub Jelinek if (e_ident[EI_CLASS] == ELFCLASS32) 271720383c53b435de6647edd78060dd7d38ade25a5Jakub Jelinek { 272720383c53b435de6647edd78060dd7d38ade25a5Jakub Jelinek if (scncnt > SIZE_MAX / (sizeof (Elf_Scn) + sizeof (Elf32_Shdr))) 273720383c53b435de6647edd78060dd7d38ade25a5Jakub Jelinek return NULL; 274720383c53b435de6647edd78060dd7d38ade25a5Jakub Jelinek } 275720383c53b435de6647edd78060dd7d38ade25a5Jakub Jelinek else if (scncnt > SIZE_MAX / (sizeof (Elf_Scn) + sizeof (Elf64_Shdr))) 276720383c53b435de6647edd78060dd7d38ade25a5Jakub Jelinek return NULL; 277720383c53b435de6647edd78060dd7d38ade25a5Jakub Jelinek 2786fd3cd104adf4107aa64e1c1e84028b4ea0b3296Roland McGrath /* We can now allocate the memory. Even if there are no section headers, 2796fd3cd104adf4107aa64e1c1e84028b4ea0b3296Roland McGrath we allocate space for a zeroth section in case we need it later. */ 2806fd3cd104adf4107aa64e1c1e84028b4ea0b3296Roland McGrath const size_t scnmax = (scncnt ?: (cmd == ELF_C_RDWR || cmd == ELF_C_RDWR_MMAP) 2816fd3cd104adf4107aa64e1c1e84028b4ea0b3296Roland McGrath ? 1 : 0); 282fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper Elf *elf = allocate_elf (fildes, map_address, offset, maxsize, cmd, parent, 2836fd3cd104adf4107aa64e1c1e84028b4ea0b3296Roland McGrath ELF_K_ELF, scnmax * sizeof (Elf_Scn)); 284b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (elf == NULL) 285b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Not enough memory. */ 286b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return NULL; 287b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2886fd3cd104adf4107aa64e1c1e84028b4ea0b3296Roland McGrath assert ((unsigned int) scncnt == scncnt); 2896fd3cd104adf4107aa64e1c1e84028b4ea0b3296Roland McGrath assert (offsetof (struct Elf, state.elf32.scns) 2906fd3cd104adf4107aa64e1c1e84028b4ea0b3296Roland McGrath == offsetof (struct Elf, state.elf64.scns)); 2916fd3cd104adf4107aa64e1c1e84028b4ea0b3296Roland McGrath elf->state.elf32.scns.cnt = scncnt; 2926fd3cd104adf4107aa64e1c1e84028b4ea0b3296Roland McGrath elf->state.elf32.scns.max = scnmax; 2936fd3cd104adf4107aa64e1c1e84028b4ea0b3296Roland McGrath 294b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Some more or less arbitrary value. */ 295b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper elf->state.elf.scnincr = 10; 296b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 297fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper /* Make the class easily available. */ 298fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper elf->class = e_ident[EI_CLASS]; 299fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper 300b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (e_ident[EI_CLASS] == ELFCLASS32) 301b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 302b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* This pointer might not be directly usable if the alignment is 303b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper not sufficient for the architecture. */ 304b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf32_Ehdr *ehdr = (Elf32_Ehdr *) ((char *) map_address + offset); 305b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 306b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* This is a 32-bit binary. */ 307b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (map_address != NULL && e_ident[EI_DATA] == MY_ELFDATA 308b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && (ALLOW_UNALIGNED 309b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper || ((((uintptr_t) ehdr) & (__alignof__ (Elf32_Ehdr) - 1)) == 0 310b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && ((uintptr_t) ((char *) ehdr + ehdr->e_shoff) 311b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper & (__alignof__ (Elf32_Shdr) - 1)) == 0 312b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && ((uintptr_t) ((char *) ehdr + ehdr->e_phoff) 313b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper & (__alignof__ (Elf32_Phdr) - 1)) == 0))) 314b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 315b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* We can use the mmapped memory. */ 316fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper elf->state.elf32.ehdr = ehdr; 317720383c53b435de6647edd78060dd7d38ade25a5Jakub Jelinek 318720383c53b435de6647edd78060dd7d38ade25a5Jakub Jelinek if (unlikely (ehdr->e_shoff >= maxsize) 319720383c53b435de6647edd78060dd7d38ade25a5Jakub Jelinek || unlikely (maxsize - ehdr->e_shoff 320720383c53b435de6647edd78060dd7d38ade25a5Jakub Jelinek < scncnt * sizeof (Elf32_Shdr))) 321720383c53b435de6647edd78060dd7d38ade25a5Jakub Jelinek { 322720383c53b435de6647edd78060dd7d38ade25a5Jakub Jelinek free_and_out: 323720383c53b435de6647edd78060dd7d38ade25a5Jakub Jelinek free (elf); 324720383c53b435de6647edd78060dd7d38ade25a5Jakub Jelinek __libelf_seterrno (ELF_E_INVALID_FILE); 325720383c53b435de6647edd78060dd7d38ade25a5Jakub Jelinek return NULL; 326720383c53b435de6647edd78060dd7d38ade25a5Jakub Jelinek } 327fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper elf->state.elf32.shdr 328fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper = (Elf32_Shdr *) ((char *) ehdr + ehdr->e_shoff); 329957072c18a906a43f0b428997d0c2b0da478213bRoland McGrath 330957072c18a906a43f0b428997d0c2b0da478213bRoland McGrath /* Don't precache the phdr pointer here. 331957072c18a906a43f0b428997d0c2b0da478213bRoland McGrath elf32_getphdr will validate it against the size when asked. */ 332b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 333b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper for (size_t cnt = 0; cnt < scncnt; ++cnt) 334b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 335b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper elf->state.elf32.scns.data[cnt].index = cnt; 336b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper elf->state.elf32.scns.data[cnt].elf = elf; 337b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper elf->state.elf32.scns.data[cnt].shdr.e32 = 338b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper &elf->state.elf32.shdr[cnt]; 339429502fd324d731feb939a5db4b7e0723adac616Roland McGrath if (likely (elf->state.elf32.shdr[cnt].sh_offset < maxsize) 340429502fd324d731feb939a5db4b7e0723adac616Roland McGrath && likely (maxsize - elf->state.elf32.shdr[cnt].sh_offset 341429502fd324d731feb939a5db4b7e0723adac616Roland McGrath <= elf->state.elf32.shdr[cnt].sh_size)) 342429502fd324d731feb939a5db4b7e0723adac616Roland McGrath elf->state.elf32.scns.data[cnt].rawdata_base = 343429502fd324d731feb939a5db4b7e0723adac616Roland McGrath elf->state.elf32.scns.data[cnt].data_base = 344429502fd324d731feb939a5db4b7e0723adac616Roland McGrath ((char *) map_address + offset 345429502fd324d731feb939a5db4b7e0723adac616Roland McGrath + elf->state.elf32.shdr[cnt].sh_offset); 346b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper elf->state.elf32.scns.data[cnt].list = &elf->state.elf32.scns; 3473cbdd387c752999255aea91600b5cfdefbeac7d0Ulrich Drepper 3483cbdd387c752999255aea91600b5cfdefbeac7d0Ulrich Drepper /* If this is a section with an extended index add a 3493cbdd387c752999255aea91600b5cfdefbeac7d0Ulrich Drepper reference in the section which uses the extended 3503cbdd387c752999255aea91600b5cfdefbeac7d0Ulrich Drepper index. */ 3513cbdd387c752999255aea91600b5cfdefbeac7d0Ulrich Drepper if (elf->state.elf32.shdr[cnt].sh_type == SHT_SYMTAB_SHNDX 3523cbdd387c752999255aea91600b5cfdefbeac7d0Ulrich Drepper && elf->state.elf32.shdr[cnt].sh_link < scncnt) 3533cbdd387c752999255aea91600b5cfdefbeac7d0Ulrich Drepper elf->state.elf32.scns.data[elf->state.elf32.shdr[cnt].sh_link].shndx_index 3543cbdd387c752999255aea91600b5cfdefbeac7d0Ulrich Drepper = cnt; 3553cbdd387c752999255aea91600b5cfdefbeac7d0Ulrich Drepper 3563cbdd387c752999255aea91600b5cfdefbeac7d0Ulrich Drepper /* Set the own shndx_index field in case it has not yet 3573cbdd387c752999255aea91600b5cfdefbeac7d0Ulrich Drepper been set. */ 3583cbdd387c752999255aea91600b5cfdefbeac7d0Ulrich Drepper if (elf->state.elf32.scns.data[cnt].shndx_index == 0) 3593cbdd387c752999255aea91600b5cfdefbeac7d0Ulrich Drepper elf->state.elf32.scns.data[cnt].shndx_index = -1; 360b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 361b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 362b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 363b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 364fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper /* Copy the ELF header. */ 365fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper elf->state.elf32.ehdr = memcpy (&elf->state.elf32.ehdr_mem, e_ident, 366fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper sizeof (Elf32_Ehdr)); 367b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 368b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (e_ident[EI_DATA] != MY_ELFDATA) 369b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 370b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper CONVERT (elf->state.elf32.ehdr_mem.e_type); 371b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper CONVERT (elf->state.elf32.ehdr_mem.e_machine); 372b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper CONVERT (elf->state.elf32.ehdr_mem.e_version); 373b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper CONVERT (elf->state.elf32.ehdr_mem.e_entry); 374b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper CONVERT (elf->state.elf32.ehdr_mem.e_phoff); 375b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper CONVERT (elf->state.elf32.ehdr_mem.e_shoff); 376b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper CONVERT (elf->state.elf32.ehdr_mem.e_flags); 377b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper CONVERT (elf->state.elf32.ehdr_mem.e_ehsize); 378b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper CONVERT (elf->state.elf32.ehdr_mem.e_phentsize); 379b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper CONVERT (elf->state.elf32.ehdr_mem.e_phnum); 380b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper CONVERT (elf->state.elf32.ehdr_mem.e_shentsize); 381b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper CONVERT (elf->state.elf32.ehdr_mem.e_shnum); 382b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper CONVERT (elf->state.elf32.ehdr_mem.e_shstrndx); 383b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 384b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 385b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper for (size_t cnt = 0; cnt < scncnt; ++cnt) 386b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 387b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper elf->state.elf32.scns.data[cnt].index = cnt; 388b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper elf->state.elf32.scns.data[cnt].elf = elf; 389b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper elf->state.elf32.scns.data[cnt].list = &elf->state.elf32.scns; 390b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 391b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 392b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 393b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* So far only one block with sections. */ 394b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper elf->state.elf32.scns_last = &elf->state.elf32.scns; 395b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 396b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 397b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 398b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* This pointer might not be directly usable if the alignment is 399b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper not sufficient for the architecture. */ 400b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf64_Ehdr *ehdr = (Elf64_Ehdr *) ((char *) map_address + offset); 401b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 402b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* This is a 64-bit binary. */ 403b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (map_address != NULL && e_ident[EI_DATA] == MY_ELFDATA 404b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && (ALLOW_UNALIGNED 405b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper || ((((uintptr_t) ehdr) & (__alignof__ (Elf64_Ehdr) - 1)) == 0 406b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && ((uintptr_t) ((char *) ehdr + ehdr->e_shoff) 407b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper & (__alignof__ (Elf64_Shdr) - 1)) == 0 408b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && ((uintptr_t) ((char *) ehdr + ehdr->e_phoff) 409b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper & (__alignof__ (Elf64_Phdr) - 1)) == 0))) 410b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 411b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* We can use the mmapped memory. */ 412fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper elf->state.elf64.ehdr = ehdr; 413720383c53b435de6647edd78060dd7d38ade25a5Jakub Jelinek 414720383c53b435de6647edd78060dd7d38ade25a5Jakub Jelinek if (unlikely (ehdr->e_shoff >= maxsize) 415720383c53b435de6647edd78060dd7d38ade25a5Jakub Jelinek || unlikely (ehdr->e_shoff 416720383c53b435de6647edd78060dd7d38ade25a5Jakub Jelinek + scncnt * sizeof (Elf32_Shdr) > maxsize)) 417720383c53b435de6647edd78060dd7d38ade25a5Jakub Jelinek goto free_and_out; 418fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper elf->state.elf64.shdr 419fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper = (Elf64_Shdr *) ((char *) ehdr + ehdr->e_shoff); 420957072c18a906a43f0b428997d0c2b0da478213bRoland McGrath 421957072c18a906a43f0b428997d0c2b0da478213bRoland McGrath /* Don't precache the phdr pointer here. 422957072c18a906a43f0b428997d0c2b0da478213bRoland McGrath elf64_getphdr will validate it against the size when asked. */ 423b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 424b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper for (size_t cnt = 0; cnt < scncnt; ++cnt) 425b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 426b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper elf->state.elf64.scns.data[cnt].index = cnt; 427b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper elf->state.elf64.scns.data[cnt].elf = elf; 428b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper elf->state.elf64.scns.data[cnt].shdr.e64 = 429b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper &elf->state.elf64.shdr[cnt]; 430429502fd324d731feb939a5db4b7e0723adac616Roland McGrath if (likely (elf->state.elf64.shdr[cnt].sh_offset < maxsize) 431429502fd324d731feb939a5db4b7e0723adac616Roland McGrath && likely (maxsize - elf->state.elf64.shdr[cnt].sh_offset 432429502fd324d731feb939a5db4b7e0723adac616Roland McGrath <= elf->state.elf64.shdr[cnt].sh_size)) 433429502fd324d731feb939a5db4b7e0723adac616Roland McGrath elf->state.elf64.scns.data[cnt].rawdata_base = 434429502fd324d731feb939a5db4b7e0723adac616Roland McGrath elf->state.elf64.scns.data[cnt].data_base = 435429502fd324d731feb939a5db4b7e0723adac616Roland McGrath ((char *) map_address + offset 436429502fd324d731feb939a5db4b7e0723adac616Roland McGrath + elf->state.elf64.shdr[cnt].sh_offset); 437b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper elf->state.elf64.scns.data[cnt].list = &elf->state.elf64.scns; 4383cbdd387c752999255aea91600b5cfdefbeac7d0Ulrich Drepper 4393cbdd387c752999255aea91600b5cfdefbeac7d0Ulrich Drepper /* If this is a section with an extended index add a 4403cbdd387c752999255aea91600b5cfdefbeac7d0Ulrich Drepper reference in the section which uses the extended 4413cbdd387c752999255aea91600b5cfdefbeac7d0Ulrich Drepper index. */ 4423cbdd387c752999255aea91600b5cfdefbeac7d0Ulrich Drepper if (elf->state.elf64.shdr[cnt].sh_type == SHT_SYMTAB_SHNDX 4433cbdd387c752999255aea91600b5cfdefbeac7d0Ulrich Drepper && elf->state.elf64.shdr[cnt].sh_link < scncnt) 4443cbdd387c752999255aea91600b5cfdefbeac7d0Ulrich Drepper elf->state.elf64.scns.data[elf->state.elf64.shdr[cnt].sh_link].shndx_index 4453cbdd387c752999255aea91600b5cfdefbeac7d0Ulrich Drepper = cnt; 4463cbdd387c752999255aea91600b5cfdefbeac7d0Ulrich Drepper 4473cbdd387c752999255aea91600b5cfdefbeac7d0Ulrich Drepper /* Set the own shndx_index field in case it has not yet 4483cbdd387c752999255aea91600b5cfdefbeac7d0Ulrich Drepper been set. */ 4493cbdd387c752999255aea91600b5cfdefbeac7d0Ulrich Drepper if (elf->state.elf64.scns.data[cnt].shndx_index == 0) 4503cbdd387c752999255aea91600b5cfdefbeac7d0Ulrich Drepper elf->state.elf64.scns.data[cnt].shndx_index = -1; 451b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 452b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 453b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 454b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 455fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper /* Copy the ELF header. */ 456fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper elf->state.elf64.ehdr = memcpy (&elf->state.elf64.ehdr_mem, e_ident, 457fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper sizeof (Elf64_Ehdr)); 458b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 459b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (e_ident[EI_DATA] != MY_ELFDATA) 460b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 461b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper CONVERT (elf->state.elf64.ehdr_mem.e_type); 462b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper CONVERT (elf->state.elf64.ehdr_mem.e_machine); 463b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper CONVERT (elf->state.elf64.ehdr_mem.e_version); 464b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper CONVERT (elf->state.elf64.ehdr_mem.e_entry); 465b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper CONVERT (elf->state.elf64.ehdr_mem.e_phoff); 466b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper CONVERT (elf->state.elf64.ehdr_mem.e_shoff); 467b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper CONVERT (elf->state.elf64.ehdr_mem.e_flags); 468b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper CONVERT (elf->state.elf64.ehdr_mem.e_ehsize); 469b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper CONVERT (elf->state.elf64.ehdr_mem.e_phentsize); 470b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper CONVERT (elf->state.elf64.ehdr_mem.e_phnum); 471b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper CONVERT (elf->state.elf64.ehdr_mem.e_shentsize); 472b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper CONVERT (elf->state.elf64.ehdr_mem.e_shnum); 473b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper CONVERT (elf->state.elf64.ehdr_mem.e_shstrndx); 474b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 475b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 476b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper for (size_t cnt = 0; cnt < scncnt; ++cnt) 477b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 478b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper elf->state.elf64.scns.data[cnt].index = cnt; 479b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper elf->state.elf64.scns.data[cnt].elf = elf; 480b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper elf->state.elf64.scns.data[cnt].list = &elf->state.elf64.scns; 481b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 482b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 483b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 484b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* So far only one block with sections. */ 485b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper elf->state.elf64.scns_last = &elf->state.elf64.scns; 486b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 487b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 488b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return elf; 489b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 490b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 491b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 492b08d5a8fb42f4586d756068065186b5af7e48daUlrich DrepperElf * 493077c65f3be02e5d01b0c4dea3f6c854077d156fcUlrich Drepperinternal_function 494b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper__libelf_read_mmaped_file (int fildes, void *map_address, off_t offset, 495b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size_t maxsize, Elf_Cmd cmd, Elf *parent) 496b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 497b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* We have to find out what kind of file this is. We handle ELF 498b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper files and archives. To find out what we have we must look at the 499b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper header. The header for an ELF file is EI_NIDENT bytes in size, 500b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper the header for an archive file SARMAG bytes long. */ 501fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper unsigned char *e_ident = (unsigned char *) map_address + offset; 502b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 503b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* See what kind of object we have here. */ 504fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper Elf_Kind kind = determine_kind (e_ident, maxsize); 505b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 506b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper switch (kind) 507b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 508b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case ELF_K_ELF: 509fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper return file_read_elf (fildes, map_address, e_ident, offset, maxsize, 510fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper cmd, parent); 511b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 512b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case ELF_K_AR: 513b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return file_read_ar (fildes, map_address, offset, maxsize, cmd, parent); 514b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 515b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper default: 516b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 517b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 518b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 519b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* This case is easy. Since we cannot do anything with this file 520b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper create a dummy descriptor. */ 521b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return allocate_elf (fildes, map_address, offset, maxsize, cmd, parent, 522b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ELF_K_NONE, 0); 523b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 524b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 525b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 526b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic Elf * 527b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperread_unmmaped_file (int fildes, off_t offset, size_t maxsize, Elf_Cmd cmd, 528b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf *parent) 529b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 530b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* We have to find out what kind of file this is. We handle ELF 531b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper files and archives. To find out what we have we must read the 532fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper header. The identification header for an ELF file is EI_NIDENT 533fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper bytes in size, but we read the whole ELF header since we will 534fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper need it anyway later. For archives the header in SARMAG bytes 535fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper long. Read the maximum of these numbers. 536fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper 537fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper XXX We have to change this for the extended `ar' format some day. 538490063eb2bd6a131104c0070aa0fa37d0b037c49Ulrich Drepper 539fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper Use a union to ensure alignment. We might later access the 540fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper memory as a ElfXX_Ehdr. */ 541fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper union 542fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper { 543fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper Elf64_Ehdr ehdr; 544fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper unsigned char header[MAX (sizeof (Elf64_Ehdr), SARMAG)]; 545fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper } mem; 546b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 547b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Read the head of the file. */ 548fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper ssize_t nread = pread_retry (fildes, mem.header, 549fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper MIN (MAX (sizeof (Elf64_Ehdr), SARMAG), 550fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper maxsize), 551fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper offset); 552fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper if (unlikely (nread == -1)) 553237188e4d764598300a577e08fd872339812fb2cPetr Machata { 554237188e4d764598300a577e08fd872339812fb2cPetr Machata /* We cannot even read the head of the file. Maybe FILDES is associated 555237188e4d764598300a577e08fd872339812fb2cPetr Machata with an unseekable device. This is nothing we can handle. */ 556237188e4d764598300a577e08fd872339812fb2cPetr Machata __libelf_seterrno (ELF_E_INVALID_FILE); 557237188e4d764598300a577e08fd872339812fb2cPetr Machata return NULL; 558237188e4d764598300a577e08fd872339812fb2cPetr Machata } 559b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 560b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* See what kind of object we have here. */ 561fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper Elf_Kind kind = determine_kind (mem.header, nread); 562b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 563b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper switch (kind) 564b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 565b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case ELF_K_AR: 566b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return file_read_ar (fildes, NULL, offset, maxsize, cmd, parent); 567b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 568b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case ELF_K_ELF: 569b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Make sure at least the ELF header is contained in the file. */ 570fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper if ((size_t) nread >= (mem.header[EI_CLASS] == ELFCLASS32 571fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper ? sizeof (Elf32_Ehdr) : sizeof (Elf64_Ehdr))) 572fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper return file_read_elf (fildes, NULL, mem.header, offset, maxsize, cmd, 573fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper parent); 574b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* FALLTHROUGH */ 575b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 576b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper default: 577b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 578b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 579b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 580b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* This case is easy. Since we cannot do anything with this file 581b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper create a dummy descriptor. */ 582b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return allocate_elf (fildes, NULL, offset, maxsize, cmd, parent, 583b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ELF_K_NONE, 0); 584b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 585b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 586b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 587b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Open a file for reading. If possible we will try to mmap() the file. */ 588b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic struct Elf * 589b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperread_file (int fildes, off_t offset, size_t maxsize, 590b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf_Cmd cmd, Elf *parent) 591b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 592b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper void *map_address = NULL; 593b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper int use_mmap = (cmd == ELF_C_READ_MMAP || cmd == ELF_C_RDWR_MMAP 594b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper || cmd == ELF_C_WRITE_MMAP 595b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper || cmd == ELF_C_READ_MMAP_PRIVATE); 596b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 597b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (use_mmap) 598b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 599b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (parent == NULL) 600b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 601b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (maxsize == ~((size_t) 0)) 602b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 603b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* We don't know in the moment how large the file is. 604b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Determine it now. */ 605b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper struct stat st; 606b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 607b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (fstat (fildes, &st) == 0 608b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && (sizeof (size_t) >= sizeof (st.st_size) 609b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper || st.st_size <= ~((size_t) 0))) 610b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper maxsize = (size_t) st.st_size; 611b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 612b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 613b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* We try to map the file ourself. */ 614b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper map_address = mmap (NULL, maxsize, (cmd == ELF_C_READ_MMAP 615b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ? PROT_READ 616b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper : PROT_READ|PROT_WRITE), 617b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cmd == ELF_C_READ_MMAP_PRIVATE 618ce0bdb6ee5f977af9e565f2871ba2b1b37d162a5Ulrich Drepper || cmd == ELF_C_READ_MMAP 619b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ? MAP_PRIVATE : MAP_SHARED, 620b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper fildes, offset); 621b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 622b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (map_address == MAP_FAILED) 623b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper map_address = NULL; 624b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 625b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 626b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 627b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* The parent is already loaded. Use it. */ 628b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper assert (maxsize != ~((size_t) 0)); 629b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 630b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper map_address = parent->map_address; 631b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 632b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 633b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 634b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* If we have the file in memory optimize the access. */ 635b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (map_address != NULL) 636b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 637fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper assert (map_address != MAP_FAILED); 638b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 639fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper struct Elf *result = __libelf_read_mmaped_file (fildes, map_address, 640fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper offset, maxsize, cmd, 641fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper parent); 642b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 643b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* If something went wrong during the initialization unmap the 644b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper memory if we mmaped here. */ 645b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (result == NULL 646b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && (parent == NULL 647b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper || parent->map_address != map_address)) 648b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper munmap (map_address, maxsize); 649b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else if (parent == NULL) 650b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Remember that we mmap()ed the memory. */ 651b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper result->flags |= ELF_F_MMAPPED; 652b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 653b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return result; 654b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 655b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 656b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Otherwise we have to do it the hard way. We read as much as necessary 657b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper from the file whenever we need information which is not available. */ 658b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return read_unmmaped_file (fildes, offset, maxsize, cmd, parent); 659b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 660b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 661b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 662b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Find the entry with the long names for the content of this archive. */ 663b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic const char * 664b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperread_long_names (Elf *elf) 665b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 666b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper off_t offset = SARMAG; /* This is the first entry. */ 667b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper struct ar_hdr hdrm; 668b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper struct ar_hdr *hdr; 669b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper char *newp; 670b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size_t len; 671b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 672b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper while (1) 673b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 674b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (elf->map_address != NULL) 675b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 676b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (offset + sizeof (struct ar_hdr) > elf->maximum_size) 677b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return NULL; 678b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 679b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* The data is mapped. */ 680b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper hdr = (struct ar_hdr *) (elf->map_address + offset); 681b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 682b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 683b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 684b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Read the header from the file. */ 685fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper if (unlikely (pread_retry (elf->fildes, &hdrm, sizeof (hdrm), 686fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper elf->start_offset + offset) 687fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper != sizeof (hdrm))) 688b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return NULL; 689b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 690b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper hdr = &hdrm; 691b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 692b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 693b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper len = atol (hdr->ar_size); 694b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 695b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (memcmp (hdr->ar_name, "// ", 16) == 0) 696b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 697b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 698b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper offset += sizeof (struct ar_hdr) + ((len + 1) & ~1l); 699b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 700b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 701b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Due to the stupid format of the long name table entry (which are not 702b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper NUL terminted) we have to provide an appropriate representation anyhow. 703b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Therefore we always make a copy which has the appropriate form. */ 704b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper newp = (char *) malloc (len); 705b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (newp != NULL) 706b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 707b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper char *runp; 708b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 709b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (elf->map_address != NULL) 710b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Simply copy it over. */ 711b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper elf->state.ar.long_names = (char *) memcpy (newp, 712b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper elf->map_address + offset 713b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper + sizeof (struct ar_hdr), 714b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper len); 715b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 716b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 717fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper if (unlikely ((size_t) pread_retry (elf->fildes, newp, len, 718fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper elf->start_offset + offset 719fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper + sizeof (struct ar_hdr)) 720fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper != len)) 721b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 722b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* We were not able to read all data. */ 723b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper free (newp); 724b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper elf->state.ar.long_names = NULL; 725b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return NULL; 726b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 727b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper elf->state.ar.long_names = newp; 728b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 729b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 730b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper elf->state.ar.long_names_len = len; 731b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 732b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Now NUL-terminate the strings. */ 733b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper runp = newp; 734b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper while (1) 735b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 736b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper runp = (char *) memchr (runp, '/', newp + len - runp); 737b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (runp == NULL) 738b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* This was the last entry. */ 739b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 740b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 741b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* NUL-terminate the string. */ 742b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper *runp = '\0'; 743b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 744ce0bdb6ee5f977af9e565f2871ba2b1b37d162a5Ulrich Drepper /* Skip the NUL byte and the \012. */ 745b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper runp += 2; 746b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 747b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* A sanity check. Somebody might have generated invalid 748b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper archive. */ 749b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (runp >= newp + len) 750b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 751b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 752b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 753b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 754b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return newp; 755b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 756b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 757b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 758b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Read the next archive header. */ 759b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperint 760077c65f3be02e5d01b0c4dea3f6c854077d156fcUlrich Drepperinternal_function 76102f66452635df3d01f7e57845c3362ab828e3d89Ulrich Drepper__libelf_next_arhdr_wrlock (elf) 762b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf *elf; 763b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 764b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper struct ar_hdr *ar_hdr; 765b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf_Arhdr *elf_ar_hdr; 766b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 767b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (elf->map_address != NULL) 768b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 769b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* See whether this entry is in the file. */ 770fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper if (unlikely (elf->state.ar.offset + sizeof (struct ar_hdr) 771fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper > elf->start_offset + elf->maximum_size)) 772b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 773b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* This record is not anymore in the file. */ 774b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper __libelf_seterrno (ELF_E_RANGE); 775b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return -1; 776b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 777b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ar_hdr = (struct ar_hdr *) (elf->map_address + elf->state.ar.offset); 778b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 779b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 780b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 781b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ar_hdr = &elf->state.ar.ar_hdr; 782b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 783fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper if (unlikely (pread_retry (elf->fildes, ar_hdr, sizeof (struct ar_hdr), 784fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper elf->state.ar.offset) 785fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper != sizeof (struct ar_hdr))) 786b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 787b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Something went wrong while reading the file. */ 788b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper __libelf_seterrno (ELF_E_RANGE); 789b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return -1; 790b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 791b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 792b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 793b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* One little consistency check. */ 794fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper if (unlikely (memcmp (ar_hdr->ar_fmag, ARFMAG, 2) != 0)) 795b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 796b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* This is no valid archive. */ 797b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper __libelf_seterrno (ELF_E_ARCHIVE_FMAG); 798b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return -1; 799b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 800b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 801b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Copy the raw name over to a NUL terminated buffer. */ 802b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper *((char *) __mempcpy (elf->state.ar.raw_name, ar_hdr->ar_name, 16)) = '\0'; 803b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 804b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper elf_ar_hdr = &elf->state.ar.elf_ar_hdr; 805b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 806b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Now convert the `struct ar_hdr' into `Elf_Arhdr'. 807b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Determine whether this is a special entry. */ 808b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ar_hdr->ar_name[0] == '/') 809b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 810b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ar_hdr->ar_name[1] == ' ' 811b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && memcmp (ar_hdr->ar_name, "/ ", 16) == 0) 812b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* This is the index. */ 813b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper elf_ar_hdr->ar_name = memcpy (elf->state.ar.ar_name, "/", 2); 814e1873141a517738d8c50923e40525bb2ae6db68aPetr Machata else if (ar_hdr->ar_name[1] == 'S' 815e1873141a517738d8c50923e40525bb2ae6db68aPetr Machata && memcmp (ar_hdr->ar_name, "/SYM64/ ", 16) == 0) 816e1873141a517738d8c50923e40525bb2ae6db68aPetr Machata /* 64-bit index. */ 817e1873141a517738d8c50923e40525bb2ae6db68aPetr Machata elf_ar_hdr->ar_name = memcpy (elf->state.ar.ar_name, "/SYM64/", 8); 818b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else if (ar_hdr->ar_name[1] == '/' 819b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && memcmp (ar_hdr->ar_name, "// ", 16) == 0) 820b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* This is the array with the long names. */ 821b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper elf_ar_hdr->ar_name = memcpy (elf->state.ar.ar_name, "//", 3); 822fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper else if (likely (isdigit (ar_hdr->ar_name[1]))) 823b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 824b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size_t offset; 825b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 826b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* This is a long name. First we have to read the long name 827b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper table, if this hasn't happened already. */ 828fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper if (unlikely (elf->state.ar.long_names == NULL 829fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper && read_long_names (elf) == NULL)) 830b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 831b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* No long name table although it is reference. The archive is 832b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper broken. */ 833b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper __libelf_seterrno (ELF_E_INVALID_ARCHIVE); 834b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return -1; 835b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 836b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 837b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper offset = atol (ar_hdr->ar_name + 1); 838fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper if (unlikely (offset >= elf->state.ar.long_names_len)) 839b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 840b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* The index in the long name table is larger than the table. */ 841b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper __libelf_seterrno (ELF_E_INVALID_ARCHIVE); 842b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return -1; 843b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 844b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper elf_ar_hdr->ar_name = elf->state.ar.long_names + offset; 845b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 846b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 847b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 848b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* This is none of the known special entries. */ 849b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper __libelf_seterrno (ELF_E_INVALID_ARCHIVE); 850b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return -1; 851b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 852b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 853b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 854b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 855b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper char *endp; 856b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 857b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* It is a normal entry. Copy over the name. */ 858b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper endp = (char *) memccpy (elf->state.ar.ar_name, ar_hdr->ar_name, 859b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper '/', 16); 860b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (endp != NULL) 861b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper endp[-1] = '\0'; 862b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 863b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper { 864b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper /* In the old BSD style of archive, there is no / terminator. 865b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper Instead, there is space padding at the end of the name. */ 866b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper size_t i = 15; 867b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper do 868b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper elf->state.ar.ar_name[i] = '\0'; 869b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper while (i > 0 && elf->state.ar.ar_name[--i] == ' '); 870b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper } 871b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 872b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper elf_ar_hdr->ar_name = elf->state.ar.ar_name; 873b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 874b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 875059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath if (unlikely (ar_hdr->ar_size[0] == ' ')) 876059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath /* Something is really wrong. We cannot live without a size for 877059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath the member since it will not be possible to find the next 878059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath archive member. */ 879059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath { 880059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath __libelf_seterrno (ELF_E_INVALID_ARCHIVE); 881059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath return -1; 882059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath } 883059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath 884b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Since there are no specialized functions to convert ASCII to 885b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper time_t, uid_t, gid_t, mode_t, and off_t we use either atol or 886b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper atoll depending on the size of the types. We are also prepared 887b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper for the case where the whole field in the `struct ar_hdr' is 888b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper filled in which case we cannot simply use atol/l but instead have 889b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper to create a temporary copy. */ 890b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 891059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath#define INT_FIELD(FIELD) \ 892059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath do \ 893059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath { \ 894059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath char buf[sizeof (ar_hdr->FIELD) + 1]; \ 895059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath const char *string = ar_hdr->FIELD; \ 896059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath if (ar_hdr->FIELD[sizeof (ar_hdr->FIELD) - 1] != ' ') \ 897059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath { \ 898059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath *((char *) __mempcpy (buf, ar_hdr->FIELD, sizeof (ar_hdr->FIELD))) \ 899059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath = '\0'; \ 900059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath string = buf; \ 901059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath } \ 902059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath if (sizeof (elf_ar_hdr->FIELD) <= sizeof (long int)) \ 903059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath elf_ar_hdr->FIELD = (__typeof (elf_ar_hdr->FIELD)) atol (string); \ 904059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath else \ 905059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath elf_ar_hdr->FIELD = (__typeof (elf_ar_hdr->FIELD)) atoll (string); \ 906059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath } \ 907059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath while (0) 908059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath 909059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath INT_FIELD (ar_date); 910059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath INT_FIELD (ar_uid); 911059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath INT_FIELD (ar_gid); 912059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath INT_FIELD (ar_mode); 913059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath INT_FIELD (ar_size); 914b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 915b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return 0; 916b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 917b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 918b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 919b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* We were asked to return a clone of an existing descriptor. This 920b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper function must be called with the lock on the parent descriptor 921b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper being held. */ 922b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic Elf * 923b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperdup_elf (int fildes, Elf_Cmd cmd, Elf *ref) 924b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 925b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper struct Elf *result; 926b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 927b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (fildes == -1) 928b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Allow the user to pass -1 as the file descriptor for the new file. */ 929b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper fildes = ref->fildes; 930b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* The file descriptor better should be the same. If it was disconnected 931b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper already (using `elf_cntl') we do not test it. */ 932fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper else if (unlikely (ref->fildes != -1 && fildes != ref->fildes)) 933b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 934b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper __libelf_seterrno (ELF_E_FD_MISMATCH); 935b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return NULL; 936b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 937b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 938b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* The mode must allow reading. I.e., a descriptor creating with a 939b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper command different then ELF_C_READ, ELF_C_WRITE and ELF_C_RDWR is 940b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper not allowed. */ 941fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper if (unlikely (ref->cmd != ELF_C_READ && ref->cmd != ELF_C_READ_MMAP 942fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper && ref->cmd != ELF_C_WRITE && ref->cmd != ELF_C_WRITE_MMAP 943fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper && ref->cmd != ELF_C_RDWR && ref->cmd != ELF_C_RDWR_MMAP 944fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper && ref->cmd != ELF_C_READ_MMAP_PRIVATE)) 945b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 946b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper __libelf_seterrno (ELF_E_INVALID_OP); 947b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return NULL; 948b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 949b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 950b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Now it is time to distinguish between reading normal files and 951b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper archives. Normal files can easily be handled be incrementing the 952b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper reference counter and return the same descriptor. */ 953b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ref->kind != ELF_K_AR) 954b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 955b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ++ref->ref_count; 956b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return ref; 957b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 958b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 959b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* This is an archive. We must create a descriptor for the archive 960b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper member the internal pointer of the archive file desriptor is 961b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper pointing to. First read the header of the next member if this 962b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper has not happened already. */ 963b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ref->state.ar.elf_ar_hdr.ar_name == NULL 96402f66452635df3d01f7e57845c3362ab828e3d89Ulrich Drepper && __libelf_next_arhdr_wrlock (ref) != 0) 965b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Something went wrong. Maybe there is no member left. */ 966b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return NULL; 967b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 968b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* We have all the information we need about the next archive member. 969b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Now create a descriptor for it. */ 970b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper result = read_file (fildes, ref->state.ar.offset + sizeof (struct ar_hdr), 971b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ref->state.ar.elf_ar_hdr.ar_size, cmd, ref); 972b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 973b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Enlist this new descriptor in the list of children. */ 974b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (result != NULL) 975b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 976b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper result->next = ref->state.ar.children; 977b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ref->state.ar.children = result; 978b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 979b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 980b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return result; 981b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 982b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 983b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 984b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Return desriptor for empty file ready for writing. */ 985b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic struct Elf * 986b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperwrite_file (int fd, Elf_Cmd cmd) 987b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 988b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* We simply create an empty `Elf' structure. */ 989b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#define NSCNSALLOC 10 990b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf *result = allocate_elf (fd, NULL, 0, 0, cmd, NULL, ELF_K_ELF, 991b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper NSCNSALLOC * sizeof (Elf_Scn)); 992b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 993b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (result != NULL) 994b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 995b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* We have to write to the file in any case. */ 996b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper result->flags = ELF_F_DIRTY; 997b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 998b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Some more or less arbitrary value. */ 999b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper result->state.elf.scnincr = NSCNSALLOC; 1000b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1001b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* We have allocated room for some sections. */ 1002b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper assert (offsetof (struct Elf, state.elf32.scns) 1003b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper == offsetof (struct Elf, state.elf64.scns)); 1004b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper result->state.elf.scns_last = &result->state.elf32.scns; 1005b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper result->state.elf32.scns.max = NSCNSALLOC; 1006b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1007b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1008b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return result; 1009b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 1010b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1011b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1012b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Return a descriptor for the file belonging to FILDES. */ 1013b08d5a8fb42f4586d756068065186b5af7e48daUlrich DrepperElf * 1014b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperelf_begin (fildes, cmd, ref) 1015b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper int fildes; 1016b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf_Cmd cmd; 1017b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf *ref; 1018b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 1019b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf *retval; 1020b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1021fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper if (unlikely (! __libelf_version_initialized)) 1022b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1023b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Version wasn't set so far. */ 1024b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper __libelf_seterrno (ELF_E_NO_VERSION); 1025b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return NULL; 1026b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1027b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1028b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ref != NULL) 1029b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Make sure the descriptor is not suddenly going away. */ 1030b4d6f0f8064f2b706ea9035ef0393d8299671390Roland McGrath rwlock_rdlock (ref->lock); 1031fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper else if (unlikely (fcntl (fildes, F_GETFL) == -1 && errno == EBADF)) 1032b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1033b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* We cannot do anything productive without a file descriptor. */ 1034b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper __libelf_seterrno (ELF_E_INVALID_FILE); 1035b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return NULL; 1036b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1037b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 103802f66452635df3d01f7e57845c3362ab828e3d89Ulrich Drepper Elf *lock_dup_elf () 103902f66452635df3d01f7e57845c3362ab828e3d89Ulrich Drepper { 104002f66452635df3d01f7e57845c3362ab828e3d89Ulrich Drepper /* We need wrlock to dup an archive. */ 104102f66452635df3d01f7e57845c3362ab828e3d89Ulrich Drepper if (ref->kind == ELF_K_AR) 104202f66452635df3d01f7e57845c3362ab828e3d89Ulrich Drepper { 104302f66452635df3d01f7e57845c3362ab828e3d89Ulrich Drepper rwlock_unlock (ref->lock); 104402f66452635df3d01f7e57845c3362ab828e3d89Ulrich Drepper rwlock_wrlock (ref->lock); 104502f66452635df3d01f7e57845c3362ab828e3d89Ulrich Drepper } 104602f66452635df3d01f7e57845c3362ab828e3d89Ulrich Drepper 104702f66452635df3d01f7e57845c3362ab828e3d89Ulrich Drepper /* Duplicate the descriptor. */ 104802f66452635df3d01f7e57845c3362ab828e3d89Ulrich Drepper return dup_elf (fildes, cmd, ref); 104902f66452635df3d01f7e57845c3362ab828e3d89Ulrich Drepper } 105002f66452635df3d01f7e57845c3362ab828e3d89Ulrich Drepper 1051b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper switch (cmd) 1052b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1053b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case ELF_C_NULL: 1054b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* We simply return a NULL pointer. */ 1055b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper retval = NULL; 1056b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 1057b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1058b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case ELF_C_READ_MMAP_PRIVATE: 1059b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* If we have a reference it must also be opened this way. */ 1060fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper if (unlikely (ref != NULL && ref->cmd != ELF_C_READ_MMAP_PRIVATE)) 1061b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1062b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper __libelf_seterrno (ELF_E_INVALID_CMD); 1063b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper retval = NULL; 1064b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 1065b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1066b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* FALLTHROUGH */ 1067b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1068b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case ELF_C_READ: 1069b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case ELF_C_READ_MMAP: 1070b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ref != NULL) 107102f66452635df3d01f7e57845c3362ab828e3d89Ulrich Drepper retval = lock_dup_elf (); 1072b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 1073b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Create descriptor for existing file. */ 1074b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper retval = read_file (fildes, 0, ~((size_t) 0), cmd, NULL); 1075b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 1076b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1077b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case ELF_C_RDWR: 1078b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case ELF_C_RDWR_MMAP: 1079b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* If we have a REF object it must also be opened using this 1080b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper command. */ 1081b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ref != NULL) 1082b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1083fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper if (unlikely (ref->cmd != ELF_C_RDWR && ref->cmd != ELF_C_RDWR_MMAP 1084fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper && ref->cmd != ELF_C_WRITE 1085fbe998a0b1be1f006bc72e5138fb38c188cc0433Ulrich Drepper && ref->cmd != ELF_C_WRITE_MMAP)) 1086b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1087b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* This is not ok. REF must also be opened for writing. */ 1088b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper __libelf_seterrno (ELF_E_INVALID_CMD); 1089b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper retval = NULL; 1090b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1091b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 109202f66452635df3d01f7e57845c3362ab828e3d89Ulrich Drepper retval = lock_dup_elf (); 1093b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1094b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 1095b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Create descriptor for existing file. */ 1096b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper retval = read_file (fildes, 0, ~((size_t) 0), cmd, NULL); 1097b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 1098b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1099b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case ELF_C_WRITE: 1100b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case ELF_C_WRITE_MMAP: 1101b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* We ignore REF and prepare a descriptor to write a new file. */ 1102b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper retval = write_file (fildes, cmd); 1103b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 1104b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1105b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper default: 1106b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper __libelf_seterrno (ELF_E_INVALID_CMD); 1107b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper retval = NULL; 1108b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 1109b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1110b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1111b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Release the lock. */ 1112b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ref != NULL) 1113b4d6f0f8064f2b706ea9035ef0393d8299671390Roland McGrath rwlock_unlock (ref->lock); 1114b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1115b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return retval; 1116b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 1117b08d5a8fb42f4586d756068065186b5af7e48daUlrich DrepperINTDEF(elf_begin) 1118