|
|
1.1 root 1: /* C compiler: UNIX code generator
2: *
3: * Outputs `stab' entries for the UNIX dbx debugger,
4: * if -g is specified.
5: */
6:
7: static char *currentfile; /* current file name */
8: static int ntypes;
9:
10: dclproto(static void stabblock,(int, int, Symbol*));
11: dclproto(static void stabfend,(Symbol, int));
12: dclproto(static void stabinit,(char *, int, char *[]));
13: dclproto(static void stabline,(Coordinate *));
14: dclproto(static void stabsym,(Symbol));
15: dclproto(static void stabtype,(Symbol));
16:
17: dclproto(static void asgncode,(Type, int));
18: dclproto(static void dbxout,(Type));
19: dclproto(static int dbxtype,(Type));
20: dclproto(static int emittype,(Type, int, int));
21:
22: /* asgncode - assign type code to ty */
23: static void asgncode(ty, lev) Type ty; {
24: if (ty->x.marked || ty->x.typeno)
25: return;
26: /* fprint(2, "asgncode(`%t',%d) ty->x.typeno=0x%x\n", ty, lev, ty->x.typeno); */
27: ty->x.marked = 1;
28: switch (ty->op) {
29: case VOLATILE: case CONST: case VOLATILE+CONST:
30: asgncode(ty->type, lev);
31: ty->x.typeno = ty->type->x.typeno;
32: break;
33: case POINTER: case FUNCTION: case ARRAY:
34: asgncode(ty->type, lev + 1);
35: /* fall thru */
36: case VOID: case CHAR: case SHORT: case INT: case UNSIGNED:
37: case FLOAT: case DOUBLE:
38: break;
39: case STRUCT: case UNION: {
40: Field p;
41: for (p = fieldlist(ty); p; p = p->link)
42: asgncode(p->type, lev + 1);
43: /* fall thru */
44: case ENUM:
45: if (ty->x.typeno == 0) {
46: ty->x.typeno = ++ntypes;
47: /* fprint(2,"`%t'=%d in asgncode\n", ty, ntypes); */
48: }
49: if (lev > 0 && (*ty->u.sym->name < '0' || *ty->u.sym->name > '9'))
50: dbxout(ty);
51: break;
52: }
53: default:
54: assert(0);
55: }
56: }
57:
58: /* dbxout - output .stabs entry for type ty */
59: static void dbxout(ty) Type ty; {
60: ty = unqual(ty);
61: if (!ty->x.printed) {
62: int col = 0;
63: print(".stabs \""), col += 8;
64: if (ty->u.sym && !(isfunc(ty) || isarray(ty) || isptr(ty)))
65: print("%s", ty->u.sym->name), col += strlen(ty->u.sym->name);
66: print(":%c", isstruct(ty) || isenum(ty) ? 'T' : 't'), col += 2;
67: emittype(ty, 0, col);
68: print("\",%d,0,0,0\n", N_LSYM);
69: }
70: }
71:
72: /* dbxtype - emit a stabs entry for type ty, return type code */
73: static int dbxtype(ty) Type ty; {
74: asgncode(ty, 0);
75: dbxout(ty);
76: return ty->x.typeno;
77: }
78:
79: /*
80: * emittype - emit ty's type number, emitting its definition if necessary.
81: * Returns the output column number after emission; col is the approximate
82: * output column before emission and is used to emit continuation lines for long
83: * struct, union, and enum types. Continuations are not emitted for other types,
84: * even if the definition is long. lev is the depth of calls to emittype.
85: */
86: static int emittype(ty, lev, col) Type ty; {
87: int tc = ty->x.typeno;
88:
89: if (isconst(ty) || isvolatile(ty)) {
90: col = emittype(ty->type, lev, col);
91: ty->x.typeno = ty->type->x.typeno;
92: ty->x.printed = 1;
93: return col;
94: }
95: if (tc == 0) {
96: ty->x.typeno = tc = ++ntypes;
97: /* fprint(2,"`%t'=%d\n", ty, tc); */
98: }
99: print("%d", tc), col += 3;
100: if (ty->x.printed)
101: return col;
102: ty->x.printed = 1;
103: switch (ty->op) {
104: case VOID: /* void is defined as itself */
105: print("=%d", tc), col += 1+3;
106: break;
107: case CHAR: /* unsigned char is a subrange of int */
108: if (ty == unsignedchar)
109: print("=r1;0;255;"), col += 10;
110: else /* following pcc, char is a subrange of itself */
111: print("=r%d;-128;127;", tc), col += 2+3+10;
112: break;
113: case SHORT: /* short is a subrange of int */
114: if (ty == unsignedshort)
115: print("=r1;0;65535;"), col += 12;
116: else /* signed */
117: print("=r1;-32768;32767;"), col += 17;
118: break;
119: case INT: /* int is a subrange of itself */
120: print("=r1;%d;%d;", INT_MIN, INT_MAX), col += 4+11+1+10+1;
121: break;
122: case UNSIGNED: /* unsigned is a subrange of int */
123: print("=r1;0;-1;"), col += 9;
124: break;
125: case FLOAT: case DOUBLE: /* float, double get sizes instead of 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: #ifdef sun
146: if (!ty->u.sym->defined) {
147: print("=x%c%s:", ty->op == STRUCT ? 's' : 'u', ty->u.sym->name);
148: col += 2+1+strlen(ty->u.sym->name)+1;
149: break;
150: }
151: #endif
152: if (lev > 0 && (*ty->u.sym->name < '0' || *ty->u.sym->name > '9')) {
153: ty->x.printed = 0;
154: break;
155: }
156: print("=%c%d", ty->op == STRUCT ? 's' : 'u', ty->size), col += 1+1+3;
157: for (p = fieldlist(ty); p; p = p->link) {
158: if (p->name)
159: print("%s:", p->name), col += strlen(p->name)+1;
160: else
161: print(":"), col += 1;
162: col = emittype(p->type, lev + 1, col);
163: if (p->lsb)
164: print(",%d,%d;", 8*p->offset +
165: (IR->little_endian ? fieldright(p) : fieldleft(p)),
166: fieldsize(p));
167: else
168: print(",%d,%d;", 8*p->offset, 8*p->type->size);
169: col += 1+3+1+3+1; /* accounts for ,%d,%d; */
170: #if mc68020 || mc68030 || sparc
171: if (col >= 80 && p->link) {
172: print("\\\\\",%d,0,0,0\n.stabs \"", N_LSYM);
173: col = 8;
174: }
175: #endif
176: }
177: print(";"), col += 1;
178: break;
179: }
180: case ENUM: {
181: Symbol *p;
182: if (lev > 0 && (*ty->u.sym->name < '0' || *ty->u.sym->name > '9')) {
183: ty->x.printed = 0;
184: break;
185: }
186: print("=e"), col += 2;
187: for (p = ty->u.sym->u.idlist; *p; p++) {
188: print("%s:%d,", (*p)->name, (*p)->u.value), col += strlen((*p)->name)+3;
189: #if mc68020 || mc68030 || sparc
190: if (col >= 80 && p[1]) {
191: print("\\\\\",%d,0,0,0\n.stabs \"", N_LSYM);
192: col = 8;
193: }
194: #endif
195: }
196: print(";"), col += 1;
197: break;
198: }
199: default:
200: assert(0);
201: }
202: return col;
203: }
204:
205: /* stabblock - output a stab entry for '{' or '}' at level lev */
206: static void stabblock(brace, lev, p) Symbol *p; {
207: if (brace == '{')
208: while (*p)
209: stabsym(*p++);
210: print(".stabd 0x%x,0,%d\n", brace == '{' ? N_LBRAC : N_RBRAC, lev);
211: }
212:
213: /* stabfend - end of function p */
214: static void stabfend(p, line) Symbol p; {}
215:
216: /* stabinit - initialize stab output */
217: static void stabinit(file, argc, argv) char *file, *argv[]; {
218: dclproto(typedef void (*Closure),(Symbol, Generic));
219:
220: if (file && *file) {
221: (*IR->segment)(CODE);
222: print("Ltext:.stabs \"%s\",0x%x,0,0,Ltext\n", file, N_SO);
223: currentfile = file;
224: }
225: stabtype(inttype->u.sym);
226: stabtype(chartype->u.sym);
227: foreach(types, 0, (Closure)stabtype, (Generic)0);
228: foreach(types, GLOBAL, (Closure)stabtype, (Generic)0);
229: }
230:
231: /* stabline - emit stab entry for source coordinate *cp */
232: static void stabline(cp) Coordinate *cp; {
233: if (cp->file && cp->file != currentfile) {
234: int lab = genlabel(1);
235: print("L%d: .stabs \"%s\",0x%x,0,0,L%d\n", lab,
236: cp->file, N_SOL, lab);
237: currentfile = cp->file;
238: }
239: print(".stabd 0x%x,0,%d\n", N_SLINE, cp->y);
240: }
241:
242: /* stabsym - output a stab entry for symbol p */
243: static void stabsym(p) Symbol p; {
244: int code, tc, sz = p->type->size;
245:
246: if (p->generated || p->computed)
247: return;
248: if (isfunc(p->type)) {
249: print(".stabs \"%s:%c%d\",%d,0,0,%s\n", p->name,
250: p->sclass == STATIC ? 'f' : 'F', dbxtype(freturn(p->type)),
251: N_FUN, p->x.name);
252: return;
253: }
254: if (IR->no_argb && p->scope == PARAM && p->structarg) {
255: assert(isptr(p->type) && isstruct(p->type->type));
256: tc = dbxtype(p->type->type);
257: sz = p->type->type->size;
258: } else
259: tc = dbxtype(p->type);
260: if (p->sclass == AUTO && p->scope == GLOBAL || p->sclass == EXTERN) {
261: print(".stabs \"%s:G", p->name);
262: code = N_GSYM;
263: } else if (p->sclass == STATIC) {
264: print(".stabs \"%s:%c%d\",%d,0,0,%s\n", p->name, p->scope == GLOBAL ? 'S' : 'V',
265: tc, p->u.seg == BSS ? N_LCSYM : N_STSYM, p->x.name);
266: return;
267: } else if (isregvar(p)) {
268: print(".stabs \"%s:r%d\",%d,0,", p->name, tc, N_RSYM);
269: #ifdef vax
270: print("0,%s\n", p->x.name);
271: #endif
272: #if mc68020 || mc68030 || NeXT
273: print("0,%s%s\n", isptr(p->type) ? "8+" : "", p->x.name);
274: #endif
275: #ifdef sparc
276: { int r = p->x.regvar->x.regnode->regnum;
277: switch (p->x.name[0]) {
278: case 'r': break;
279: case 'f': r += 32; break;
280: default: assert(0);
281: }
282: print("%d,%d\n", sz, r);
283: }
284: #endif
285: return;
286: } else if (p->scope == PARAM) {
287: print(".stabs \"%s:p", p->name);
288: code = N_PSYM;
289: } else if (p->scope >= LOCAL) {
290: print(".stabs \"%s:", p->name);
291: code = N_LSYM;
292: } else
293: assert(0);
294: print("%d\",%d,0,0,%s\n", tc, code, p->scope >= PARAM && p->sclass != EXTERN ? p->x.name : "0");
295: }
296:
297: /* stabtype - output a stab entry for type *p */
298: static void stabtype(p) Symbol p; {
299: if (p->type) {
300: if (p->sclass == 0)
301: dbxtype(p->type);
302: else if (p->sclass == TYPEDEF)
303: print(".stabs \"%s:t%d\",%d,0,0,0\n", p->name, dbxtype(p->type), N_LSYM);
304: }
305: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.