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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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