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