Annotation of src/usr.bin/pmdb/symbol.c, Revision 1.1
1.1 ! art 1: /* $PMDB: symbol.c,v 1.5 2002/03/07 14:27:08 art Exp $ */
! 2: /*
! 3: * Copyright (c) 2002 Artur Grabowski <art@openbsd.org>
! 4: * All rights reserved.
! 5: *
! 6: * Redistribution and use in source and binary forms, with or without
! 7: * modification, are permitted provided that the following conditions
! 8: * are met:
! 9: *
! 10: * 1. Redistributions of source code must retain the above copyright
! 11: * notice, this list of conditions and the following disclaimer.
! 12: * 2. The name of the author may not be used to endorse or promote products
! 13: * derived from this software without specific prior written permission.
! 14: *
! 15: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
! 16: * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
! 17: * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
! 18: * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
! 19: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
! 20: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
! 21: * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
! 22: * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
! 23: * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
! 24: * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
! 25: */
! 26:
! 27: #include <stdlib.h>
! 28: #include <stdio.h>
! 29: #include <string.h>
! 30: #include <err.h>
! 31:
! 32: #include "pmdb.h"
! 33: #include "symbol.h"
! 34:
! 35: /*
! 36: * Initialize the executable and the symbol table.
! 37: */
! 38: void
! 39: sym_init_exec(struct pstate *ps, const char *name)
! 40: {
! 41: ps->ps_sops = NULL;
! 42: ps->ps_sym_exe = NULL;
! 43: TAILQ_INIT(&ps->ps_syms);
! 44:
! 45: #ifdef PMDB_ELF
! 46: if (sym_check_elf(name, ps))
! 47: #endif
! 48: #ifdef PMDB_AOUT
! 49: if (sym_check_aout(name, ps))
! 50: #endif
! 51: warnx("sym_init_exec: %s is not a supported file format", name);
! 52:
! 53: if (ps->ps_sops) {
! 54: ps->ps_sym_exe = st_open(ps, name);
! 55: if (ps->ps_sym_exe)
! 56: ps->ps_sym_exe->st_flags |= ST_EXEC;
! 57: }
! 58: }
! 59:
! 60: /*
! 61: * Destroy all symbol tables.
! 62: */
! 63: void
! 64: sym_destroy(struct pstate *ps)
! 65: {
! 66: struct sym_table *st;
! 67:
! 68: while ((st = TAILQ_FIRST(&ps->ps_syms)) != NULL) {
! 69: TAILQ_REMOVE(&ps->ps_syms, st, st_list);
! 70: (*ps->ps_sops->sop_close)(st);
! 71: }
! 72: ps->ps_sym_exe = NULL;
! 73: }
! 74:
! 75: /*
! 76: * We have reasons to believe that the symbol tables we have are not consistent
! 77: * with the running binary. Update.
! 78: */
! 79: void
! 80: sym_update(struct pstate *ps)
! 81: {
! 82: (*ps->ps_sops->sop_update)(ps);
! 83: }
! 84:
! 85: char *
! 86: sym_name_and_offset(struct pstate *ps, reg pc, char *nam, size_t len, reg *off)
! 87: {
! 88: struct sym_table *st;
! 89: int bestoffisset = 0;
! 90: reg bestoff, noff;
! 91: char *res;
! 92:
! 93: TAILQ_FOREACH(st, &ps->ps_syms, st_list) {
! 94: res = (*ps->ps_sops->sop_name_and_off)(st, pc, &noff);
! 95: if (res == NULL)
! 96: continue;
! 97: if (noff < bestoff || !bestoffisset) {
! 98: bestoffisset = 1;
! 99: bestoff = noff;
! 100: strlcpy(nam, res, len);
! 101: }
! 102: }
! 103:
! 104: if (!bestoffisset || !strcmp(nam, "_end"))
! 105: return (NULL);
! 106:
! 107: *off = bestoff;
! 108: return (nam);
! 109: }
! 110:
! 111: int
! 112: sym_lookup(struct pstate *ps, const char *name, reg *res)
! 113: {
! 114: /*
! 115: * We let the sop do the table walking itself since it might have
! 116: * preferences about what symbols to pick (weak and stuff).
! 117: */
! 118: return ((*ps->ps_sops->sop_lookup)(ps, name, res));
! 119: }
! 120:
! 121: char *
! 122: sym_print(struct pstate *ps, reg pc, char *buf, size_t buflen)
! 123: {
! 124: char namebuf[1024], *name;
! 125: reg offs;
! 126:
! 127: name = sym_name_and_offset(ps, pc, namebuf, sizeof(namebuf), &offs);
! 128: if (name == NULL) {
! 129: snprintf(buf, buflen, "0x%lx", pc);
! 130: } else {
! 131: snprintf(buf, buflen, "%s+0x%lx(0x%lx)", name, offs, pc);
! 132: }
! 133:
! 134: return (buf);
! 135: }
! 136:
! 137: /*
! 138: * Open a symbol table and install it in the list. Don't do anything if
! 139: * it's already there.
! 140: */
! 141: struct sym_table *
! 142: st_open(struct pstate *ps, const char *name)
! 143: {
! 144: struct sym_table *st;
! 145:
! 146: TAILQ_FOREACH(st, &ps->ps_syms, st_list) {
! 147: if (!strcmp(name, st->st_fname))
! 148: return (st);
! 149: }
! 150:
! 151: warnx("Loading symbols from %s", name);
! 152:
! 153: if ((st = (*ps->ps_sops->sop_open)(name)) != NULL) {
! 154: TAILQ_INSERT_TAIL(&ps->ps_syms, st, st_list);
! 155: strlcpy(st->st_fname, name, sizeof(st->st_fname));
! 156: }
! 157:
! 158: return (st);
! 159: }
! 160: