xref: /386bsd/usr/src/kernel/ddb/db_aout.c (revision dc8b130e)
1 /*
2  * Mach Operating System
3  * Copyright (c) 1991,1990 Carnegie Mellon University
4  * All Rights Reserved.
5  *
6  * Permission to use, copy, modify and distribute this software and its
7  * documentation is hereby granted, provided that both the copyright
8  * notice and this permission notice appear in all copies of the
9  * software, derivative works or modified versions, and any portions
10  * thereof, and that both notices appear in supporting documentation.
11  *
12  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
13  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
14  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
15  *
16  * Carnegie Mellon requests users of this software to return to
17  *
18  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
19  *  School of Computer Science
20  *  Carnegie Mellon University
21  *  Pittsburgh PA 15213-3890
22  *
23  * any improvements or extensions that they make and grant Carnegie the
24  * rights to redistribute these changes.
25  */
26 /*
27  * HISTORY
28  * $Log: db_aout.c,v $
29  * Revision 1.1  1992/03/25  21:44:55  pace
30  * Initial revision
31  *
32  * Revision 2.3  91/02/05  17:05:55  mrt
33  * 	Changed to new Mach copyright
34  * 	[91/01/31  16:16:44  mrt]
35  *
36  * Revision 2.2  90/08/27  21:48:35  dbg
37  * 	Created.
38  * 	[90/08/17            dbg]
39  *
40  */
41 /*
42  *	Author: David B. Golub, Carnegie Mellon University
43  *	Date:	7/90
44  */
45 /*
46  * Symbol table routines for a.out format files.
47  */
48 
49 #include "sys/param.h"
50 #include "proc.h"
51 #include "machine/db/db_machdep.h"		/* data types */
52 #include "db_sym.h"
53 
54 #ifndef	DB_NO_AOUT
55 
56 #define _AOUT_INCLUDE_
57 #include "nlist.h"
58 
59 /*
60  * An a.out symbol table as loaded into the kernel debugger:
61  *
62  * symtab	-> size of symbol entries, in bytes
63  * sp		-> first symbol entry
64  *		   ...
65  * ep		-> last symbol entry + 1
66  * strtab	== start of string table
67  *		   size of string table in bytes,
68  *		   including this word
69  *		-> strings
70  */
71 
72 /*
73  * Find pointers to the start and end of the symbol entries,
74  * given a pointer to the start of the symbol table.
75  */
76 #define	db_get_aout_symtab(symtab, sp, ep) \
77 	(sp = (struct nlist *)((symtab) + 1), \
78 	 ep = (struct nlist *)((char *)sp + *(symtab)))
79 
80 #define SYMTAB_SPACE 79000
81 int db_symtabsize = SYMTAB_SPACE;
82 char db_symtab[SYMTAB_SPACE] = { 1 };
83 
X_db_sym_init(symtab,esymtab,name)84 X_db_sym_init(symtab, esymtab, name)
85 	int *	symtab;		/* pointer to start of symbol table */
86 	char *	esymtab;	/* pointer to end of string table,
87 				   for checking - rounded up to integer
88 				   boundary */
89 	char *	name;
90 {
91 	register struct nlist	*sym_start, *sym_end;
92 	register struct nlist	*sp;
93 	register char *	strtab;
94 	register int	strlen;
95 
96 	if (*symtab < 4) {
97 		printf ("DDB: no symbols\n");
98 		return;
99 	}
100 
101 	db_get_aout_symtab(symtab, sym_start, sym_end);
102 
103 	strtab = (char *)sym_end;
104 	strlen = *(int *)strtab;
105 
106 #if 0
107 	if (strtab + ((strlen + sizeof(int) - 1) & ~(sizeof(int)-1))
108 	    != esymtab)
109 	{
110 	    db_printf("[ %s symbol table not valid ]\n", name);
111 	    return;
112 	}
113 
114 	db_printf("[ preserving %#x bytes of %s symbol table ]\n",
115 		esymtab - (char *)symtab, name);
116 #endif
117 
118 	for (sp = sym_start; sp < sym_end; sp++) {
119 	    register int strx;
120 	    strx = sp->n_un.n_strx;
121 	    if (strx != 0) {
122 		if (strx > strlen) {
123 		    db_printf("Bad string table index (%#x)\n", strx);
124 		    sp->n_un.n_name = 0;
125 		    continue;
126 		}
127 		sp->n_un.n_name = strtab + strx;
128 	    }
129 	}
130 
131 	db_add_symbol_table(sym_start, sym_end, name, (char *)symtab);
132 }
133 
134 db_sym_t
X_db_lookup(stab,symstr)135 X_db_lookup(stab, symstr)
136 	db_symtab_t	*stab;
137 	char *		symstr;
138 {
139 	register struct nlist *sp, *ep;
140 
141 	sp = (struct nlist *)stab->start;
142 	ep = (struct nlist *)stab->end;
143 
144 	for (; sp < ep; sp++) {
145 	    if (sp->n_un.n_name == 0)
146 		continue;
147 	    if ((sp->n_type & N_STAB) == 0 &&
148 		sp->n_un.n_name != 0 &&
149 		db_eqname(sp->n_un.n_name, symstr, '_'))
150 	    {
151 		return ((db_sym_t)sp);
152 	    }
153 	}
154 	return ((db_sym_t)0);
155 }
156 
157 db_sym_t
X_db_search_symbol(symtab,off,strategy,diffp)158 X_db_search_symbol(symtab, off, strategy, diffp)
159 	db_symtab_t *	symtab;
160 	register
161 	db_addr_t	off;
162 	db_strategy_t	strategy;
163 	db_expr_t	*diffp;		/* in/out */
164 {
165 	register unsigned int	diff = *diffp;
166 	register struct nlist	*symp = 0;
167 	register struct nlist	*sp, *ep;
168 
169 	sp = (struct nlist *)symtab->start;
170 	ep = (struct nlist *)symtab->end;
171 
172 	for (; sp < ep; sp++) {
173 	    if (sp->n_un.n_name == 0)
174 		continue;
175 	    if ((sp->n_type & N_STAB) != 0)
176 		continue;
177 	    if (off >= sp->n_value) {
178 		if (off - sp->n_value < diff) {
179 		    diff = off - sp->n_value;
180 		    symp = sp;
181 		    if (diff == 0)
182 			break;
183 		}
184 		else if (off - sp->n_value == diff) {
185 		    if (symp == 0)
186 			symp = sp;
187 		    else if ((symp->n_type & N_EXT) == 0 &&
188 				(sp->n_type & N_EXT) != 0)
189 			symp = sp;	/* pick the external symbol */
190 		}
191 	    }
192 	}
193 	if (symp == 0) {
194 	    *diffp = off;
195 	}
196 	else {
197 	    *diffp = diff;
198 	}
199 	return ((db_sym_t)symp);
200 }
201 
202 /*
203  * Return the name and value for a symbol.
204  */
205 void
X_db_symbol_values(sym,namep,valuep)206 X_db_symbol_values(sym, namep, valuep)
207 	db_sym_t	sym;
208 	char		**namep;
209 	db_expr_t	*valuep;
210 {
211 	register struct nlist *sp;
212 
213 	sp = (struct nlist *)sym;
214 	if (namep)
215 	    *namep = sp->n_un.n_name;
216 	if (valuep)
217 	    *valuep = sp->n_value;
218 }
219 
220 boolean_t
X_db_line_at_pc()221 X_db_line_at_pc()
222 {
223 	return (FALSE);
224 }
225 
226 /*
227  * Initialization routine for a.out files.
228  */
kdb_init()229 kdb_init()
230 {
231 #if 0
232 	extern char	*esym;
233 	extern int	end;
234 
235 	if (esym > (char *)&end) {
236 	    X_db_sym_init((int *)&end, esym, "mach");
237 	}
238 #endif
239 
240 	X_db_sym_init (db_symtab, 0, "mach");
241 }
242 
243 #if 0
244 /*
245  * Read symbol table from file.
246  * (should be somewhere else)
247  */
248 #include <boot_ufs/file_io.h>
249 #include <vm/vm_kern.h>
250 
251 read_symtab_from_file(fp, symtab_name)
252 	struct file	*fp;
253 	char *		symtab_name;
254 {
255 	vm_size_t	resid;
256 	kern_return_t	result;
257 	vm_offset_t	symoff;
258 	vm_size_t	symsize;
259 	vm_offset_t	stroff;
260 	vm_size_t	strsize;
261 	vm_size_t	table_size;
262 	vm_offset_t	symtab;
263 
264 	if (!get_symtab(fp, &symoff, &symsize)) {
265 	    boot_printf("[ error %d reading %s file header ]\n",
266 			result, symtab_name);
267 	    return;
268 	}
269 
270 	stroff = symoff + symsize;
271 	result = read_file(fp, (vm_offset_t)stroff,
272 			(vm_offset_t)&strsize, sizeof(strsize), &resid);
273 	if (result || resid) {
274 	    boot_printf("[ no valid symbol table present for %s ]\n",
275 		symtab_name);
276 		return;
277 	}
278 
279 	table_size = sizeof(int) + symsize + strsize;
280 	table_size = (table_size + sizeof(int)-1) & ~(sizeof(int)-1);
281 
282 	symtab = kmem_alloc_wired(kernel_map, table_size);
283 
284 	*(int *)symtab = symsize;
285 
286 	result = read_file(fp, symoff,
287 			symtab + sizeof(int), symsize, &resid);
288 	if (result || resid) {
289 	    boot_printf("[ error %d reading %s symbol table ]\n",
290 			result, symtab_name);
291 	    return;
292 	}
293 
294 	result = read_file(fp, stroff,
295 			symtab + sizeof(int) + symsize, strsize, &resid);
296 	if (result || resid) {
297 	    boot_printf("[ error %d reading %s string table ]\n",
298 			result, symtab_name);
299 	    return;
300 	}
301 
302 	X_db_sym_init((int *)symtab,
303 			(char *)(symtab + table_size),
304 			symtab_name);
305 
306 }
307 #endif
308 
309 #endif	/* DB_NO_AOUT */
310