Commit | Line | Data |
---|---|---|
4d57da58 WJ |
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 "param.h" | |
50 | #include "proc.h" | |
51 | #include <machine/db_machdep.h> /* data types */ | |
52 | #include <ddb/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 63000 | |
81 | int db_symtabsize = SYMTAB_SPACE; | |
82 | char db_symtab[SYMTAB_SPACE] = { 1 }; | |
83 | ||
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 | |
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 | |
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 | |
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 | |
221 | X_db_line_at_pc() | |
222 | { | |
223 | return (FALSE); | |
224 | } | |
225 | ||
226 | /* | |
227 | * Initialization routine for a.out files. | |
228 | */ | |
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 */ |