diff --git a/gocore/dwarf.go b/gocore/dwarf.go
new file mode 100644
index 0000000..6aa0fdd
--- /dev/null
+++ b/gocore/dwarf.go
@@ -0,0 +1,541 @@
+// Copyright 2017 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package gocore
+
+import (
+	"debug/dwarf"
+	"fmt"
+	"sort"
+	"strings"
+
+	"golang.org/x/debug/core"
+)
+
+// read DWARF types from core dump.
+func (p *Process) readDWARFTypes() {
+	d, _ := p.proc.DWARF()
+
+	// Make one of our own Types for each dwarf type.
+	r := d.Reader()
+	var types []*Type
+	for e, err := r.Next(); e != nil && err == nil; e, err = r.Next() {
+		switch e.Tag {
+		case dwarf.TagArrayType, dwarf.TagPointerType, dwarf.TagStructType, dwarf.TagBaseType, dwarf.TagSubroutineType, dwarf.TagTypedef:
+			dt, err := d.Type(e.Offset)
+			if err != nil {
+				continue
+			}
+			t := &Type{Name: gocoreName(dt), Size: dwarfSize(dt, p.proc.PtrSize())}
+			p.dwarfMap[dt] = t
+			types = append(types, t)
+		}
+	}
+
+	// Fill in fields of types. Postponed until now so we're sure
+	// we have all the Types allocated and available.
+	for dt, t := range p.dwarfMap {
+		switch x := dt.(type) {
+		case *dwarf.ArrayType:
+			t.Kind = KindArray
+			t.Elem = p.dwarfMap[x.Type]
+			t.Count = x.Count
+		case *dwarf.PtrType:
+			t.Kind = KindPtr
+			// unsafe.Pointer has a void base type.
+			if _, ok := x.Type.(*dwarf.VoidType); !ok {
+				t.Elem = p.dwarfMap[x.Type]
+			}
+		case *dwarf.StructType:
+			t.Kind = KindStruct
+			for _, f := range x.Field {
+				t.Fields = append(t.Fields, Field{Name: f.Name, Type: p.dwarfMap[f.Type], Off: f.ByteOffset})
+			}
+		case *dwarf.BoolType:
+			t.Kind = KindBool
+		case *dwarf.IntType:
+			t.Kind = KindInt
+		case *dwarf.UintType:
+			t.Kind = KindUint
+		case *dwarf.FloatType:
+			t.Kind = KindFloat
+		case *dwarf.ComplexType:
+			t.Kind = KindComplex
+		case *dwarf.FuncType:
+			t.Kind = KindFunc
+		case *dwarf.TypedefType:
+			// handle these types in the loop below
+		default:
+			panic(fmt.Sprintf("unknown type %s %T", dt, dt))
+		}
+	}
+
+	// Detect strings & slices
+	for _, t := range types {
+		if t.Kind != KindStruct {
+			continue
+		}
+		if t.Name == "string" { // TODO: also "struct runtime.stringStructDWARF" ?
+			t.Kind = KindString
+			t.Elem = t.Fields[0].Type.Elem // TODO: check that it is always uint8.
+			t.Fields = nil
+		}
+		if len(t.Name) >= 9 && t.Name[:9] == "struct []" ||
+			len(t.Name) >= 2 && t.Name[:2] == "[]" {
+			t.Kind = KindSlice
+			t.Elem = t.Fields[0].Type.Elem
+			t.Fields = nil
+		}
+	}
+
+	// Copy info from base types into typedefs.
+	r = d.Reader()
+	for dt, t := range p.dwarfMap {
+		tt, ok := dt.(*dwarf.TypedefType)
+		if !ok {
+			continue
+		}
+		base := tt.Type
+		// Walk typedef chain until we reach a non-typedef type.
+		for {
+			if x, ok := base.(*dwarf.TypedefType); ok {
+				base = x.Type
+				continue
+			}
+			break
+		}
+		bt := p.dwarfMap[base]
+
+		// Copy type info from base. Everything except the name.
+		name := t.Name
+		*t = *bt
+		t.Name = name
+
+		// Detect some special types. If the base is some particular type,
+		// then the alias gets marked as special.
+		// We have aliases like:
+		//   interface {}              -> struct runtime.eface
+		//   error                     -> struct runtime.iface
+		// Note: the base itself does not get marked as special.
+		// (Unlike strings and slices, where they do.)
+		if bt.Name == "runtime.eface" {
+			t.Kind = KindEface
+			t.Fields = nil
+		}
+		if bt.Name == "runtime.iface" {
+			t.Kind = KindIface
+			t.Fields = nil
+		}
+	}
+
+	// Make a runtime name -> Type map for existing DWARF types.
+	p.runtimeNameMap = map[string][]*Type{}
+	for dt, t := range p.dwarfMap {
+		name := runtimeName(dt)
+		p.runtimeNameMap[name] = append(p.runtimeNameMap[name], t)
+	}
+
+	// Construct the runtime.specialfinalizer type.  It won't be found
+	// in DWARF before 1.10 because it does not appear in the type of any variable.
+	// type specialfinalizer struct {
+	//      special special
+	//      fn      *funcval
+	//      nret    uintptr
+	//      fint    *_type
+	//      ot      *ptrtype
+	// }
+	if p.runtimeNameMap["runtime.specialfinalizer"] == nil {
+		special := p.findType("runtime.special")
+		p.runtimeNameMap["runtime.specialfinalizer"] = []*Type{
+			&Type{
+				Name: "runtime.specialfinalizer",
+				Size: special.Size + 4*p.proc.PtrSize(),
+				Kind: KindStruct,
+				Fields: []Field{
+					Field{
+						Name: "special",
+						Off:  0,
+						Type: special,
+					},
+					Field{
+						Name: "fn",
+						Off:  special.Size,
+						Type: p.findType("*runtime.funcval"),
+					},
+					Field{
+						Name: "nret",
+						Off:  special.Size + p.proc.PtrSize(),
+						Type: p.findType("uintptr"),
+					},
+					Field{
+						Name: "fint",
+						Off:  special.Size + 2*p.proc.PtrSize(),
+						Type: p.findType("*runtime._type"),
+					},
+					Field{
+						Name: "fn",
+						Off:  special.Size + 3*p.proc.PtrSize(),
+						Type: p.findType("*runtime.ptrtype"),
+					},
+				},
+			},
+		}
+	}
+}
+
+// dwarfSize is used to compute the size of a DWARF type.
+// dt.Size() is wrong when it returns a negative number.
+// This function implements just enough to correct the bad behavior.
+func dwarfSize(dt dwarf.Type, ptrSize int64) int64 {
+	s := dt.Size()
+	if s >= 0 {
+		return s
+	}
+	switch x := dt.(type) {
+	case *dwarf.FuncType:
+		return ptrSize // Fix for issue 21097.
+	case *dwarf.ArrayType:
+		return x.Count * dwarfSize(x.Type, ptrSize)
+	case *dwarf.TypedefType:
+		return dwarfSize(x.Type, ptrSize)
+	default:
+		panic(fmt.Sprintf("unhandled: %T", x))
+	}
+}
+
+// gocoreName generates the name this package uses to refer to a dwarf type.
+// This name differs from the dwarf name in that it stays closer to the Go name for the type.
+// For instance (dwarf name -> gocoreName)
+//   struct runtime.siginfo -> runtime.siginfo
+//   *void -> unsafe.Pointer
+//   struct struct { runtime.signalLock uint32; runtime.hz int32 } -> struct { signalLock uint32; hz int32 }
+func gocoreName(dt dwarf.Type) string {
+	switch x := dt.(type) {
+	case *dwarf.PtrType:
+		if _, ok := x.Type.(*dwarf.VoidType); ok {
+			return "unsafe.Pointer"
+		}
+		return "*" + gocoreName(x.Type)
+	case *dwarf.ArrayType:
+		return fmt.Sprintf("[%d]%s", x.Count, gocoreName(x.Type))
+	case *dwarf.StructType:
+		if !strings.HasPrefix(x.StructName, "struct {") {
+			// This is a named type, return that name.
+			return x.StructName
+		}
+		// Build gocore name from the DWARF fields.
+		s := "struct {"
+		first := true
+		for _, f := range x.Field {
+			if !first {
+				s += ";"
+			}
+			name := f.Name
+			if i := strings.Index(name, "."); i >= 0 {
+				// Remove pkg path from field names.
+				name = name[i+1:]
+			}
+			s += fmt.Sprintf(" %s %s", name, gocoreName(f.Type))
+			first = false
+		}
+		s += " }"
+		return s
+	default:
+		return dt.String()
+	}
+}
+
+// Generate the name the runtime uses for a dwarf type. The DWARF generator
+// and the runtime use slightly different names for the same underlying type.
+func runtimeName(dt dwarf.Type) string {
+	switch x := dt.(type) {
+	case *dwarf.PtrType:
+		if _, ok := x.Type.(*dwarf.VoidType); ok {
+			return "unsafe.Pointer"
+		}
+		return "*" + runtimeName(x.Type)
+	case *dwarf.ArrayType:
+		return fmt.Sprintf("[%d]%s", x.Count, runtimeName(x.Type))
+	case *dwarf.StructType:
+		if !strings.HasPrefix(x.StructName, "struct {") {
+			// This is a named type, return that name.
+			return x.StructName
+		}
+		// Figure out which fields have anonymous names.
+		var anon []bool
+		for _, f := range strings.Split(x.StructName[8:len(x.StructName)-1], ";") {
+			f = strings.TrimSpace(f)
+			anon = append(anon, !strings.Contains(f, " "))
+			// TODO: this isn't perfect. If the field type has a space in it,
+			// then this logic doesn't work. Need to search for keyword for
+			// field type, like "interface", "struct", ...
+		}
+		// Make sure anon is long enough. This probably never triggers.
+		for len(anon) < len(x.Field) {
+			anon = append(anon, false)
+		}
+
+		// Build runtime name from the DWARF fields.
+		s := "struct {"
+		first := true
+		for _, f := range x.Field {
+			if !first {
+				s += ";"
+			}
+			name := f.Name
+			if i := strings.Index(name, "."); i >= 0 {
+				name = name[i+1:]
+			}
+			if anon[0] {
+				s += fmt.Sprintf(" %s", runtimeName(f.Type))
+			} else {
+				s += fmt.Sprintf(" %s %s", name, runtimeName(f.Type))
+			}
+			first = false
+			anon = anon[1:]
+		}
+		s += " }"
+		return s
+	default:
+		name := dt.String()
+		if i := strings.LastIndex(name, "/"); i >= 0 {
+			name = name[i+1:] // Runtime uses only last name in package path.
+		}
+		return name
+	}
+}
+
+// readRuntimeConstants populates the p.rtConstants map.
+func (p *Process) readRuntimeConstants() {
+	p.rtConstants = map[string]int64{}
+
+	// Hardcoded values for Go 1.9.
+	// (Go did not have constants in DWARF before 1.10.)
+	m := p.rtConstants
+	m["_MSpanDead"] = 0
+	m["_MSpanInUse"] = 1
+	m["_MSpanManual"] = 2
+	m["_MSpanFree"] = 3
+	m["_Gidle"] = 0
+	m["_Grunnable"] = 1
+	m["_Grunning"] = 2
+	m["_Gsyscall"] = 3
+	m["_Gwaiting"] = 4
+	m["_Gdead"] = 6
+	m["_Gscan"] = 0x1000
+	m["_PCDATA_StackMapIndex"] = 0
+	m["_FUNCDATA_LocalsPointerMaps"] = 1
+	m["_FUNCDATA_ArgsPointerMaps"] = 0
+	m["tflagExtraStar"] = 1 << 1
+	m["kindGCProg"] = 1 << 6
+	m["kindDirectIface"] = 1 << 5
+	m["_PageSize"] = 1 << 13
+	m["_KindSpecialFinalizer"] = 1
+
+	// From 1.10, these constants are recorded in DWARF records.
+	d, _ := p.proc.DWARF()
+	r := d.Reader()
+	for e, err := r.Next(); e != nil && err == nil; e, err = r.Next() {
+		if e.Tag != dwarf.TagConstant {
+			continue
+		}
+		name := e.AttrField(dwarf.AttrName).Val.(string)
+		if !strings.HasPrefix(name, "runtime.") {
+			continue
+		}
+		name = name[8:]
+		c := e.AttrField(dwarf.AttrConstValue)
+		if c == nil {
+			continue
+		}
+		p.rtConstants[name] = c.Val.(int64)
+	}
+}
+
+const (
+	_DW_OP_addr           = 0x03
+	_DW_OP_call_frame_cfa = 0x9c
+	_DW_OP_plus           = 0x22
+	_DW_OP_consts         = 0x11
+)
+
+func (p *Process) readGlobals() {
+	d, _ := p.proc.DWARF()
+	r := d.Reader()
+	for e, err := r.Next(); e != nil && err == nil; e, err = r.Next() {
+		if e.Tag != dwarf.TagVariable {
+			continue
+		}
+		loc := e.AttrField(dwarf.AttrLocation).Val.([]byte)
+		if len(loc) == 0 || loc[0] != _DW_OP_addr {
+			continue
+		}
+		var a core.Address
+		if p.proc.PtrSize() == 8 {
+			a = core.Address(p.proc.ByteOrder().Uint64(loc[1:]))
+		} else {
+			a = core.Address(p.proc.ByteOrder().Uint32(loc[1:]))
+		}
+		if !p.proc.Writeable(a) {
+			// Read-only globals can't have heap pointers.
+			// TODO: keep roots around anyway?
+			continue
+		}
+		dt, err := d.Type(e.AttrField(dwarf.AttrType).Val.(dwarf.Offset))
+		if err != nil {
+			panic(err)
+		}
+		if _, ok := dt.(*dwarf.UnspecifiedType); ok {
+			continue // Ignore markers like data/edata.
+		}
+		p.globals = append(p.globals, &Root{
+			Name:  e.AttrField(dwarf.AttrName).Val.(string),
+			Addr:  a,
+			Type:  p.dwarfMap[dt],
+			Frame: nil,
+		})
+	}
+}
+
+func (p *Process) readStackVars() {
+	type Var struct {
+		name string
+		off  int64
+		typ  *Type
+	}
+	vars := map[*Func][]Var{}
+	var curfn *Func
+	d, _ := p.proc.DWARF()
+	r := d.Reader()
+	for e, err := r.Next(); e != nil && err == nil; e, err = r.Next() {
+		if e.Tag == dwarf.TagSubprogram {
+			min := core.Address(e.AttrField(dwarf.AttrLowpc).Val.(uint64))
+			max := core.Address(e.AttrField(dwarf.AttrHighpc).Val.(uint64))
+			f := p.funcTab.find(min)
+			if f == nil {
+				// some func Go doesn't know about. C?
+				curfn = nil
+			} else {
+				if f.entry != min {
+					panic("dwarf and runtime don't agree about start of " + f.name)
+				}
+				if p.funcTab.find(max-1) != f {
+					panic("function ranges don't match for " + f.name)
+				}
+				curfn = f
+			}
+			continue
+		}
+		if e.Tag != dwarf.TagVariable && e.Tag != dwarf.TagFormalParameter {
+			continue
+		}
+		aloc := e.AttrField(dwarf.AttrLocation)
+		if aloc == nil {
+			continue
+		}
+		// Interpret locations of the form
+		//    DW_OP_call_frame_cfa
+		//    DW_OP_consts <off>
+		//    DW_OP_plus
+		// (with possibly missing DW_OP_consts & DW_OP_plus for the zero offset.)
+		// TODO: handle other possible locations (e.g. register locations).
+		loc := aloc.Val.([]byte)
+		if len(loc) == 0 || loc[0] != _DW_OP_call_frame_cfa {
+			continue
+		}
+		loc = loc[1:]
+		var off int64
+		if len(loc) != 0 && loc[0] == _DW_OP_consts {
+			loc = loc[1:]
+			var s uint
+			for len(loc) > 0 {
+				b := loc[0]
+				loc = loc[1:]
+				off += int64(b&0x7f) << s
+				s += 7
+				if b&0x80 == 0 {
+					break
+				}
+			}
+			off = off << (64 - s) >> (64 - s)
+			if len(loc) == 0 || loc[0] != _DW_OP_plus {
+				continue
+			}
+			loc = loc[1:]
+		}
+		if len(loc) != 0 {
+			continue // more stuff we don't recognize
+		}
+		dt, err := d.Type(e.AttrField(dwarf.AttrType).Val.(dwarf.Offset))
+		if err != nil {
+			panic(err)
+		}
+		name := e.AttrField(dwarf.AttrName).Val.(string)
+		vars[curfn] = append(vars[curfn], Var{name: name, off: off, typ: p.dwarfMap[dt]})
+	}
+
+	// Get roots from goroutine stacks.
+	for _, g := range p.goroutines {
+		for _, f := range g.frames {
+			// Start with all pointer slots as unnamed.
+			unnamed := map[core.Address]bool{}
+			for a := range f.Live {
+				unnamed[a] = true
+			}
+			// Emit roots for DWARF entries.
+			for _, v := range vars[f.f] {
+				r := &Root{
+					Name:  v.name,
+					Addr:  f.max.Add(v.off),
+					Type:  v.typ,
+					Frame: f,
+				}
+				f.roots = append(f.roots, r)
+				// Remove this variable from the set of unnamed pointers.
+				for a := r.Addr; a < r.Addr.Add(r.Type.Size); a = a.Add(p.proc.PtrSize()) {
+					delete(unnamed, a)
+				}
+			}
+			// Emit roots for unnamed pointer slots in the frame.
+			// Make deterministic by sorting first.
+			s := make([]core.Address, 0, len(unnamed))
+			for a := range unnamed {
+				s = append(s, a)
+			}
+			sort.Slice(s, func(i, j int) bool { return s[i] < s[j] })
+			for _, a := range s {
+				r := &Root{
+					Name:  "unk",
+					Addr:  a,
+					Type:  p.findType("unsafe.Pointer"),
+					Frame: f,
+				}
+				f.roots = append(f.roots, r)
+			}
+		}
+	}
+}
+
+/* Dwarf encoding notes
+
+type XXX sss
+
+translates to a dwarf type pkg.XXX of the type of sss (uint, float, ...)
+
+exception: if sss is a struct or array, then we get two types, the "unnamed" and "named" type.
+The unnamed type is a dwarf struct type with name "struct pkg.XXX" or a dwarf array type with
+name [N]elem.
+Then there is a typedef with pkg.XXX pointing to "struct pkg.XXX" or [N]elem.
+
+For structures, lowercase field names are prepended with the package name (pkg path?).
+
+type XXX interface{}
+pkg.XXX is a typedef to "struct runtime.eface"
+type XXX interface{f()}
+pkg.XXX is a typedef to "struct runtime.iface"
+
+Sometimes there is even a chain of identically-named typedefs. I have no idea why.
+main.XXX -> main.XXX -> struct runtime.iface
+
+*/
diff --git a/gocore/gocore_test.go b/gocore/gocore_test.go
new file mode 100644
index 0000000..ab6d980
--- /dev/null
+++ b/gocore/gocore_test.go
@@ -0,0 +1,165 @@
+// Copyright 2017 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package gocore
+
+import (
+	"reflect"
+	"testing"
+
+	"golang.org/x/debug/core"
+)
+
+// loadTest loads a simple core file which resulted from running the
+// following program on linux/amd64 with go 1.9.0 (the earliest supported runtime):
+// package main
+// func main() {
+//         _ = *(*int)(nil)
+// }
+func loadExample(t *testing.T) *Process {
+	c, err := core.Core("testdata/core", "testdata")
+	if err != nil {
+		t.Fatalf("can't load test core file: %s", err)
+	}
+	p, err := Core(c, FlagTypes|FlagReverse)
+	if err != nil {
+		t.Fatalf("can't parse Go core: %s", err)
+	}
+	return p
+}
+
+func TestObjects(t *testing.T) {
+	p := loadExample(t)
+	n := 0
+	p.ForEachObject(func(x Object) bool {
+		n++
+		return true
+	})
+	if n != 104 {
+		t.Errorf("#objects = %d, want 104", n)
+	}
+}
+
+func TestRoots(t *testing.T) {
+	p := loadExample(t)
+	n := 0
+	p.ForEachRoot(func(r *Root) bool {
+		n++
+		return true
+	})
+	if n != 257 {
+		t.Errorf("#roots = %d, want 257", n)
+	}
+}
+
+// TestConfig checks the configuration accessors.
+func TestConfig(t *testing.T) {
+	p := loadExample(t)
+	if v := p.BuildVersion(); v != "go1.9" {
+		t.Errorf("version=%s, wanted go1.9", v)
+	}
+	if n := p.Stats().Size; n != 2732032 {
+		t.Errorf("all stats=%d, want 2732032", n)
+	}
+}
+
+func TestFindFunc(t *testing.T) {
+	p := loadExample(t)
+	a := core.Address(0x404000)
+	f := p.FindFunc(a)
+	if f == nil {
+		t.Errorf("can't find function at %x", a)
+		return
+	}
+	if n := f.Name(); n != "runtime.recvDirect" {
+		t.Errorf("funcname(%x)=%s, want runtime.recvDirect", a, n)
+	}
+}
+
+func TestTypes(t *testing.T) {
+	p := loadExample(t)
+	// Check the type of a few objects.
+	for _, s := range [...]struct {
+		addr   core.Address
+		size   int64
+		kind   Kind
+		name   string
+		repeat int64
+	}{
+		{0xc420000480, 384, KindStruct, "runtime.g", 1},
+		{0xc42000a020, 32, KindPtr, "*runtime.g", 4},
+		{0xc420082000, 96, KindStruct, "hchan<bool>", 1},
+		{0xc420062000, 64, KindStruct, "runtime._defer", 1},
+	} {
+		x, i := p.FindObject(s.addr)
+		if x == 0 {
+			t.Errorf("can't find object at %x", s.addr)
+			continue
+		}
+		if i != 0 {
+			t.Errorf("offset(%x)=%d, want 0", s.addr, i)
+		}
+		if p.Size(x) != s.size {
+			t.Errorf("size(%x)=%d, want %d", s.addr, p.Size(x), s.size)
+		}
+		typ, repeat := p.Type(x)
+		if typ.Kind != s.kind {
+			t.Errorf("kind(%x)=%s, want %s", s.addr, typ.Kind, s.kind)
+		}
+		if typ.Name != s.name {
+			t.Errorf("name(%x)=%s, want %s", s.addr, typ.Name, s.name)
+		}
+		if repeat != s.repeat {
+			t.Errorf("repeat(%x)=%d, want %d", s.addr, repeat, s.repeat)
+		}
+
+		y, i := p.FindObject(s.addr + 1)
+		if y != x {
+			t.Errorf("can't find object at %x", s.addr+1)
+		}
+		if i != 1 {
+			t.Errorf("offset(%x)=%d, want i", s.addr, i)
+		}
+	}
+}
+
+func TestReverse(t *testing.T) {
+	p := loadExample(t)
+
+	// Build the pointer map.
+	// m[x]=y means address x has a pointer to address y.
+	m1 := map[core.Address]core.Address{}
+	p.ForEachObject(func(x Object) bool {
+		p.ForEachPtr(x, func(i int64, y Object, j int64) bool {
+			m1[p.Addr(x).Add(i)] = p.Addr(y).Add(j)
+			return true
+		})
+		return true
+	})
+	p.ForEachRoot(func(r *Root) bool {
+		p.ForEachRootPtr(r, func(i int64, y Object, j int64) bool {
+			m1[r.Addr.Add(i)] = p.Addr(y).Add(j)
+			return true
+		})
+		return true
+	})
+
+	// Build the same, with reverse entries.
+	m2 := map[core.Address]core.Address{}
+	p.ForEachObject(func(y Object) bool {
+		p.ForEachReversePtr(y, func(x Object, r *Root, i, j int64) bool {
+			if r != nil {
+				m2[r.Addr.Add(i)] = p.Addr(y).Add(j)
+			} else {
+				m2[p.Addr(x).Add(i)] = p.Addr(y).Add(j)
+			}
+			return true
+		})
+		return true
+	})
+
+	if !reflect.DeepEqual(m1, m2) {
+		t.Errorf("forward and reverse edges don't match")
+	}
+}
diff --git a/gocore/goroutine.go b/gocore/goroutine.go
new file mode 100644
index 0000000..b4891eb
--- /dev/null
+++ b/gocore/goroutine.go
@@ -0,0 +1,108 @@
+// Copyright 2017 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package gocore
+
+import (
+	"golang.org/x/debug/core"
+)
+
+type Goroutine struct {
+	r         region // inferior region holding the runtime.g
+	stackSize int64  // current stack allocation
+	frames    []*Frame
+
+	// TODO: defers, in-progress panics
+}
+
+// Stack returns the total allocated stack for g.
+func (g *Goroutine) Stack() int64 {
+	return g.stackSize
+}
+
+// Addr returns the address of the runtime.g that identifies this goroutine.
+func (g *Goroutine) Addr() core.Address {
+	return g.r.a
+}
+
+// Frames returns the list of frames on the stack of the Goroutine.
+// The first frame is the most recent one.
+// This list is post-optimization, so any inlined calls, tail calls, etc.
+// will not appear.
+func (g *Goroutine) Frames() []*Frame {
+	return g.frames
+}
+
+// A Frame represents the local variables of a single Go function invocation.
+// (Note that in the presence of inlining, a Frame may contain local variables
+// for more than one Go function invocation.)
+type Frame struct {
+	parent   *Frame
+	f        *Func        // function whose activation record this frame is
+	pc       core.Address // resumption point
+	min, max core.Address // extent of stack frame
+
+	// Set of locations that contain a live pointer. Note that this set
+	// may contain locations outside the frame (in particular, the args
+	// for the frame).
+	Live map[core.Address]bool
+
+	roots []*Root // GC roots in this frame
+
+	// TODO: keep vars from dwarf around?
+}
+
+// Func returns the function for which this frame is an activation record.
+func (f *Frame) Func() *Func {
+	return f.f
+}
+
+// Min returns the minimum address of this frame.
+func (f *Frame) Min() core.Address {
+	return f.min
+}
+
+// Max returns the maximum address of this frame.
+func (f *Frame) Max() core.Address {
+	return f.max
+}
+
+// PC returns the program counter of the next instruction to be executed by this frame.
+func (f *Frame) PC() core.Address {
+	return f.pc
+}
+
+// Roots returns a list of all the garbage collection roots in the frame.
+func (f *Frame) Roots() []*Root {
+	return f.roots
+}
+
+// Parent returns the parent frame of f, or nil if it is the top of the stack.
+func (f *Frame) Parent() *Frame {
+	return f.parent
+}
+
+// A Func represents a Go function.
+type Func struct {
+	r         region // inferior region holding a runtime._func
+	module    *module
+	name      string
+	entry     core.Address
+	frameSize pcTab // map from pc to frame size at that pc
+	pcdata    []int32
+	funcdata  []core.Address
+	stackMap  pcTab // map from pc to stack map # (index into locals and args bitmaps)
+	closure   *Type // the type to use for closures of this function. Lazily allocated.
+}
+
+// Name returns the name of the function, as reported by DWARF.
+// Names are opaque; do not depend on the format of the returned name.
+func (f *Func) Name() string {
+	return f.name
+}
+
+// Entry returns the address of the entry point of f.
+func (f *Func) Entry() core.Address {
+	return f.entry
+}
diff --git a/gocore/module.go b/gocore/module.go
new file mode 100644
index 0000000..93b5451
--- /dev/null
+++ b/gocore/module.go
@@ -0,0 +1,192 @@
+// Copyright 2017 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package gocore
+
+import (
+	"fmt"
+	"sort"
+
+	"golang.org/x/debug/core"
+)
+
+type module struct {
+	r             region       // inferior region holding a runtime.moduledata
+	types, etypes core.Address // range that holds all the runtime._type data in this module
+}
+
+func (p *Process) readModules() {
+	// Note: the cast is necessary for cores generated by Go 1.9, where
+	// runtime.moduledata is just an unsafe.Pointer.
+	ms := p.rtGlobals["modulesSlice"].Cast("*[]*runtime.moduledata").Deref()
+	n := ms.SliceLen()
+	for i := int64(0); i < n; i++ {
+		md := ms.SliceIndex(i).Deref()
+		p.modules = append(p.modules, p.readModule(md))
+	}
+	p.funcTab.sort()
+}
+
+func (p *Process) readModule(r region) *module {
+	m := &module{r: r}
+	m.types = core.Address(r.Field("types").Uintptr())
+	m.etypes = core.Address(r.Field("etypes").Uintptr())
+
+	// Read the pc->function table
+	pcln := r.Field("pclntable")
+	ftab := r.Field("ftab")
+	n := ftab.SliceLen() - 1 // last slot is a dummy, just holds entry
+	for i := int64(0); i < n; i++ {
+		ft := ftab.SliceIndex(i)
+		min := core.Address(ft.Field("entry").Uintptr())
+		max := core.Address(ftab.SliceIndex(i + 1).Field("entry").Uintptr())
+		fr := pcln.SliceIndex(int64(ft.Field("funcoff").Uintptr())).Cast("runtime._func")
+		f := m.readFunc(fr, pcln)
+		if f.entry != min {
+			panic(fmt.Errorf("entry %x and min %x don't match for %s", f.entry, min, f.name))
+		}
+		p.funcTab.add(min, max, f)
+	}
+
+	return m
+}
+
+// readFunc parses a runtime._func and returns a *Func.
+// r must have type runtime._func.
+// pcln must have type []byte and represent the module's pcln table region.
+func (m *module) readFunc(r region, pcln region) *Func {
+	f := &Func{module: m, r: r}
+	f.entry = core.Address(r.Field("entry").Uintptr())
+	f.name = r.p.proc.ReadCString(pcln.SliceIndex(int64(r.Field("nameoff").Int32())).a)
+	f.frameSize.read(r.p.proc, pcln.SliceIndex(int64(r.Field("pcsp").Int32())).a)
+
+	// Parse pcdata and funcdata, which are laid out beyond the end of the _func.
+	a := r.a.Add(int64(r.p.findType("runtime._func").Size))
+	n := r.Field("npcdata").Int32()
+	for i := int32(0); i < n; i++ {
+		f.pcdata = append(f.pcdata, r.p.proc.ReadInt32(a))
+		a = a.Add(4)
+	}
+	a = a.Align(r.p.proc.PtrSize())
+	n = r.Field("nfuncdata").Int32()
+	for i := int32(0); i < n; i++ {
+		f.funcdata = append(f.funcdata, r.p.proc.ReadPtr(a))
+		a = a.Add(r.p.proc.PtrSize())
+	}
+
+	// Read pcln tables we need.
+	if stackmap := int(r.p.rtConstants["_PCDATA_StackMapIndex"]); stackmap < len(f.pcdata) {
+		f.stackMap.read(r.p.proc, pcln.SliceIndex(int64(f.pcdata[stackmap])).a)
+	} else {
+		f.stackMap.setEmpty()
+	}
+
+	return f
+}
+
+type funcTabEntry struct {
+	min, max core.Address
+	f        *Func
+}
+
+type funcTab struct {
+	entries []funcTabEntry
+}
+
+// add records that PCs in the range [min,max) map to function f.
+func (t *funcTab) add(min, max core.Address, f *Func) {
+	t.entries = append(t.entries, funcTabEntry{min: min, max: max, f: f})
+}
+
+// sort must be called after all the adds, but before any find.
+func (t *funcTab) sort() {
+	sort.Slice(t.entries, func(i, j int) bool {
+		return t.entries[i].min < t.entries[j].min
+	})
+}
+
+// Finds a Func for the given address.  Sort must have been called already.
+func (t *funcTab) find(pc core.Address) *Func {
+	n := sort.Search(len(t.entries), func(i int) bool {
+		return t.entries[i].max > pc
+	})
+	if n == len(t.entries) || pc < t.entries[n].min || pc >= t.entries[n].max {
+		return nil
+	}
+	return t.entries[n].f
+}
+
+// a pcTab maps from an offset in a function to an int64.
+type pcTab struct {
+	entries []pcTabEntry
+}
+
+type pcTabEntry struct {
+	bytes int64 // # of bytes this entry covers
+	val   int64 // value over that range of bytes
+}
+
+// read parses a pctab from the core file at address data.
+func (t *pcTab) read(core *core.Process, data core.Address) {
+	var pcQuantum int64
+	switch core.Arch() {
+	case "386", "amd64", "amd64p32":
+		pcQuantum = 1
+	case "s390x":
+		pcQuantum = 2
+	case "arm", "arm64", "mips", "mipsle", "mips64", "mips64le", "ppc64", "ppc64le":
+		pcQuantum = 4
+	default:
+		panic("unknown architecture " + core.Arch())
+	}
+	val := int64(-1)
+	first := true
+	for {
+		// Advance value.
+		v, n := readVarint(core, data)
+		if v == 0 && !first {
+			return
+		}
+		data = data.Add(n)
+		if v&1 != 0 {
+			val += ^(v >> 1)
+		} else {
+			val += v >> 1
+		}
+
+		// Advance pc.
+		v, n = readVarint(core, data)
+		data = data.Add(n)
+		t.entries = append(t.entries, pcTabEntry{bytes: v * pcQuantum, val: val})
+		first = false
+	}
+}
+
+func (t *pcTab) setEmpty() {
+	t.entries = []pcTabEntry{{bytes: 1<<63 - 1, val: -1}}
+}
+
+func (t *pcTab) find(off int64) int64 {
+	for _, e := range t.entries {
+		if off < e.bytes {
+			return e.val
+		}
+		off -= e.bytes
+	}
+	panic("can't find pctab entry")
+}
+
+// readVarint reads a varint from the core file.
+// val is the value, n is the number of bytes consumed.
+func readVarint(core *core.Process, a core.Address) (val, n int64) {
+	for {
+		b := core.ReadUint8(a)
+		val |= int64(b&0x7f) << uint(n*7)
+		n++
+		a++
+		if b&0x80 == 0 {
+			return
+		}
+	}
+}
diff --git a/gocore/object.go b/gocore/object.go
new file mode 100644
index 0000000..6990e33
--- /dev/null
+++ b/gocore/object.go
@@ -0,0 +1,339 @@
+// Copyright 2017 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package gocore
+
+import (
+	"math/bits"
+	"strings"
+
+	"golang.org/x/debug/core"
+)
+
+// An Object represents a single object in the Go heap.
+type Object core.Address
+
+// markObjects finds all the live objects in the heap and marks them
+// in the p.heapInfo mark fields.
+func (p *Process) markObjects() {
+	ptrSize := p.proc.PtrSize()
+
+	// number of live objects found so far
+	n := 0
+	// total size of live objects
+	var live int64
+
+	var q []Object
+
+	// Function to call when we find a new pointer.
+	add := func(x core.Address) {
+		h := p.findHeapInfo(x)
+		if h == nil || h.base == 0 { // not in heap or not in a valid span
+			// Invalid spans can happen with intra-stack pointers.
+			return
+		}
+		// Round down to object start.
+		x = h.base.Add(x.Sub(h.base) / h.size * h.size)
+		// Object start may map to a different info. Reload.
+		h = p.findHeapInfo(x)
+		// Find mark bit
+		b := uint64(x) % heapInfoSize / 8
+		if h.mark&(uint64(1)<<b) != 0 { // already found
+			return
+		}
+		h.mark |= uint64(1) << b
+		n++
+		live += h.size
+		q = append(q, Object(x))
+	}
+
+	// Start with scanning all the roots.
+	// Note that we don't just use the DWARF roots, just in case DWARF isn't complete.
+	// Instead we use exactly what the runtime uses.
+
+	// Goroutine roots
+	for _, g := range p.goroutines {
+		for _, f := range g.frames {
+			for a := range f.Live {
+				add(p.proc.ReadPtr(a))
+			}
+		}
+	}
+
+	// Global roots
+	for _, m := range p.modules {
+		for _, s := range [2]string{"data", "bss"} {
+			min := core.Address(m.r.Field(s).Uintptr())
+			max := core.Address(m.r.Field("e" + s).Uintptr())
+			gc := m.r.Field("gc" + s + "mask").Field("bytedata").Address()
+			num := max.Sub(min) / ptrSize
+			for i := int64(0); i < num; i++ {
+				if p.proc.ReadUint8(gc.Add(i/8))>>uint(i%8)&1 != 0 {
+					add(p.proc.ReadPtr(min.Add(i * ptrSize)))
+				}
+			}
+		}
+	}
+
+	// Finalizers
+	for _, r := range p.globals {
+		if !strings.HasPrefix(r.Name, "finalizer for ") {
+			continue
+		}
+		for _, f := range r.Type.Fields {
+			if f.Type.Kind == KindPtr {
+				add(p.proc.ReadPtr(r.Addr.Add(f.Off)))
+			}
+		}
+	}
+
+	// Expand root set to all reachable objects.
+	for len(q) > 0 {
+		x := q[len(q)-1]
+		q = q[:len(q)-1]
+
+		// Scan object for pointers.
+		size := p.Size(x)
+		for i := int64(0); i < size; i += ptrSize {
+			a := core.Address(x).Add(i)
+			if p.isPtrFromHeap(a) {
+				add(p.proc.ReadPtr(a))
+			}
+		}
+	}
+
+	p.nObj = n
+
+	// Initialize firstIdx fields in the heapInfo, for fast object index lookups.
+	for i := len(p.heapInfo) - 1; i >= 0; i-- {
+		h := &p.heapInfo[i]
+		if h.mark == 0 { // not really necessary, just leave -1 sentinel as a double check.
+			continue
+		}
+		n -= bits.OnesCount64(h.mark)
+		h.firstIdx = n
+	}
+
+	// Update stats to include the live/garbage distinction.
+	alloc := p.Stats().Child("heap").Child("in use spans").Child("alloc")
+	alloc.Children = []*Stats{
+		&Stats{"live", live, nil},
+		&Stats{"garbage", alloc.Size - live, nil},
+	}
+}
+
+// isPtrFromHeap reports whether the inferior at address a contains a pointer.
+// a must be somewhere in the heap.
+func (p *Process) isPtrFromHeap(a core.Address) bool {
+	// Convert arena offset in words to bitmap offset in bits.
+	off := a.Sub(p.arenaStart)
+	off >>= p.proc.LogPtrSize()
+
+	// Find bit in bitmap. It goes backwards from the end.
+	// Each byte contains pointer/nonpointer bits for 4 words in its low nybble.
+	return p.proc.ReadUint8(p.bitmapEnd.Add(-(off>>2)-1))>>uint(off&3)&1 != 0
+}
+
+// IsPtr reports whether the inferior at address a contains a pointer.
+func (p *Process) IsPtr(a core.Address) bool {
+	if a >= p.arenaStart && a < p.arenaUsed {
+		return p.isPtrFromHeap(a)
+	}
+	for _, m := range p.modules {
+		for _, s := range [2]string{"data", "bss"} {
+			min := core.Address(m.r.Field(s).Uintptr())
+			max := core.Address(m.r.Field("e" + s).Uintptr())
+			if a < min || a >= max {
+				continue
+			}
+			gc := m.r.Field("gc" + s + "mask").Field("bytedata").Address()
+			i := a.Sub(min)
+			return p.proc.ReadUint8(gc.Add(i/8))>>uint(i%8) != 0
+		}
+	}
+	// Everywhere else can't be a pointer. At least, not a pointer into the Go heap.
+	// TODO: stacks?
+	// TODO: finalizers?
+	return false
+}
+
+// FindObject finds the object containing a.  Returns that object and the offset within
+// that object to which a points.
+// Returns 0,0 if a doesn't point to a live heap object.
+func (p *Process) FindObject(a core.Address) (Object, int64) {
+	// Round down to the start of an object.
+	h := p.findHeapInfo(a)
+	if h == nil || h.size == 0 {
+		// Not in Go heap, or in a span
+		// that doesn't hold Go objects (freed, stacks, ...)
+		return 0, 0
+	}
+	x := h.base.Add(a.Sub(h.base) / h.size * h.size)
+	// Check if object is marked.
+	h = p.findHeapInfo(x)
+	if h.mark>>(uint64(x)%heapInfoSize/8)&1 == 0 {
+		return 0, 0
+	}
+	return Object(x), a.Sub(x)
+}
+
+func (p *Process) findObjectIndex(a core.Address) (int, int64) {
+	x, off := p.FindObject(a)
+	if x == 0 {
+		return -1, 0
+	}
+	h := p.findHeapInfo(core.Address(x))
+	return h.firstIdx + bits.OnesCount64(h.mark&(uint64(1)<<(uint64(x)%heapInfoSize/8)-1)), off
+}
+
+// ForEachObject calls fn with each object in the Go heap.
+// If fn returns false, ForEachObject returns immediately.
+func (p *Process) ForEachObject(fn func(x Object) bool) {
+	for i := 0; i < len(p.heapInfo); i++ {
+		m := p.heapInfo[i].mark
+		for m != 0 {
+			j := bits.TrailingZeros64(m)
+			m &= m - 1
+			if !fn(Object(p.arenaStart.Add(int64(i)*heapInfoSize + int64(j)*8))) {
+				return
+			}
+		}
+	}
+}
+
+// ForEachRoot calls fn with each garbage collection root.
+// If fn returns false, ForEachRoot returns immediately.
+func (p *Process) ForEachRoot(fn func(r *Root) bool) {
+	for _, r := range p.globals {
+		if !fn(r) {
+			return
+		}
+	}
+	for _, g := range p.goroutines {
+		for _, f := range g.frames {
+			for _, r := range f.roots {
+				if !fn(r) {
+					return
+				}
+			}
+		}
+	}
+}
+
+// Addr returns the starting address of x.
+func (p *Process) Addr(x Object) core.Address {
+	return core.Address(x)
+}
+
+// Size returns the size of x in bytes.
+func (p *Process) Size(x Object) int64 {
+	return p.findHeapInfo(core.Address(x)).size
+}
+
+// Type returns the type and repeat count for the object x.
+// x contains at least repeat copies of the returned type.
+// FlagTypes must have been passed to Core when p was constructed.
+func (p *Process) Type(x Object) (*Type, int64) {
+	i, _ := p.findObjectIndex(core.Address(x))
+	return p.types[i].t, p.types[i].r
+}
+
+// ForEachPtr calls fn for all heap pointers it finds in x.
+// It calls fn with:
+//   the offset of the pointer slot in x
+//   the pointed-to object y
+//   the offset in y where the pointer points.
+// If fn returns false, ForEachPtr returns immediately.
+// For an edge from an object to its finalizer, the first argument
+// passed to fn will be -1. (TODO: implement)
+func (p *Process) ForEachPtr(x Object, fn func(int64, Object, int64) bool) {
+	size := p.Size(x)
+	for i := int64(0); i < size; i += p.proc.PtrSize() {
+		a := core.Address(x).Add(i)
+		if !p.isPtrFromHeap(a) {
+			continue
+		}
+		ptr := p.proc.ReadPtr(a)
+		y, off := p.FindObject(ptr)
+		if y != 0 {
+			if !fn(i, y, off) {
+				return
+			}
+		}
+	}
+}
+
+// ForEachRootPtr behaves like ForEachPtr but it starts with a Root instead of an Object.
+func (p *Process) ForEachRootPtr(r *Root, fn func(int64, Object, int64) bool) {
+	edges1(p, r, 0, r.Type, fn)
+}
+
+// edges1 calls fn for the edges found in an object of type t living at offset off in the root r.
+// If fn returns false, return immediately with false.
+func edges1(p *Process, r *Root, off int64, t *Type, fn func(int64, Object, int64) bool) bool {
+	switch t.Kind {
+	case KindBool, KindInt, KindUint, KindFloat, KindComplex:
+		// no edges here
+	case KindIface, KindEface:
+		// The first word is a type or itab.
+		// Itabs are never in the heap.
+		// Types might be, though.
+		a := r.Addr.Add(off)
+		if r.Frame == nil || r.Frame.Live[a] {
+			dst, off2 := p.FindObject(p.proc.ReadPtr(a))
+			if dst != 0 {
+				if !fn(off, dst, off2) {
+					return false
+				}
+			}
+		}
+		// Treat second word like a pointer.
+		off += p.proc.PtrSize()
+		fallthrough
+	case KindPtr, KindString, KindSlice, KindFunc:
+		a := r.Addr.Add(off)
+		if r.Frame == nil || r.Frame.Live[a] {
+			dst, off2 := p.FindObject(p.proc.ReadPtr(a))
+			if dst != 0 {
+				if !fn(off, dst, off2) {
+					return false
+				}
+			}
+		}
+	case KindArray:
+		s := t.Elem.Size
+		for i := int64(0); i < t.Count; i++ {
+			if !edges1(p, r, off+i*s, t.Elem, fn) {
+				return false
+			}
+		}
+	case KindStruct:
+		for _, f := range t.Fields {
+			if !edges1(p, r, off+f.Off, f.Type, fn) {
+				return false
+			}
+		}
+	}
+	return true
+}
+
+const heapInfoSize = 512
+
+// Information for heapInfoSize bytes of heap.
+type heapInfo struct {
+	base     core.Address // start of the span containing this heap region
+	size     int64        // size of objects in the span
+	mark     uint64       // 64 mark bits, one for every 8 bytes
+	firstIdx int          // the index of the first object that starts in this region (-1 if none)
+}
+
+// findHeapInfo finds the heapInfo structure for a.
+// Returns nil if a is not a heap address.
+func (p *Process) findHeapInfo(a core.Address) *heapInfo {
+	if a < p.arenaStart || a >= p.arenaUsed {
+		return nil
+	}
+	i := a.Sub(p.arenaStart) / heapInfoSize
+	return &p.heapInfo[i]
+}
diff --git a/gocore/process.go b/gocore/process.go
new file mode 100644
index 0000000..2e061c8
--- /dev/null
+++ b/gocore/process.go
@@ -0,0 +1,546 @@
+// Copyright 2017 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package gocore
+
+import (
+	"debug/dwarf"
+	"fmt"
+	"strings"
+
+	"golang.org/x/debug/core"
+)
+
+// A Process represents the state of a Go process that core dumped.
+type Process struct {
+	proc *core.Process
+
+	arenaStart core.Address
+	arenaUsed  core.Address
+	bitmapEnd  core.Address
+
+	// data structure for fast object finding
+	heapInfo []heapInfo
+
+	// number of live objects
+	nObj int
+
+	goroutines []*Goroutine
+
+	// runtime info
+	rtGlobals   map[string]region
+	rtConstants map[string]int64
+
+	// A module is a loadable unit. Most Go programs have 1, programs
+	// which load plugins will have more.
+	modules []*module
+
+	// address -> function mapping
+	funcTab funcTab
+
+	// map from dwarf type to *Type
+	dwarfMap map[dwarf.Type]*Type
+
+	// map from address of runtime._type to *Type
+	runtimeMap map[core.Address]*Type
+
+	// map from runtime type name to the set of *Type with that name
+	// Used to find candidates to put in the runtimeMap map.
+	runtimeNameMap map[string][]*Type
+
+	// memory usage by category
+	stats *Stats
+
+	buildVersion string
+
+	globals []*Root
+
+	// Types of each object, indexed by object index.
+	// Only initialized if FlagTypes is passed to Core.
+	types []typeInfo
+
+	// Reverse edges.
+	// The reverse edges for object #i are redge[ridx[i]:ridx[i+1]].
+	// A "reverse edge" for object #i is a location in memory where a pointer
+	// to object #i lives.
+	// Only initialized if FlagReverse is passed to Core.
+	redge []core.Address
+	ridx  []int64
+	// Sorted list of all roots.
+	// Only initialized if FlagReverse is passed to Core.
+	rootIdx []*Root
+}
+
+// Process returns the core.Process used to construct this Process.
+func (p *Process) Process() *core.Process {
+	return p.proc
+}
+
+func (p *Process) Goroutines() []*Goroutine {
+	return p.goroutines
+}
+
+// Stats returns a breakdown of the program's memory use by category.
+func (p *Process) Stats() *Stats {
+	return p.stats
+}
+
+// BuildVersion returns the Go version that was used to build the inferior binary.
+func (p *Process) BuildVersion() string {
+	return p.buildVersion
+}
+
+func (p *Process) Globals() []*Root {
+	return p.globals
+}
+
+// FindFunc returns the function which contains the code at address pc, if any.
+func (p *Process) FindFunc(pc core.Address) *Func {
+	return p.funcTab.find(pc)
+}
+
+func (p *Process) findType(name string) *Type {
+	s := p.runtimeNameMap[name]
+	if len(s) == 0 {
+		panic("can't find type " + name)
+	}
+	return s[0]
+}
+
+// A Flags indicates optional analyses for Core to compute.
+type Flags uint8
+
+const (
+	// FlagTypes requests that Core compute type information for all Go objects,
+	// required to use the Type function.
+	// Setting this flag will require more initialization time and use more memory.
+	FlagTypes Flags = 1 << iota
+	// FlagReverse requests that Core compute reverse edge information,
+	// required to use ForEachReversePtr.
+	// Setting this flag will require more initialization time and use more memory.
+	FlagReverse
+)
+
+// Core takes a loaded core file and extracts Go information from it.
+// flags is a bitmask of data that should be extracted from the core.
+func Core(proc *core.Process, flags Flags) (p *Process, err error) {
+	// Make sure we have DWARF info.
+	if _, err := proc.DWARF(); err != nil {
+		return nil, err
+	}
+
+	// Guard against failures of proc.Read* routines.
+	/*
+		defer func() {
+			e := recover()
+			if e == nil {
+				return
+			}
+			p = nil
+			if x, ok := e.(error); ok {
+				err = x
+				return
+			}
+			panic(e) // Not an error, re-panic it.
+		}()
+	*/
+
+	p = &Process{
+		proc:       proc,
+		runtimeMap: map[core.Address]*Type{},
+		dwarfMap:   map[dwarf.Type]*Type{},
+	}
+
+	// Initialize everything that just depends on DWARF.
+	p.readDWARFTypes()
+	p.readRuntimeConstants()
+	p.readGlobals()
+
+	// Find runtime globals we care about. Initialize regions for them.
+	p.rtGlobals = map[string]region{}
+	for _, g := range p.globals {
+		if strings.HasPrefix(g.Name, "runtime.") {
+			p.rtGlobals[g.Name[8:]] = region{p: p, a: g.Addr, typ: g.Type}
+		}
+	}
+
+	// Read all the data that depend on runtime globals.
+	p.buildVersion = p.rtGlobals["buildVersion"].String()
+	p.readModules()
+	p.readSpans()
+	p.readGs()
+	p.readStackVars() // needs to be after readGs.
+	p.markObjects()   // needs to be after readGlobals, readStackVars.
+	if flags&FlagTypes != 0 {
+		p.typeHeap() // needs to be after markObjects.
+	}
+	if flags&FlagReverse != 0 {
+		p.reverseEdges() // needs to be after markObjects.
+	}
+
+	return p, nil
+}
+
+func (p *Process) readSpans() {
+	mheap := p.rtGlobals["mheap_"]
+
+	spanTableStart := mheap.Field("spans").SlicePtr().Address()
+	spanTableEnd := spanTableStart.Add(mheap.Field("spans").SliceCap() * p.proc.PtrSize())
+	arenaStart := core.Address(mheap.Field("arena_start").Uintptr())
+	arenaUsed := core.Address(mheap.Field("arena_used").Uintptr())
+	arenaEnd := core.Address(mheap.Field("arena_end").Uintptr())
+	bitmapEnd := core.Address(mheap.Field("bitmap").Uintptr())
+	bitmapStart := bitmapEnd.Add(-int64(mheap.Field("bitmap_mapped").Uintptr()))
+
+	p.arenaStart = arenaStart
+	p.arenaUsed = arenaUsed
+	p.bitmapEnd = bitmapEnd
+
+	var all int64
+	var text int64
+	var readOnly int64
+	var heap int64
+	var spanTable int64
+	var bitmap int64
+	var data int64
+	var bss int64 // also includes mmap'd regions
+	for _, m := range p.proc.Mappings() {
+		size := m.Size()
+		all += size
+		switch m.Perm() {
+		case core.Read:
+			readOnly += size
+		case core.Read | core.Exec:
+			text += size
+		case core.Read | core.Write:
+			if m.CopyOnWrite() {
+				// Check if m.file == text's file? That could distinguish
+				// data segment from mmapped file.
+				data += size
+				break
+			}
+			attribute := func(x, y core.Address, p *int64) {
+				a := x.Max(m.Min())
+				b := y.Min(m.Max())
+				if a < b {
+					*p += b.Sub(a)
+					size -= b.Sub(a)
+				}
+			}
+			attribute(spanTableStart, spanTableEnd, &spanTable)
+			attribute(arenaStart, arenaEnd, &heap)
+			attribute(bitmapStart, bitmapEnd, &bitmap)
+			// Any other anonymous mapping is bss.
+			// TODO: how to distinguish original bss from anonymous mmap?
+			bss += size
+		default:
+			panic("weird mapping " + m.Perm().String())
+		}
+	}
+	pageSize := p.rtConstants["_PageSize"]
+
+	// Span types
+	spanInUse := uint8(p.rtConstants["_MSpanInUse"])
+	spanManual := uint8(p.rtConstants["_MSpanManual"])
+	spanDead := uint8(p.rtConstants["_MSpanDead"])
+	spanFree := uint8(p.rtConstants["_MSpanFree"])
+
+	// Process spans.
+	if pageSize%heapInfoSize != 0 {
+		panic(fmt.Sprintf("page size not a multiple of %d", heapInfoSize))
+	}
+	p.heapInfo = make([]heapInfo, (p.arenaUsed-p.arenaStart)/heapInfoSize)
+	allspans := mheap.Field("allspans")
+	var allSpanSize int64
+	var freeSpanSize int64
+	var manualSpanSize int64
+	var inUseSpanSize int64
+	var allocSize int64
+	var freeSize int64
+	var spanRoundSize int64
+	var manualAllocSize int64
+	var manualFreeSize int64
+	n := allspans.SliceLen()
+	for i := int64(0); i < n; i++ {
+		s := allspans.SliceIndex(i).Deref()
+		min := core.Address(s.Field("startAddr").Uintptr())
+		elemSize := int64(s.Field("elemsize").Uintptr())
+		nPages := int64(s.Field("npages").Uintptr())
+		spanSize := nPages * pageSize
+		max := min.Add(spanSize)
+		allSpanSize += spanSize
+		switch s.Field("state").Uint8() {
+		case spanInUse:
+			inUseSpanSize += spanSize
+			n := int64(s.Field("nelems").Uintptr())
+			// An object is allocated if it is marked as
+			// allocated or it is below freeindex.
+			x := s.Field("allocBits").Address()
+			alloc := make([]bool, n)
+			for i := int64(0); i < n; i++ {
+				alloc[i] = p.proc.ReadUint8(x.Add(i/8))>>uint(i%8)&1 != 0
+			}
+			k := int64(s.Field("freeindex").Uintptr())
+			for i := int64(0); i < k; i++ {
+				alloc[i] = true
+			}
+			for i := int64(0); i < n; i++ {
+				if alloc[i] {
+					allocSize += elemSize
+				} else {
+					freeSize += elemSize
+				}
+			}
+			spanRoundSize += spanSize - n*elemSize
+			for a := min; a < max; a += heapInfoSize {
+				p.heapInfo[(a.Sub(p.arenaStart))/heapInfoSize] = heapInfo{base: min, size: elemSize, firstIdx: -1}
+			}
+
+			// Process special records.
+			for sp := s.Field("specials"); sp.Address() != 0; sp = sp.Field("next") {
+				sp = sp.Deref() // *special to special
+				if sp.Field("kind").Uint8() != uint8(p.rtConstants["_KindSpecialFinalizer"]) {
+					// All other specials (just profile records) can't point into the heap.
+					continue
+				}
+				obj := min.Add(int64(sp.Field("offset").Uint16()))
+				p.globals = append(p.globals,
+					&Root{
+						Name:  fmt.Sprintf("finalizer for %x", obj),
+						Addr:  sp.a,
+						Type:  p.findType("runtime.specialfinalizer"),
+						Frame: nil,
+					})
+				// TODO: these aren't really "globals", as they
+				// are kept alive by the object they reference being alive.
+				// But we have no way of adding edges from an object to
+				// the corresponding finalizer data, so we punt on that thorny
+				// issue for now.
+			}
+		case spanFree:
+			freeSpanSize += spanSize
+		case spanDead:
+			// These are just deallocated span descriptors. They use no heap.
+		case spanManual:
+			manualSpanSize += spanSize
+			manualAllocSize += spanSize
+			for x := core.Address(s.Field("manualFreeList").Cast("uintptr").Uintptr()); x != 0; x = p.proc.ReadPtr(x) {
+				manualAllocSize -= elemSize
+				manualFreeSize += elemSize
+			}
+		}
+	}
+
+	p.stats = &Stats{"all", all, []*Stats{
+		&Stats{"text", text, nil},
+		&Stats{"readonly", readOnly, nil},
+		&Stats{"data", data, nil},
+		&Stats{"bss", bss, nil},
+		&Stats{"heap", heap, []*Stats{
+			&Stats{"in use spans", inUseSpanSize, []*Stats{
+				&Stats{"alloc", allocSize, nil},
+				&Stats{"free", freeSize, nil},
+				&Stats{"round", spanRoundSize, nil},
+			}},
+			&Stats{"manual spans", manualSpanSize, []*Stats{
+				&Stats{"alloc", manualAllocSize, nil},
+				&Stats{"free", manualFreeSize, nil},
+			}},
+			&Stats{"free spans", freeSpanSize, nil},
+		}},
+		&Stats{"ptr bitmap", bitmap, nil},
+		&Stats{"span table", spanTable, nil},
+	}}
+
+	var check func(*Stats)
+	check = func(s *Stats) {
+		if len(s.Children) == 0 {
+			return
+		}
+		var sum int64
+		for _, c := range s.Children {
+			sum += c.Size
+		}
+		if sum != s.Size {
+			panic(fmt.Sprintf("check failed for %s: %d vs %d", s.Name, s.Size, sum))
+		}
+		for _, c := range s.Children {
+			check(c)
+		}
+	}
+	check(p.stats)
+}
+
+func (p *Process) readGs() {
+	// TODO: figure out how to "flush" running Gs.
+	allgs := p.rtGlobals["allgs"]
+	n := allgs.SliceLen()
+	for i := int64(0); i < n; i++ {
+		r := allgs.SliceIndex(i).Deref()
+		g := p.readG(r)
+		if g == nil {
+			continue
+		}
+		p.goroutines = append(p.goroutines, g)
+	}
+}
+
+func (p *Process) readG(r region) *Goroutine {
+	g := &Goroutine{r: r}
+	stk := r.Field("stack")
+	g.stackSize = int64(stk.Field("hi").Uintptr() - stk.Field("lo").Uintptr())
+
+	var osT *core.Thread // os thread working on behalf of this G (if any).
+	mp := r.Field("m")
+	if mp.Address() != 0 {
+		m := mp.Deref()
+		pid := m.Field("procid").Uint64()
+		// TODO check that m.curg points to g?
+		for _, t := range p.proc.Threads() {
+			if t.Pid() == pid {
+				osT = t
+			}
+		}
+	}
+	status := r.Field("atomicstatus").Uint32()
+	status &^= uint32(p.rtConstants["_Gscan"])
+	var sp, pc core.Address
+	switch status {
+	case uint32(p.rtConstants["_Gidle"]):
+		return g
+	case uint32(p.rtConstants["_Grunnable"]), uint32(p.rtConstants["_Gwaiting"]):
+		sched := r.Field("sched")
+		sp = core.Address(sched.Field("sp").Uintptr())
+		pc = core.Address(sched.Field("pc").Uintptr())
+	case uint32(p.rtConstants["_Grunning"]):
+		sp = osT.SP()
+		pc = osT.PC()
+		// TODO: back up to the calling frame?
+	case uint32(p.rtConstants["_Gsyscall"]):
+		sp = core.Address(r.Field("syscallsp").Uintptr())
+		pc = core.Address(r.Field("syscallpc").Uintptr())
+		// TODO: or should we use the osT registers?
+	case uint32(p.rtConstants["_Gdead"]):
+		return nil
+		// TODO: copystack, others?
+	default:
+		// Unknown state. We can't read the frames, so just bail now.
+		// TODO: make this switch complete and then panic here.
+		// TODO: or just return nil?
+		return g
+	}
+	for {
+		f := p.readFrame(sp, pc)
+		if f.f.name == "runtime.goexit" {
+			break
+		}
+		if len(g.frames) > 0 {
+			g.frames[len(g.frames)-1].parent = f
+		}
+		g.frames = append(g.frames, f)
+
+		if f.f.name == "runtime.sigtrampgo" {
+			// Continue traceback at location where the signal
+			// interrupted normal execution.
+			ctxt := p.proc.ReadPtr(sp.Add(16)) // 3rd arg
+			//ctxt is a *ucontext
+			mctxt := ctxt.Add(5 * 8)
+			// mctxt is a *mcontext
+			sp = p.proc.ReadPtr(mctxt.Add(15 * 8))
+			pc = p.proc.ReadPtr(mctxt.Add(16 * 8))
+			// TODO: totally arch-dependent!
+		} else {
+			sp = f.max
+			pc = core.Address(p.proc.ReadUintptr(sp - 8)) // TODO:amd64 only
+		}
+		if pc == 0 {
+			// TODO: when would this happen?
+			break
+		}
+		if f.f.name == "runtime.systemstack" {
+			// switch over to goroutine stack
+			sched := r.Field("sched")
+			sp = core.Address(sched.Field("sp").Uintptr())
+			pc = core.Address(sched.Field("pc").Uintptr())
+		}
+	}
+	return g
+}
+
+func (p *Process) readFrame(sp, pc core.Address) *Frame {
+	f := p.funcTab.find(pc)
+	if f == nil {
+		panic(fmt.Errorf("  pc not found %x\n", pc))
+	}
+	off := pc.Sub(f.entry)
+	size := f.frameSize.find(off)
+	size += p.proc.PtrSize() // TODO: on amd64, the pushed return address
+
+	frame := &Frame{f: f, pc: pc, min: sp, max: sp.Add(size)}
+
+	// Find live ptrs in locals
+	live := map[core.Address]bool{}
+	if x := int(p.rtConstants["_FUNCDATA_LocalsPointerMaps"]); x < len(f.funcdata) {
+		locals := region{p: p, a: f.funcdata[x], typ: p.findType("runtime.stackmap")}
+		n := locals.Field("n").Int32()       // # of bitmaps
+		nbit := locals.Field("nbit").Int32() // # of bits per bitmap
+		idx := f.stackMap.find(off)
+		if idx < 0 {
+			idx = 0
+		}
+		if idx < int64(n) {
+			bits := locals.Field("bytedata").a.Add(int64(nbit+7) / 8 * idx)
+			base := frame.max.Add(-16).Add(-int64(nbit) * p.proc.PtrSize())
+			// TODO: -16 for amd64. Return address and parent's frame pointer
+			for i := int64(0); i < int64(nbit); i++ {
+				if p.proc.ReadUint8(bits.Add(i/8))>>uint(i&7)&1 != 0 {
+					live[base.Add(i*p.proc.PtrSize())] = true
+				}
+			}
+		}
+	}
+	// Same for args
+	if x := int(p.rtConstants["_FUNCDATA_ArgsPointerMaps"]); x < len(f.funcdata) {
+		args := region{p: p, a: f.funcdata[x], typ: p.findType("runtime.stackmap")}
+		n := args.Field("n").Int32()       // # of bitmaps
+		nbit := args.Field("nbit").Int32() // # of bits per bitmap
+		idx := f.stackMap.find(off)
+		if idx < 0 {
+			idx = 0
+		}
+		if idx < int64(n) {
+			bits := args.Field("bytedata").a.Add(int64(nbit+7) / 8 * idx)
+			base := frame.max
+			// TODO: add to base for LR archs.
+			for i := int64(0); i < int64(nbit); i++ {
+				if p.proc.ReadUint8(bits.Add(i/8))>>uint(i&7)&1 != 0 {
+					live[base.Add(i*p.proc.PtrSize())] = true
+				}
+			}
+		}
+	}
+	frame.Live = live
+
+	return frame
+}
+
+// A Stats struct is the node of a tree representing the entire memory
+// usage of the Go program. Children of a node break its usage down
+// by category.
+// We maintain the invariant that, if there are children,
+// Size == sum(c.Size for c in Children).
+type Stats struct {
+	Name     string
+	Size     int64
+	Children []*Stats
+}
+
+func (s *Stats) Child(name string) *Stats {
+	for _, c := range s.Children {
+		if c.Name == name {
+			return c
+		}
+	}
+	return nil
+}
diff --git a/gocore/region.go b/gocore/region.go
new file mode 100644
index 0000000..b0fdc79
--- /dev/null
+++ b/gocore/region.go
@@ -0,0 +1,159 @@
+// Copyright 2017 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package gocore
+
+import "golang.org/x/debug/core"
+
+// A region is a piece of the virtual address space of the inferior.
+// It has an address and a type.
+// Note that it is the type of the thing in the region,
+// not the type of the reference to the region.
+type region struct {
+	p   *Process
+	a   core.Address
+	typ *Type
+}
+
+// Address returns the address that a region of pointer type points to.
+func (r region) Address() core.Address {
+	if r.typ.Kind != KindPtr {
+		panic("can't ask for the Address of a non-pointer " + r.typ.Name)
+	}
+	return r.p.proc.ReadPtr(r.a)
+}
+
+// Int returns the int value stored in r.
+func (r region) Int() int64 {
+	if r.typ.Kind != KindInt || r.typ.Size != r.p.proc.PtrSize() {
+		panic("not an int: " + r.typ.Name)
+	}
+	return r.p.proc.ReadInt(r.a)
+}
+
+// Uintptr returns the uintptr value stored in r.
+func (r region) Uintptr() uint64 {
+	if r.typ.Kind != KindUint || r.typ.Size != r.p.proc.PtrSize() {
+		panic("not a uintptr: " + r.typ.Name)
+	}
+	return r.p.proc.ReadUintptr(r.a)
+}
+
+// Cast the region to the given type.
+func (r region) Cast(typ string) region {
+	return region{p: r.p, a: r.a, typ: r.p.findType(typ)}
+}
+
+// Deref loads from a pointer. r must contain a pointer.
+func (r region) Deref() region {
+	if r.typ.Kind != KindPtr {
+		panic("can't deref on non-pointer: " + r.typ.Name)
+	}
+	if r.typ.Elem == nil {
+		panic("can't deref unsafe.Pointer")
+	}
+	p := r.p.proc.ReadPtr(r.a)
+	return region{p: r.p, a: p, typ: r.typ.Elem}
+}
+
+// Uint64 returns the uint64 value stored in r.
+// r must have type uint64.
+func (r region) Uint64() uint64 {
+	if r.typ.Kind != KindUint || r.typ.Size != 8 {
+		panic("bad uint64 type " + r.typ.Name)
+	}
+	return r.p.proc.ReadUint64(r.a)
+}
+
+// Uint32 returns the uint32 value stored in r.
+// r must have type uint32.
+func (r region) Uint32() uint32 {
+	if r.typ.Kind != KindUint || r.typ.Size != 4 {
+		panic("bad uint32 type " + r.typ.Name)
+	}
+	return r.p.proc.ReadUint32(r.a)
+}
+
+// Int32 returns the int32 value stored in r.
+// r must have type int32.
+func (r region) Int32() int32 {
+	if r.typ.Kind != KindInt || r.typ.Size != 4 {
+		panic("bad int32 type " + r.typ.Name)
+	}
+	return r.p.proc.ReadInt32(r.a)
+}
+
+// Uint16 returns the uint16 value stored in r.
+// r must have type uint16.
+func (r region) Uint16() uint16 {
+	if r.typ.Kind != KindUint || r.typ.Size != 2 {
+		panic("bad uint16 type " + r.typ.Name)
+	}
+	return r.p.proc.ReadUint16(r.a)
+}
+
+// Uint8 returns the uint8 value stored in r.
+// r must have type uint8.
+func (r region) Uint8() uint8 {
+	if r.typ.Kind != KindUint || r.typ.Size != 1 {
+		panic("bad uint8 type " + r.typ.Name)
+	}
+	return r.p.proc.ReadUint8(r.a)
+}
+
+// String returns the value of the string stored in r.
+func (r region) String() string {
+	if r.typ.Kind != KindString {
+		panic("bad string type " + r.typ.Name)
+	}
+	p := r.p.proc.ReadPtr(r.a)
+	n := r.p.proc.ReadUintptr(r.a.Add(r.p.proc.PtrSize()))
+	b := make([]byte, n)
+	r.p.proc.ReadAt(b, p)
+	return string(b)
+}
+
+// SliceIndex indexes a slice (a[n]). r must contain a slice.
+// n must be in bounds for the slice.
+func (r region) SliceIndex(n int64) region {
+	if r.typ.Kind != KindSlice {
+		panic("can't index a non-slice")
+	}
+	p := r.p.proc.ReadPtr(r.a)
+	return region{p: r.p, a: p.Add(n * r.typ.Elem.Size), typ: r.typ.Elem}
+}
+
+// SlicePtr returns the pointer inside a slice. r must contain a slice.
+func (r region) SlicePtr() region {
+	if r.typ.Kind != KindSlice {
+		panic("can't Ptr a non-slice")
+	}
+	return region{p: r.p, a: r.a, typ: &Type{Name: "*" + r.typ.Name[2:], Size: r.p.proc.PtrSize(), Kind: KindPtr, Elem: r.typ.Elem}}
+}
+
+// SliceLen returns the length of a slice. r must contain a slice.
+func (r region) SliceLen() int64 {
+	if r.typ.Kind != KindSlice {
+		panic("can't len a non-slice")
+	}
+	return r.p.proc.ReadInt(r.a.Add(r.p.proc.PtrSize()))
+}
+
+// SliceCap returns the capacity of a slice. r must contain a slice.
+func (r region) SliceCap() int64 {
+	if r.typ.Kind != KindSlice {
+		panic("can't cap a non-slice")
+	}
+	return r.p.proc.ReadInt(r.a.Add(2 * r.p.proc.PtrSize()))
+}
+
+// Field returns the part of r which contains the field f.
+// r must contain a struct, and f must be one of its fields.
+func (r region) Field(f string) region {
+	finfo := r.typ.field(f)
+	if finfo == nil {
+		panic("can't find field " + r.typ.Name + "." + f)
+	}
+	return region{p: r.p, a: r.a.Add(finfo.Off), typ: finfo.Type}
+}
diff --git a/gocore/reverse.go b/gocore/reverse.go
new file mode 100644
index 0000000..6cda39d
--- /dev/null
+++ b/gocore/reverse.go
@@ -0,0 +1,112 @@
+// Copyright 2017 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package gocore
+
+import (
+	"sort"
+
+	"golang.org/x/debug/core"
+)
+
+func (p *Process) reverseEdges() {
+	// First, count the number of edges into each object.
+	// This allows for efficient packing of the reverse edge storage.
+	cnt := make([]int64, p.nObj+1)
+	p.ForEachObject(func(x Object) bool {
+		p.ForEachPtr(x, func(_ int64, y Object, _ int64) bool {
+			idx, _ := p.findObjectIndex(p.Addr(y))
+			cnt[idx]++
+			return true
+		})
+		return true
+	})
+	p.ForEachRoot(func(r *Root) bool {
+		p.ForEachRootPtr(r, func(_ int64, y Object, _ int64) bool {
+			idx, _ := p.findObjectIndex(p.Addr(y))
+			cnt[idx]++
+			return true
+		})
+		return true
+	})
+
+	// Compute cumulative count of all incoming edges up to and including each object.
+	var n int64
+	for idx, c := range cnt {
+		n += c
+		cnt[idx] = n
+	}
+
+	// Allocate all the storage for the reverse edges.
+	p.redge = make([]core.Address, n)
+
+	// Add edges to the lists.
+	p.ForEachObject(func(x Object) bool {
+		p.ForEachPtr(x, func(i int64, y Object, _ int64) bool {
+			idx, _ := p.findObjectIndex(p.Addr(y))
+			e := cnt[idx]
+			e--
+			cnt[idx] = e
+			p.redge[e] = p.Addr(x).Add(i)
+			return true
+		})
+		return true
+	})
+	p.ForEachRoot(func(r *Root) bool {
+		p.ForEachRootPtr(r, func(i int64, y Object, _ int64) bool {
+			idx, _ := p.findObjectIndex(p.Addr(y))
+			e := cnt[idx]
+			e--
+			cnt[idx] = e
+			p.redge[e] = r.Addr.Add(i)
+			return true
+		})
+		return true
+	})
+	// At this point, cnt contains the cumulative count of all edges up to
+	// but *not* including each object.
+	p.ridx = cnt
+
+	// Make root index.
+	p.ForEachRoot(func(r *Root) bool {
+		p.rootIdx = append(p.rootIdx, r)
+		return true
+	})
+	sort.Slice(p.rootIdx, func(i, j int) bool { return p.rootIdx[i].Addr < p.rootIdx[j].Addr })
+}
+
+// ForEachReversePtr calls fn for all pointers it finds pointing to y.
+// It calls fn with:
+//   the object or root which points to y (exactly one will be non-nil)
+//   the offset i in that object or root where the pointer appears.
+//   the offset j in y where the pointer points.
+// If fn returns false, ForEachReversePtr returns immediately.
+// FlagReverse must have been passed to Core when p was constructed.
+func (p *Process) ForEachReversePtr(y Object, fn func(x Object, r *Root, i, j int64) bool) {
+	idx, _ := p.findObjectIndex(p.Addr(y))
+	for _, a := range p.redge[p.ridx[idx]:p.ridx[idx+1]] {
+		// Read pointer, compute offset in y.
+		ptr := p.proc.ReadPtr(a)
+		j := ptr.Sub(p.Addr(y))
+
+		// Find source of pointer.
+		x, i := p.FindObject(a)
+		if x != 0 {
+			// Source is an object.
+			if !fn(x, nil, i, j) {
+				return
+			}
+			continue
+		}
+		// Source is a root.
+		k := sort.Search(len(p.rootIdx), func(k int) bool {
+			r := p.rootIdx[k]
+			return a < r.Addr.Add(r.Type.Size)
+		})
+		r := p.rootIdx[k]
+		if !fn(0, r, a.Sub(r.Addr), j) {
+			return
+		}
+	}
+}
diff --git a/gocore/root.go b/gocore/root.go
new file mode 100644
index 0000000..89a1ce8
--- /dev/null
+++ b/gocore/root.go
@@ -0,0 +1,22 @@
+// Copyright 2017 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package gocore
+
+import (
+	"golang.org/x/debug/core"
+)
+
+// A Root is an area of memory that might have pointers into the Go heap.
+type Root struct {
+	Name string
+	Addr core.Address
+	Type *Type // always non-nil
+	// Frame, if non-nil, points to the frame in which this root lives.
+	// Roots with non-nil Frame fields refer to local variables on a stack.
+	// A stack root might be a large type, with some of its fields live and
+	// others dead. Consult Frame.Live to find out which pointers in a stack
+	// root are live.
+	Frame *Frame
+}
diff --git a/gocore/testdata/README b/gocore/testdata/README
new file mode 100644
index 0000000..11d9761
--- /dev/null
+++ b/gocore/testdata/README
@@ -0,0 +1,14 @@
+This directory contains a simple core file for use in testing.
+
+It was generated by running the following program with go1.9.0.
+
+package main
+
+func main() {
+	_ = *(*int)(nil)
+}
+
+The core file includes the executable by reference using an absolute
+path.  The executable was at /tmp/test, so that path is reproduced
+here so the core dump reader can find the executable using this
+testdata directory as the base directory.
diff --git a/gocore/testdata/core b/gocore/testdata/core
new file mode 100644
index 0000000..55318de
--- /dev/null
+++ b/gocore/testdata/core
Binary files differ
diff --git a/gocore/testdata/tmp/test b/gocore/testdata/tmp/test
new file mode 100755
index 0000000..f3353b2
--- /dev/null
+++ b/gocore/testdata/tmp/test
Binary files differ
diff --git a/gocore/type.go b/gocore/type.go
new file mode 100644
index 0000000..17c9c57
--- /dev/null
+++ b/gocore/type.go
@@ -0,0 +1,609 @@
+// Copyright 2017 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package gocore
+
+import (
+	"fmt"
+	"strings"
+
+	"golang.org/x/debug/core"
+)
+
+// A Type is the representation of the type of a Go object.
+// Types are not necessarily canonical.
+// Names are opaque; do not depend on the format of the returned name.
+type Type struct {
+	Name string
+	Size int64
+	Kind Kind
+
+	// Fields only valid for a subset of kinds.
+	Count  int64   // for kind == KindArray
+	Elem   *Type   // for kind == Kind{Ptr,Array,Slice,String}. nil for unsafe.Pointer. Always uint8 for KindString.
+	Fields []Field // for kind == KindStruct
+}
+
+type Kind uint8
+
+const (
+	KindNone Kind = iota
+	KindBool
+	KindInt
+	KindUint
+	KindFloat
+	KindComplex
+	KindArray
+	KindPtr // includes chan, map, unsafe.Pointer
+	KindIface
+	KindEface
+	KindSlice
+	KindString
+	KindStruct
+	KindFunc
+)
+
+func (k Kind) String() string {
+	return [...]string{
+		"KindNone",
+		"KindBool",
+		"KindInt",
+		"KindUint",
+		"KindFloat",
+		"KindComplex",
+		"KindArray",
+		"KindPtr",
+		"KindIface",
+		"KindEface",
+		"KindSlice",
+		"KindString",
+		"KindStruct",
+		"KindFunc",
+	}[k]
+}
+
+// A Field represents a single field of a struct type.
+type Field struct {
+	Name string
+	Off  int64
+	Type *Type
+}
+
+func (t *Type) String() string {
+	return t.Name
+}
+
+func (t *Type) field(name string) *Field {
+	if t.Kind != KindStruct {
+		panic("asking for field of non-struct")
+	}
+	for i := range t.Fields {
+		f := &t.Fields[i]
+		if f.Name == name {
+			return f
+		}
+	}
+	return nil
+}
+
+// Convert the address of a runtime._type to a *Type.
+// Guaranteed to return a non-nil *Type.
+func (p *Process) runtimeType2Type(a core.Address) *Type {
+	if t := p.runtimeMap[a]; t != nil {
+		return t
+	}
+
+	// Read runtime._type.size
+	r := region{p: p, a: a, typ: p.findType("runtime._type")}
+	size := int64(r.Field("size").Uintptr())
+
+	// Find module this type is in.
+	var m *module
+	for _, x := range p.modules {
+		if x.types <= a && a < x.etypes {
+			m = x
+			break
+		}
+	}
+
+	// Read information out of the runtime._type.
+	var name string
+	if m != nil {
+		x := m.types.Add(int64(r.Field("str").Int32()))
+		n := uint16(p.proc.ReadUint8(x.Add(1)))<<8 + uint16(p.proc.ReadUint8(x.Add(2)))
+		b := make([]byte, n)
+		p.proc.ReadAt(b, x.Add(3))
+		name = string(b)
+		if r.Field("tflag").Uint8()&uint8(p.rtConstants["tflagExtraStar"]) != 0 {
+			name = name[1:]
+		}
+	} else {
+		// A reflect-generated type.
+		// TODO: The actual name is in the runtime.reflectOffs map.
+		// Too hard to look things up in maps here, just allocate a placeholder for now.
+		name = fmt.Sprintf("reflect.generated%x", a)
+	}
+
+	// Read ptr/nonptr bits
+	ptrSize := p.proc.PtrSize()
+	nptrs := int64(r.Field("ptrdata").Uintptr()) / ptrSize
+	var ptrs []int64
+	if r.Field("kind").Uint8()&uint8(p.rtConstants["kindGCProg"]) == 0 {
+		gcdata := r.Field("gcdata").Address()
+		for i := int64(0); i < nptrs; i++ {
+			if p.proc.ReadUint8(gcdata.Add(i/8))>>uint(i%8)&1 != 0 {
+				ptrs = append(ptrs, i*ptrSize)
+			}
+		}
+	} else {
+		// TODO: run GC program to get ptr indexes
+	}
+
+	// Find a Type that matches this type.
+	// (The matched type will be one constructed from DWARF info.)
+	// It must match name, size, and pointer bits.
+	var candidates []*Type
+	for _, t := range p.runtimeNameMap[name] {
+		if size == t.Size && equal(ptrs, t.ptrs()) {
+			candidates = append(candidates, t)
+		}
+	}
+	var t *Type
+	if len(candidates) > 0 {
+		// If a runtime type matches more than one DWARF type,
+		// pick one arbitrarily.
+		// This looks mostly harmless. DWARF has some redundant entries.
+		// For example, [32]uint8 appears twice.
+		// TODO: investigate the reason for this duplication.
+		t = candidates[0]
+	} else {
+		// There's no corresponding DWARF type.  Make our own.
+		t = &Type{Name: name, Size: size, Kind: KindStruct}
+		n := t.Size / ptrSize
+
+		// Types to use for ptr/nonptr fields of runtime types which
+		// have no corresponding DWARF type.
+		ptr := p.findType("unsafe.Pointer")
+		nonptr := p.findType("uintptr")
+		if ptr == nil || nonptr == nil {
+			panic("ptr / nonptr standins missing")
+		}
+
+		for i := int64(0); i < n; i++ {
+			typ := nonptr
+			if len(ptrs) > 0 && ptrs[0] == i*ptrSize {
+				typ = ptr
+				ptrs = ptrs[1:]
+			}
+			t.Fields = append(t.Fields, Field{
+				Name: fmt.Sprintf("f%d", i),
+				Off:  i * ptrSize,
+				Type: typ,
+			})
+
+		}
+		if t.Size%ptrSize != 0 {
+			// TODO: tail of <ptrSize data.
+		}
+	}
+	// Memoize.
+	p.runtimeMap[a] = t
+
+	return t
+}
+
+// ptrs returns a sorted list of pointer offsets in t.
+func (t *Type) ptrs() []int64 {
+	return t.ptrs1(nil, 0)
+}
+func (t *Type) ptrs1(s []int64, off int64) []int64 {
+	switch t.Kind {
+	case KindPtr, KindFunc, KindSlice, KindString:
+		s = append(s, off)
+	case KindIface, KindEface:
+		s = append(s, off, off+t.Size/2)
+	case KindArray:
+		if t.Count > 10000 {
+			// Be careful about really large types like [1e9]*byte.
+			// To process such a type we'd make a huge ptrs list.
+			// The ptrs list here is only used for matching
+			// a runtime type with a dwarf type, and for making
+			// fields for types with no dwarf type.
+			// Both uses can fail with no terrible repercussions.
+			// We still will scan the whole object during markObjects, for example.
+			// TODO: make this more robust somehow.
+			break
+		}
+		for i := int64(0); i < t.Count; i++ {
+			s = t.Elem.ptrs1(s, off)
+			off += t.Elem.Size
+		}
+	case KindStruct:
+		for _, f := range t.Fields {
+			s = f.Type.ptrs1(s, off+f.Off)
+		}
+	default:
+		// no pointers
+	}
+	return s
+}
+
+func equal(a, b []int64) bool {
+	if len(a) != len(b) {
+		return false
+	}
+	for i, x := range a {
+		if x != b[i] {
+			return false
+		}
+	}
+	return true
+}
+
+// A typeInfo contains information about the type of an object.
+// A slice of these hold the results of typing the heap.
+type typeInfo struct {
+	// This object has an effective type of [r]t.
+	// Parts of the object beyond the first r*t.Size bytes have unknown type.
+	// If t == nil, the type is unknown. (TODO: provide access to ptr/nonptr bits in this case.)
+	t *Type
+	r int64
+}
+
+// A typeChunk records type information for a portion of an object.
+// Similar to a typeInfo, but it has an offset so it can be used for interior typings.
+type typeChunk struct {
+	off int64
+	t   *Type
+	r   int64
+}
+
+func (c typeChunk) min() int64 {
+	return c.off
+}
+func (c typeChunk) max() int64 {
+	return c.off + c.r*c.t.Size
+}
+func (c typeChunk) size() int64 {
+	return c.r * c.t.Size
+}
+func (c typeChunk) matchingAlignment(d typeChunk) bool {
+	if c.t != d.t {
+		panic("can't check alignment of differently typed chunks")
+	}
+	return (c.off-d.off)%c.t.Size == 0
+}
+
+func (c typeChunk) merge(d typeChunk) typeChunk {
+	t := c.t
+	if t != d.t {
+		panic("can't merge chunks with different types")
+	}
+	size := t.Size
+	if (c.off-d.off)%size != 0 {
+		panic("can't merge poorly aligned chunks")
+	}
+	min := c.min()
+	max := c.max()
+	if max < d.min() || min > d.max() {
+		panic("can't merge chunks which don't overlap or abut")
+	}
+	if x := d.min(); x < min {
+		min = x
+	}
+	if x := d.max(); x > max {
+		max = x
+	}
+	return typeChunk{off: min, t: t, r: (max - min) / size}
+}
+func (c typeChunk) String() string {
+	return fmt.Sprintf("%x[%d]%s", c.off, c.r, c.t)
+}
+
+// typeHeap tries to label all the heap objects with types.
+func (p *Process) typeHeap() {
+	// Type info for the start of each object. a.k.a. "0 offset" typings.
+	p.types = make([]typeInfo, p.nObj)
+
+	// Type info for the interior of objects, a.k.a. ">0 offset" typings.
+	// Type information is arranged in chunks. Chunks are stored in an
+	// arbitrary order, and are guaranteed to not overlap. If types are
+	// equal, chunks are also guaranteed not to abut.
+	// Interior typings are kept separate because they hopefully are rare.
+	// TODO: They aren't really that rare. On some large heaps I tried
+	// ~50% of objects have an interior pointer into them.
+	// Keyed by object index.
+	interior := map[int][]typeChunk{}
+
+	// Typings we know about but haven't scanned yet.
+	type workRecord struct {
+		a core.Address
+		t *Type
+		r int64
+	}
+	var work []workRecord
+
+	// add records the fact that we know the object at address a has
+	// r copies of type t.
+	add := func(a core.Address, t *Type, r int64) {
+		if a == 0 { // nil pointer
+			return
+		}
+		i, off := p.findObjectIndex(a)
+		if i < 0 { // pointer doesn't point to an object in the Go heap
+			return
+		}
+		if off == 0 {
+			// We have a 0-offset typing. Replace existing 0-offset typing
+			// if the new one is larger.
+			ot := p.types[i].t
+			or := p.types[i].r
+			if ot == nil || r*t.Size > or*ot.Size {
+				if t == ot {
+					// Scan just the new section.
+					work = append(work, workRecord{
+						a: a.Add(or * ot.Size),
+						t: t,
+						r: r - or,
+					})
+				} else {
+					// Rescan the whole typing using the updated type.
+					work = append(work, workRecord{
+						a: a,
+						t: t,
+						r: r,
+					})
+				}
+				p.types[i].t = t
+				p.types[i].r = r
+			}
+			return
+		}
+
+		// Add an interior typing to object #i.
+		c := typeChunk{off: off, t: t, r: r}
+
+		// Merge the given typing into the chunks we already know.
+		// TODO: this could be O(n) per insert if there are lots of internal pointers.
+		chunks := interior[i]
+		newchunks := chunks[:0]
+		addWork := true
+		for _, d := range chunks {
+			if c.max() <= d.min() || c.min() >= d.max() {
+				// c does not overlap with d.
+				if c.t == d.t && (c.max() == d.min() || c.min() == d.max()) {
+					// c and d abut and share the same base type. Merge them.
+					c = c.merge(d)
+					continue
+				}
+				// Keep existing chunk d.
+				// Overwrites chunks slice, but we're only merging chunks so it
+				// can't overwrite to-be-processed elements.
+				newchunks = append(newchunks, d)
+				continue
+			}
+			// There is some overlap. There are a few possibilities:
+			// 1) One is completely contained in the other.
+			// 2) Both are slices of a larger underlying array.
+			// 3) Some unsafe trickery has happened. Non-containing overlap
+			//    can only happen in safe Go via case 2.
+			if c.min() >= d.min() && c.max() <= d.max() {
+				// 1a: c is contained within the existing chunk d.
+				// Note that there can be a type mismatch between c and d,
+				// but we don't care. We use the larger chunk regardless.
+				c = d
+				addWork = false // We've already scanned all of c.
+				continue
+			}
+			if d.min() >= c.min() && d.max() <= c.max() {
+				// 1b: existing chunk d is completely covered by c.
+				continue
+			}
+			if c.t == d.t && c.matchingAlignment(d) {
+				// Union two regions of the same base type. Case 2 above.
+				c = c.merge(d)
+				continue
+			}
+			if c.size() < d.size() {
+				// Keep the larger of the two chunks.
+				c = d
+				addWork = false
+			}
+		}
+		// Add new chunk to list of chunks for object.
+		newchunks = append(newchunks, c)
+		interior[i] = newchunks
+		// Also arrange to scan the new chunk. Note that if we merged
+		// with an existing chunk (or chunks), those will get rescanned.
+		// Duplicate work, but that's ok. TODO: but could be expensive.
+		if addWork {
+			work = append(work, workRecord{
+				a: a.Add(c.off - off),
+				t: c.t,
+				r: c.r,
+			})
+		}
+	}
+
+	// Get typings starting at roots.
+	fr := &frameReader{p: p}
+	p.ForEachRoot(func(r *Root) bool {
+		if r.Frame != nil {
+			fr.live = r.Frame.Live
+			p.typeObject(r.Addr, r.Type, fr, add)
+		} else {
+			p.typeObject(r.Addr, r.Type, p.proc, add)
+		}
+		return true
+	})
+
+	// Propagate typings through the heap.
+	for len(work) > 0 {
+		c := work[len(work)-1]
+		work = work[:len(work)-1]
+		for i := int64(0); i < c.r; i++ {
+			p.typeObject(c.a.Add(i*c.t.Size), c.t, p.proc, add)
+		}
+	}
+
+	// Merge any interior typings with the 0-offset typing.
+	for i, chunks := range interior {
+		t := p.types[i].t
+		r := p.types[i].r
+		if t == nil {
+			continue // We have no type info at offset 0.
+		}
+		for _, c := range chunks {
+			if c.max() <= r*t.Size {
+				// c is completely contained in the 0-offset typing. Ignore it.
+				continue
+			}
+			if c.min() <= r*t.Size {
+				// Typings overlap or abut. Extend if we can.
+				if c.t == t && c.min()%t.Size == 0 {
+					r = c.max() / t.Size
+					p.types[i].r = r
+				}
+				continue
+			}
+			// Note: at this point we throw away any interior typings that weren't
+			// merged with the 0-offset typing.  TODO: make more use of this info.
+		}
+	}
+}
+
+type reader interface {
+	ReadPtr(core.Address) core.Address
+	ReadInt(core.Address) int64
+}
+
+// A frameReader reads data out of a stack frame.
+// Any pointer slots marked as dead will read as nil instead of their real value.
+type frameReader struct {
+	p    *Process
+	live map[core.Address]bool
+}
+
+func (fr *frameReader) ReadPtr(a core.Address) core.Address {
+	if !fr.live[a] {
+		return 0
+	}
+	return fr.p.proc.ReadPtr(a)
+}
+func (fr *frameReader) ReadInt(a core.Address) int64 {
+	return fr.p.proc.ReadInt(a)
+}
+
+// typeObject takes an address and a type for the data at that address.
+// For each pointer it finds in the memory at that address, it calls add with the pointer
+// and the type + repeat count of the thing that it points to.
+func (p *Process) typeObject(a core.Address, t *Type, r reader, add func(core.Address, *Type, int64)) {
+	ptrSize := p.proc.PtrSize()
+
+	switch t.Kind {
+	case KindBool, KindInt, KindUint, KindFloat, KindComplex:
+		// Nothing to do
+	case KindEface, KindIface:
+		// interface. Use the type word to determine the type
+		// of the pointed-to object.
+		typ := r.ReadPtr(a)
+		if typ == 0 { // nil interface
+			return
+		}
+		ptr := r.ReadPtr(a.Add(ptrSize))
+		if t.Kind == KindIface {
+			typ = p.proc.ReadPtr(typ.Add(p.findType("runtime.itab").field("_type").Off))
+		}
+		// TODO: for KindEface, type the typ pointer. It might point to the heap
+		// if the type was allocated with reflect.
+		dt := p.runtimeType2Type(typ)
+		typr := region{p: p, a: typ, typ: p.findType("runtime._type")}
+		if typr.Field("kind").Uint8()&uint8(p.rtConstants["kindDirectIface"]) != 0 {
+			// Find the base type of the pointer held in the interface.
+		findptr:
+			if dt.Kind == KindArray {
+				dt = dt.Elem
+				goto findptr
+			}
+			if dt.Kind == KindStruct {
+				for _, f := range dt.Fields {
+					if f.Type.Size != 0 {
+						dt = f.Type
+						goto findptr
+					}
+				}
+			}
+			if dt.Kind != KindPtr {
+				panic(fmt.Sprintf("direct type isn't a pointer %s", dt.Kind))
+			}
+			dt = dt.Elem
+		}
+		add(ptr, dt, 1)
+	case KindString:
+		ptr := r.ReadPtr(a)
+		len := r.ReadInt(a.Add(ptrSize))
+		add(ptr, t.Elem, len)
+	case KindSlice:
+		ptr := r.ReadPtr(a)
+		cap := r.ReadInt(a.Add(2 * ptrSize))
+		add(ptr, t.Elem, cap)
+	case KindPtr:
+		if t.Elem != nil { // unsafe.Pointer has a nil Elem field.
+			add(r.ReadPtr(a), t.Elem, 1)
+		}
+	case KindFunc:
+		// The referent is a closure. We don't know much about the
+		// type of the referent. Its first entry is a code pointer.
+		// The runtime._type we want exists in the binary (for all
+		// heap-allocated closures, anyway) but it would be hard to find
+		// just given the pc.
+		closure := r.ReadPtr(a)
+		if closure == 0 {
+			break
+		}
+		pc := p.proc.ReadPtr(closure)
+		f := p.funcTab.find(pc)
+		if f == nil {
+			panic(fmt.Sprintf("can't find func for closure pc %x", pc))
+		}
+		ft := f.closure
+		if ft == nil {
+			ft = &Type{Name: "closure for " + f.name, Size: ptrSize, Kind: KindPtr}
+			// For now, treat a closure like an unsafe.Pointer.
+			// TODO: better value for size?
+			f.closure = ft
+		}
+		p.typeObject(closure, ft, r, add)
+	case KindArray:
+		n := t.Elem.Size
+		for i := int64(0); i < t.Count; i++ {
+			p.typeObject(a.Add(i*n), t.Elem, r, add)
+		}
+	case KindStruct:
+		if strings.HasPrefix(t.Name, "hash<") {
+			// Special case - maps have a pointer to the first bucket
+			// but it really types all the buckets (like a slice would).
+			var bPtr core.Address
+			var bTyp *Type
+			var n int64
+			for _, f := range t.Fields {
+				if f.Name == "buckets" {
+					bPtr = p.proc.ReadPtr(a.Add(f.Off))
+					bTyp = f.Type.Elem
+				}
+				if f.Name == "B" {
+					n = int64(1) << p.proc.ReadUint8(a.Add(f.Off))
+				}
+			}
+			add(bPtr, bTyp, n)
+			// TODO: also oldbuckets
+		}
+		// TODO: also special case for channels?
+		for _, f := range t.Fields {
+			p.typeObject(a.Add(f.Off), f.Type, r, add)
+		}
+	default:
+		panic(fmt.Sprintf("unknown type kind %s\n", t.Kind))
+	}
+}
