From 95f57b01e21feb457e79eaf52d593422c318024f Mon Sep 17 00:00:00 2001 From: rsc Date: Wed, 21 Apr 2004 02:03:00 +0000 Subject: Clean up the dwarf code. --- src/libmach/dwarf.h | 3 +- src/libmach/dwarfdump.c | 2 +- src/libmach/dwarfinfo.c | 90 ++++++++++++++++++++++----------------------- src/libmach/dwarfpubnames.c | 2 +- src/libmach/symdwarf.c | 7 ++-- 5 files changed, 50 insertions(+), 54 deletions(-) diff --git a/src/libmach/dwarf.h b/src/libmach/dwarf.h index 08365239..9404a370 100644 --- a/src/libmach/dwarf.h +++ b/src/libmach/dwarf.h @@ -392,7 +392,8 @@ int dwarflookuptag(Dwarf*, ulong, ulong, DwarfSym*); int dwarfenumunit(Dwarf*, ulong, DwarfSym*); int dwarfseeksym(Dwarf*, ulong, ulong, DwarfSym*); int dwarfenum(Dwarf*, DwarfSym*); -int dwarfnextsym(Dwarf*, DwarfSym*, int); +int dwarfnextsym(Dwarf*, DwarfSym*); +int dwarfnextsymat(Dwarf*, DwarfSym*, int); int dwarfpctoline(Dwarf*, ulong, char**, char**, char**, ulong*, ulong*, ulong*); int dwarfunwind(Dwarf*, ulong, DwarfExpr*, DwarfExpr*, DwarfExpr*, int); ulong dwarfget1(DwarfBuf*); diff --git a/src/libmach/dwarfdump.c b/src/libmach/dwarfdump.c index 47c38c37..b894a060 100644 --- a/src/libmach/dwarfdump.c +++ b/src/libmach/dwarfdump.c @@ -43,7 +43,7 @@ main(int argc, char **argv) if(dwarfenum(d, &s) < 0) sysfatal("dwarfenumall: %r"); - while(dwarfnextsym(d, &s, 1) == 1){ + while(dwarfnextsym(d, &s) == 1){ switch(s.attrs.tag){ case TagCompileUnit: print("compileunit %s\n", s.attrs.name); diff --git a/src/libmach/dwarfinfo.c b/src/libmach/dwarfinfo.c index 82b27a33..ef994ec5 100644 --- a/src/libmach/dwarfinfo.c +++ b/src/libmach/dwarfinfo.c @@ -121,13 +121,10 @@ dwarflookupnameinunit(Dwarf *d, ulong unit, char *name, DwarfSym *s) if(dwarfenumunit(d, unit, s) < 0) return -1; - dwarfnextsym(d, s, 1); /* s is now the CompileUnit */ - if(dwarfnextsym(d, s, 1) == 1){ /* s is now the first child of the compile unit */ - do{ - if(s->attrs.name && strcmp(s->attrs.name, name) == 0) - return 0; - }while(dwarfnextsym(d, s, 0) == 1); - } + dwarfnextsymat(d, s, 0); /* s is now the CompileUnit */ + while(dwarfnextsymat(d, s, 1) == 1) + if(s->attrs.name && strcmp(s->attrs.name, name) == 0) + return 0; werrstr("symbol '%s' not found", name); return -1; } @@ -137,12 +134,9 @@ int dwarflookupsubname(Dwarf *d, DwarfSym *parent, char *name, DwarfSym *s) { *s = *parent; - dwarfnextsym(d, s, 1); - if(s->depth == parent->depth+1) - do{ - if(s->attrs.name && strcmp(s->attrs.name, name) == 0) - return 0; - }while(dwarfnextsym(d, s, 0) == 1); + while(dwarfnextsymat(d, s, parent->depth+1)) + if(s->attrs.name && strcmp(s->attrs.name, name) == 0) + return 0; werrstr("symbol '%s' not found", name); return -1; } @@ -153,16 +147,12 @@ dwarflookuptag(Dwarf *d, ulong unit, ulong tag, DwarfSym *s) if(dwarfenumunit(d, unit, s) < 0) return -1; - dwarfnextsym(d, s, 1); /* s is now the CompileUnit */ + dwarfnextsymat(d, s, 0); /* s is now the CompileUnit */ if(s->attrs.tag == tag) return 0; - - if(dwarfnextsym(d, s, 1) == 1){ /* s is now the first child of the compile unit */ - do{ - if(s->attrs.tag == tag) - return 0; - }while(dwarfnextsym(d, s, 0) == 1); - } + while(dwarfnextsymat(d, s, 1) == 1) + if(s->attrs.tag == tag) + return 0; werrstr("symbol with tag 0x%lux not found", tag); return -1; } @@ -173,7 +163,7 @@ dwarfseeksym(Dwarf *d, ulong unit, ulong off, DwarfSym *s) if(dwarfenumunit(d, unit, s) < 0) return -1; s->b.p = d->info.data + unit + off; - if(dwarfnextsym(d, s, 1) != 1) + if(dwarfnextsymat(d, s, 0) != 1) return -1; return 0; } @@ -184,17 +174,15 @@ dwarflookupfn(Dwarf *d, ulong unit, ulong pc, DwarfSym *s) if(dwarfenumunit(d, unit, s) < 0) return -1; - if(dwarfnextsym(d, s, 1) != 1) + if(dwarfnextsymat(d, s, 0) != 1) return -1; /* s is now the CompileUnit */ - if(dwarfnextsym(d, s, 1) == 1){ /* s is now the first child of the compile unit */ - do{ - if(s->attrs.tag != TagSubprogram) - continue; - if(s->attrs.lowpc <= pc && pc < s->attrs.highpc) - return 0; - }while(dwarfnextsym(d, s, 0) == 1); + while(dwarfnextsymat(d, s, 1) == 1){ + if(s->attrs.tag != TagSubprogram) + continue; + if(s->attrs.lowpc <= pc && pc < s->attrs.highpc) + return 0; } werrstr("fn containing pc 0x%lux not found", pc); return -1; @@ -248,8 +236,8 @@ dwarfenum(Dwarf *d, DwarfSym *s) return 0; } -static int -_dwarfnextsym(Dwarf *d, DwarfSym *s) +int +dwarfnextsym(Dwarf *d, DwarfSym *s) { ulong num; DwarfAbbrev *a; @@ -288,31 +276,39 @@ top: } int -dwarfnextsym(Dwarf *d, DwarfSym *s, int recurse) +dwarfnextsymat(Dwarf *d, DwarfSym *s, int depth) { int r; - int depth; - ulong sib; - - if(recurse) - return _dwarfnextsym(d, s); + DwarfSym t; + uint sib; - depth = s->depth; - if(s->attrs.have.sibling){ + if(s->depth == depth && s->attrs.have.sibling){ sib = s->attrs.sibling; if(sib < d->info.len && d->info.data+sib >= s->b.p) s->b.p = d->info.data+sib; s->attrs.haskids = 0; } - do{ - r = _dwarfnextsym(d, s); - if(r <= 0) + /* + * The funny game with t and s make sure that + * if we get to the end of a run of a particular + * depth, we leave s so that a call to nextsymat with depth-1 + * will actually produce the desired guy. We could change + * the interface to dwarfnextsym instead, but I'm scared + * to touch it. + */ + t = *s; + for(;;){ + if((r = dwarfnextsym(d, &t)) != 1) return r; - }while(s->depth != depth); - if(s->depth < depth) - return 0; - return 1; + if(t.depth < depth){ + /* went too far - nothing to see */ + return 0; + } + *s = t; + if(t.depth == depth) + return 1; + } } typedef struct Parse Parse; diff --git a/src/libmach/dwarfpubnames.c b/src/libmach/dwarfpubnames.c index b09d2866..68ff9116 100644 --- a/src/libmach/dwarfpubnames.c +++ b/src/libmach/dwarfpubnames.c @@ -44,7 +44,7 @@ _dwarfnametounit(Dwarf *d, char *name, DwarfBlock *bl, DwarfSym *s) return -1; } s->b.p = d->info.data + unit + off; - if(dwarfnextsym(d, s, 1) < 0) + if(dwarfnextsym(d, s) < 0) return -1; if(s->attrs.name==nil || strcmp(s->attrs.name, name)!=0){ werrstr("unexpected name %#q in lookup for %#q", s->attrs.name, name); diff --git a/src/libmach/symdwarf.c b/src/libmach/symdwarf.c index 8ced09f4..8c41d127 100644 --- a/src/libmach/symdwarf.c +++ b/src/libmach/symdwarf.c @@ -119,7 +119,7 @@ dwarflenum(Fhdr *fhdr, Symbol *p, char *name, uint j, Loc l, Symbol *s) depth = 1; bpoff = 8; - while(dwarfnextsym(fhdr->dwarf, &ds, 1) == 1 && depth < ds.depth){ + while(dwarfnextsym(fhdr->dwarf, &ds) == 1 && depth < ds.depth){ if(ds.attrs.tag != TagVariable){ if(ds.attrs.tag != TagFormalParameter && ds.attrs.tag != TagUnspecifiedParameters) @@ -200,9 +200,8 @@ dwarfsyminit(Fhdr *fp) if(dwarfenum(d, &s) < 0) return; - while(dwarfnextsym(d, &s, s.depth!=1) == 1){ - if(s.depth != 1) - continue; + dwarfnextsymat(d, &s, 0); + while(dwarfnextsymat(d, &s, 1) == 1){ if(s.attrs.name == nil) continue; switch(s.attrs.tag){ -- cgit v1.2.3