1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22 /*
23 * Copyright 1996-2002 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 #pragma ident "%Z%%M% %I% %E% SMI"
28
29 #include <unistd.h>
30 #include <math.h>
31 #include "stabs.h"
32
33 void forth_do_sou(struct tdesc *tdp, struct node *np);
34 void forth_do_enum(struct tdesc *tdp, struct node *np);
35 void forth_do_intrinsic(struct tdesc *tdp, struct node *np);
36
37 static void switch_on_type(struct mlist *mlp, struct tdesc *tdp,
38 char *format, int level);
39
40 static void print_intrinsic(struct mlist *mlp, struct tdesc *tdp,
41 char *format, int level);
42 static void print_forward(struct mlist *mlp, struct tdesc *tdp,
43 char *format, int level);
44 static void print_pointer(struct mlist *mlp, struct tdesc *tdp,
45 char *format, int level);
46 static void print_array(struct mlist *mlp, struct tdesc *tdp,
47 char *format, int level);
48 static void print_function(struct mlist *mlp, struct tdesc *tdp,
49 char *format, int level);
50 static void print_union(struct mlist *mlp, struct tdesc *tdp,
51 char *format, int level);
52 static void print_enum(struct mlist *mlp, struct tdesc *tdp,
53 char *format, int level);
54 static void print_forward(struct mlist *mlp, struct tdesc *tdp,
55 char *format, int level);
56 static void print_typeof(struct mlist *mlp, struct tdesc *tdp,
57 char *format, int level);
58 static void print_struct(struct mlist *mlp, struct tdesc *tdp,
59 char *format, int level);
60 static void print_volatile(struct mlist *mlp, struct tdesc *tdp,
61 char *format, int level);
62
63 void
forth_do_intrinsic(struct tdesc * tdp,struct node * np)64 forth_do_intrinsic(struct tdesc *tdp, struct node *np)
65 {
66 }
67
68 void
forth_do_sou(struct tdesc * tdp,struct node * np)69 forth_do_sou(struct tdesc *tdp, struct node *np)
70 {
71 struct mlist *mlp;
72 struct child *chp;
73 char *format;
74
75 printf("\n");
76 printf("vocabulary %s-words\n", np->name);
77 printf("h# %x constant %s-sz\n", tdp->size, np->name);
78 printf("%x ' %s-words c-struct .%s\n",
79 tdp->size, np->name, np->name);
80 printf("also %s-words definitions\n\n", np->name);
81
82 /*
83 * Run thru all the fields of a struct and print them out
84 */
85 for (mlp = tdp->data.members.back; mlp != NULL; mlp = mlp->prev) {
86 /*
87 * If there's a child list, only print those members.
88 */
89 if (np->child) {
90 if (mlp->name == NULL)
91 continue;
92 chp = find_child(np, mlp->name);
93 if (chp == NULL)
94 continue;
95 format = chp->format;
96 } else
97 format = NULL;
98 if (mlp->fdesc == NULL)
99 continue;
100 switch_on_type(mlp, mlp->fdesc, format, 0);
101 }
102 printf("\nkdbg-words definitions\n");
103 printf("previous\n\n");
104 printf("\\ end %s section\n\n", np->name);
105 }
106
107 void
forth_do_enum(struct tdesc * tdp,struct node * np)108 forth_do_enum(struct tdesc *tdp, struct node *np)
109 {
110 int nelem = 0;
111 struct elist *elp;
112
113 printf("\n");
114 for (elp = tdp->data.emem; elp != NULL; elp = elp->next) {
115 printf("here ,\" %s\" %x\n", elp->name, elp->number);
116 nelem++;
117 }
118 printf("%x c-enum .%s\n", nelem, np->name);
119 }
120
121 static void
switch_on_type(struct mlist * mlp,struct tdesc * tdp,char * format,int level)122 switch_on_type(struct mlist *mlp, struct tdesc *tdp, char *format, int level)
123 {
124 switch (tdp->type) {
125 case INTRINSIC:
126 print_intrinsic(mlp, tdp, format, level);
127 break;
128 case POINTER:
129 print_pointer(mlp, tdp, format, level);
130 break;
131 case ARRAY:
132 print_array(mlp, tdp, format, level);
133 break;
134 case FUNCTION:
135 print_function(mlp, tdp, format, level);
136 break;
137 case UNION:
138 print_union(mlp, tdp, format, level);
139 break;
140 case ENUM:
141 print_enum(mlp, tdp, format, level);
142 break;
143 case FORWARD:
144 print_forward(mlp, tdp, format, level);
145 break;
146 case TYPEOF:
147 print_typeof(mlp, tdp, format, level);
148 break;
149 case STRUCT:
150 print_struct(mlp, tdp, format, level);
151 break;
152 case VOLATILE:
153 print_volatile(mlp, tdp, format, level);
154 break;
155 default:
156 fprintf(stderr, "Switch to Unknown type\n");
157 error = B_TRUE;
158 break;
159 }
160 }
161
162 static void
print_forward(struct mlist * mlp,struct tdesc * tdp,char * format,int level)163 print_forward(struct mlist *mlp, struct tdesc *tdp, char *format, int level)
164 {
165 fprintf(stderr, "%s never defined\n", mlp->name);
166 error = B_TRUE;
167 }
168
169 static void
print_typeof(struct mlist * mlp,struct tdesc * tdp,char * format,int level)170 print_typeof(struct mlist *mlp, struct tdesc *tdp, char *format, int level)
171 {
172 switch_on_type(mlp, tdp->data.tdesc, format, level);
173 }
174
175 static void
print_volatile(struct mlist * mlp,struct tdesc * tdp,char * format,int level)176 print_volatile(struct mlist *mlp, struct tdesc *tdp, char *format, int level)
177 {
178 switch_on_type(mlp, tdp->data.tdesc, format, level);
179 }
180
181 static void
print_intrinsic(struct mlist * mlp,struct tdesc * tdp,char * format,int level)182 print_intrinsic(struct mlist *mlp, struct tdesc *tdp, char *format, int level)
183 {
184 format = convert_format(format, ".x");
185
186 if (level != 0) {
187 switch (tdp->size) {
188 case 1:
189 printf("' c@ ' %s", format);
190 break;
191 case 2:
192 printf("' w@ ' %s", format);
193 break;
194 case 4:
195 printf("' l@ ' %s", format);
196 break;
197 case 8:
198 printf("' x@ ' %s", format);
199 break;
200 }
201 /*
202 * Check for bit field.
203 */
204 } else if (mlp->size != 0 &&
205 ((mlp->size % 8) != 0 || (mlp->offset % mlp->size) != 0)) {
206 int offset, shift, mask;
207
208 offset = (mlp->offset / 32) * 4;
209 shift = 32 - ((mlp->offset % 32) + mlp->size);
210 mask = ((int)pow(2, mlp->size) - 1) << shift;
211 printf("' %s %x %x %x bits-field %s\n",
212 format, shift, mask, offset, mlp->name);
213 } else if (mlp->name != NULL) {
214 switch (tdp->size) {
215 case 1:
216 printf("' %s %x byte-field %s\n",
217 format, mlp->offset / 8, mlp->name);
218 break;
219 case 2:
220 printf("' %s %x short-field %s\n",
221 format, mlp->offset / 8, mlp->name);
222 break;
223 case 4:
224 printf("' %s %x long-field %s\n",
225 format, mlp->offset / 8, mlp->name);
226 break;
227 case 8:
228 printf("' %s %x ext-field %s\n",
229 format, mlp->offset / 8, mlp->name);
230 break;
231 }
232 }
233 }
234
235 static void
print_pointer(struct mlist * mlp,struct tdesc * tdp,char * format,int level)236 print_pointer(struct mlist *mlp, struct tdesc *tdp, char *format, int level)
237 {
238 format = convert_format(format, ".x");
239 if (level != 0) {
240 switch (tdp->size) {
241 case 1:
242 printf("' c@ ' %s", format);
243 break;
244 case 2:
245 printf("' w@ ' %s", format);
246 break;
247 case 4:
248 printf("' l@ ' %s", format);
249 break;
250 case 8:
251 printf("' x@ ' %s", format);
252 break;
253 }
254 } else {
255 printf("' %s %x ptr-field %s\n",
256 format, mlp->offset / 8, mlp->name);
257 }
258 }
259
260 static void
print_array(struct mlist * mlp,struct tdesc * tdp,char * format,int level)261 print_array(struct mlist *mlp, struct tdesc *tdp, char *format, int level)
262 {
263 struct ardef *ap = tdp->data.ardef;
264 int items, inc, limit;
265
266 if (level > 0) {
267 printf("' noop ' .x");
268 } else {
269 items = ap->indices->range_end - ap->indices->range_start + 1;
270 inc = (mlp->size / items) / 8;
271 limit = mlp->size / 8;
272 switch_on_type(mlp, ap->contents, format, level + 1);
273 printf(" %x %x %x array-field", limit, inc, mlp->offset / 8);
274 printf(" %s\n", mlp->name);
275 }
276 }
277
278 static void
print_function(struct mlist * mlp,struct tdesc * tdp,char * format,int level)279 print_function(struct mlist *mlp, struct tdesc *tdp, char *format, int level)
280 {
281 fprintf(stderr, "function in struct %s\n", tdp->name);
282 error = B_TRUE;
283 }
284
285 static void
print_struct(struct mlist * mlp,struct tdesc * tdp,char * format,int level)286 print_struct(struct mlist *mlp, struct tdesc *tdp, char *format, int level)
287 {
288 format = convert_format(format, ".x");
289 if (level != 0)
290 printf("' noop ' %s", format);
291 else {
292 printf("' %s %x struct-field %s\n",
293 format, mlp->offset / 8, mlp->name);
294 }
295 }
296
297 static void
print_union(struct mlist * mlp,struct tdesc * tdp,char * format,int level)298 print_union(struct mlist *mlp, struct tdesc *tdp, char *format, int level)
299 {
300 format = convert_format(format, ".x");
301 if (level != 0)
302 printf("' noop ' %s", format);
303 else {
304 printf("' %s %x struct-field %s\n",
305 format, mlp->offset / 8, mlp->name);
306 }
307 }
308
309 static void
print_enum(struct mlist * mlp,struct tdesc * tdp,char * format,int level)310 print_enum(struct mlist *mlp, struct tdesc *tdp, char *format, int level)
311 {
312 format = convert_format(format, ".d");
313
314 if (level != 0)
315 printf("' l@ ' %s", format);
316 else
317 printf("' %s %x long-field %s\n",
318 format, mlp->offset / 8, mlp->name);
319 }
320