[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.7

1.7     ! mickey      1: /*     $OpenBSD: symbol.c,v 1.6 2002/07/24 14:06:27 vincent 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:
1.6       vincent    70:        if (!(ps->ps_flags & PSF_SYMBOLS))
                     71:                return;
1.1       art        72:        while ((st = TAILQ_FIRST(&ps->ps_syms)) != NULL) {
                     73:                TAILQ_REMOVE(&ps->ps_syms, st, st_list);
                     74:                (*ps->ps_sops->sop_close)(st);
                     75:        }
                     76:        ps->ps_sym_exe = NULL;
                     77: }
                     78:
                     79: /*
                     80:  * We have reasons to believe that the symbol tables we have are not consistent
                     81:  * with the running binary. Update.
                     82:  */
                     83: void
                     84: sym_update(struct pstate *ps)
                     85: {
                     86:        (*ps->ps_sops->sop_update)(ps);
                     87: }
                     88:
                     89: char *
                     90: sym_name_and_offset(struct pstate *ps, reg pc, char *nam, size_t len, reg *off)
                     91: {
                     92:        struct sym_table *st;
                     93:        int bestoffisset = 0;
                     94:        reg bestoff, noff;
                     95:        char *res;
                     96:
                     97:        TAILQ_FOREACH(st, &ps->ps_syms, st_list) {
                     98:                res = (*ps->ps_sops->sop_name_and_off)(st, pc, &noff);
                     99:                if (res == NULL)
                    100:                        continue;
                    101:                if (noff < bestoff || !bestoffisset) {
                    102:                        bestoffisset = 1;
                    103:                        bestoff = noff;
                    104:                        strlcpy(nam, res, len);
                    105:                }
                    106:        }
                    107:
                    108:        if (!bestoffisset || !strcmp(nam, "_end"))
                    109:                return (NULL);
                    110:
                    111:        *off = bestoff;
                    112:        return (nam);
                    113: }
                    114:
                    115: int
                    116: sym_lookup(struct pstate *ps, const char *name, reg *res)
                    117: {
                    118:        /*
                    119:         * We let the sop do the table walking itself since it might have
                    120:         * preferences about what symbols to pick (weak and stuff).
                    121:         */
                    122:        return ((*ps->ps_sops->sop_lookup)(ps, name, res));
                    123: }
                    124:
                    125: char *
                    126: sym_print(struct pstate *ps, reg pc, char *buf, size_t buflen)
                    127: {
                    128:        char namebuf[1024], *name;
                    129:        reg offs;
                    130:
                    131:        name = sym_name_and_offset(ps, pc, namebuf, sizeof(namebuf), &offs);
                    132:        if (name == NULL) {
                    133:                snprintf(buf, buflen, "0x%lx", pc);
                    134:        } else {
1.7     ! mickey    135:                if (offs)
        !           136:                        snprintf(buf, buflen, "%s+0x%lx(0x%lx)",
        !           137:                            name, offs, pc);
        !           138:                else
        !           139:                        snprintf(buf, buflen, "%s(0x%lx)", name, pc);
1.1       art       140:        }
                    141:
                    142:        return (buf);
                    143: }
                    144:
                    145: /*
                    146:  * Open a symbol table and install it in the list. Don't do anything if
                    147:  * it's already there.
                    148:  */
                    149: struct sym_table *
1.3       art       150: st_open(struct pstate *ps, const char *name, reg offs)
1.1       art       151: {
                    152:        struct sym_table *st;
                    153:
                    154:        TAILQ_FOREACH(st, &ps->ps_syms, st_list) {
1.3       art       155:                if (!strcmp(name, st->st_fname) && (st->st_offs == offs))
1.1       art       156:                        return (st);
                    157:        }
                    158:
1.4       art       159:        warnx("Loading symbols from %s at 0x%lx", name, offs);
1.1       art       160:
                    161:        if ((st = (*ps->ps_sops->sop_open)(name)) != NULL) {
                    162:                TAILQ_INSERT_TAIL(&ps->ps_syms, st, st_list);
                    163:                strlcpy(st->st_fname, name, sizeof(st->st_fname));
1.5       art       164:                st->st_offs = offs;
1.1       art       165:        }
                    166:
                    167:        return (st);
                    168: }
                    169:
1.4       art       170: /*
                    171:  * Load a symbol table from file argv[1] at offset argv[2].
                    172:  */
                    173: int
                    174: cmd_sym_load(int argc, char **argv, void *arg)
                    175: {
                    176:        struct pstate *ps = arg;
                    177:        char *fname, *ep;
                    178:        reg offs;
                    179:
                    180:        fname = argv[1];
                    181:        errno = 0;
                    182:        offs = strtol(argv[2], &ep, 0);
                    183:        if (argv[2][0] == '\0' || *ep != '\0' || errno == ERANGE) {
                    184:                fprintf(stderr, "%s is not a valid offset\n", argv[2]);
                    185:                return (0);
                    186:        }
                    187:
                    188:        if (st_open(ps, fname, offs) == NULL) {
                    189:                warnx("symbol loading failed");
                    190:        }
                    191:
                    192:        return (0);
                    193: }