runtime: fix gdb printing of maps
Fixes #5098

R=minux.ma, bradfitz, khr, rsc
CC=golang-dev
https://golang.org/cl/7746045
diff --git a/src/pkg/runtime/runtime-gdb.py b/src/pkg/runtime/runtime-gdb.py
index eff9a40..cb70ca02 100644
--- a/src/pkg/runtime/runtime-gdb.py
+++ b/src/pkg/runtime/runtime-gdb.py
@@ -84,26 +84,35 @@
 		return str(self.val.type)
 
 	def children(self):
-		stab = self.val['st']
-		i = 0
-		for v in self.traverse_hash(stab):
-			yield ("[%d]" % i, v['key'])
-			yield ("[%d]" % (i + 1), v['val'])
-			i += 2
-
-	def traverse_hash(self, stab):
-		ptr = stab['entry'].address
-		last = stab['last']
-		while ptr <= last:
-			v = ptr.dereference()
-			ptr = ptr + 1
-			if v['hash'] == 0: continue
-			if v['hash'] & 63 == 63:   # subtable
-				for v in self.traverse_hash(v['key'].cast(self.val['st'].type)):
-					yield v
-			else:
-				yield v
-
+		B = self.val['b']
+		buckets = self.val['buckets']
+		oldbuckets = self.val['oldbuckets']
+		flags = self.val['flags']
+		inttype = self.val['hash0'].type
+		cnt = 0
+		for bucket in xrange(2 ** B):
+			bp = buckets + bucket
+			if oldbuckets:
+				oldbucket = bucket & (2 ** (B - 1) - 1)
+				oldbp = oldbuckets + oldbucket
+				oldb = oldbp.dereference()
+				if (oldb['overflow'].cast(inttype) & 1) == 0: # old bucket not evacuated yet
+					if bucket >= 2 ** (B - 1): continue   # already did old bucket
+					bp = oldbp
+			while bp:
+				b = bp.dereference()
+				for i in xrange(8):
+					if b['tophash'][i] != 0:
+						k = b['keys'][i]
+						v = b['values'][i]
+						if flags & 1:
+							k = k.dereference()
+						if flags & 2:
+							v = v.dereference()
+						yield '%d' % cnt, k
+						yield '%d' % (cnt + 1), v
+						cnt += 2
+				bp = b['overflow']
 
 class ChanTypePrinter:
 	"""Pretty print chan[T] types.