File: [local] / src / usr.bin / pmdb / Attic / symbol.c (download)
Revision 1.7, Fri Mar 28 23:33:27 2003 UTC (21 years, 2 months ago) by mickey
Branch: MAIN
CVS Tags: OPENBSD_5_2_BASE, OPENBSD_5_2, OPENBSD_5_1_BASE, OPENBSD_5_1, OPENBSD_5_0_BASE, OPENBSD_5_0, OPENBSD_4_9_BASE, OPENBSD_4_9, OPENBSD_4_8_BASE, OPENBSD_4_8, OPENBSD_4_7_BASE, OPENBSD_4_7, OPENBSD_4_6_BASE, OPENBSD_4_6, OPENBSD_4_5_BASE, OPENBSD_4_5, OPENBSD_4_4_BASE, OPENBSD_4_4, OPENBSD_4_3_BASE, OPENBSD_4_3, OPENBSD_4_2_BASE, OPENBSD_4_2, OPENBSD_4_1_BASE, OPENBSD_4_1, OPENBSD_4_0_BASE, OPENBSD_4_0, OPENBSD_3_9_BASE, OPENBSD_3_9, OPENBSD_3_8_BASE, OPENBSD_3_8, OPENBSD_3_7_BASE, OPENBSD_3_7, OPENBSD_3_6_BASE, OPENBSD_3_6, OPENBSD_3_5_BASE, OPENBSD_3_5, OPENBSD_3_4_BASE, OPENBSD_3_4 Changes since 1.6: +6 -2 lines
do not core dump on stripped executables. revmap the registers printed to the symbols even for cores (already happens for live executables); art@ said it should wait until after the release and so it is already after the release now
|
/* $OpenBSD: symbol.c,v 1.7 2003/03/28 23:33:27 mickey Exp $ */
/*
* Copyright (c) 2002 Artur Grabowski <art@openbsd.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <err.h>
#include <errno.h>
#include "pmdb.h"
#include "symbol.h"
/*
* Initialize the executable and the symbol table.
*/
void
sym_init_exec(struct pstate *ps, const char *name)
{
ps->ps_sops = NULL;
ps->ps_sym_exe = NULL;
TAILQ_INIT(&ps->ps_syms);
#ifdef PMDB_ELF
if (sym_check_elf(name, ps))
#endif
#ifdef PMDB_AOUT
if (sym_check_aout(name, ps))
#endif
warnx("sym_init_exec: %s is not a supported file format", name);
if (ps->ps_sops) {
/* XXX - this 0 doesn't have to be correct.. */
ps->ps_sym_exe = st_open(ps, name, 0);
if (ps->ps_sym_exe)
ps->ps_sym_exe->st_flags |= ST_EXEC;
}
}
/*
* Destroy all symbol tables.
*/
void
sym_destroy(struct pstate *ps)
{
struct sym_table *st;
if (!(ps->ps_flags & PSF_SYMBOLS))
return;
while ((st = TAILQ_FIRST(&ps->ps_syms)) != NULL) {
TAILQ_REMOVE(&ps->ps_syms, st, st_list);
(*ps->ps_sops->sop_close)(st);
}
ps->ps_sym_exe = NULL;
}
/*
* We have reasons to believe that the symbol tables we have are not consistent
* with the running binary. Update.
*/
void
sym_update(struct pstate *ps)
{
(*ps->ps_sops->sop_update)(ps);
}
char *
sym_name_and_offset(struct pstate *ps, reg pc, char *nam, size_t len, reg *off)
{
struct sym_table *st;
int bestoffisset = 0;
reg bestoff, noff;
char *res;
TAILQ_FOREACH(st, &ps->ps_syms, st_list) {
res = (*ps->ps_sops->sop_name_and_off)(st, pc, &noff);
if (res == NULL)
continue;
if (noff < bestoff || !bestoffisset) {
bestoffisset = 1;
bestoff = noff;
strlcpy(nam, res, len);
}
}
if (!bestoffisset || !strcmp(nam, "_end"))
return (NULL);
*off = bestoff;
return (nam);
}
int
sym_lookup(struct pstate *ps, const char *name, reg *res)
{
/*
* We let the sop do the table walking itself since it might have
* preferences about what symbols to pick (weak and stuff).
*/
return ((*ps->ps_sops->sop_lookup)(ps, name, res));
}
char *
sym_print(struct pstate *ps, reg pc, char *buf, size_t buflen)
{
char namebuf[1024], *name;
reg offs;
name = sym_name_and_offset(ps, pc, namebuf, sizeof(namebuf), &offs);
if (name == NULL) {
snprintf(buf, buflen, "0x%lx", pc);
} else {
if (offs)
snprintf(buf, buflen, "%s+0x%lx(0x%lx)",
name, offs, pc);
else
snprintf(buf, buflen, "%s(0x%lx)", name, pc);
}
return (buf);
}
/*
* Open a symbol table and install it in the list. Don't do anything if
* it's already there.
*/
struct sym_table *
st_open(struct pstate *ps, const char *name, reg offs)
{
struct sym_table *st;
TAILQ_FOREACH(st, &ps->ps_syms, st_list) {
if (!strcmp(name, st->st_fname) && (st->st_offs == offs))
return (st);
}
warnx("Loading symbols from %s at 0x%lx", name, offs);
if ((st = (*ps->ps_sops->sop_open)(name)) != NULL) {
TAILQ_INSERT_TAIL(&ps->ps_syms, st, st_list);
strlcpy(st->st_fname, name, sizeof(st->st_fname));
st->st_offs = offs;
}
return (st);
}
/*
* Load a symbol table from file argv[1] at offset argv[2].
*/
int
cmd_sym_load(int argc, char **argv, void *arg)
{
struct pstate *ps = arg;
char *fname, *ep;
reg offs;
fname = argv[1];
errno = 0;
offs = strtol(argv[2], &ep, 0);
if (argv[2][0] == '\0' || *ep != '\0' || errno == ERANGE) {
fprintf(stderr, "%s is not a valid offset\n", argv[2]);
return (0);
}
if (st_open(ps, fname, offs) == NULL) {
warnx("symbol loading failed");
}
return (0);
}