Commit Diff


commit - 87a478a361877db7c4f904da527cb72d4eff6de2
commit + 95f57b01e21feb457e79eaf52d593422c318024f
blob - 0836523930951a40a383002be9b2aff438c4fa9e
blob + 9404a37019494ce650df73ec38a176e504b88046
--- src/libmach/dwarf.h
+++ 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*);
blob - 47c38c378c6239726c223bb2905785f49320440e
blob + b894a0605c43a83960666b05fee52164ebd7ad57
--- src/libmach/dwarfdump.c
+++ 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);
blob - 82b27a336d93b6133107e49bf7bf26927e20069a
blob + ef994ec5456ddcdc52439cc06cdf9ad31c7b37e6
--- src/libmach/dwarfinfo.c
+++ src/libmach/dwarfinfo.c
@@ -121,13 +121,10 @@ dwarflookupnameinunit(Dwarf *d, ulong unit, char *name
 	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, DwarfS
 	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
 	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
 	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;
+	DwarfSym t;
+	uint sib;
 
-	if(recurse)
-		return _dwarfnextsym(d, s);
-
-	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;
blob - b09d2866dea642e8f679d85259ee3a62967a93d8
blob + 68ff911605745af41b119a5e45d5422ab422b430
--- src/libmach/dwarfpubnames.c
+++ src/libmach/dwarfpubnames.c
@@ -44,7 +44,7 @@ _dwarfnametounit(Dwarf *d, char *name, DwarfBlock *bl,
 					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);
blob - 8ced09f4478e83933dbe52fc1e2166db3f701789
blob + 8c41d127c605b0f15d0d9c401715ff3cc748dc7a
--- src/libmach/symdwarf.c
+++ src/libmach/symdwarf.c
@@ -119,7 +119,7 @@ dwarflenum(Fhdr *fhdr, Symbol *p, char *name, uint j, 
 	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){