[BACK]Return to symbol.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / pmdb

Annotation of src/usr.bin/pmdb/symbol.c, Revision 1.5

1.5     ! art         1: /*     $OpenBSD: symbol.c,v 1.4 2002/03/15 18:04:41 art Exp $  */
1.1       art         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>
1.4       art        31: #include <errno.h>
1.1       art        32:
                     33: #include "pmdb.h"
                     34: #include "symbol.h"
                     35:
                     36: /*
                     37:  * Initialize the executable and the symbol table.
                     38:  */
                     39: void
                     40: sym_init_exec(struct pstate *ps, const char *name)
                     41: {
                     42:        ps->ps_sops = NULL;
                     43:        ps->ps_sym_exe = NULL;
                     44:        TAILQ_INIT(&ps->ps_syms);
                     45:
                     46: #ifdef PMDB_ELF
                     47:        if (sym_check_elf(name, ps))
                     48: #endif
                     49: #ifdef PMDB_AOUT
                     50:        if (sym_check_aout(name, ps))
                     51: #endif
                     52:                warnx("sym_init_exec: %s is not a supported file format", name);
                     53:
                     54:        if (ps->ps_sops) {
1.3       art        55:                /* XXX - this 0 doesn't have to be correct.. */
                     56:                ps->ps_sym_exe = st_open(ps, name, 0);
1.1       art        57:                if (ps->ps_sym_exe)
                     58:                        ps->ps_sym_exe->st_flags |= ST_EXEC;
                     59:        }
                     60: }
                     61:
                     62: /*
                     63:  * Destroy all symbol tables.
                     64:  */
                     65: void
                     66: sym_destroy(struct pstate *ps)
                     67: {
                     68:        struct sym_table *st;
                     69:
                     70:        while ((st = TAILQ_FIRST(&ps->ps_syms)) != NULL) {
                     71:                TAILQ_REMOVE(&ps->ps_syms, st, st_list);
                     72:                (*ps->ps_sops->sop_close)(st);
                     73:        }
                     74:        ps->ps_sym_exe = NULL;
                     75: }
                     76:
                     77: /*
                     78:  * We have reasons to believe that the symbol tables we have are not consistent
                     79:  * with the running binary. Update.
                     80:  */
                     81: void
                     82: sym_update(struct pstate *ps)
                     83: {
                     84:        (*ps->ps_sops->sop_update)(ps);
                     85: }
                     86:
                     87: char *
                     88: sym_name_and_offset(struct pstate *ps, reg pc, char *nam, size_t len, reg *off)
                     89: {
                     90:        struct sym_table *st;
                     91:        int bestoffisset = 0;
                     92:        reg bestoff, noff;
                     93:        char *res;
                     94:
                     95:        TAILQ_FOREACH(st, &ps->ps_syms, st_list) {
                     96:                res = (*ps->ps_sops->sop_name_and_off)(st, pc, &noff);
                     97:                if (res == NULL)
                     98:                        continue;
                     99:                if (noff < bestoff || !bestoffisset) {
                    100:                        bestoffisset = 1;
                    101:                        bestoff = noff;
                    102:                        strlcpy(nam, res, len);
                    103:                }
                    104:        }
                    105:
                    106:        if (!bestoffisset || !strcmp(nam, "_end"))
                    107:                return (NULL);
                    108:
                    109:        *off = bestoff;
                    110:        return (nam);
                    111: }
                    112:
                    113: int
                    114: sym_lookup(struct pstate *ps, const char *name, reg *res)
                    115: {
                    116:        /*
                    117:         * We let the sop do the table walking itself since it might have
                    118:         * preferences about what symbols to pick (weak and stuff).
                    119:         */
                    120:        return ((*ps->ps_sops->sop_lookup)(ps, name, res));
                    121: }
                    122:
                    123: char *
                    124: sym_print(struct pstate *ps, reg pc, char *buf, size_t buflen)
                    125: {
                    126:        char namebuf[1024], *name;
                    127:        reg offs;
                    128:
                    129:        name = sym_name_and_offset(ps, pc, namebuf, sizeof(namebuf), &offs);
                    130:        if (name == NULL) {
                    131:                snprintf(buf, buflen, "0x%lx", pc);
                    132:        } else {
                    133:                snprintf(buf, buflen, "%s+0x%lx(0x%lx)", name, offs, pc);
                    134:        }
                    135:
                    136:        return (buf);
                    137: }
                    138:
                    139: /*
                    140:  * Open a symbol table and install it in the list. Don't do anything if
                    141:  * it's already there.
                    142:  */
                    143: struct sym_table *
1.3       art       144: st_open(struct pstate *ps, const char *name, reg offs)
1.1       art       145: {
                    146:        struct sym_table *st;
                    147:
                    148:        TAILQ_FOREACH(st, &ps->ps_syms, st_list) {
1.3       art       149:                if (!strcmp(name, st->st_fname) && (st->st_offs == offs))
1.1       art       150:                        return (st);
                    151:        }
                    152:
1.4       art       153:        warnx("Loading symbols from %s at 0x%lx", name, offs);
1.1       art       154:
                    155:        if ((st = (*ps->ps_sops->sop_open)(name)) != NULL) {
                    156:                TAILQ_INSERT_TAIL(&ps->ps_syms, st, st_list);
                    157:                strlcpy(st->st_fname, name, sizeof(st->st_fname));
1.5     ! art       158:                st->st_offs = offs;
1.1       art       159:        }
                    160:
                    161:        return (st);
                    162: }
                    163:
1.4       art       164: /*
                    165:  * Load a symbol table from file argv[1] at offset argv[2].
                    166:  */
                    167: int
                    168: cmd_sym_load(int argc, char **argv, void *arg)
                    169: {
                    170:        struct pstate *ps = arg;
                    171:        char *fname, *ep;
                    172:        reg offs;
                    173:
                    174:        fname = argv[1];
                    175:        errno = 0;
                    176:        offs = strtol(argv[2], &ep, 0);
                    177:        if (argv[2][0] == '\0' || *ep != '\0' || errno == ERANGE) {
                    178:                fprintf(stderr, "%s is not a valid offset\n", argv[2]);
                    179:                return (0);
                    180:        }
                    181:
                    182:        if (st_open(ps, fname, offs) == NULL) {
                    183:                warnx("symbol loading failed");
                    184:        }
                    185:
                    186:        return (0);
                    187: }