Quake-III-Arena

Quake III Arena GPL Source Release
Log | Files | Refs

stab.c (9415B)


      1 #include <string.h>
      2 #include <stdlib.h>
      3 #include "c.h"
      4 #include "stab.h"
      5 
      6 
      7 static char *currentfile;       /* current file name */
      8 static int ntypes;
      9 
     10 extern Interface sparcIR;
     11 
     12 char *stabprefix = "L";
     13 
     14 extern char *stabprefix;
     15 extern void stabblock(int, int, Symbol*);
     16 extern void stabend(Coordinate *, Symbol, Coordinate **, Symbol *, Symbol *);
     17 extern void stabfend(Symbol, int);
     18 extern void stabinit(char *, int, char *[]);
     19 extern void stabline(Coordinate *);
     20 extern void stabsym(Symbol);
     21 extern void stabtype(Symbol);
     22 
     23 static void asgncode(Type, int);
     24 static void dbxout(Type);
     25 static int dbxtype(Type);
     26 static int emittype(Type, int, int);
     27 
     28 /* asgncode - assign type code to ty */
     29 static void asgncode(Type ty, int lev) {
     30 	if (ty->x.marked || ty->x.typeno)
     31 		return;
     32 	ty->x.marked = 1;
     33 	switch (ty->op) {
     34 	case VOLATILE: case CONST: case VOLATILE+CONST:
     35 		asgncode(ty->type, lev);
     36 		ty->x.typeno = ty->type->x.typeno;
     37 		break;
     38 	case POINTER: case FUNCTION: case ARRAY:
     39 		asgncode(ty->type, lev + 1);
     40 		/* fall thru */
     41 	case VOID: case INT: case UNSIGNED: case FLOAT:
     42 		break;
     43 	case STRUCT: case UNION: {
     44 		Field p;
     45 		for (p = fieldlist(ty); p; p = p->link)
     46 			asgncode(p->type, lev + 1);
     47 		/* fall thru */
     48 	case ENUM:
     49 		if (ty->x.typeno == 0)
     50 			ty->x.typeno = ++ntypes;
     51 		if (lev > 0 && (*ty->u.sym->name < '0' || *ty->u.sym->name > '9'))
     52 			dbxout(ty);
     53 		break;
     54 		}
     55 	default:
     56 		assert(0);
     57 	}
     58 }
     59 
     60 /* dbxout - output .stabs entry for type ty */
     61 static void dbxout(Type ty) {
     62 	ty = unqual(ty);
     63 	if (!ty->x.printed) {
     64 		int col = 0;
     65 		print(".stabs \""), col += 8;
     66 		if (ty->u.sym && !(isfunc(ty) || isarray(ty) || isptr(ty)))
     67 			print("%s", ty->u.sym->name), col += strlen(ty->u.sym->name);
     68 		print(":%c", isstruct(ty) || isenum(ty) ? 'T' : 't'), col += 2;
     69 		emittype(ty, 0, col);
     70 		print("\",%d,0,0,0\n", N_LSYM);
     71 	}
     72 }
     73 
     74 /* dbxtype - emit a stabs entry for type ty, return type code */
     75 static int dbxtype(Type ty) {
     76 	asgncode(ty, 0);
     77 	dbxout(ty);
     78 	return ty->x.typeno;
     79 }
     80 
     81 /*
     82  * emittype - emit ty's type number, emitting its definition if necessary.
     83  * Returns the output column number after emission; col is the approximate
     84  * output column before emission and is used to emit continuation lines for long
     85  * struct, union, and enum types. Continuations are not emitted for other types,
     86  * even if the definition is long. lev is the depth of calls to emittype.
     87  */
     88 static int emittype(Type ty, int lev, int col) {
     89 	int tc = ty->x.typeno;
     90 
     91 	if (isconst(ty) || isvolatile(ty)) {
     92 		col = emittype(ty->type, lev, col);
     93 		ty->x.typeno = ty->type->x.typeno;
     94 		ty->x.printed = 1;
     95 		return col;
     96 	}
     97 	if (tc == 0) {
     98 		ty->x.typeno = tc = ++ntypes;
     99 /*              fprint(2,"`%t'=%d\n", ty, tc); */
    100 	}
    101 	print("%d", tc), col += 3;
    102 	if (ty->x.printed)
    103 		return col;
    104 	ty->x.printed = 1;
    105 	switch (ty->op) {
    106 	case VOID:	/* void is defined as itself */
    107 		print("=%d", tc), col += 1+3;
    108 		break;
    109 	case INT:
    110 		if (ty == chartype)	/* plain char is a subrange of itself */
    111 			print("=r%d;%d;%d;", tc, ty->u.sym->u.limits.min.i, ty->u.sym->u.limits.max.i),
    112 				col += 2+3+2*2.408*ty->size+2;
    113 		else			/* other signed ints are subranges of int */
    114 			print("=r1;%D;%D;", ty->u.sym->u.limits.min.i, ty->u.sym->u.limits.max.i),
    115 				col += 4+2*2.408*ty->size+2;
    116 		break;
    117 	case UNSIGNED:
    118 		if (ty == chartype)	/* plain char is a subrange of itself */
    119 			print("=r%d;0;%u;", tc, ty->u.sym->u.limits.max.i),
    120 				col += 2+3+2+2.408*ty->size+1;
    121 		else			/* other signed ints are subranges of int */
    122 			print("=r1;0;%U;", ty->u.sym->u.limits.max.i),
    123 				col += 4+2.408*ty->size+1;
    124 		break;
    125 	case FLOAT:	/* float, double, long double get sizes, not ranges */
    126 		print("=r1;%d;0;", ty->size), col += 4+1+3;
    127 		break;
    128 	case POINTER:
    129 		print("=*"), col += 2;
    130 		col = emittype(ty->type, lev + 1, col);
    131 		break;
    132 	case FUNCTION:
    133 		print("=f"), col += 2;
    134 		col = emittype(ty->type, lev + 1, col);
    135 		break;
    136 	case ARRAY:	/* array includes subscript as an int range */
    137 		if (ty->size && ty->type->size)
    138 			print("=ar1;0;%d;", ty->size/ty->type->size - 1), col += 7+3+1;
    139 		else
    140 			print("=ar1;0;-1;"), col += 10;
    141 		col = emittype(ty->type, lev + 1, col);
    142 		break;
    143 	case STRUCT: case UNION: {
    144 		Field p;
    145 		if (!ty->u.sym->defined) {
    146 			print("=x%c%s:", ty->op == STRUCT ? 's' : 'u', ty->u.sym->name);
    147 			col += 2+1+strlen(ty->u.sym->name)+1;
    148 			break;
    149 		}
    150 		if (lev > 0 && (*ty->u.sym->name < '0' || *ty->u.sym->name > '9')) {
    151 			ty->x.printed = 0;
    152 			break;
    153 		}
    154 		print("=%c%d", ty->op == STRUCT ? 's' : 'u', ty->size), col += 1+1+3;
    155 		for (p = fieldlist(ty); p; p = p->link) {
    156 			if (p->name)
    157 				print("%s:", p->name), col += strlen(p->name)+1;
    158 			else
    159 				print(":"), col += 1;
    160 			col = emittype(p->type, lev + 1, col);
    161 			if (p->lsb)
    162 				print(",%d,%d;", 8*p->offset +
    163 					(IR->little_endian ? fieldright(p) : fieldleft(p)),
    164 					fieldsize(p));
    165 			else
    166 				print(",%d,%d;", 8*p->offset, 8*p->type->size);
    167 			col += 1+3+1+3+1;	/* accounts for ,%d,%d; */
    168 			if (col >= 80 && p->link) {
    169 				print("\\\\\",%d,0,0,0\n.stabs \"", N_LSYM);
    170 				col = 8;
    171 			}
    172 		}
    173 		print(";"), col += 1;
    174 		break;
    175 		}
    176 	case ENUM: {
    177 		Symbol *p;
    178 		if (lev > 0 && (*ty->u.sym->name < '0' || *ty->u.sym->name > '9')) {
    179 			ty->x.printed = 0;
    180 			break;
    181 		}
    182 		print("=e"), col += 2;
    183 		for (p = ty->u.sym->u.idlist; *p; p++) {
    184 			print("%s:%d,", (*p)->name, (*p)->u.value), col += strlen((*p)->name)+3;
    185 			if (col >= 80 && p[1]) {
    186 				print("\\\\\",%d,0,0,0\n.stabs \"", N_LSYM);
    187 				col = 8;
    188 			}
    189 		}
    190 		print(";"), col += 1;
    191 		break;
    192 		}
    193 	default:
    194 		assert(0);
    195 	}
    196 	return col;
    197 }
    198 
    199 /* stabblock - output a stab entry for '{' or '}' at level lev */
    200 void stabblock(int brace, int lev, Symbol *p) {
    201 	if (brace == '{')
    202 		while (*p)
    203 			stabsym(*p++);
    204 	if (IR == &sparcIR)
    205 		print(".stabd 0x%x,0,%d\n", brace == '{' ? N_LBRAC : N_RBRAC, lev);
    206 	else {
    207 		int lab = genlabel(1);
    208 		print(".stabn 0x%x,0,%d,%s%d-%s\n", brace == '{' ? N_LBRAC : N_RBRAC, lev,
    209 			stabprefix, lab, cfunc->x.name);
    210 		print("%s%d:\n", stabprefix, lab);
    211 	}
    212 }
    213 
    214 /* stabinit - initialize stab output */
    215 void stabinit(char *file, int argc, char *argv[]) {
    216 	typedef void (*Closure)(Symbol, void *);
    217 	extern char *getcwd(char *, size_t);
    218 
    219 	print(".stabs \"lcc4_compiled.\",0x%x,0,0,0\n", N_OPT);
    220 	if (file && *file) {
    221 		char buf[1024], *cwd = getcwd(buf, sizeof buf);
    222 		if (cwd)
    223 			print(".stabs \"%s/\",0x%x,0,3,%stext0\n", cwd, N_SO, stabprefix);
    224 		print(".stabs \"%s\",0x%x,0,3,%stext0\n", file, N_SO, stabprefix);
    225 		(*IR->segment)(CODE);
    226 		print("%stext0:\n", stabprefix, N_SO);
    227 		currentfile = file;
    228 	}
    229 	dbxtype(inttype);
    230 	dbxtype(chartype);
    231 	dbxtype(doubletype);
    232 	dbxtype(floattype);
    233 	dbxtype(longdouble);
    234 	dbxtype(longtype);
    235 	dbxtype(longlong);
    236 	dbxtype(shorttype);
    237 	dbxtype(signedchar);
    238 	dbxtype(unsignedchar);
    239 	dbxtype(unsignedlong);
    240 	dbxtype(unsignedlonglong);
    241 	dbxtype(unsignedshort);
    242 	dbxtype(unsignedtype);
    243 	dbxtype(voidtype);
    244 	foreach(types, GLOBAL, (Closure)stabtype, NULL);
    245 }
    246 
    247 /* stabline - emit stab entry for source coordinate *cp */
    248 void stabline(Coordinate *cp) {
    249 	if (cp->file && cp->file != currentfile) {
    250 		int lab = genlabel(1);
    251 		print(".stabs \"%s\",0x%x,0,0,%s%d\n", cp->file, N_SOL, stabprefix, lab);
    252 		print("%s%d:\n", stabprefix, lab);
    253 		currentfile = cp->file;
    254 	}
    255 	if (IR == &sparcIR)
    256 		print(".stabd 0x%x,0,%d\n", N_SLINE, cp->y);
    257 	else {
    258 		int lab = genlabel(1);
    259 		print(".stabn 0x%x,0,%d,%s%d-%s\n", N_SLINE, cp->y,
    260 			stabprefix, lab, cfunc->x.name);
    261 		print("%s%d:\n", stabprefix, lab);
    262 	}
    263 }
    264 
    265 /* stabsym - output a stab entry for symbol p */
    266 void stabsym(Symbol p) {
    267 	int code, tc, sz = p->type->size;
    268 
    269 	if (p->generated || p->computed)
    270 		return;
    271 	if (isfunc(p->type)) {
    272 		print(".stabs \"%s:%c%d\",%d,0,0,%s\n", p->name,
    273 			p->sclass == STATIC ? 'f' : 'F', dbxtype(freturn(p->type)),
    274 			N_FUN, p->x.name);
    275 		return;
    276 	}
    277 	if (!IR->wants_argb && p->scope == PARAM && p->structarg) {
    278 		assert(isptr(p->type) && isstruct(p->type->type));
    279 		tc = dbxtype(p->type->type);
    280 		sz = p->type->type->size;
    281 	} else
    282 		tc = dbxtype(p->type);
    283 	if (p->sclass == AUTO && p->scope == GLOBAL || p->sclass == EXTERN) {
    284 		print(".stabs \"%s:G", p->name);
    285 		code = N_GSYM;
    286 	} else if (p->sclass == STATIC) {
    287 		print(".stabs \"%s:%c%d\",%d,0,0,%s\n", p->name, p->scope == GLOBAL ? 'S' : 'V',
    288 			tc, p->u.seg == BSS ? N_LCSYM : N_STSYM, p->x.name);
    289 		return;
    290 	} else if (p->sclass == REGISTER) {
    291 		if (p->x.regnode) {
    292 			int r = p->x.regnode->number;
    293 			if (p->x.regnode->set == FREG)
    294 				r += 32;	/* floating point */
    295 				print(".stabs \"%s:%c%d\",%d,0,", p->name,
    296 					p->scope == PARAM ? 'P' : 'r', tc, N_RSYM);
    297 			print("%d,%d\n", sz, r);
    298 		}
    299 		return;
    300 	} else if (p->scope == PARAM) {
    301 		print(".stabs \"%s:p", p->name);
    302 		code = N_PSYM;
    303 	} else if (p->scope >= LOCAL) {
    304 		print(".stabs \"%s:", p->name);
    305 		code = N_LSYM;
    306 	} else
    307 		assert(0);
    308 	print("%d\",%d,0,0,%s\n", tc, code,
    309 		p->scope >= PARAM && p->sclass != EXTERN ? p->x.name : "0");
    310 }
    311 
    312 /* stabtype - output a stab entry for type *p */
    313 void stabtype(Symbol p) {
    314 	if (p->type) {
    315 		if (p->sclass == 0)
    316 			dbxtype(p->type);
    317 		else if (p->sclass == TYPEDEF)
    318 			print(".stabs \"%s:t%d\",%d,0,0,0\n", p->name, dbxtype(p->type), N_LSYM);
    319 	}
    320 }
    321 
    322 /* stabend - finalize a function */
    323 void stabfend(Symbol p, int lineno) {}
    324 
    325 /* stabend - finalize stab output */
    326 void stabend(Coordinate *cp, Symbol p, Coordinate **cpp, Symbol *sp, Symbol *stab) {
    327 	(*IR->segment)(CODE);
    328 	print(".stabs \"\", %d, 0, 0,%setext\n", N_SO, stabprefix);
    329 	print("%setext:\n", stabprefix);
    330 }