Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:plunky:20120422210740

Diff

Diff from 1.34 to:

Annotations

Annotate by Age | Author | Mixed | None
/fisheye/browse/pcc/pcc/cc/ccom/stabs.c

Annotated File View

plunky
1.34
1 /*      $Id: stabs.c,v 1.34 2012/04/22 21:07:41 plunky Exp $    */
ragge
1.6
2
ragge
1.1
3 /*
ragge
1.6
4  * Copyright (c) 2004 Anders Magnusson (ragge@ludd.luth.se).
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. The name of the author may not be used to endorse or promote products
16  *    derived from this software without specific prior written permission
ragge
1.1
17  *
ragge
1.6
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29
30 /*
31  * Simple implementation of the "stabs" debugging format.
32  * Not complete but at least makes it possible to set breakpoints,
33  * examine simple variables and do stack traces.
34  * Based on the stabs documentation that follows gdb.
ragge
1.1
35  */
36
37 #include "pass1.h"
38
pj
1.8
39 #ifdef STABS
40
ragge
1.1
41 #include <sys/types.h>
ragge
1.5
42 #include <stdarg.h>
ragge
1.14
43 #include <string.h>
ragge
1.1
44
45 #define STABHASH        256
46 #define INTNUM          1       /* internal number of type "int" */
mickey
1.25
47 #undef BIT2BYTE /* from external.h */
ragge
1.1
48 #define BIT2BYTE(x)     ((x)/SZCHAR)
49
ragge
1.6
50 #ifndef STABLBL
51 #error macdefs.h must define STABLBL
52 #endif
53
gmcgarry
1.19
54 /* defines taken from BSD <stab.h> */
55 #define N_GSYM          0x20    /* global symbol */
56 #define N_FUN           0x24    /* procedure name */
57 #define N_LCSYM         0x28    /* bss segment variable */
58 #define N_RSYM          0x40    /* register variable */
59 #define N_SLINE         0x44    /* text segment line number */
60 #define N_SO            0x64    /* main source file name */
61 #define N_LSYM          0x80    /* stack variable */
62 #define N_SOL           0x84    /* included source file name */
63 #define N_PSYM          0xa0    /* parameter variable */
64 #define N_LBRAC         0xc0    /* left bracket */
65 #define N_RBRAC         0xe0    /* right bracket */
66
ragge
1.1
67 /*
68  * Local type mapping
69  * Types are defined as a typeword, a dimension pointer (in the case
70  * of arrays) and struct/union/enum declarations.
71  * Function prototypes are ignored.
72  */
73 static struct stabtype {
74         struct stabtype *next;  /* linked list */
75         TWORD type;             /* pcc type number */
76         union dimfun *df;       /* dimension of arrays */
ragge
1.31
77         struct attr *ap;        /* struct/union/enum declarations */
ragge
1.1
78         int num;                /* local type number */
79 } *stabhash[STABHASH];
80 static int ntypes;
81 static char *curfun;
82 static int stablbl = 10;
ragge
1.26
83 extern int inftn;
ragge
1.1
84
85 void ptype(char *nameint numint inhnumlong long minlong long max);
ragge
1.31
86 struct stabtype *addtype(TWORDunion dimfun *, struct attr *);
87 struct stabtype *findtype(TWORD tunion dimfun *dfstruct attr *sue);
ragge
1.15
88 void printtype(struct symtab *schar *strint len);
ragge
1.13
89 void cprint(int p2char *fmt, ...);
ragge
1.1
90
ragge
1.12
91 #define MAXPSTR 100
92
ragge
1.14
93 extern int isinlining;
94
ragge
1.1
95 /*
96  * Output type definitions for the stab debugging format.
97  * Note that "int" is always internal number 1.
98  */
99 void
plunky
1.34
100 stabs_init(void)
ragge
1.1
101 {
102         struct stabtype *st;
103
ragge
1.32
104 #define ADDTYPE(y) addtype(y, NULL, 0)
ragge
1.1
105
106         ptype("int"ADDTYPE(INT)->numINTNUMMIN_INTMAX_INT);
107
108         st = ADDTYPE(CHAR);
109         ptype("char"st->numst->num0MAX_CHAR);
110         ptype("short"ADDTYPE(SHORT)->numINTNUMMIN_SHORTMAX_SHORT);
111         ptype("long"ADDTYPE(LONG)->numINTNUMMIN_LONGMAX_LONG);
112         ptype("long long"ADDTYPE(LONGLONG)->numINTNUM,
113              MIN_LONGLONGMAX_LONGLONG);
114         ptype("unsigned char"ADDTYPE(UCHAR)->numINTNUM0MAX_UCHAR);
115         ptype("unsigned short"ADDTYPE(USHORT)->numINTNUM0MAX_USHORT);
116         ptype("unsigned int"ADDTYPE(UNSIGNED)->numINTNUM0MAX_UNSIGNED);
117         ptype("unsigned long"ADDTYPE(ULONG)->numINTNUM0MAX_ULONG);
118         ptype("unsigned long long"ADDTYPE(ULONGLONG)->numINTNUM,
119             0MAX_ULONGLONG);
120
121         ptype("float"ADDTYPE(FLOAT)->numINTNUM40);
122         ptype("double"ADDTYPE(DOUBLE)->numINTNUM80);
123         ptype("long double"ADDTYPE(LDOUBLE)->numINTNUM120);
124         st = ADDTYPE(VOID);
ragge
1.26
125         cprint(0"\t.stabs \"void:t%d=r%d\",%d,0,0,0\n",
ragge
1.1
126             st->numst->numN_LSYM);
127
128 }
129
130 /*
131  * Print a type in stabs format
132  */
133 void
134 ptype(char *nameint numint inhnumlong long minlong long max)
135 {
ragge
1.26
136         cprint(0"\t.stabs \"%s:t%d=r%d;%lld;%lld;\",%d,0,0,0\n",
ragge
1.1
137             namenuminhnumminmaxN_LSYM);
138 }
139
140 /*
141  * Add a new local type to the hash table.
142  * The search key is the (type, df, sue) triple.
143  */
144 struct stabtype *
ragge
1.31
145 addtype(TWORD tunion dimfun *dfstruct attr *ap)
ragge
1.1
146 {
147         struct stabtype *st;
148
149         st = permalloc(sizeof(struct stabtype));
150         st->type = t;
151         st->df = df;
ragge
1.31
152         st->ap = ap;
ragge
1.1
153         st->num = ++ntypes;
154         st->next = stabhash[t & (STABHASH-1)];
155         stabhash[t & (STABHASH-1)] = st;
156         return st;
157 }
158
159 /*
160  * Search for a given type and return a type pointer (or NULL).
161  */
162 struct stabtype *
ragge
1.31
163 findtype(TWORD tunion dimfun *dfstruct attr *ap)
ragge
1.1
164 {
165         struct stabtype *st;
166         union dimfun *dw, *dx;
167         TWORD tw;
168
169         st = stabhash[t & (STABHASH-1)];
170         for (; stst = st->next) {
ragge
1.31
171                 if (t != st->type || ap != st->ap)
ragge
1.1
172                         continue;
173                 /* Ok, type and sue matches, check dimensions */
174                 if (st->df == NULL)
175                         return st/* no arrays, got match */
176                 dw = st->df;
177                 dx = df;
178                 tw = t;
179                 for (; tw > BTMASKtw = DECREF(tw)) {
180                         if (ISARY(tw)) {
181                                 if (dw->ddim == dx->ddim)
182                                         dw++, dx++;
183                                 else
184                                         break;
185                         }
186                 }
187                 if (tw <= BTMASK)
188                         return st;
189         }
190         return NULL;
191 }
192
193 /*
194  * Print current line number.
195  */
196 void
197 stabs_line(int line)
198 {
ragge
1.26
199         if (inftn == 0)
200                 return/* ignore */
gmcgarry
1.18
201 #ifdef STAB_LINE_ABSOLUTE
ragge
1.26
202         cprint(1"\t.stabn %d,0,%d," STABLBL "\n" STABLBL ":\n",
203             N_SLINElinestablblstablbl);
gmcgarry
1.18
204 #else
ragge
1.26
205         cprint(1"\t.stabn %d,0,%d," STABLBL "-%s\n" STABLBL ":\n",
gmcgarry
1.29
206             N_SLINElinestablblcurfunstablbl);
gmcgarry
1.18
207 #endif
ragge
1.26
208         stablbl++;
ragge
1.1
209 }
210
211 /*
212  * Start of block.
213  */
214 void
215 stabs_lbrac(int blklvl)
216 {
gmcgarry
1.18
217 #ifdef STAB_LINE_ABSOLUTE
ragge
1.26
218         cprint(1"\t.stabn %d,0,%d," STABLBL "\n" STABLBL ":\n",
219             N_LBRACblklvlstablblstablbl);
gmcgarry
1.18
220 #else
ragge
1.26
221         cprint(1"\t.stabn %d,0,%d," STABLBL "-%s\n" STABLBL ":\n",
gmcgarry
1.29
222             N_LBRACblklvlstablblcurfunstablbl);
gmcgarry
1.18
223 #endif
ragge
1.26
224         stablbl++;
ragge
1.1
225 }
226
227 /*
228  * End of block.
229  */
230 void
231 stabs_rbrac(int blklvl)
232 {
gmcgarry
1.18
233 #ifdef STAB_LINE_ABSOLUTE
ragge
1.26
234         cprint(1"\t.stabn %d,0,%d," STABLBL "\n" STABLBL ":\n",
235             N_RBRACblklvlstablblstablbl);
gmcgarry
1.18
236 #else
ragge
1.26
237         cprint(1"\t.stabn %d,0,%d," STABLBL "-%s\n" STABLBL ":\n",
gmcgarry
1.29
238             N_RBRACblklvlstablblcurfunstablbl);
gmcgarry
1.18
239 #endif
ragge
1.26
240         stablbl++;
ragge
1.1
241 }
242
gmcgarry
1.27
243 static char *mainfile;
244
ragge
1.1
245 /*
246  * Print current file and set mark.
247  */
248 void
249 stabs_file(char *fname)
250 {
251         if (mainfile == NULL)
252                 mainfile = fname/* first call */
ragge
1.26
253         cprint(inftn"\t.stabs \"%s\",%d,0,0," STABLBL "\n" STABLBL ":\n",
254             fnamefname == mainfile ? N_SO : N_SOLstablblstablbl);
255         stablbl++;
ragge
1.1
256 }
257
258 /*
gmcgarry
1.27
259  * Print end mark
260  */
261 void
262 stabs_efile(char *fname)
263 {
264         cprint(inftn"\t.stabs \"\",%d,0,0," STABLBL "\n" STABLBL ":\n",
265             fname == mainfile ? N_SO : N_SOLstablblstablbl);
266         stablbl++;
267 }
268
269 /*
ragge
1.1
270  * Print beginning of function.
271  */
272 void
273 stabs_func(struct symtab *s)
274 {
ragge
1.12
275         char str[MAXPSTR];
276
ragge
1.28
277         if ((curfun = s->soname) == NULL)
278                 curfun = addname(exname(s->sname));
ragge
1.15
279         printtype(sstrsizeof(str));
ragge
1.26
280         cprint(1"\t.stabs     \"%s:%c%s\",%d,0,%d,%s\n",
ragge
1.12
281             curfuns->sclass == STATIC ? 'f' : 'F'str,
ragge
1.31
282             N_FUN0curfun);
ragge
1.1
283 }
284
285 /*
286  * Print a (complex) type.
287  * Will also create subtypes.
288  * Printed string is like "20=*21=*1".
289  */
290 void
ragge
1.15
291 printtype(struct symtab *schar *ostrint len)
ragge
1.1
292 {
293         struct stabtype *st;
294         union dimfun *df = s->sdf;
ragge
1.31
295         struct attr *ap = s->sap;
ragge
1.1
296         TWORD t = s->stype;
ragge
1.12
297         int op = 0;
ragge
1.1
298
299         /* Print out not-yet-found types */
300         if (ISFTN(t))
301                 t = DECREF(t);
ragge
1.31
302         st = findtype(tdfap);
ragge
1.1
303         while (st == NULL && t > BTMASK) {
ragge
1.31
304                 st = addtype(tdfap);
ragge
1.15
305                 op+=snprintf(ostr+oplen - op"%d="st->num);
ragge
1.1
306                 if (ISFTN(t))
ragge
1.12
307                         ostr[op++] = 'f';
ragge
1.1
308                 else if (ISPTR(t))
ragge
1.12
309                         ostr[op++] = '*';
310                 else if (ISARY(t)) {
ragge
1.15
311                         op+=snprintf(ostr+oplen - op"ar%d;0;%d;"INTNUMdf->ddim-1);
ragge
1.12
312                 } else
ragge
1.1
313                         cerror("printtype: notype");
314                 if (ISARY(t))
315                         df++;
316                 t = DECREF(t);
ragge
1.31
317                 st = findtype(tdfap);
ragge
1.12
318                 if (op > MAXPSTR-10)
319                         cerror("printtype: too difficult expression");
ragge
1.1
320         }
321         /* print out basic type. may have to be entered in case of sue */
ragge
1.15
322         snprintf(ostr+oplen - op"%d"st == NULL ? 1 : st->num);
323         /* snprintf here null-terminated the string */
ragge
1.1
324 }
325
326 void
327 stabs_newsym(struct symtab *s)
328 {
ragge
1.24
329         extern int fun_inline;
ragge
1.9
330         char *sname;
ragge
1.12
331         char ostr[MAXPSTR];
plunky
1.33
332         OFFSZ suesizesz;
ragge
1.1
333
334         if (ISFTN(s->stype))
335                 return/* functions are handled separate */
336
ragge
1.3
337         if (s->sclass == STNAME || s->sclass == UNAME || s->sclass == MOS ||
338             s->sclass == ENAME || s->sclass == MOU || s->sclass == MOE ||
ragge
1.31
339             s->sclass == TYPEDEF || (s->sclass & FIELD) || ISSOU(s->stype))
ragge
1.3
340                 return/* XXX - fix structs */
341
ragge
1.28
342         if ((sname = s->soname) == NULL)
343                 sname = exname(s->sname);
ragge
1.31
344         sz = tsize(s->stypes->sdfs->sap);
345         suesize = BIT2BYTE(sz);
gmcgarry
1.20
346         if (suesize > 32767)
347                 suesize = 32767;
348         else if (suesize < -32768)
349                 suesize = -32768;
ragge
1.9
350
ragge
1.15
351         printtype(sostrsizeof(ostr));
ragge
1.1
352         switch (s->sclass) {
ragge
1.6
353         case PARAM:
plunky
1.33
354                 cprint(0"\t.stabs \"%s:p%s\",%d,0," CONFMT ",%d\n",
355                     snameostrN_PSYM, (CONSZ)suesizeBIT2BYTE(s->soffset));
ragge
1.6
356                 break;
357
ragge
1.1
358         case AUTO:
plunky
1.33
359                 cprint(0"\t.stabs \"%s:%s\",%d,0," CONFMT ",%d\n",
360                     snameostrN_LSYM, (CONSZ)suesizeBIT2BYTE(s->soffset));
ragge
1.1
361                 break;
362
363         case STATIC:
364                 if (blevel)
plunky
1.33
365                         cprint(0"\t.stabs \"%s:V%s\",%d,0," CONFMT "," LABFMT "\n",
366                             snameostrN_LCSYM, (CONSZ)suesizes->soffset);
ragge
1.1
367                 else
plunky
1.33
368                         cprint(0"\t.stabs \"%s:S%s\",%d,0," CONFMT ",%s\n",
369                             snameostrN_LCSYM, (CONSZ)suesizesname);
ragge
1.1
370                 break;
371
372         case EXTERN:
373         case EXTDEF:
plunky
1.33
374                 cprint(0"\t.stabs \"%s:G%s\",%d,0," CONFMT ",0\n",
375                     snameostrN_GSYM, (CONSZ)suesize);
ragge
1.1
376                 break;
377
ragge
1.10
378         case REGISTER:
plunky
1.33
379                 cprint(0"\t.stabs \"%s:r%s\",%d,0,%d,%d\n",
380                     snameostrN_RSYM1s->soffset);
ragge
1.10
381                 break;
plunky
1.33
382
ragge
1.24
383         case SNULL:
384                 if (fun_inline)
385                         break;
386                 /* FALLTHROUGH */
ragge
1.1
387         default:
ragge
1.3
388                 cerror("fix stab_newsym; class %d"s->sclass);
ragge
1.1
389         }
390 }
391
392 void
393 stabs_chgsym(struct symtab *s)
394 {
395 }
396
ragge
1.6
397 /*
398  * define a struct.
399  */
400 void
ragge
1.31
401 stabs_struct(struct symtab *pstruct attr *ap)
ragge
1.6
402 {
403 }
404
ragge
1.26
405 struct stabsv {
406         SLIST_ENTRY(stabsvnext;
ragge
1.23
407         char *str;
ragge
1.26
408 } ;
409 static SLIST_HEAD(, stabsvstpole = { NULL, &stpole.q_forw };
ragge
1.23
410
ragge
1.26
411 /*
412  * Global variable debug info is printed out directly.
413  * For functions and their declarations, both the labels and 
414  * the debug info is put into ASM nodes and follows their statements
415  * into pass2.  
416  * Due to the possible unsync between pass1 and 2 and where the 
417  * stabs info for text is sent over the following syncing is used:
418  * curfun == 0
419  *      print out everything; only data will be.
420  * curfun != 0 && inftn == 0
421  *      save in linked list
422  * curfun != 0 && inftn != 0
423  *      print linked list first, empty it, then arg.
424  */
425 void
ragge
1.13
426 cprint(int p2char *fmt, ...)
ragge
1.5
427 {
ragge
1.30
428 #define CPBSZ   200
429         char buf[CPBSZ];
ragge
1.26
430         struct stabsv *w;
431         va_list ap;
ragge
1.12
432         char *str;
ragge
1.5
433
ragge
1.24
434         if (isinlining)
435                 return/* XXX do not save any inline functions currently */
436
ragge
1.5
437         va_start(apfmt);
ragge
1.13
438         if (p2) {
ragge
1.30
439                 if (vsnprintf(bufCPBSZfmtap) >= CPBSZ)
440                         werror("stab symbol line too long, truncating");
441                 str = tmpstrdup(buf);
ragge
1.23
442                 if (inftn == 0) {
ragge
1.26
443                         w = tmpalloc(sizeof(struct stabsv));
ragge
1.23
444                         w->str = str;
ragge
1.26
445                         SLIST_INSERT_LAST(&stpolewnext);
ragge
1.23
446                 } else {
ragge
1.26
447                         if (stpole.q_last != &stpole.q_forw) {
448                                 SLIST_FOREACH(w, &stpolenext) {
449                                         send_passt(IP_ASMw->str);
450                                 }
451                                 SLIST_INIT(&stpole);
452                         }
ragge
1.23
453                         send_passt(IP_ASMstr);
454                 }
ragge
1.22
455         } else
ragge
1.12
456                 vprintf(fmtap);
ragge
1.5
457         va_end(ap);
458 }
pj
1.7
459
460 #endif
FishEye: Open Source License registered to PCC.
Your maintenance has expired. You can renew your license at http://www.atlassian.com/fisheye/renew
Atlassian FishEye, CVS analysis. (Version:1.6.3 Build:build-336 2008-11-04) - Administration - Page generated 2014-10-02 08:30 +0200