7 strcmpcolon(char *a, char *bcolon)
12 p = strchr(bcolon, ':');
14 return strcmp(a, bcolon);
16 i = strncmp(a, bcolon, len);
25 stabcvtsym(StabSym *stab, Symbol *sym, char *dir, char *file, int i)
30 * Zero out the : to avoid allocating a new name string.
31 * The type info can be found by looking past the NUL.
32 * This is going to get us in trouble...
34 if((p = strchr(stab->name, ':')) != nil)
37 p = stab->name+strlen(stab->name)+1;
39 sym->name = stab->name;
40 sym->u.stabs.dir = dir;
41 sym->u.stabs.file = file;
51 case 'F': /* global function */
54 case 'Q': /* static procedure */
55 case 'f': /* static function */
56 case 'I': /* nested procedure */
57 case 'J': /* nested function */
61 sym->loc.type = LADDR;
62 sym->loc.addr = stab->value;
69 sym->loc.type = LADDR;
70 sym->loc.addr = stab->value;
74 case 'S': /* file-scope static variable */
77 case 'G': /* global variable */
79 sym->loc.type = LNONE;
81 case 'r': /* register variable */
87 case 's': /* local variable */
90 sym->loc.type = LOFFSET;
91 sym->loc.offset = stab->value;
94 case 'a': /* by reference */
95 case 'D': /* f.p. parameter */
96 case 'i': /* register parameter */
97 case 'p': /* "normal" parameter */
98 case 'P': /* register parameter */
99 case 'v': /* by reference */
100 case 'X': /* function return variable */
104 sym->loc.type = LREG;
105 sym->loc.reg = "XXX";
107 sym->loc.type = LOFFSET;
108 sym->loc.offset = stab->value;
109 sym->loc.reg = "XXX";
119 stabssyminit(Fhdr *fp)
124 StabSym sym, lastfun;
128 int locals, autos, params;
132 werrstr("no stabs info");
145 memset(&lastfun, 0, sizeof lastfun);
146 for(i=0; stabsym(stabs, i, &sym)>=0; i++){
149 if(sym.name == nil || *sym.name == 0){
153 if(sym.name[strlen(sym.name)-1] == '/')
160 xinc = realloc(inc, (ninc+32)*sizeof(inc[0]));
162 memset(xinc+ninc, 0, 32*sizeof(inc[0]));
168 inc[ninc] = sym.name;
176 /* condensed include - same effect as previous BINCL/EINCL pair */
178 case N_GSYM: /* global variable */
179 /* only includes type, so useless for now */
183 /* marks end of function */
185 fun->hiloc.type = LADDR;
186 fun->hiloc.addr = fun->loc.addr + sym.value;
190 if(fun && lastfun.value==sym.value && lastfun.name==sym.name){
191 fun->u.stabs.locals = i;
194 /* create new symbol, add it */
197 if(stabcvtsym(&sym, &s, dir, file, i) < 0)
199 if((fun = _addsym(fp, &s)) == nil)
209 if(fun->u.stabs.frameptr == -1){
211 * Try to distinguish functions with a real frame pointer
212 * from functions with a virtual frame pointer, based on
213 * whether the first parameter is in the right location and
214 * whether the autos have negative offsets.
216 * This heuristic works most of the time. On the 386, we
217 * cannot distinguish between a v. function with no autos
218 * but a frame of size 4 and a f.p. function with no autos and
219 * no frame. Anything else we'll get right.
221 * Another way to go about this would be to have
222 * mach-specific functions to inspect the function
223 * prologues when we're not sure. What we have
224 * already should be enough, though.
226 if(params==0 && sym.type == N_PSYM){
227 if(sym.value != 8 && sym.value >= 4){
228 /* XXX 386 specific, but let's find another system before generalizing */
229 fun->u.stabs.frameptr = 0;
230 fun->u.stabs.framesize = sym.value - 4;
232 }else if(sym.type == N_LSYM){
234 fun->u.stabs.frameptr = 0;
236 fun->u.stabs.framesize = 8 - 4;
238 fun->u.stabs.frameptr = 1;
241 if(sym.type == N_PSYM)
243 if(sym.type == N_LSYM)
248 case N_STSYM: /* static file-scope variable */
249 /* create new symbol, add it */
250 if(stabcvtsym(&sym, &s, dir, file, i) < 0)
252 if(_addsym(fp, &s) == nil)
266 stabspc2file(Fhdr *fhdr, ulong pc, char *buf, uint nbuf, ulong *pline)
276 if((s = ffindsym(fhdr, l, CTEXT)) == nil
277 || stabsym(&fhdr->stabs, s->u.stabs.i, &ss) < 0)
282 for(i=s->u.stabs.i+1; stabsym(&fhdr->stabs, i, &ss) >= 0; i++){
283 if(ss.type == N_FUN && ss.name == nil)
285 if(ss.type == N_SLINE){
286 if(basepc+ss.value > pc)
294 snprint(buf, nbuf, "%s%s", s->u.stabs.dir, s->u.stabs.file);
296 snprint(buf, nbuf, "%s", s->u.stabs.file);
301 stabsline2pc(Fhdr *fhdr, ulong startpc, ulong line, ulong *pc)
311 if((s = ffindsym(fhdr, l, CTEXT)) == nil)
317 for(i=s->u.stabs.i+1; stabsym(&fhdr->stabs, i, &ss) >= 0; i++){
320 if(ss.type == N_SLINE){
321 if(basepc+ss.value >= startpc)
323 if(trigger && ss.desc >= line){
324 *pc = basepc+ss.value;
333 stabslenum(Fhdr *fhdr, Symbol *p, char *name, uint j, Loc l, Symbol *s)
338 for(i=p->u.stabs.locals; stabsym(&fhdr->stabs, i, &ss)>=0; i++){
339 if(ss.type == N_FUN && ss.name == nil)
346 if(strcmpcolon(name, ss.name) != 0)
354 if(stabcvtsym(&ss, s, p->u.stabs.dir, p->u.stabs.file, i) < 0)
356 if(s->loc.type == LOFFSET){
357 if(p->u.stabs.frameptr == 0)
358 s->loc.reg = mach->sp;
360 s->loc.reg = mach->fp;
362 if(l.type && loccmp(&l, &s->loc) != 0)
373 stabslookuplsym(Fhdr *fhdr, Symbol *p, char *name, Symbol *s)
375 return stabslenum(fhdr, p, name, 0, zl, s);
379 stabsindexlsym(Fhdr *fhdr, Symbol *p, uint i, Symbol *s)
381 return stabslenum(fhdr, p, nil, i, zl, s);
385 stabsfindlsym(Fhdr *fhdr, Symbol *p, Loc l, Symbol *s)
387 return stabslenum(fhdr, p, nil, 0, l, s);
393 if(stabssyminit(fp) < 0)
395 fp->pc2file = stabspc2file;
396 fp->line2pc = stabsline2pc;
397 fp->lookuplsym = stabslookuplsym;
398 fp->indexlsym = stabsindexlsym;
399 fp->findlsym = stabsfindlsym;