1*949c1c4eSmiod /* $OpenBSD: db_sym.c,v 1.57 2024/11/07 16:02:29 miod Exp $ */
256c88695Sniklas /* $NetBSD: db_sym.c,v 1.24 2000/08/11 22:50:47 tv Exp $ */
3df930be7Sderaadt
4df930be7Sderaadt /*
5df930be7Sderaadt * Mach Operating System
6b2471a9dSmickey * Copyright (c) 1993,1992,1991,1990 Carnegie Mellon University
7df930be7Sderaadt * All Rights Reserved.
8df930be7Sderaadt *
9df930be7Sderaadt * Permission to use, copy, modify and distribute this software and its
10df930be7Sderaadt * documentation is hereby granted, provided that both the copyright
11df930be7Sderaadt * notice and this permission notice appear in all copies of the
12df930be7Sderaadt * software, derivative works or modified versions, and any portions
13df930be7Sderaadt * thereof, and that both notices appear in supporting documentation.
14df930be7Sderaadt *
15b2471a9dSmickey * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
16df930be7Sderaadt * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
17df930be7Sderaadt * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
18df930be7Sderaadt *
19df930be7Sderaadt * Carnegie Mellon requests users of this software to return to
20df930be7Sderaadt *
21df930be7Sderaadt * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
22df930be7Sderaadt * School of Computer Science
23df930be7Sderaadt * Carnegie Mellon University
24df930be7Sderaadt * Pittsburgh PA 15213-3890
25df930be7Sderaadt *
26b2471a9dSmickey * any improvements or extensions that they make and grant Carnegie Mellon
27b2471a9dSmickey * the rights to redistribute these changes.
28df930be7Sderaadt */
29df930be7Sderaadt
30df930be7Sderaadt #include <sys/param.h>
314fa33424Sniklas #include <sys/systm.h>
32df930be7Sderaadt
33df930be7Sderaadt #include <machine/db_machdep.h>
34df930be7Sderaadt
3556c88695Sniklas #include <ddb/db_lex.h>
36df930be7Sderaadt #include <ddb/db_sym.h>
373ed44a89Smickey #include <ddb/db_output.h>
383ed44a89Smickey #include <ddb/db_command.h>
39df930be7Sderaadt
409bdf46bfSderaadt extern char end[];
419bdf46bfSderaadt
42901f37c0Smickey /*
4356c88695Sniklas * Initialize the kernel debugger by initializing the master symbol
4456c88695Sniklas * table. Note that if initializing the master symbol table fails,
4556c88695Sniklas * no other symbol tables can be loaded.
4656c88695Sniklas */
4756c88695Sniklas void
ddb_init(void)486ecb06d0Sjsg ddb_init(void)
4956c88695Sniklas {
5056c88695Sniklas const char *name = "bsd";
5156c88695Sniklas extern char *esym;
52414976a8Smlarkin #if defined(__sparc64__) || defined(__mips__) || defined(__amd64__) || \
53414976a8Smlarkin defined(__i386__)
540edd4aceSart extern char *ssym;
550edd4aceSart #endif
560edd4aceSart char *xssym, *xesym;
5756c88695Sniklas
580edd4aceSart xesym = esym;
59414976a8Smlarkin #if defined(__sparc64__) || defined(__mips__) || defined(__amd64__) || \
60414976a8Smlarkin defined(__i386__)
610edd4aceSart xssym = ssym;
620edd4aceSart #else
63895da776Sfrantzen xssym = (char *)&end;
640edd4aceSart #endif
6556c88695Sniklas /*
6656c88695Sniklas * Do this check now for the master symbol table to avoid printing
6756c88695Sniklas * the message N times.
6856c88695Sniklas */
690edd4aceSart if ((((vaddr_t)xssym) & (sizeof(long) - 1)) != 0) {
7056c88695Sniklas printf("[ %s symbol table has bad start address %p ]\n",
710edd4aceSart name, xssym);
7256c88695Sniklas return;
7356c88695Sniklas }
7456c88695Sniklas
75fbc22d8dSmpi if (xesym != NULL && xesym != xssym) {
76fbc22d8dSmpi if (db_elf_sym_init((vaddr_t)xesym - (vaddr_t)xssym, xssym,
7751015a3eSmpi xesym, name) == 1)
7856c88695Sniklas return;
7956c88695Sniklas }
8056c88695Sniklas
8156c88695Sniklas printf("[ no symbol table formats found ]\n");
8256c88695Sniklas }
8356c88695Sniklas
8451015a3eSmpi int
db_eqname(const char * src,const char * dst,int c)85*949c1c4eSmiod db_eqname(const char *src, const char *dst, int c)
86df930be7Sderaadt {
87df930be7Sderaadt if (!strcmp(src, dst))
8851015a3eSmpi return (1);
89df930be7Sderaadt if (src[0] == c)
90df930be7Sderaadt return (!strcmp(src+1,dst));
9151015a3eSmpi return (0);
92df930be7Sderaadt }
93df930be7Sderaadt
94df930be7Sderaadt /*
95df930be7Sderaadt * Find the closest symbol to val, and return its name
96df930be7Sderaadt * and the difference between val and the symbol found.
97df930be7Sderaadt */
9862781896Smpi Elf_Sym *
db_search_symbol(vaddr_t val,db_strategy_t strategy,db_expr_t * offp)9908f058f8Smpi db_search_symbol(vaddr_t val, db_strategy_t strategy, db_expr_t *offp)
100df930be7Sderaadt {
10156c88695Sniklas unsigned int diff;
102b53beb00Sniklas db_expr_t newdiff;
10362781896Smpi Elf_Sym *ret = NULL, *sym;
104df930be7Sderaadt
10556c88695Sniklas newdiff = diff = ~0;
1066933210dSmpi sym = db_elf_sym_search(val, strategy, &newdiff);
10756c88695Sniklas if (newdiff < diff) {
108df930be7Sderaadt diff = newdiff;
109df930be7Sderaadt ret = sym;
110df930be7Sderaadt }
111df930be7Sderaadt *offp = diff;
112df930be7Sderaadt return ret;
113df930be7Sderaadt }
114df930be7Sderaadt
115df930be7Sderaadt /*
116e4adc412Sjasper * Print the closest symbol to a value.
117df930be7Sderaadt *
118df930be7Sderaadt * After matching the symbol according to the given strategy
119df930be7Sderaadt * we print it in the name+offset format, provided the symbol's
120df930be7Sderaadt * value is close enough (eg smaller than db_maxoff).
121df930be7Sderaadt * We also attempt to print [filename:linenum] when applicable
122df930be7Sderaadt * (eg for procedure names).
123df930be7Sderaadt *
124df930be7Sderaadt * If we could not find a reasonable name+offset representation,
125df930be7Sderaadt * then we just print the value in hex. Small values might get
126df930be7Sderaadt * bogus symbol associations, e.g. 3 might get some absolute
127df930be7Sderaadt * value like _INCLUDE_VERSION or something, therefore we do
128df930be7Sderaadt * not accept symbols whose value is zero (and use plain hex).
129df930be7Sderaadt * Also, avoid printing as "end+0x????" which is useless.
130df930be7Sderaadt * The variable db_lastsym is used instead of "end" in case we
131df930be7Sderaadt * add support for symbols in loadable driver modules.
132df930be7Sderaadt */
13356c88695Sniklas unsigned long db_lastsym = (unsigned long)end;
13456c88695Sniklas unsigned int db_maxoff = 0x10000000;
135df930be7Sderaadt
136df930be7Sderaadt
137df930be7Sderaadt void
db_printsym(db_expr_t off,db_strategy_t strategy,int (* pr)(const char *,...))13833ca0db6Sart db_printsym(db_expr_t off, db_strategy_t strategy,
13933ca0db6Sart int (*pr)(const char *, ...))
140df930be7Sderaadt {
141df930be7Sderaadt db_expr_t d;
142*949c1c4eSmiod const char *filename;
143*949c1c4eSmiod const char *name;
144df930be7Sderaadt db_expr_t value;
145df930be7Sderaadt int linenum;
14662781896Smpi Elf_Sym *cursym;
147dee4176fSart char buf[DB_FORMAT_BUF_SIZE];
148df930be7Sderaadt
14956c88695Sniklas if (off <= db_lastsym) {
150df930be7Sderaadt cursym = db_search_symbol(off, strategy, &d);
151df930be7Sderaadt db_symbol_values(cursym, &name, &value);
152df930be7Sderaadt if (name && (d < db_maxoff) && value) {
15333ca0db6Sart (*pr)("%s", name);
15456c88695Sniklas if (d) {
15533ca0db6Sart (*pr)("+%s", db_format(buf, sizeof(buf),
156dee4176fSart d, DB_FORMAT_R, 1, 0));
15756c88695Sniklas }
1584da10c57Sclaudio if (strategy == DB_STGY_PROC) {
1596933210dSmpi if (db_elf_line_at_pc(cursym, &filename,
1606933210dSmpi &linenum, off))
16133ca0db6Sart (*pr)(" [%s:%d]", filename, linenum);
162df930be7Sderaadt }
163df930be7Sderaadt return;
164df930be7Sderaadt }
165df930be7Sderaadt }
16656c88695Sniklas
16733ca0db6Sart (*pr)("%s", db_format(buf, sizeof(buf), off, DB_FORMAT_N, 1, 0));
168df930be7Sderaadt return;
169df930be7Sderaadt }
170