xref: /illumos-gate/usr/src/tools/stabs/forth.c (revision 7c478bd9)
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