Commit | Line | Data |
---|---|---|
15637ed4 RG |
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. | |
15637ed4 | 25 | * |
4c45483e | 26 | * $Id: db_aout.c,v 1.3 1993/10/16 16:47:06 rgrimes Exp $ |
15637ed4 | 27 | */ |
cbeffc91 | 28 | |
15637ed4 RG |
29 | /* |
30 | * Author: David B. Golub, Carnegie Mellon University | |
31 | * Date: 7/90 | |
32 | */ | |
33 | /* | |
34 | * Symbol table routines for a.out format files. | |
35 | */ | |
36 | ||
37 | #include "param.h" | |
4c45483e | 38 | #include "systm.h" |
15637ed4 | 39 | #include "proc.h" |
4c45483e | 40 | #include "ddb/ddb.h" |
15637ed4 RG |
41 | #include <ddb/db_sym.h> |
42 | ||
43 | #ifndef DB_NO_AOUT | |
44 | ||
45 | #define _AOUT_INCLUDE_ | |
46 | #include "nlist.h" | |
47 | ||
48 | /* | |
49 | * An a.out symbol table as loaded into the kernel debugger: | |
50 | * | |
51 | * symtab -> size of symbol entries, in bytes | |
52 | * sp -> first symbol entry | |
53 | * ... | |
54 | * ep -> last symbol entry + 1 | |
55 | * strtab == start of string table | |
56 | * size of string table in bytes, | |
57 | * including this word | |
58 | * -> strings | |
59 | */ | |
60 | ||
61 | /* | |
62 | * Find pointers to the start and end of the symbol entries, | |
63 | * given a pointer to the start of the symbol table. | |
64 | */ | |
65 | #define db_get_aout_symtab(symtab, sp, ep) \ | |
66 | (sp = (struct nlist *)((symtab) + 1), \ | |
67 | ep = (struct nlist *)((char *)sp + *(symtab))) | |
68 | ||
e0be6391 | 69 | #ifndef SYMTAB_SPACE |
15637ed4 | 70 | #define SYMTAB_SPACE 63000 |
e0be6391 RG |
71 | #endif /*SYMTAB_SPACE*/ |
72 | ||
15637ed4 RG |
73 | int db_symtabsize = SYMTAB_SPACE; |
74 | char db_symtab[SYMTAB_SPACE] = { 1 }; | |
75 | ||
4c45483e | 76 | void |
15637ed4 RG |
77 | X_db_sym_init(symtab, esymtab, name) |
78 | int * symtab; /* pointer to start of symbol table */ | |
79 | char * esymtab; /* pointer to end of string table, | |
80 | for checking - rounded up to integer | |
81 | boundary */ | |
82 | char * name; | |
83 | { | |
84 | register struct nlist *sym_start, *sym_end; | |
85 | register struct nlist *sp; | |
86 | register char * strtab; | |
87 | register int strlen; | |
88 | ||
89 | if (*symtab < 4) { | |
90 | printf ("DDB: no symbols\n"); | |
91 | return; | |
92 | } | |
93 | ||
94 | db_get_aout_symtab(symtab, sym_start, sym_end); | |
95 | ||
96 | strtab = (char *)sym_end; | |
97 | strlen = *(int *)strtab; | |
98 | ||
99 | #if 0 | |
100 | if (strtab + ((strlen + sizeof(int) - 1) & ~(sizeof(int)-1)) | |
101 | != esymtab) | |
102 | { | |
103 | db_printf("[ %s symbol table not valid ]\n", name); | |
104 | return; | |
105 | } | |
106 | ||
107 | db_printf("[ preserving %#x bytes of %s symbol table ]\n", | |
108 | esymtab - (char *)symtab, name); | |
109 | #endif | |
110 | ||
111 | for (sp = sym_start; sp < sym_end; sp++) { | |
112 | register int strx; | |
113 | strx = sp->n_un.n_strx; | |
114 | if (strx != 0) { | |
115 | if (strx > strlen) { | |
116 | db_printf("Bad string table index (%#x)\n", strx); | |
117 | sp->n_un.n_name = 0; | |
118 | continue; | |
119 | } | |
120 | sp->n_un.n_name = strtab + strx; | |
121 | } | |
122 | } | |
123 | ||
124 | db_add_symbol_table(sym_start, sym_end, name, (char *)symtab); | |
125 | } | |
126 | ||
127 | db_sym_t | |
128 | X_db_lookup(stab, symstr) | |
129 | db_symtab_t *stab; | |
130 | char * symstr; | |
131 | { | |
132 | register struct nlist *sp, *ep; | |
133 | ||
134 | sp = (struct nlist *)stab->start; | |
135 | ep = (struct nlist *)stab->end; | |
136 | ||
137 | for (; sp < ep; sp++) { | |
138 | if (sp->n_un.n_name == 0) | |
139 | continue; | |
140 | if ((sp->n_type & N_STAB) == 0 && | |
141 | sp->n_un.n_name != 0 && | |
142 | db_eqname(sp->n_un.n_name, symstr, '_')) | |
143 | { | |
144 | return ((db_sym_t)sp); | |
145 | } | |
146 | } | |
147 | return ((db_sym_t)0); | |
148 | } | |
149 | ||
150 | db_sym_t | |
151 | X_db_search_symbol(symtab, off, strategy, diffp) | |
152 | db_symtab_t * symtab; | |
153 | register | |
154 | db_addr_t off; | |
155 | db_strategy_t strategy; | |
156 | db_expr_t *diffp; /* in/out */ | |
157 | { | |
158 | register unsigned int diff = *diffp; | |
159 | register struct nlist *symp = 0; | |
160 | register struct nlist *sp, *ep; | |
161 | ||
162 | sp = (struct nlist *)symtab->start; | |
163 | ep = (struct nlist *)symtab->end; | |
164 | ||
165 | for (; sp < ep; sp++) { | |
166 | if (sp->n_un.n_name == 0) | |
167 | continue; | |
168 | if ((sp->n_type & N_STAB) != 0) | |
169 | continue; | |
170 | if (off >= sp->n_value) { | |
171 | if (off - sp->n_value < diff) { | |
172 | diff = off - sp->n_value; | |
173 | symp = sp; | |
174 | if (diff == 0) | |
175 | break; | |
176 | } | |
177 | else if (off - sp->n_value == diff) { | |
178 | if (symp == 0) | |
179 | symp = sp; | |
180 | else if ((symp->n_type & N_EXT) == 0 && | |
181 | (sp->n_type & N_EXT) != 0) | |
182 | symp = sp; /* pick the external symbol */ | |
183 | } | |
184 | } | |
185 | } | |
186 | if (symp == 0) { | |
187 | *diffp = off; | |
188 | } | |
189 | else { | |
190 | *diffp = diff; | |
191 | } | |
192 | return ((db_sym_t)symp); | |
193 | } | |
194 | ||
195 | /* | |
196 | * Return the name and value for a symbol. | |
197 | */ | |
198 | void | |
199 | X_db_symbol_values(sym, namep, valuep) | |
200 | db_sym_t sym; | |
201 | char **namep; | |
202 | db_expr_t *valuep; | |
203 | { | |
204 | register struct nlist *sp; | |
205 | ||
206 | sp = (struct nlist *)sym; | |
207 | if (namep) | |
208 | *namep = sp->n_un.n_name; | |
209 | if (valuep) | |
210 | *valuep = sp->n_value; | |
211 | } | |
212 | ||
213 | boolean_t | |
214 | X_db_line_at_pc() | |
215 | { | |
216 | return (FALSE); | |
217 | } | |
218 | ||
219 | /* | |
220 | * Initialization routine for a.out files. | |
221 | */ | |
4c45483e GW |
222 | void |
223 | kdb_init(void) | |
15637ed4 RG |
224 | { |
225 | #if 0 | |
226 | extern char *esym; | |
227 | extern int end; | |
228 | ||
229 | if (esym > (char *)&end) { | |
230 | X_db_sym_init((int *)&end, esym, "mach"); | |
231 | } | |
232 | #endif | |
233 | ||
234 | X_db_sym_init (db_symtab, 0, "mach"); | |
235 | } | |
236 | ||
237 | #if 0 | |
238 | /* | |
239 | * Read symbol table from file. | |
240 | * (should be somewhere else) | |
241 | */ | |
242 | #include <boot_ufs/file_io.h> | |
243 | #include <vm/vm_kern.h> | |
244 | ||
245 | read_symtab_from_file(fp, symtab_name) | |
246 | struct file *fp; | |
247 | char * symtab_name; | |
248 | { | |
249 | vm_size_t resid; | |
250 | kern_return_t result; | |
251 | vm_offset_t symoff; | |
252 | vm_size_t symsize; | |
253 | vm_offset_t stroff; | |
254 | vm_size_t strsize; | |
255 | vm_size_t table_size; | |
256 | vm_offset_t symtab; | |
257 | ||
258 | if (!get_symtab(fp, &symoff, &symsize)) { | |
259 | boot_printf("[ error %d reading %s file header ]\n", | |
260 | result, symtab_name); | |
261 | return; | |
262 | } | |
263 | ||
264 | stroff = symoff + symsize; | |
265 | result = read_file(fp, (vm_offset_t)stroff, | |
266 | (vm_offset_t)&strsize, sizeof(strsize), &resid); | |
267 | if (result || resid) { | |
268 | boot_printf("[ no valid symbol table present for %s ]\n", | |
269 | symtab_name); | |
270 | return; | |
271 | } | |
272 | ||
273 | table_size = sizeof(int) + symsize + strsize; | |
274 | table_size = (table_size + sizeof(int)-1) & ~(sizeof(int)-1); | |
275 | ||
276 | symtab = kmem_alloc_wired(kernel_map, table_size); | |
277 | ||
278 | *(int *)symtab = symsize; | |
279 | ||
280 | result = read_file(fp, symoff, | |
281 | symtab + sizeof(int), symsize, &resid); | |
282 | if (result || resid) { | |
283 | boot_printf("[ error %d reading %s symbol table ]\n", | |
284 | result, symtab_name); | |
285 | return; | |
286 | } | |
287 | ||
288 | result = read_file(fp, stroff, | |
289 | symtab + sizeof(int) + symsize, strsize, &resid); | |
290 | if (result || resid) { | |
291 | boot_printf("[ error %d reading %s string table ]\n", | |
292 | result, symtab_name); | |
293 | return; | |
294 | } | |
295 | ||
296 | X_db_sym_init((int *)symtab, | |
297 | (char *)(symtab + table_size), | |
298 | symtab_name); | |
299 | ||
300 | } | |
301 | #endif | |
302 | ||
303 | #endif /* DB_NO_AOUT */ |