xref: /illumos-gate/usr/src/tools/stabs/genassym.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 2003 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 genassym_do_sou(struct tdesc *tdp, struct node *np);
34 void genassym_do_enum(struct tdesc *tdp, struct node *np);
35 void genassym_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 static int stabs_log2(unsigned int value);
63 
64 void
genassym_do_intrinsic(struct tdesc * tdp,struct node * np)65 genassym_do_intrinsic(struct tdesc *tdp, struct node *np)
66 {
67 	if (np->format != NULL) {
68 		char *upper = uc(np->format);
69 
70 		printf("#define\t%s 0x%x\n", upper, tdp->size);
71 
72 		free(upper);
73 	}
74 }
75 
76 
77 void
genassym_do_sou(struct tdesc * tdp,struct node * np)78 genassym_do_sou(struct tdesc *tdp, struct node *np)
79 {
80 	struct mlist *mlp;
81 	struct child *chp;
82 	char *format;
83 
84 	if (np->format != NULL) {
85 		char *upper = uc(np->format);
86 		int l;
87 
88 		printf("#define\t%s 0x%x\n", upper, tdp->size);
89 
90 		if ((np->format2 != NULL) &&
91 		    (l = stabs_log2(tdp->size)) != -1) {
92 			printf("#define\t%s 0x%x\n", np->format2, l);
93 		}
94 
95 		free(upper);
96 	}
97 
98 	/*
99 	 * Run thru all the fields of a struct and print them out
100 	 */
101 	for (mlp = tdp->data.members.forw; mlp != NULL; mlp = mlp->next) {
102 		/*
103 		 * If there's a child list, only print those members.
104 		 */
105 		if (np->child != NULL) {
106 			if (mlp->name == NULL)
107 				continue;
108 			chp = find_child(np, mlp->name);
109 			if (chp == NULL)
110 				continue;
111 			format = uc(chp->format);
112 		} else {
113 			format = NULL;
114 		}
115 		if (mlp->fdesc == NULL)
116 			continue;
117 		switch_on_type(mlp, mlp->fdesc, format, 0);
118 		if (format != NULL)
119 			free(format);
120 	}
121 }
122 
123 void
genassym_do_enum(struct tdesc * tdp,struct node * np)124 genassym_do_enum(struct tdesc *tdp, struct node *np)
125 {
126 	int nelem = 0;
127 	struct elist *elp;
128 
129 	printf("\n");
130 	for (elp = tdp->data.emem; elp != NULL; elp = elp->next) {
131 		printf("#define\tENUM_%s 0x%x\n", elp->name, elp->number);
132 		nelem++;
133 	}
134 	printf("%x c-enum .%s\n", nelem, np->name);
135 }
136 
137 static void
switch_on_type(struct mlist * mlp,struct tdesc * tdp,char * format,int level)138 switch_on_type(struct mlist *mlp, struct tdesc *tdp, char *format, int level)
139 {
140 	boolean_t allocated = B_FALSE;
141 
142 	if (format == NULL) {
143 		allocated = B_TRUE;
144 		format = uc(mlp->name);
145 	}
146 
147 	switch (tdp->type) {
148 	case INTRINSIC:
149 		print_intrinsic(mlp, tdp, format, level);
150 		break;
151 	case POINTER:
152 		print_pointer(mlp, tdp, format, level);
153 		break;
154 	case ARRAY:
155 		print_array(mlp, tdp, format, level);
156 		break;
157 	case FUNCTION:
158 		print_function(mlp, tdp, format, level);
159 		break;
160 	case UNION:
161 		print_union(mlp, tdp, format, level);
162 		break;
163 	case ENUM:
164 		print_enum(mlp, tdp, format, level);
165 		break;
166 	case FORWARD:
167 		print_forward(mlp, tdp, format, level);
168 		break;
169 	case TYPEOF:
170 		print_typeof(mlp, tdp, format, level);
171 		break;
172 	case STRUCT:
173 		print_struct(mlp, tdp, format, level);
174 		break;
175 	case VOLATILE:
176 		print_volatile(mlp, tdp, format, level);
177 		break;
178 	default:
179 		fprintf(stderr, "Switch to Unknown type\n");
180 		error = B_TRUE;
181 		break;
182 	}
183 	if (allocated)
184 		free(format);
185 }
186 
187 
188 static void
print_forward(struct mlist * mlp,struct tdesc * tdp,char * format,int level)189 print_forward(struct mlist *mlp, struct tdesc *tdp, char *format, int level)
190 {
191 	fprintf(stderr, "%s never defined\n", mlp->name);
192 	error = B_TRUE;
193 }
194 
195 static void
print_typeof(struct mlist * mlp,struct tdesc * tdp,char * format,int level)196 print_typeof(struct mlist *mlp, struct tdesc *tdp, char *format, int level)
197 {
198 	switch_on_type(mlp, tdp->data.tdesc, format, level);
199 }
200 
201 static void
print_volatile(struct mlist * mlp,struct tdesc * tdp,char * format,int level)202 print_volatile(struct mlist *mlp, struct tdesc *tdp, char *format, int level)
203 {
204 	switch_on_type(mlp, tdp->data.tdesc, format, level);
205 }
206 
207 static void
print_intrinsic(struct mlist * mlp,struct tdesc * tdp,char * format,int level)208 print_intrinsic(struct mlist *mlp, struct tdesc *tdp,
209     char *format, int level)
210 {
211 	if (level != 0) {
212 		switch (tdp->size) {
213 		case 1:
214 			printf("/* ' c@ ' %s */", format);
215 			break;
216 		case 2:
217 			printf("/* ' w@ ' %s */", format);
218 			break;
219 		case 4:
220 			printf("/* ' l@ ' %s */", format);
221 			break;
222 		case 8:
223 			printf("/* ' x@ ' %s */", format);
224 			break;
225 		}
226 	/*
227 	 * Check for bit field.
228 	 */
229 	} else if (mlp->size != 0 &&
230 	    ((mlp->size % 8) != 0 || (mlp->offset % mlp->size) != 0)) {
231 		int offset, shift, mask;
232 
233 		offset = (mlp->offset / 32) * 4;
234 		shift = 32 - ((mlp->offset % 32) + mlp->size);
235 		mask = ((int)pow(2, mlp->size) - 1) << shift;
236 
237 		printf("#define\t%s_SHIFT 0x%x\n", format, shift);
238 		printf("#define\t%s_MASK 0x%x\n", format, mask);
239 		printf("#define\t%s_OFFSET 0x%x\n", format, offset);
240 	} else if (mlp->name != NULL) {
241 		printf("#define\t%s 0x%x\n", format, mlp->offset / 8);
242 	}
243 }
244 
245 static void
print_pointer(struct mlist * mlp,struct tdesc * tdp,char * format,int level)246 print_pointer(struct mlist *mlp, struct tdesc *tdp, char *format, int level)
247 {
248 	if (level != 0) {
249 		switch (tdp->size) {
250 		case 1:
251 			printf("/* ' c@ ' %s */", format);
252 			break;
253 		case 2:
254 			printf("/* ' w@ ' %s */", format);
255 			break;
256 		case 4:
257 			printf("/* ' l@ ' %s */", format);
258 			break;
259 		case 8:
260 			printf("/* ' x@ ' %s */", format);
261 			break;
262 		}
263 	} else {
264 		printf("#define\t%s 0x%x\n", format, mlp->offset / 8);
265 	}
266 }
267 
268 static void
print_array(struct mlist * mlp,struct tdesc * tdp,char * format,int level)269 print_array(struct mlist *mlp, struct tdesc *tdp, char *format, int level)
270 {
271 	struct ardef *ap = tdp->data.ardef;
272 	int items, inc;
273 
274 	if (level == 0) {
275 		items = ap->indices->range_end - ap->indices->range_start + 1;
276 		inc = (mlp->size / items) / 8;
277 		printf("#define\t%s 0x%x\n", format, mlp->offset / 8);
278 		printf("#define\t%s_INCR 0x%x\n", format, inc);
279 	}
280 }
281 
282 static void
print_function(struct mlist * mlp,struct tdesc * tdp,char * format,int level)283 print_function(struct mlist *mlp, struct tdesc *tdp, char *format, int level)
284 {
285 	fprintf(stderr, "function in struct %s\n", tdp->name);
286 	error = B_TRUE;
287 }
288 
289 static void
print_struct(struct mlist * mlp,struct tdesc * tdp,char * format,int level)290 print_struct(struct mlist *mlp, struct tdesc *tdp, char *format, int level)
291 {
292 	if (level != 0)
293 		printf("/* ' noop ' %s */", format);
294 	else
295 		printf("#define\t%s 0x%x\n", format, mlp->offset / 8);
296 }
297 
298 static void
print_union(struct mlist * mlp,struct tdesc * tdp,char * format,int level)299 print_union(struct mlist *mlp, struct tdesc *tdp, char *format, int level)
300 {
301 	if (level != 0)
302 		printf("/* ' noop ' %s */", format);
303 	else
304 		printf("#define\t%s 0x%x\n", format, mlp->offset / 8);
305 }
306 
307 static void
print_enum(struct mlist * mlp,struct tdesc * tdp,char * format,int level)308 print_enum(struct mlist *mlp, struct tdesc *tdp, char *format, int level)
309 {
310 	if (level != 0)
311 		printf("/* ' l@ ' %s */", format);
312 	else
313 		printf("#define\t%s 0x%x\n", format, mlp->offset / 8);
314 }
315 
316 static int
stabs_log2(unsigned int value)317 stabs_log2(unsigned int value)
318 {
319 	int log = 1;
320 	int i;
321 
322 	for (i = 0; i < sizeof (value) * 8; i++) {
323 		if ((log << i) == value)
324 			return (i);
325 	}
326 	return (-1);
327 }
328