1*297f4619Sad /* $NetBSD: elf32.c,v 1.1 2006/09/07 00:50:45 ad Exp $ */ 2*297f4619Sad 3*297f4619Sad /*- 4*297f4619Sad * Copyright (c) 2006 The NetBSD Foundation, Inc. 5*297f4619Sad * All rights reserved. 6*297f4619Sad * 7*297f4619Sad * This code is derived from software contributed to The NetBSD Foundation 8*297f4619Sad * by Andrew Doran. 9*297f4619Sad * 10*297f4619Sad * Redistribution and use in source and binary forms, with or without 11*297f4619Sad * modification, are permitted provided that the following conditions 12*297f4619Sad * are met: 13*297f4619Sad * 1. Redistributions of source code must retain the above copyright 14*297f4619Sad * notice, this list of conditions and the following disclaimer. 15*297f4619Sad * 2. Redistributions in binary form must reproduce the above copyright 16*297f4619Sad * notice, this list of conditions and the following disclaimer in the 17*297f4619Sad * documentation and/or other materials provided with the distribution. 18*297f4619Sad * 3. All advertising materials mentioning features or use of this software 19*297f4619Sad * must display the following acknowledgement: 20*297f4619Sad * This product includes software developed by the NetBSD 21*297f4619Sad * Foundation, Inc. and its contributors. 22*297f4619Sad * 4. Neither the name of The NetBSD Foundation nor the names of its 23*297f4619Sad * contributors may be used to endorse or promote products derived 24*297f4619Sad * from this software without specific prior written permission. 25*297f4619Sad * 26*297f4619Sad * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 27*297f4619Sad * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 28*297f4619Sad * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 29*297f4619Sad * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 30*297f4619Sad * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 31*297f4619Sad * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 32*297f4619Sad * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 33*297f4619Sad * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 34*297f4619Sad * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 35*297f4619Sad * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36*297f4619Sad * POSSIBILITY OF SUCH DAMAGE. 37*297f4619Sad */ 38*297f4619Sad 39*297f4619Sad /* 40*297f4619Sad * Copyright (c) 1996 Christopher G. Demetriou 41*297f4619Sad * All rights reserved. 42*297f4619Sad * 43*297f4619Sad * Redistribution and use in source and binary forms, with or without 44*297f4619Sad * modification, are permitted provided that the following conditions 45*297f4619Sad * are met: 46*297f4619Sad * 1. Redistributions of source code must retain the above copyright 47*297f4619Sad * notice, this list of conditions and the following disclaimer. 48*297f4619Sad * 2. Redistributions in binary form must reproduce the above copyright 49*297f4619Sad * notice, this list of conditions and the following disclaimer in the 50*297f4619Sad * documentation and/or other materials provided with the distribution. 51*297f4619Sad * 3. All advertising materials mentioning features or use of this software 52*297f4619Sad * must display the following acknowledgement: 53*297f4619Sad * This product includes software developed for the 54*297f4619Sad * NetBSD Project. See http://www.NetBSD.org/ for 55*297f4619Sad * information about NetBSD. 56*297f4619Sad * 4. The name of the author may not be used to endorse or promote products 57*297f4619Sad * derived from this software without specific prior written permission. 58*297f4619Sad * 59*297f4619Sad * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 60*297f4619Sad * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 61*297f4619Sad * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 62*297f4619Sad * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 63*297f4619Sad * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 64*297f4619Sad * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 65*297f4619Sad * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 66*297f4619Sad * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 67*297f4619Sad * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 68*297f4619Sad * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 69*297f4619Sad * 70*297f4619Sad * <<Id: LICENSE,v 1.2 2000/06/14 15:57:33 cgd Exp>> 71*297f4619Sad */ 72*297f4619Sad 73*297f4619Sad #include <sys/cdefs.h> 74*297f4619Sad #if !defined(lint) 75*297f4619Sad __RCSID("$NetBSD: elf32.c,v 1.1 2006/09/07 00:50:45 ad Exp $"); 76*297f4619Sad #endif 77*297f4619Sad 78*297f4619Sad #ifndef ELFSIZE 79*297f4619Sad #define ELFSIZE 32 80*297f4619Sad #endif 81*297f4619Sad 82*297f4619Sad #include <sys/param.h> 83*297f4619Sad #include <sys/exec_elf.h> 84*297f4619Sad #include <sys/queue.h> 85*297f4619Sad #include <sys/lockstat.h> 86*297f4619Sad 87*297f4619Sad #include <stdio.h> 88*297f4619Sad #include <stdlib.h> 89*297f4619Sad #include <string.h> 90*297f4619Sad #include <unistd.h> 91*297f4619Sad #include <err.h> 92*297f4619Sad 93*297f4619Sad #include "extern.h" 94*297f4619Sad 95*297f4619Sad #if (ELFSIZE == 32) 96*297f4619Sad #define NAME(x) x##32 97*297f4619Sad #elif (ELFSIZE == 64) 98*297f4619Sad #define NAME(x) x##64 99*297f4619Sad #endif 100*297f4619Sad 101*297f4619Sad static int nsyms; 102*297f4619Sad static Elf_Sym *symp; 103*297f4619Sad static char *strp; 104*297f4619Sad 105*297f4619Sad int 106*297f4619Sad NAME(loadsym)(int fd) 107*297f4619Sad { 108*297f4619Sad Elf_Shdr symhdr, strhdr; 109*297f4619Sad Elf_Ehdr ehdr; 110*297f4619Sad size_t sz; 111*297f4619Sad off_t off; 112*297f4619Sad int i; 113*297f4619Sad 114*297f4619Sad /* 115*297f4619Sad * Read the ELF header and make sure it's OK. 116*297f4619Sad */ 117*297f4619Sad if (pread(fd, &ehdr, sizeof(ehdr), 0) != sizeof(ehdr)) 118*297f4619Sad return -1; 119*297f4619Sad 120*297f4619Sad if (memcmp(ehdr.e_ident, ELFMAG, SELFMAG) != 0 || 121*297f4619Sad ehdr.e_ident[EI_CLASS] != ELFCLASS) 122*297f4619Sad return -1; 123*297f4619Sad 124*297f4619Sad switch (ehdr.e_machine) { 125*297f4619Sad ELFDEFNNAME(MACHDEP_ID_CASES) 126*297f4619Sad default: 127*297f4619Sad return -1; 128*297f4619Sad } 129*297f4619Sad 130*297f4619Sad /* 131*297f4619Sad * Find the symbol table header, and make sure the binary isn't 132*297f4619Sad * stripped. 133*297f4619Sad */ 134*297f4619Sad off = ehdr.e_shoff; 135*297f4619Sad for (i = 0; i < ehdr.e_shnum; i++, off += sizeof(symhdr)) { 136*297f4619Sad sz = pread(fd, &symhdr, sizeof(symhdr), off); 137*297f4619Sad if (sz != sizeof(symhdr)) 138*297f4619Sad err(EXIT_FAILURE, "pread (section headers)"); 139*297f4619Sad if (symhdr.sh_type == SHT_SYMTAB) 140*297f4619Sad break; 141*297f4619Sad } 142*297f4619Sad if (i == ehdr.e_shnum || symhdr.sh_offset == 0) 143*297f4619Sad err(EXIT_FAILURE, "namelist is stripped"); 144*297f4619Sad 145*297f4619Sad /* 146*297f4619Sad * Pull in the string table header, and then read in both the symbol 147*297f4619Sad * table and string table proper. 148*297f4619Sad * 149*297f4619Sad * XXX We can't use mmap(), as /dev/ksyms doesn't support mmap yet. 150*297f4619Sad */ 151*297f4619Sad off = ehdr.e_shoff + symhdr.sh_link * sizeof(symhdr); 152*297f4619Sad if (pread(fd, &strhdr, sizeof(strhdr), off) != sizeof(strhdr)) 153*297f4619Sad err(EXIT_FAILURE, "pread"); 154*297f4619Sad 155*297f4619Sad if ((symp = malloc(symhdr.sh_size)) == NULL) 156*297f4619Sad err(EXIT_FAILURE, "malloc (symbol table)"); 157*297f4619Sad sz = pread(fd, symp, symhdr.sh_size, symhdr.sh_offset ); 158*297f4619Sad if (sz != symhdr.sh_size) 159*297f4619Sad err(EXIT_FAILURE, "pread (symbol table)"); 160*297f4619Sad 161*297f4619Sad if ((strp = malloc(strhdr.sh_size)) == NULL) 162*297f4619Sad err(EXIT_FAILURE, "malloc (string table)"); 163*297f4619Sad sz = pread(fd, strp, strhdr.sh_size, strhdr.sh_offset); 164*297f4619Sad if (sz != strhdr.sh_size) 165*297f4619Sad err(EXIT_FAILURE, "pread (string table)"); 166*297f4619Sad 167*297f4619Sad nsyms = (int)(symhdr.sh_size / sizeof(Elf_Sym)); 168*297f4619Sad 169*297f4619Sad return 0; 170*297f4619Sad } 171*297f4619Sad 172*297f4619Sad int 173*297f4619Sad NAME(findsym)(findsym_t find, char *name, uintptr_t *start, uintptr_t *end) 174*297f4619Sad { 175*297f4619Sad static int lastptr[FIND_MAX]; 176*297f4619Sad uintptr_t sa, ea; 177*297f4619Sad int i, rv; 178*297f4619Sad 179*297f4619Sad rv = -1; 180*297f4619Sad 181*297f4619Sad #ifdef dump_core 182*297f4619Sad for (i = lastptr[find];;) { 183*297f4619Sad #else 184*297f4619Sad for (i = 0; i < nsyms; i++) { 185*297f4619Sad #endif 186*297f4619Sad switch (find) { 187*297f4619Sad case LOCK_BYNAME: 188*297f4619Sad if (ELF_ST_TYPE(symp[i].st_info) != STT_OBJECT) 189*297f4619Sad break; 190*297f4619Sad if (strcmp(&strp[symp[i].st_name], name) != 0) 191*297f4619Sad break; 192*297f4619Sad *start = (uintptr_t)symp[i].st_value; 193*297f4619Sad *end = *start + (uintptr_t)symp[i].st_size; 194*297f4619Sad goto found; 195*297f4619Sad 196*297f4619Sad case LOCK_BYADDR: 197*297f4619Sad if (ELF_ST_TYPE(symp[i].st_info) != STT_OBJECT) 198*297f4619Sad break; 199*297f4619Sad if (*start != (uintptr_t)symp[i].st_value) 200*297f4619Sad break; 201*297f4619Sad strcpy(name, &strp[symp[i].st_name]); 202*297f4619Sad goto found; 203*297f4619Sad 204*297f4619Sad case FUNC_BYNAME: 205*297f4619Sad if (ELF_ST_TYPE(symp[i].st_info) != STT_FUNC) 206*297f4619Sad break; 207*297f4619Sad if (strcmp(&strp[symp[i].st_name], name) != 0) 208*297f4619Sad break; 209*297f4619Sad *start = (uintptr_t)symp[i].st_value; 210*297f4619Sad *end = *start + (uintptr_t)symp[i].st_size; 211*297f4619Sad goto found; 212*297f4619Sad 213*297f4619Sad case FUNC_BYADDR: 214*297f4619Sad if (ELF_ST_TYPE(symp[i].st_info) != STT_FUNC) 215*297f4619Sad break; 216*297f4619Sad sa = (uintptr_t)symp[i].st_value; 217*297f4619Sad ea = sa + (uintptr_t)symp[i].st_size - 1; 218*297f4619Sad if (*start < sa || *start > ea) 219*297f4619Sad break; 220*297f4619Sad sprintf(name, "%s+0x%x", 221*297f4619Sad &strp[symp[i].st_name], (int)(*start - sa)); 222*297f4619Sad goto found; 223*297f4619Sad 224*297f4619Sad default: 225*297f4619Sad break; 226*297f4619Sad } 227*297f4619Sad 228*297f4619Sad #ifdef dump_core 229*297f4619Sad if (++i >= nsyms) 230*297f4619Sad i = 0; 231*297f4619Sad if (i == lastptr[find]) 232*297f4619Sad return -1; 233*297f4619Sad #endif 234*297f4619Sad } 235*297f4619Sad 236*297f4619Sad return -1; 237*297f4619Sad 238*297f4619Sad found: 239*297f4619Sad lastptr[find] = i; 240*297f4619Sad return 0; 241*297f4619Sad } 242