Home | History | Annotate | Download | only in stabs
      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