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 64 forth_do_intrinsic(struct tdesc *tdp, struct node *np) 65 { 66 } 67 68 void 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 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 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 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 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 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 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 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 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 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 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 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 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