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: