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