Commit | Line | Data |
---|---|---|
920dae64 AT |
1 | /* |
2 | * ========== Copyright Header Begin ========================================== | |
3 | * | |
4 | * Hypervisor Software File: forth.c | |
5 | * | |
6 | * Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved. | |
7 | * | |
8 | * - Do no alter or remove copyright notices | |
9 | * | |
10 | * - Redistribution and use of this software in source and binary forms, with | |
11 | * or without modification, are permitted provided that the following | |
12 | * conditions are met: | |
13 | * | |
14 | * - Redistribution of source code must retain the above copyright notice, | |
15 | * this list of conditions and the following disclaimer. | |
16 | * | |
17 | * - Redistribution in binary form must reproduce the above copyright notice, | |
18 | * this list of conditions and the following disclaimer in the | |
19 | * documentation and/or other materials provided with the distribution. | |
20 | * | |
21 | * Neither the name of Sun Microsystems, Inc. or the names of contributors | |
22 | * may be used to endorse or promote products derived from this software | |
23 | * without specific prior written permission. | |
24 | * | |
25 | * This software is provided "AS IS," without a warranty of any kind. | |
26 | * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, | |
27 | * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A | |
28 | * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN | |
29 | * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR | |
30 | * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR | |
31 | * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN | |
32 | * OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR | |
33 | * FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE | |
34 | * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, | |
35 | * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF | |
36 | * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. | |
37 | * | |
38 | * You acknowledge that this software is not designed, licensed or | |
39 | * intended for use in the design, construction, operation or maintenance of | |
40 | * any nuclear facility. | |
41 | * | |
42 | * ========== Copyright Header End ============================================ | |
43 | */ | |
44 | /* | |
45 | * CDDL HEADER START | |
46 | * | |
47 | * The contents of this file are subject to the terms of the | |
48 | * Common Development and Distribution License (the "License"). | |
49 | * You may not use this file except in compliance with the License. | |
50 | * | |
51 | * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE | |
52 | * or http://www.opensolaris.org/os/licensing. | |
53 | * See the License for the specific language governing permissions | |
54 | * and limitations under the License. | |
55 | * | |
56 | * When distributing Covered Code, include this CDDL HEADER in each | |
57 | * file and include the License file at usr/src/OPENSOLARIS.LICENSE. | |
58 | * If applicable, add the following below this CDDL HEADER, with the | |
59 | * fields enclosed by brackets "[]" replaced with your own identifying | |
60 | * information: Portions Copyright [yyyy] [name of copyright owner] | |
61 | * | |
62 | * CDDL HEADER END | |
63 | */ | |
64 | ||
65 | /* | |
66 | * Copyright 2007 Sun Microsystems, Inc. All rights reserved. | |
67 | * Use is subject to license terms. | |
68 | */ | |
69 | ||
70 | #pragma ident "@(#)forth.c 1.2 07/06/07 SMI" | |
71 | ||
72 | #include <unistd.h> | |
73 | #include <math.h> | |
74 | #include "stabs.h" | |
75 | ||
76 | void forth_do_sou(struct tdesc *tdp, struct node *np); | |
77 | void forth_do_enum(struct tdesc *tdp, struct node *np); | |
78 | void forth_do_intrinsic(struct tdesc *tdp, struct node *np); | |
79 | ||
80 | static void switch_on_type(struct mlist *mlp, struct tdesc *tdp, | |
81 | char *format, int level); | |
82 | ||
83 | static void print_intrinsic(struct mlist *mlp, struct tdesc *tdp, | |
84 | char *format, int level); | |
85 | static void print_forward(struct mlist *mlp, struct tdesc *tdp, | |
86 | char *format, int level); | |
87 | static void print_pointer(struct mlist *mlp, struct tdesc *tdp, | |
88 | char *format, int level); | |
89 | static void print_array(struct mlist *mlp, struct tdesc *tdp, | |
90 | char *format, int level); | |
91 | static void print_function(struct mlist *mlp, struct tdesc *tdp, | |
92 | char *format, int level); | |
93 | static void print_union(struct mlist *mlp, struct tdesc *tdp, | |
94 | char *format, int level); | |
95 | static void print_enum(struct mlist *mlp, struct tdesc *tdp, | |
96 | char *format, int level); | |
97 | static void print_forward(struct mlist *mlp, struct tdesc *tdp, | |
98 | char *format, int level); | |
99 | static void print_typeof(struct mlist *mlp, struct tdesc *tdp, | |
100 | char *format, int level); | |
101 | static void print_struct(struct mlist *mlp, struct tdesc *tdp, | |
102 | char *format, int level); | |
103 | static void print_volatile(struct mlist *mlp, struct tdesc *tdp, | |
104 | char *format, int level); | |
105 | ||
106 | void | |
107 | forth_do_intrinsic(struct tdesc *tdp, struct node *np) | |
108 | { | |
109 | } | |
110 | ||
111 | void | |
112 | forth_do_sou(struct tdesc *tdp, struct node *np) | |
113 | { | |
114 | struct mlist *mlp; | |
115 | struct child *chp; | |
116 | char *format; | |
117 | ||
118 | printf("\n"); | |
119 | printf("vocabulary %s-words\n", np->name); | |
120 | printf("h# %x constant %s-sz\n", tdp->size, np->name); | |
121 | printf("%x ' %s-words c-struct .%s\n", | |
122 | tdp->size, np->name, np->name); | |
123 | printf("also %s-words definitions\n\n", np->name); | |
124 | ||
125 | /* | |
126 | * Run thru all the fields of a struct and print them out | |
127 | */ | |
128 | for (mlp = tdp->data.members.back; mlp != NULL; mlp = mlp->prev) { | |
129 | /* | |
130 | * If there's a child list, only print those members. | |
131 | */ | |
132 | if (np->child) { | |
133 | if (mlp->name == NULL) | |
134 | continue; | |
135 | chp = find_child(np, mlp->name); | |
136 | if (chp == NULL) | |
137 | continue; | |
138 | format = chp->format; | |
139 | } else | |
140 | format = NULL; | |
141 | if (mlp->fdesc == NULL) | |
142 | continue; | |
143 | switch_on_type(mlp, mlp->fdesc, format, 0); | |
144 | } | |
145 | printf("\nkdbg-words definitions\n"); | |
146 | printf("previous\n\n"); | |
147 | printf("\\ end %s section\n\n", np->name); | |
148 | } | |
149 | ||
150 | void | |
151 | forth_do_enum(struct tdesc *tdp, struct node *np) | |
152 | { | |
153 | int nelem = 0; | |
154 | struct elist *elp; | |
155 | ||
156 | printf("\n"); | |
157 | for (elp = tdp->data.emem; elp != NULL; elp = elp->next) { | |
158 | printf("here ,\" %s\" %x\n", elp->name, elp->number); | |
159 | nelem++; | |
160 | } | |
161 | printf("%x c-enum .%s\n", nelem, np->name); | |
162 | } | |
163 | ||
164 | static void | |
165 | switch_on_type(struct mlist *mlp, struct tdesc *tdp, char *format, int level) | |
166 | { | |
167 | switch (tdp->type) { | |
168 | case INTRINSIC: | |
169 | print_intrinsic(mlp, tdp, format, level); | |
170 | break; | |
171 | case POINTER: | |
172 | print_pointer(mlp, tdp, format, level); | |
173 | break; | |
174 | case ARRAY: | |
175 | print_array(mlp, tdp, format, level); | |
176 | break; | |
177 | case FUNCTION: | |
178 | print_function(mlp, tdp, format, level); | |
179 | break; | |
180 | case UNION: | |
181 | print_union(mlp, tdp, format, level); | |
182 | break; | |
183 | case ENUM: | |
184 | print_enum(mlp, tdp, format, level); | |
185 | break; | |
186 | case FORWARD: | |
187 | print_forward(mlp, tdp, format, level); | |
188 | break; | |
189 | case TYPEOF: | |
190 | print_typeof(mlp, tdp, format, level); | |
191 | break; | |
192 | case STRUCT: | |
193 | print_struct(mlp, tdp, format, level); | |
194 | break; | |
195 | case VOLATILE: | |
196 | print_volatile(mlp, tdp, format, level); | |
197 | break; | |
198 | default: | |
199 | fprintf(stderr, "Switch to Unknown type\n"); | |
200 | error = B_TRUE; | |
201 | break; | |
202 | } | |
203 | } | |
204 | ||
205 | static void | |
206 | print_forward(struct mlist *mlp, struct tdesc *tdp, char *format, int level) | |
207 | { | |
208 | fprintf(stderr, "%s never defined\n", mlp->name); | |
209 | error = B_TRUE; | |
210 | } | |
211 | ||
212 | static void | |
213 | print_typeof(struct mlist *mlp, struct tdesc *tdp, char *format, int level) | |
214 | { | |
215 | switch_on_type(mlp, tdp->data.tdesc, format, level); | |
216 | } | |
217 | ||
218 | static void | |
219 | print_volatile(struct mlist *mlp, struct tdesc *tdp, char *format, int level) | |
220 | { | |
221 | switch_on_type(mlp, tdp->data.tdesc, format, level); | |
222 | } | |
223 | ||
224 | static void | |
225 | print_intrinsic(struct mlist *mlp, struct tdesc *tdp, char *format, int level) | |
226 | { | |
227 | format = convert_format(format, ".x"); | |
228 | ||
229 | if (level != 0) { | |
230 | switch (tdp->size) { | |
231 | case 1: | |
232 | printf("' c@ ' %s", format); | |
233 | break; | |
234 | case 2: | |
235 | printf("' w@ ' %s", format); | |
236 | break; | |
237 | case 4: | |
238 | printf("' l@ ' %s", format); | |
239 | break; | |
240 | case 8: | |
241 | printf("' x@ ' %s", format); | |
242 | break; | |
243 | } | |
244 | /* | |
245 | * Check for bit field. | |
246 | */ | |
247 | } else if (mlp->size != 0 && | |
248 | ((mlp->size % 8) != 0 || (mlp->offset % mlp->size) != 0)) { | |
249 | int offset, shift, mask; | |
250 | ||
251 | offset = (mlp->offset / 32) * 4; | |
252 | shift = 32 - ((mlp->offset % 32) + mlp->size); | |
253 | mask = ((int)pow(2, mlp->size) - 1) << shift; | |
254 | printf("' %s %x %x %x bits-field %s\n", | |
255 | format, shift, mask, offset, mlp->name); | |
256 | } else if (mlp->name != NULL) { | |
257 | switch (tdp->size) { | |
258 | case 1: | |
259 | printf("' %s %x byte-field %s\n", | |
260 | format, mlp->offset / 8, mlp->name); | |
261 | break; | |
262 | case 2: | |
263 | printf("' %s %x short-field %s\n", | |
264 | format, mlp->offset / 8, mlp->name); | |
265 | break; | |
266 | case 4: | |
267 | printf("' %s %x long-field %s\n", | |
268 | format, mlp->offset / 8, mlp->name); | |
269 | break; | |
270 | case 8: | |
271 | printf("' %s %x ext-field %s\n", | |
272 | format, mlp->offset / 8, mlp->name); | |
273 | break; | |
274 | } | |
275 | } | |
276 | } | |
277 | ||
278 | static void | |
279 | print_pointer(struct mlist *mlp, struct tdesc *tdp, char *format, int level) | |
280 | { | |
281 | format = convert_format(format, ".x"); | |
282 | if (level != 0) { | |
283 | switch (tdp->size) { | |
284 | case 1: | |
285 | printf("' c@ ' %s", format); | |
286 | break; | |
287 | case 2: | |
288 | printf("' w@ ' %s", format); | |
289 | break; | |
290 | case 4: | |
291 | printf("' l@ ' %s", format); | |
292 | break; | |
293 | case 8: | |
294 | printf("' x@ ' %s", format); | |
295 | break; | |
296 | } | |
297 | } else { | |
298 | printf("' %s %x ptr-field %s\n", | |
299 | format, mlp->offset / 8, mlp->name); | |
300 | } | |
301 | } | |
302 | ||
303 | static void | |
304 | print_array(struct mlist *mlp, struct tdesc *tdp, char *format, int level) | |
305 | { | |
306 | struct ardef *ap = tdp->data.ardef; | |
307 | int items, inc, limit; | |
308 | ||
309 | if (level > 0) { | |
310 | printf("' noop ' .x"); | |
311 | } else { | |
312 | items = ap->indices->range_end - ap->indices->range_start + 1; | |
313 | inc = (mlp->size / items) / 8; | |
314 | limit = mlp->size / 8; | |
315 | switch_on_type(mlp, ap->contents, format, level + 1); | |
316 | printf(" %x %x %x array-field", limit, inc, mlp->offset / 8); | |
317 | printf(" %s\n", mlp->name); | |
318 | } | |
319 | } | |
320 | ||
321 | static void | |
322 | print_function(struct mlist *mlp, struct tdesc *tdp, char *format, int level) | |
323 | { | |
324 | fprintf(stderr, "function in struct %s\n", tdp->name); | |
325 | error = B_TRUE; | |
326 | } | |
327 | ||
328 | static void | |
329 | print_struct(struct mlist *mlp, struct tdesc *tdp, char *format, int level) | |
330 | { | |
331 | format = convert_format(format, ".x"); | |
332 | if (level != 0) | |
333 | printf("' noop ' %s", format); | |
334 | else { | |
335 | printf("' %s %x struct-field %s\n", | |
336 | format, mlp->offset / 8, mlp->name); | |
337 | } | |
338 | } | |
339 | ||
340 | static void | |
341 | print_union(struct mlist *mlp, struct tdesc *tdp, char *format, int level) | |
342 | { | |
343 | format = convert_format(format, ".x"); | |
344 | if (level != 0) | |
345 | printf("' noop ' %s", format); | |
346 | else { | |
347 | printf("' %s %x struct-field %s\n", | |
348 | format, mlp->offset / 8, mlp->name); | |
349 | } | |
350 | } | |
351 | ||
352 | static void | |
353 | print_enum(struct mlist *mlp, struct tdesc *tdp, char *format, int level) | |
354 | { | |
355 | format = convert_format(format, ".d"); | |
356 | ||
357 | if (level != 0) | |
358 | printf("' l@ ' %s", format); | |
359 | else | |
360 | printf("' %s %x long-field %s\n", | |
361 | format, mlp->offset / 8, mlp->name); | |
362 | } |