|
|
1.1 ! root 1: /* ! 2: * Copyright (C) 2014 Free Software Foundation, Inc. ! 3: * ! 4: * This program is free software; you can redistribute it and/or ! 5: * modify it under the terms of the GNU General Public License as ! 6: * published by the Free Software Foundation; either version 2, or (at ! 7: * your option) any later version. ! 8: * ! 9: * This program is distributed in the hope that it will be useful, but ! 10: * WITHOUT ANY WARRANTY; without even the implied warranty of ! 11: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ! 12: * General Public License for more details. ! 13: * ! 14: * You should have received a copy of the GNU General Public License ! 15: * along with this program. If not, see <http://www.gnu.org/licenses/>. ! 16: */ ! 17: /* ! 18: * Mach Operating System ! 19: * Copyright (c) 1991,1990 Carnegie Mellon University ! 20: * All Rights Reserved. ! 21: * ! 22: * Permission to use, copy, modify and distribute this software and its ! 23: * documentation is hereby granted, provided that both the copyright ! 24: * notice and this permission notice appear in all copies of the ! 25: * software, derivative works or modified versions, and any portions ! 26: * thereof, and that both notices appear in supporting documentation. ! 27: * ! 28: * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" ! 29: * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR ! 30: * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. ! 31: * ! 32: * Carnegie Mellon requests users of this software to return to ! 33: * ! 34: * Software Distribution Coordinator or [email protected] ! 35: * School of Computer Science ! 36: * Carnegie Mellon University ! 37: * Pittsburgh PA 15213-3890 ! 38: * ! 39: * any improvements or extensions that they make and grant Carnegie Mellon ! 40: * the rights to redistribute these changes. ! 41: */ ! 42: /* ! 43: * Author: David B. Golub, Carnegie Mellon University ! 44: * Date: 7/90 ! 45: */ ! 46: ! 47: #if MACH_KDB ! 48: ! 49: /* ! 50: * Symbol table routines for ELF format files. ! 51: */ ! 52: ! 53: #include <string.h> ! 54: #include <mach/std_types.h> ! 55: #include <mach/exec/elf.h> ! 56: #include <machine/db_machdep.h> /* data types */ ! 57: #include <machine/vm_param.h> ! 58: #include <ddb/db_output.h> ! 59: #include <ddb/db_sym.h> ! 60: #include <ddb/db_elf.h> ! 61: ! 62: #ifndef DB_NO_ELF ! 63: ! 64: struct db_symtab_elf { ! 65: int type; ! 66: Elf32_Sym *start; ! 67: Elf32_Sym *end; ! 68: char *strings; ! 69: char *map_pointer; /* symbols are for this map only, ! 70: if not null */ ! 71: char name[SYMTAB_NAME_LEN]; ! 72: /* symtab name */ ! 73: }; ! 74: ! 75: boolean_t ! 76: elf_db_sym_init (unsigned shdr_num, ! 77: vm_size_t shdr_size, ! 78: vm_offset_t shdr_addr, ! 79: unsigned shdr_shndx, ! 80: char *name, ! 81: char *task_addr) ! 82: { ! 83: Elf32_Shdr *shdr, *symtab, *strtab; ! 84: const char *shstrtab; ! 85: int i; ! 86: ! 87: if (shdr_num == 0) ! 88: return FALSE; ! 89: ! 90: if (shdr_size != sizeof *shdr) ! 91: return FALSE; ! 92: ! 93: shdr = (Elf32_Shdr *) shdr_addr; ! 94: ! 95: if (shdr[shdr_shndx].sh_type != SHT_STRTAB) ! 96: return FALSE; ! 97: ! 98: shstrtab = (const char *) phystokv (shdr[shdr_shndx].sh_addr); ! 99: ! 100: symtab = strtab = NULL; ! 101: for (i = 0; i < shdr_num; i++) ! 102: switch (shdr[i].sh_type) { ! 103: case SHT_SYMTAB: ! 104: if (symtab) ! 105: db_printf ("Ignoring additional ELF symbol table at %d\n", i); ! 106: else ! 107: symtab = &shdr[i]; ! 108: break; ! 109: ! 110: case SHT_STRTAB: ! 111: if (strcmp (&shstrtab[shdr[i].sh_name], ".strtab") == 0) { ! 112: if (strtab) ! 113: db_printf ("Ignoring additional ELF string table at %d\n", i); ! 114: else ! 115: strtab = &shdr[i]; ! 116: } ! 117: break; ! 118: } ! 119: ! 120: if (symtab == NULL || strtab == NULL) ! 121: return FALSE; ! 122: ! 123: if (db_add_symbol_table (SYMTAB_ELF, ! 124: (char *) phystokv (symtab->sh_addr), ! 125: (char *) phystokv (symtab->sh_addr)+symtab->sh_size, ! 126: name, ! 127: (char *) phystokv (strtab->sh_addr), ! 128: task_addr)) { ! 129: db_printf ("Loaded ELF symbol table for %s (%d symbols)\n", ! 130: name, symtab->sh_size / sizeof (Elf32_Sym)); ! 131: return TRUE; ! 132: } ! 133: ! 134: return FALSE; ! 135: } ! 136: ! 137: /* ! 138: * lookup symbol by name ! 139: */ ! 140: db_sym_t ! 141: elf_db_lookup (db_symtab_t *stab, ! 142: char *symstr) ! 143: { ! 144: struct db_symtab_elf *self = (struct db_symtab_elf *) stab; ! 145: Elf32_Sym *s; ! 146: ! 147: for (s = self->start; s < self->end; s++) ! 148: if (strcmp (symstr, &self->strings[s->st_name]) == 0) ! 149: return (db_sym_t) s; ! 150: ! 151: return NULL; ! 152: } ! 153: ! 154: db_sym_t ! 155: elf_db_search_symbol (db_symtab_t *stab, ! 156: db_addr_t off, ! 157: db_strategy_t strategy, ! 158: db_expr_t *diffp) /* in/out */ ! 159: { ! 160: struct db_symtab_elf *self = (struct db_symtab_elf *) stab; ! 161: unsigned long diff = *diffp; ! 162: Elf32_Sym *s, *symp = NULL; ! 163: ! 164: for (s = self->start; s < self->end; s++) { ! 165: if (s->st_name == 0) ! 166: continue; ! 167: ! 168: if (strategy == DB_STGY_XTRN && (s->st_info & STB_GLOBAL) == 0) ! 169: continue; ! 170: ! 171: if (off >= s->st_value) { ! 172: if (s->st_info == STT_FUNC) ! 173: continue; ! 174: ! 175: if (off - s->st_value < diff) { ! 176: diff = off - s->st_value; ! 177: symp = s; ! 178: if (diff == 0 && (s->st_info & STB_GLOBAL)) ! 179: break; ! 180: } else if (off - s->st_value == diff) { ! 181: if (symp == NULL) ! 182: symp = s; ! 183: else if ((symp->st_info & STB_GLOBAL) == 0 ! 184: && (s->st_info & STB_GLOBAL) != 0) ! 185: symp = s; /* pick the external symbol */ ! 186: } ! 187: } ! 188: } ! 189: ! 190: if (symp == NULL) ! 191: *diffp = off; ! 192: else ! 193: *diffp = diff; ! 194: ! 195: return (db_sym_t) symp; ! 196: } ! 197: ! 198: /* ! 199: * Return the name and value for a symbol. ! 200: */ ! 201: void ! 202: elf_db_symbol_values (db_symtab_t *stab, ! 203: db_sym_t sym, ! 204: char **namep, ! 205: db_expr_t *valuep) ! 206: { ! 207: struct db_symtab_elf *self = (struct db_symtab_elf *) stab; ! 208: Elf32_Sym *s = (Elf32_Sym *) sym; ! 209: ! 210: if (namep) ! 211: *namep = &self->strings[s->st_name]; ! 212: if (valuep) ! 213: *valuep = s->st_value; ! 214: } ! 215: ! 216: /* ! 217: * Find filename and lineno within, given the current pc. ! 218: */ ! 219: boolean_t ! 220: elf_db_line_at_pc (db_symtab_t *stab, ! 221: db_sym_t sym, ! 222: char **file, ! 223: int *line, ! 224: db_addr_t pc) ! 225: { ! 226: /* XXX Parse DWARF information. */ ! 227: return FALSE; ! 228: } ! 229: ! 230: #endif /* DB_NO_ELF */ ! 231: ! 232: #endif /* MACH_KDB */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.