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: