xref: /openbsd/sys/ddb/db_sym.c (revision 949c1c4e)
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