1 1.13 christos /* $NetBSD: exec_elf32.c,v 1.13 2016/09/21 16:25:41 christos Exp $ */ 2 1.1 cgd 3 1.1 cgd /* 4 1.8 cgd * Copyright (c) 1996 Christopher G. Demetriou 5 1.8 cgd * All rights reserved. 6 1.8 cgd * 7 1.1 cgd * Redistribution and use in source and binary forms, with or without 8 1.1 cgd * modification, are permitted provided that the following conditions 9 1.1 cgd * are met: 10 1.1 cgd * 1. Redistributions of source code must retain the above copyright 11 1.1 cgd * notice, this list of conditions and the following disclaimer. 12 1.1 cgd * 2. Redistributions in binary form must reproduce the above copyright 13 1.1 cgd * notice, this list of conditions and the following disclaimer in the 14 1.1 cgd * documentation and/or other materials provided with the distribution. 15 1.9 cgd * 3. The name of the author may not be used to endorse or promote products 16 1.8 cgd * derived from this software without specific prior written permission. 17 1.8 cgd * 18 1.1 cgd * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 1.1 cgd * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 1.1 cgd * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 1.1 cgd * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 1.1 cgd * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23 1.1 cgd * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 1.1 cgd * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 1.1 cgd * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 1.1 cgd * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 1.1 cgd * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 1.8 cgd * 29 1.9 cgd * <<Id: LICENSE_GC,v 1.1 2001/10/01 23:24:05 cgd Exp>> 30 1.1 cgd */ 31 1.1 cgd 32 1.2 lukem #include <sys/cdefs.h> 33 1.1 cgd #ifndef lint 34 1.13 christos __RCSID("$NetBSD: exec_elf32.c,v 1.13 2016/09/21 16:25:41 christos Exp $"); 35 1.1 cgd #endif /* not lint */ 36 1.1 cgd 37 1.1 cgd #ifndef ELFSIZE 38 1.1 cgd #define ELFSIZE 32 39 1.1 cgd #endif 40 1.1 cgd 41 1.1 cgd #include <sys/types.h> 42 1.1 cgd #include <stdio.h> 43 1.1 cgd #include <string.h> 44 1.1 cgd #include "extern.h" 45 1.1 cgd 46 1.1 cgd #if defined(NLIST_ELF32) || defined(NLIST_ELF64) 47 1.1 cgd #include <sys/exec_elf.h> 48 1.1 cgd #endif 49 1.1 cgd 50 1.1 cgd #if (defined(NLIST_ELF32) && (ELFSIZE == 32)) || \ 51 1.1 cgd (defined(NLIST_ELF64) && (ELFSIZE == 64)) 52 1.1 cgd 53 1.1 cgd #define check(off, size) ((off < 0) || (off + size > mappedsize)) 54 1.1 cgd #define BAD do { rv = -1; goto out; } while (0) 55 1.1 cgd 56 1.1 cgd int 57 1.13 christos ELFNAMEEND(check)(const char *mappedfile, size_t mappedsize) 58 1.1 cgd { 59 1.10 tsutsui const Elf_Ehdr *ehdrp; 60 1.1 cgd int rv; 61 1.1 cgd 62 1.1 cgd rv = 0; 63 1.1 cgd 64 1.1 cgd if (check(0, sizeof *ehdrp)) 65 1.1 cgd BAD; 66 1.10 tsutsui ehdrp = (const Elf_Ehdr *)&mappedfile[0]; 67 1.1 cgd 68 1.5 kleink if (memcmp(ehdrp->e_ident, ELFMAG, SELFMAG) != 0 || 69 1.5 kleink ehdrp->e_ident[EI_CLASS] != ELFCLASS) 70 1.1 cgd BAD; 71 1.1 cgd 72 1.1 cgd switch (ehdrp->e_machine) { 73 1.1 cgd ELFDEFNNAME(MACHDEP_ID_CASES) 74 1.1 cgd 75 1.1 cgd default: 76 1.1 cgd BAD; 77 1.1 cgd } 78 1.1 cgd 79 1.1 cgd out: 80 1.1 cgd return (rv); 81 1.1 cgd } 82 1.1 cgd 83 1.1 cgd int 84 1.13 christos ELFNAMEEND(findoff)(const char *mappedfile, size_t mappedsize, u_long vmaddr, 85 1.13 christos size_t *fileoffp, u_long text_addr) 86 1.1 cgd { 87 1.10 tsutsui const Elf_Ehdr *ehdrp; 88 1.11 tsutsui const Elf_Phdr *phdrp; 89 1.11 tsutsui Elf_Off phdr_off; 90 1.11 tsutsui Elf_Word phdr_size; 91 1.1 cgd #if (ELFSIZE == 32) 92 1.11 tsutsui Elf32_Half nphdr, i; 93 1.1 cgd #elif (ELFSIZE == 64) 94 1.12 joerg Elf64_Word nphdr, i; 95 1.1 cgd #endif 96 1.1 cgd int rv; 97 1.1 cgd 98 1.1 cgd rv = 0; 99 1.1 cgd 100 1.10 tsutsui ehdrp = (const Elf_Ehdr *)&mappedfile[0]; 101 1.11 tsutsui nphdr = ehdrp->e_phnum; 102 1.11 tsutsui phdr_off = ehdrp->e_phoff; 103 1.11 tsutsui phdr_size = sizeof(Elf_Phdr) * nphdr; 104 1.1 cgd 105 1.11 tsutsui if (check(0, phdr_off + phdr_size)) 106 1.1 cgd BAD; 107 1.11 tsutsui phdrp = (const Elf_Phdr *)&mappedfile[phdr_off]; 108 1.1 cgd 109 1.11 tsutsui #define IS_TEXT(p) (p.p_flags & PF_X) 110 1.11 tsutsui #define IS_DATA(p) (p.p_flags & PF_W) 111 1.11 tsutsui 112 1.11 tsutsui for (i = 0; i < nphdr; i++) { 113 1.11 tsutsui if ((IS_TEXT(phdrp[i]) || IS_DATA(phdrp[i])) && 114 1.11 tsutsui phdrp[i].p_vaddr <= vmaddr && 115 1.11 tsutsui vmaddr < phdrp[i].p_vaddr + phdrp[i].p_filesz) { 116 1.1 cgd *fileoffp = vmaddr - 117 1.11 tsutsui phdrp[i].p_vaddr + phdrp[i].p_offset; 118 1.1 cgd break; 119 1.1 cgd } 120 1.1 cgd } 121 1.11 tsutsui if (i == nphdr) 122 1.1 cgd BAD; 123 1.1 cgd 124 1.1 cgd out: 125 1.1 cgd return (rv); 126 1.1 cgd } 127 1.1 cgd 128 1.1 cgd #endif /* include this size of ELF */ 129