1
/* $Id: stabs.c,v 1.31 2010/08/11 14:08:44 ragge Exp $ */
4
* Copyright (c) 2004 Anders Magnusson (ragge@ludd.luth.se).
7
* Redistribution and use in source and binary forms, with or without
8
* modification, are permitted provided that the following conditions
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
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.
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.
41
#include <sys/types.h>
46
#define INTNUM 1 /* internal number of type "int" */
47
#undef BIT2BYTE /* from external.h */
48
#define BIT2BYTE(x) ((x)/SZCHAR)
51
#error macdefs.h must define STABLBL
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 */
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.
73
static struct stabtype {
74
struct stabtype *next; /* linked list */
75
TWORD type; /* pcc type number */
76
union dimfun *df; /* dimension of arrays */
77
struct attr *ap; /* struct/union/enum declarations */
78
int num; /* local type number */
79
} *stabhash[STABHASH];
82
static int stablbl = 10;
85
void ptype(char *name, int num, int inhnum, long long min, long long max);
86
struct stabtype *addtype(TWORD, union dimfun *, struct attr *);
87
struct stabtype *findtype(TWORD t, union dimfun *df, struct attr *sue);
88
void printtype(struct symtab *s, char *str, int len);
89
void cprint(int p2, char *fmt, ...);
93
extern int isinlining;
96
* Output type definitions for the stab debugging format.
97
* Note that "int" is always internal number 1.
104
#define ADDTYPE(y) addtype(y, NULL, MKAP(y))
106
ptype("int", ADDTYPE(INT)->num, INTNUM, MIN_INT, MAX_INT);
109
ptype("char", st->num, st->num, 0, MAX_CHAR);
110
ptype("short", ADDTYPE(SHORT)->num, INTNUM, MIN_SHORT, MAX_SHORT);
111
ptype("long", ADDTYPE(LONG)->num, INTNUM, MIN_LONG, MAX_LONG);
112
ptype("long long", ADDTYPE(LONGLONG)->num, INTNUM,
113
MIN_LONGLONG, MAX_LONGLONG);
114
ptype("unsigned char", ADDTYPE(UCHAR)->num, INTNUM, 0, MAX_UCHAR);
115
ptype("unsigned short", ADDTYPE(USHORT)->num, INTNUM, 0, MAX_USHORT);
116
ptype("unsigned int", ADDTYPE(UNSIGNED)->num, INTNUM, 0, MAX_UNSIGNED);
117
ptype("unsigned long", ADDTYPE(ULONG)->num, INTNUM, 0, MAX_ULONG);
118
ptype("unsigned long long", ADDTYPE(ULONGLONG)->num, INTNUM,
121
ptype("float", ADDTYPE(FLOAT)->num, INTNUM, 4, 0);
122
ptype("double", ADDTYPE(DOUBLE)->num, INTNUM, 8, 0);
123
ptype("long double", ADDTYPE(LDOUBLE)->num, INTNUM, 12, 0);
125
cprint(0, "\t.stabs \"void:t%d=r%d\",%d,0,0,0\n",
126
st->num, st->num, N_LSYM);
131
* Print a type in stabs format
134
ptype(char *name, int num, int inhnum, long long min, long long max)
136
cprint(0, "\t.stabs \"%s:t%d=r%d;%lld;%lld;\",%d,0,0,0\n",
137
name, num, inhnum, min, max, N_LSYM);
141
* Add a new local type to the hash table.
142
* The search key is the (type, df, sue) triple.
145
addtype(TWORD t, union dimfun *df, struct attr *ap)
149
st = permalloc(sizeof(struct stabtype));
154
st->next = stabhash[t & (STABHASH-1)];
155
stabhash[t & (STABHASH-1)] = st;
160
* Search for a given type and return a type pointer (or NULL).
163
findtype(TWORD t, union dimfun *df, struct attr *ap)
166
union dimfun *dw, *dx;
169
st = stabhash[t & (STABHASH-1)];
170
for (; st; st = st->next) {
171
if (t != st->type || ap != st->ap)
173
/* Ok, type and sue matches, check dimensions */
175
return st; /* no arrays, got match */
179
for (; tw > BTMASK; tw = DECREF(tw)) {
181
if (dw->ddim == dx->ddim)
194
* Print current line number.
201
#ifdef STAB_LINE_ABSOLUTE
202
cprint(1, "\t.stabn %d,0,%d," STABLBL "\n" STABLBL ":\n",
203
N_SLINE, line, stablbl, stablbl);
205
cprint(1, "\t.stabn %d,0,%d," STABLBL "-%s\n" STABLBL ":\n",
206
N_SLINE, line, stablbl, curfun, stablbl);
215
stabs_lbrac(int blklvl)
217
#ifdef STAB_LINE_ABSOLUTE
218
cprint(1, "\t.stabn %d,0,%d," STABLBL "\n" STABLBL ":\n",
219
N_LBRAC, blklvl, stablbl, stablbl);
221
cprint(1, "\t.stabn %d,0,%d," STABLBL "-%s\n" STABLBL ":\n",
222
N_LBRAC, blklvl, stablbl, curfun, stablbl);
231
stabs_rbrac(int blklvl)
233
#ifdef STAB_LINE_ABSOLUTE
234
cprint(1, "\t.stabn %d,0,%d," STABLBL "\n" STABLBL ":\n",
235
N_RBRAC, blklvl, stablbl, stablbl);
237
cprint(1, "\t.stabn %d,0,%d," STABLBL "-%s\n" STABLBL ":\n",
238
N_RBRAC, blklvl, stablbl, curfun, stablbl);
243
static char *mainfile;
246
* Print current file and set mark.
249
stabs_file(char *fname)
251
if (mainfile == NULL)
252
mainfile = fname; /* first call */
253
cprint(inftn, "\t.stabs \"%s\",%d,0,0," STABLBL "\n" STABLBL ":\n",
254
fname, fname == mainfile ? N_SO : N_SOL, stablbl, stablbl);
262
stabs_efile(char *fname)
264
cprint(inftn, "\t.stabs \"\",%d,0,0," STABLBL "\n" STABLBL ":\n",
265
fname == mainfile ? N_SO : N_SOL, stablbl, stablbl);
270
* Print beginning of function.
273
stabs_func(struct symtab *s)
277
if ((curfun = s->soname) == NULL)
278
curfun = addname(exname(s->sname));
279
printtype(s, str, sizeof(str));
280
cprint(1, "\t.stabs \"%s:%c%s\",%d,0,%d,%s\n",
281
curfun, s->sclass == STATIC ? 'f' : 'F', str,
286
* Print a (complex) type.
287
* Will also create subtypes.
288
* Printed string is like "20=*21=*1".
291
printtype(struct symtab *s, char *ostr, int len)
294
union dimfun *df = s->sdf;
295
struct attr *ap = s->sap;
299
/* Print out not-yet-found types */
302
st = findtype(t, df, ap);
303
while (st == NULL && t > BTMASK) {
304
st = addtype(t, df, ap);
305
op+=snprintf(ostr+op, len - op, "%d=", st->num);
311
op+=snprintf(ostr+op, len - op, "ar%d;0;%d;", INTNUM, df->ddim-1);
313
cerror("printtype: notype");
317
st = findtype(t, df, ap);
319
cerror("printtype: too difficult expression");
321
/* print out basic type. may have to be entered in case of sue */
322
snprintf(ostr+op, len - op, "%d", st == NULL ? 1 : st->num);
323
/* snprintf here null-terminated the string */
327
stabs_newsym(struct symtab *s)
329
extern int fun_inline;
335
return; /* functions are handled separate */
337
if (s->sclass == STNAME || s->sclass == UNAME || s->sclass == MOS ||
338
s->sclass == ENAME || s->sclass == MOU || s->sclass == MOE ||
339
s->sclass == TYPEDEF || (s->sclass & FIELD) || ISSOU(s->stype))
340
return; /* XXX - fix structs */
342
if ((sname = s->soname) == NULL)
343
sname = exname(s->sname);
344
sz = tsize(s->stype, s->sdf, s->sap);
345
suesize = BIT2BYTE(sz);
348
else if (suesize < -32768)
351
printtype(s, ostr, sizeof(ostr));
354
cprint(0, "\t.stabs \"%s:p%s\",%d,0,%d,%d\n", sname, ostr,
355
N_PSYM, suesize, BIT2BYTE(s->soffset));
359
cprint(0, "\t.stabs \"%s:%s\",%d,0,%d,%d\n", sname, ostr,
360
N_LSYM, suesize, BIT2BYTE(s->soffset));
365
cprint(0, "\t.stabs \"%s:V%s\",%d,0,%d," LABFMT "\n", sname, ostr,
366
N_LCSYM, suesize, s->soffset);
368
cprint(0, "\t.stabs \"%s:S%s\",%d,0,%d,%s\n", sname, ostr,
369
N_LCSYM, suesize, sname);
374
cprint(0, "\t.stabs \"%s:G%s\",%d,0,%d,0\n", sname, ostr,
379
cprint(0, "\t.stabs \"%s:r%s\",%d,0,%d,%d\n", sname, ostr,
380
N_RSYM, 1, s->soffset);
387
cerror("fix stab_newsym; class %d", s->sclass);
392
stabs_chgsym(struct symtab *s)
400
stabs_struct(struct symtab *p, struct attr *ap)
405
SLIST_ENTRY(stabsv) next;
408
static SLIST_HEAD(, stabsv) stpole = { NULL, &stpole.q_forw };
411
* Global variable debug info is printed out directly.
412
* For functions and their declarations, both the labels and
413
* the debug info is put into ASM nodes and follows their statements
415
* Due to the possible unsync between pass1 and 2 and where the
416
* stabs info for text is sent over the following syncing is used:
418
* print out everything; only data will be.
419
* curfun != 0 && inftn == 0
420
* save in linked list
421
* curfun != 0 && inftn != 0
422
* print linked list first, empty it, then arg.
425
cprint(int p2, char *fmt, ...)
434
return; /* XXX do not save any inline functions currently */
438
if (vsnprintf(buf, CPBSZ, fmt, ap) >= CPBSZ)
439
werror("stab symbol line too long, truncating");
440
str = tmpstrdup(buf);
442
w = tmpalloc(sizeof(struct stabsv));
444
SLIST_INSERT_LAST(&stpole, w, next);
446
if (stpole.q_last != &stpole.q_forw) {
447
SLIST_FOREACH(w, &stpole, next) {
448
send_passt(IP_ASM, w->str);
452
send_passt(IP_ASM, str);