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

1.3     ! art         1: /*     $OpenBSD: symbol.c,v 1.2 2002/03/15 16:41:06 jason 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>
                     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) {
1.3     ! art        54:                /* XXX - this 0 doesn't have to be correct.. */
        !            55:                ps->ps_sym_exe = st_open(ps, name, 0);
1.1       art        56:                if (ps->ps_sym_exe)
                     57:                        ps->ps_sym_exe->st_flags |= ST_EXEC;
                     58:        }
                     59: }
                     60:
                     61: /*
                     62:  * Destroy all symbol tables.
                     63:  */
                     64: void
                     65: sym_destroy(struct pstate *ps)
                     66: {
                     67:        struct sym_table *st;
                     68:
                     69:        while ((st = TAILQ_FIRST(&ps->ps_syms)) != NULL) {
                     70:                TAILQ_REMOVE(&ps->ps_syms, st, st_list);
                     71:                (*ps->ps_sops->sop_close)(st);
                     72:        }
                     73:        ps->ps_sym_exe = NULL;
                     74: }
                     75:
                     76: /*
                     77:  * We have reasons to believe that the symbol tables we have are not consistent
                     78:  * with the running binary. Update.
                     79:  */
                     80: void
                     81: sym_update(struct pstate *ps)
                     82: {
                     83:        (*ps->ps_sops->sop_update)(ps);
                     84: }
                     85:
                     86: char *
                     87: sym_name_and_offset(struct pstate *ps, reg pc, char *nam, size_t len, reg *off)
                     88: {
                     89:        struct sym_table *st;
                     90:        int bestoffisset = 0;
                     91:        reg bestoff, noff;
                     92:        char *res;
                     93:
                     94:        TAILQ_FOREACH(st, &ps->ps_syms, st_list) {
                     95:                res = (*ps->ps_sops->sop_name_and_off)(st, pc, &noff);
                     96:                if (res == NULL)
                     97:                        continue;
                     98:                if (noff < bestoff || !bestoffisset) {
                     99:                        bestoffisset = 1;
                    100:                        bestoff = noff;
                    101:                        strlcpy(nam, res, len);
                    102:                }
                    103:        }
                    104:
                    105:        if (!bestoffisset || !strcmp(nam, "_end"))
                    106:                return (NULL);
                    107:
                    108:        *off = bestoff;
                    109:        return (nam);
                    110: }
                    111:
                    112: int
                    113: sym_lookup(struct pstate *ps, const char *name, reg *res)
                    114: {
                    115:        /*
                    116:         * We let the sop do the table walking itself since it might have
                    117:         * preferences about what symbols to pick (weak and stuff).
                    118:         */
                    119:        return ((*ps->ps_sops->sop_lookup)(ps, name, res));
                    120: }
                    121:
                    122: char *
                    123: sym_print(struct pstate *ps, reg pc, char *buf, size_t buflen)
                    124: {
                    125:        char namebuf[1024], *name;
                    126:        reg offs;
                    127:
                    128:        name = sym_name_and_offset(ps, pc, namebuf, sizeof(namebuf), &offs);
                    129:        if (name == NULL) {
                    130:                snprintf(buf, buflen, "0x%lx", pc);
                    131:        } else {
                    132:                snprintf(buf, buflen, "%s+0x%lx(0x%lx)", name, offs, pc);
                    133:        }
                    134:
                    135:        return (buf);
                    136: }
                    137:
                    138: /*
                    139:  * Open a symbol table and install it in the list. Don't do anything if
                    140:  * it's already there.
                    141:  */
                    142: struct sym_table *
1.3     ! art       143: st_open(struct pstate *ps, const char *name, reg offs)
1.1       art       144: {
                    145:        struct sym_table *st;
                    146:
                    147:        TAILQ_FOREACH(st, &ps->ps_syms, st_list) {
1.3     ! art       148:                if (!strcmp(name, st->st_fname) && (st->st_offs == offs))
1.1       art       149:                        return (st);
                    150:        }
                    151:
                    152:        warnx("Loading symbols from %s", name);
                    153:
                    154:        if ((st = (*ps->ps_sops->sop_open)(name)) != NULL) {
                    155:                TAILQ_INSERT_TAIL(&ps->ps_syms, st, st_list);
                    156:                strlcpy(st->st_fname, name, sizeof(st->st_fname));
                    157:        }
1.3     ! art       158:
        !           159:        st->st_offs = offs;
1.1       art       160:
                    161:        return (st);
                    162: }
                    163: