all: delete obsolete/unsupported packages

Per discussion in proposal #25503, delete a number of packages which
were at best unmaintained and at worst completely broken. We don't think
anyone is using these.

IF THIS CHANGE BREAKS YOU:
Please file a bug on the main Go issue tracker and we'll try to work
something out. Go 1.11 will definitely cause problems for any users of
these packages without some work.

Change-Id: I19365e87d84c9a295bf6cf705a001992839a7dc7
Reviewed-on: https://go-review.googlesource.com/121017
Run-TryBot: Heschi Kreinick <heschi@google.com>
Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
diff --git a/arch/arch.go b/arch/arch.go
deleted file mode 100644
index acd2ee9..0000000
--- a/arch/arch.go
+++ /dev/null
@@ -1,176 +0,0 @@
-// Copyright 2014 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 arch contains architecture-specific definitions.
-package arch // import "golang.org/x/debug/arch"
-
-import (
-	"encoding/binary"
-	"math"
-)
-
-const MaxBreakpointSize = 4 // TODO
-
-// Architecture defines the architecture-specific details for a given machine.
-type Architecture struct {
-	// BreakpointSize is the size of a breakpoint instruction, in bytes.
-	BreakpointSize int
-	// IntSize is the size of the int type, in bytes.
-	IntSize int
-	// PointerSize is the size of a pointer, in bytes.
-	PointerSize int
-	// ByteOrder is the byte order for ints and pointers.
-	ByteOrder binary.ByteOrder
-	// FloatByteOrder is the byte order for floats.
-	FloatByteOrder  binary.ByteOrder
-	BreakpointInstr [MaxBreakpointSize]byte
-}
-
-func (a *Architecture) Int(buf []byte) int64 {
-	return int64(a.Uint(buf))
-}
-
-func (a *Architecture) Uint(buf []byte) uint64 {
-	if len(buf) != a.IntSize {
-		panic("bad IntSize")
-	}
-	switch a.IntSize {
-	case 4:
-		return uint64(a.ByteOrder.Uint32(buf[:4]))
-	case 8:
-		return a.ByteOrder.Uint64(buf[:8])
-	}
-	panic("no IntSize")
-}
-
-func (a *Architecture) Int16(buf []byte) int16 {
-	return int16(a.Uint16(buf))
-}
-
-func (a *Architecture) Int32(buf []byte) int32 {
-	return int32(a.Uint32(buf))
-}
-
-func (a *Architecture) Int64(buf []byte) int64 {
-	return int64(a.Uint64(buf))
-}
-
-func (a *Architecture) Uint16(buf []byte) uint16 {
-	return a.ByteOrder.Uint16(buf)
-}
-
-func (a *Architecture) Uint32(buf []byte) uint32 {
-	return a.ByteOrder.Uint32(buf)
-}
-
-func (a *Architecture) Uint64(buf []byte) uint64 {
-	return a.ByteOrder.Uint64(buf)
-}
-
-func (a *Architecture) IntN(buf []byte) int64 {
-	if len(buf) == 0 {
-		return 0
-	}
-	x := int64(0)
-	if a.ByteOrder == binary.LittleEndian {
-		i := len(buf) - 1
-		x = int64(int8(buf[i])) // sign-extended
-		for i--; i >= 0; i-- {
-			x <<= 8
-			x |= int64(buf[i]) // not sign-extended
-		}
-	} else {
-		x = int64(int8(buf[0])) // sign-extended
-		for i := 1; i < len(buf); i++ {
-			x <<= 8
-			x |= int64(buf[i]) // not sign-extended
-		}
-	}
-	return x
-}
-
-func (a *Architecture) UintN(buf []byte) uint64 {
-	u := uint64(0)
-	if a.ByteOrder == binary.LittleEndian {
-		shift := uint(0)
-		for _, c := range buf {
-			u |= uint64(c) << shift
-			shift += 8
-		}
-	} else {
-		for _, c := range buf {
-			u <<= 8
-			u |= uint64(c)
-		}
-	}
-	return u
-}
-
-func (a *Architecture) Uintptr(buf []byte) uint64 {
-	if len(buf) != a.PointerSize {
-		panic("bad PointerSize")
-	}
-	switch a.PointerSize {
-	case 4:
-		return uint64(a.ByteOrder.Uint32(buf[:4]))
-	case 8:
-		return a.ByteOrder.Uint64(buf[:8])
-	}
-	panic("no PointerSize")
-}
-
-func (a *Architecture) Float32(buf []byte) float32 {
-	if len(buf) != 4 {
-		panic("bad float32 size")
-	}
-	return math.Float32frombits(a.FloatByteOrder.Uint32(buf))
-}
-
-func (a *Architecture) Float64(buf []byte) float64 {
-	if len(buf) != 8 {
-		panic("bad float64 size")
-	}
-	return math.Float64frombits(a.FloatByteOrder.Uint64(buf))
-}
-
-func (a *Architecture) Complex64(buf []byte) complex64 {
-	if len(buf) != 8 {
-		panic("bad complex64 size")
-	}
-	return complex(a.Float32(buf[0:4]), a.Float32(buf[4:8]))
-}
-
-func (a *Architecture) Complex128(buf []byte) complex128 {
-	if len(buf) != 16 {
-		panic("bad complex128 size")
-	}
-	return complex(a.Float64(buf[0:8]), a.Float64(buf[8:16]))
-}
-
-var AMD64 = Architecture{
-	BreakpointSize:  1,
-	IntSize:         8,
-	PointerSize:     8,
-	ByteOrder:       binary.LittleEndian,
-	FloatByteOrder:  binary.LittleEndian,
-	BreakpointInstr: [MaxBreakpointSize]byte{0xCC}, // INT 3
-}
-
-var X86 = Architecture{
-	BreakpointSize:  1,
-	IntSize:         4,
-	PointerSize:     4,
-	ByteOrder:       binary.LittleEndian,
-	FloatByteOrder:  binary.LittleEndian,
-	BreakpointInstr: [MaxBreakpointSize]byte{0xCC}, // INT 3
-}
-
-var ARM = Architecture{
-	BreakpointSize:  4, // TODO
-	IntSize:         4,
-	PointerSize:     4,
-	ByteOrder:       binary.LittleEndian,
-	FloatByteOrder:  binary.LittleEndian,                             // TODO
-	BreakpointInstr: [MaxBreakpointSize]byte{0x00, 0x00, 0x00, 0x00}, // TODO
-}
diff --git a/cmd/debugproxy/main.go b/cmd/debugproxy/main.go
deleted file mode 100644
index 942790b..0000000
--- a/cmd/debugproxy/main.go
+++ /dev/null
@@ -1,72 +0,0 @@
-// Copyright 2014 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.
-
-// debugproxy connects to the target binary, and serves an RPC interface using
-// the types in server/protocol to access and control it.
-package main
-
-import (
-	"flag"
-	"fmt"
-	"log"
-	"net/rpc"
-	"os"
-
-	"golang.org/x/debug/server"
-)
-
-var (
-	textFlag = flag.String("text", "", "file name of binary being debugged")
-)
-
-func main() {
-	log.SetFlags(0)
-	log.SetPrefix("debugproxy: ")
-	flag.Parse()
-	if *textFlag == "" {
-		flag.Usage()
-		os.Exit(2)
-	}
-	s, err := server.New(*textFlag)
-	if err != nil {
-		fmt.Printf("server.New: %v\n", err)
-		os.Exit(2)
-	}
-	err = rpc.Register(s)
-	if err != nil {
-		fmt.Printf("rpc.Register: %v\n", err)
-		os.Exit(2)
-	}
-	fmt.Println("OK")
-	log.Print("starting server")
-	rpc.ServeConn(&rwc{
-		os.Stdin,
-		os.Stdout,
-	})
-	log.Print("server finished")
-}
-
-// rwc creates a single io.ReadWriteCloser from a read side and a write side.
-// It allows us to do RPC using standard in and standard out.
-type rwc struct {
-	r *os.File
-	w *os.File
-}
-
-func (rwc *rwc) Read(p []byte) (int, error) {
-	return rwc.r.Read(p)
-}
-
-func (rwc *rwc) Write(p []byte) (int, error) {
-	return rwc.w.Write(p)
-}
-
-func (rwc *rwc) Close() error {
-	rerr := rwc.r.Close()
-	werr := rwc.w.Close()
-	if rerr != nil {
-		return rerr
-	}
-	return werr
-}
diff --git a/doc/ptrace-nptl.txt b/doc/ptrace-nptl.txt
deleted file mode 100644
index 81f6a10..0000000
--- a/doc/ptrace-nptl.txt
+++ /dev/null
@@ -1,128 +0,0 @@
-ptrace and NTPL, the missing manpage
-
-== Signals ==
-
-A signal sent to a ptrace'd process or thread causes only the thread
-that receives it to stop and report to the attached process.
-
-Use tgkill to target a signal (for example, SIGSTOP) at a particular
-thread.  If you use kill, the signal could be delivered to another
-thread in the same process.
-
-Note that SIGSTOP differs from its usual behavior when a process is
-being traced.  Usually, a SIGSTOP sent to any thread in a thread group
-will stop all threads in the thread group.  When a thread is traced,
-however, a SIGSTOP affects only the receiving thread (and any other
-threads in the thread group that are not traced).
-
-SIGKILL behaves like it does for non-traced processes.  It affects all
-threads in the process and terminates them without the WSTOPSIG event
-generated by other signals.  However, if PTRACE_O_TRACEEXIT is set,
-the attached process will still receive PTRACE_EVENT_EXIT events
-before receiving WIFSIGNALED events.
-
-See "Following thread death" for a caveat regarding signal delivery to
-zombie threads.
-
-== Waiting on threads ==
-
-Cloned threads in ptrace'd processes are treated similarly to cloned
-threads in your own process.  Thus, you must use the __WALL option in
-order to receive notifications from threads created by the child
-process.  Similarly, the __WCLONE option will wait only on
-notifications from threads created by the child process and *not* on
-notifications from the initial child thread.
-
-Even when waiting on a specific thread's PID using waitpid or similar,
-__WALL or __WCLONE is necessary or waitpid will return ECHILD.
-
-== Attaching to existing threads ==
-
-libthread_db (which gdb uses), attaches to existing threads by pulling
-the pthread data structures out of the traced process.  The much
-easier way is to traverse the /proc/PID/task directory, though it's
-unclear how the semantics of these two approaches differ.
-
-Unfortunately, if the main thread has exited (but the overall process
-has not), it sticks around as a zombie process.  This zombie will
-appear in the /proc/PID/task directory, but trying to attach to it
-will yield EPERM.  In this case, the third field of the
-/proc/PID/task/PID/stat file will be "Z".  Attempting to open the stat
-file is also a convenient way to detect races between listing the task
-directory and the thread exiting.  Coincidentally, gdb will simply
-fail to attach to a process whose main thread is a zombie.
-
-Because new threads may be created while the debugger is in the
-process of attaching to existing threads, the debugger must repeatedly
-re-list the task directory until it has attached to (and thus stopped)
-every thread listed.
-
-In order to follow new threads created by existing threads,
-PTRACE_O_TRACECLONE must be set on each thread attached to.
-
-== Following new threads ==
-
-With the child process stopped, use PTRACE_SETOPTIONS to set the
-PTRACE_O_TRACECLONE option.  This option is per-thread, and thus must
-be set on each existing thread individually.  When an existing thread
-with PTRACE_O_TRACECLONE set spawns a new thread, the existing thread
-will stop with (SIGTRAP | PTRACE_EVENT_CLONE << 8) and the PID of the
-new thread can be retrieved with PTRACE_GETEVENTMSG on the creating
-thread.  At this time, the new thread will exist, but will initially
-be stopped with a SIGSTOP.  The new thread will automatically be
-traced and will inherit the PTRACE_O_TRACECLONE option from its
-parent.  The attached process should wait on the new thread to receive
-the SIGSTOP notification.
-
-When using waitpid(-1, ...), don't rely on the parent thread reporting
-a SIGTRAP before receiving the SIGSTOP from the new child thread.
-
-Without PTRACE_O_TRACECLONE, newly cloned threads will not be
-ptrace'd.  As a result, signals received by new threads will be
-handled in the usual way, which may affect the parent and in turn
-appear to the attached process, but attributed to the parent (possibly
-in unexpected ways).
-
-== Following thread death ==
-
-If any thread with the PTRACE_O_TRACEEXIT option set exits (either by
-returning or pthread_exit'ing), the tracing process will receive an
-immediate PTRACE_EVENT_EXIT.  At this point, the thread will still
-exist.  The exit status, encoded as for wait, can be queried using
-PTRACE_GETEVENTMSG on the exiting thread's PID.  The thread should be
-continued so it can actually exit, after which its wait behavior is
-the same as for a thread without the PTRACE_O_TRACEEXIT option.
-
-If a non-main thread exits (either by returning or pthread_exit'ing),
-its corresponding process will also exit, producing a WIFEXITED event
-(after the process is continued from a possible PTRACE_EVENT_EXIT
-event).  It is *not* necessary for another thread to ptrace_join for
-this to happen.
-
-If the main thread exits by returning, then all threads will exit,
-first generating a PTRACE_EVENT_EXIT event for each thread if
-appropriate, then producing a WIFEXITED event for each thread.
-
-If the main thread exits using pthread_exit, then it enters a
-non-waitable zombie state.  It will still produce an immediate
-PTRACE_O_TRACEEXIT event, but the WIFEXITED event will be delayed
-until the entire process exits.  This state exists so that shells
-don't think the process is done until all of the threads have exited.
-Unfortunately, signals cannot be delivered to non-waitable zombies.
-Most notably, SIGSTOP cannot be delivered; as a result, when you
-broadcast SIGSTOP to all of the threads, you must not wait for
-non-waitable zombies to stop.  Furthermore, any ptrace command on a
-non-waitable zombie, including PTRACE_DETACH, will return ESRCH.
-
-== Multi-threaded debuggers ==
-
-If the debugger itself is multi-threaded, ptrace calls must come from
-the same thread that originally attached to the remote thread.  The
-kernel simply compares the PID of the caller of ptrace against the
-tracer PID of the process passed to ptrace.  Because each debugger
-thread has a different PID, calling ptrace from a different thread
-might as well be calling it from a different process and the kernel
-will return ESRCH.
-
-wait, on the other hand, does not have this restriction.  Any debugger
-thread can wait on any thread in the attached process.
diff --git a/dwarf/buf.go b/dwarf/buf.go
deleted file mode 100644
index 73fcc9a..0000000
--- a/dwarf/buf.go
+++ /dev/null
@@ -1,203 +0,0 @@
-// Copyright 2009 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.
-
-// Buffered reading and decoding of DWARF data streams.
-
-package dwarf
-
-import (
-	"encoding/binary"
-	"fmt"
-	"strconv"
-)
-
-// Data buffer being decoded.
-type buf struct {
-	dwarf  *Data
-	order  binary.ByteOrder
-	format dataFormat
-	name   string
-	off    Offset
-	data   []byte
-	err    error
-}
-
-// Data format, other than byte order.  This affects the handling of
-// certain field formats.
-type dataFormat interface {
-	// DWARF version number.  Zero means unknown.
-	version() int
-
-	// 64-bit DWARF format?
-	dwarf64() (dwarf64 bool, isKnown bool)
-
-	// Size of an address, in bytes.  Zero means unknown.
-	addrsize() int
-}
-
-// Some parts of DWARF have no data format, e.g., abbrevs.
-type unknownFormat struct{}
-
-func (u unknownFormat) version() int {
-	return 0
-}
-
-func (u unknownFormat) dwarf64() (bool, bool) {
-	return false, false
-}
-
-func (u unknownFormat) addrsize() int {
-	return 0
-}
-
-func makeBuf(d *Data, format dataFormat, name string, off Offset, data []byte) buf {
-	return buf{d, d.order, format, name, off, data, nil}
-}
-
-func (b *buf) slice(length int) buf {
-	n := *b
-	data := b.data
-	b.skip(length) // Will validate length.
-	n.data = data[:length]
-	return n
-}
-
-func (b *buf) uint8() uint8 {
-	if len(b.data) < 1 {
-		b.error("underflow")
-		return 0
-	}
-	val := b.data[0]
-	b.data = b.data[1:]
-	b.off++
-	return val
-}
-
-func (b *buf) bytes(n int) []byte {
-	if len(b.data) < n {
-		b.error("underflow")
-		return nil
-	}
-	data := b.data[0:n]
-	b.data = b.data[n:]
-	b.off += Offset(n)
-	return data
-}
-
-func (b *buf) skip(n int) { b.bytes(n) }
-
-// string returns the NUL-terminated (C-like) string at the start of the buffer.
-// The terminal NUL is discarded.
-func (b *buf) string() string {
-	for i := 0; i < len(b.data); i++ {
-		if b.data[i] == 0 {
-			s := string(b.data[0:i])
-			b.data = b.data[i+1:]
-			b.off += Offset(i + 1)
-			return s
-		}
-	}
-	b.error("underflow")
-	return ""
-}
-
-func (b *buf) uint16() uint16 {
-	a := b.bytes(2)
-	if a == nil {
-		return 0
-	}
-	return b.order.Uint16(a)
-}
-
-func (b *buf) uint32() uint32 {
-	a := b.bytes(4)
-	if a == nil {
-		return 0
-	}
-	return b.order.Uint32(a)
-}
-
-func (b *buf) uint64() uint64 {
-	a := b.bytes(8)
-	if a == nil {
-		return 0
-	}
-	return b.order.Uint64(a)
-}
-
-// Read a varint, which is 7 bits per byte, little endian.
-// the 0x80 bit means read another byte.
-func (b *buf) varint() (c uint64, bits uint) {
-	for i := 0; i < len(b.data); i++ {
-		byte := b.data[i]
-		c |= uint64(byte&0x7F) << bits
-		bits += 7
-		if byte&0x80 == 0 {
-			b.off += Offset(i + 1)
-			b.data = b.data[i+1:]
-			return c, bits
-		}
-	}
-	return 0, 0
-}
-
-// Unsigned int is just a varint.
-func (b *buf) uint() uint64 {
-	x, _ := b.varint()
-	return x
-}
-
-// Signed int is a sign-extended varint.
-func (b *buf) int() int64 {
-	ux, bits := b.varint()
-	x := int64(ux)
-	if x&(1<<(bits-1)) != 0 {
-		x |= -1 << bits
-	}
-	return x
-}
-
-// Address-sized uint.
-func (b *buf) addr() uint64 {
-	switch b.format.addrsize() {
-	case 1:
-		return uint64(b.uint8())
-	case 2:
-		return uint64(b.uint16())
-	case 4:
-		return uint64(b.uint32())
-	case 8:
-		return uint64(b.uint64())
-	}
-	b.error("unknown address size")
-	return 0
-}
-
-// assertEmpty checks that everything has been read from b.
-func (b *buf) assertEmpty() {
-	if len(b.data) == 0 {
-		return
-	}
-	if len(b.data) > 5 {
-		b.error(fmt.Sprintf("unexpected extra data: %x...", b.data[0:5]))
-	}
-	b.error(fmt.Sprintf("unexpected extra data: %x", b.data))
-}
-
-func (b *buf) error(s string) {
-	if b.err == nil {
-		b.data = nil
-		b.err = DecodeError{b.name, b.off, s}
-	}
-}
-
-type DecodeError struct {
-	Name   string
-	Offset Offset
-	Err    string
-}
-
-func (e DecodeError) Error() string {
-	return "decoding dwarf section " + e.Name + " at offset 0x" + strconv.FormatInt(int64(e.Offset), 16) + ": " + e.Err
-}
diff --git a/dwarf/cache.go b/dwarf/cache.go
deleted file mode 100644
index cf795e7..0000000
--- a/dwarf/cache.go
+++ /dev/null
@@ -1,249 +0,0 @@
-// Copyright 2016 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 dwarf
-
-import (
-	"sort"
-)
-
-// pcToFuncEntries maps PC ranges to function entries.
-//
-// Each element contains a *Entry for a function and its corresponding start PC.
-// If we know the address one past the last instruction of a function, and it is
-// not equal to the start address of the next function, we mark that with
-// another element containing that address and a nil entry.  The elements are
-// sorted by PC.  Among elements with the same PC, those with non-nil *Entry
-// are put earlier.
-type pcToFuncEntries []pcToFuncEntry
-type pcToFuncEntry struct {
-	pc    uint64
-	entry *Entry
-}
-
-func (p pcToFuncEntries) Len() int      { return len(p) }
-func (p pcToFuncEntries) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
-func (p pcToFuncEntries) Less(i, j int) bool {
-	if p[i].pc != p[j].pc {
-		return p[i].pc < p[j].pc
-	}
-	return p[i].entry != nil && p[j].entry == nil
-}
-
-// nameCache maps each symbol name to a linked list of the entries with that name.
-type nameCache map[string]*nameCacheEntry
-type nameCacheEntry struct {
-	entry *Entry
-	link  *nameCacheEntry
-}
-
-// pcToLineEntries maps PCs to line numbers.
-//
-// It is a slice of (PC, line, file number) triples, sorted by PC.  The file
-// number is an index into the source files slice.
-// If (PC1, line1, file1) and (PC2, line2, file2) are two consecutive elements,
-// then the span of addresses [PC1, PC2) belongs to (line1, file1).  If an
-// element's file number is zero, it only marks the end of a span.
-//
-// TODO: could save memory by changing pcToLineEntries and lineToPCEntries to use
-// interval trees containing references into .debug_line.
-type pcToLineEntries []pcToLineEntry
-type pcToLineEntry struct {
-	pc   uint64
-	line uint64
-	file uint64
-}
-
-func (p pcToLineEntries) Len() int      { return len(p) }
-func (p pcToLineEntries) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
-func (p pcToLineEntries) Less(i, j int) bool {
-	if p[i].pc != p[j].pc {
-		return p[i].pc < p[j].pc
-	}
-	return p[i].file > p[j].file
-}
-
-// byFileLine is used temporarily while building lineToPCEntries.
-type byFileLine []pcToLineEntry
-
-func (b byFileLine) Len() int      { return len(b) }
-func (b byFileLine) Swap(i, j int) { b[i], b[j] = b[j], b[i] }
-func (b byFileLine) Less(i, j int) bool {
-	if b[i].file != b[j].file {
-		return b[i].file < b[j].file
-	}
-	return b[i].line < b[j].line
-}
-
-// lineToPCEntries maps line numbers to breakpoint addresses.
-//
-// The slice contains, for each source file in Data, a slice of (line, PC)
-// pairs, sorted by line.  Note that there may be more than one PC for a line.
-type lineToPCEntries [][]lineToPCEntry
-type lineToPCEntry struct {
-	line uint64
-	pc   uint64
-}
-
-func (d *Data) buildLineToPCCache(pclfs pcToLineEntries) {
-	// TODO: only include lines where is_stmt is true
-	sort.Sort(byFileLine(pclfs))
-	// Make a slice of (line, PC) pairs for each (non-zero) file.
-	var (
-		c        = make(lineToPCEntries, len(d.sourceFiles))
-		curSlice []lineToPCEntry
-	)
-	for i, pclf := range pclfs {
-		if pclf.file == 0 {
-			// This entry indicated the end of an instruction sequence, not a breakpoint.
-			continue
-		}
-		curSlice = append(curSlice, lineToPCEntry{line: pclf.line, pc: pclf.pc})
-		if i+1 == len(pclfs) || pclf.file != pclfs[i+1].file {
-			// curSlice now contains all of the entries for pclf.file.
-			if pclf.file > 0 && pclf.file < uint64(len(c)) {
-				c[pclf.file] = curSlice
-			}
-			curSlice = nil
-		}
-	}
-	d.lineToPCEntries = c
-}
-
-func (d *Data) buildPCToLineCache(cache pcToLineEntries) {
-	// Sort cache by PC (in increasing order), then by file number (in decreasing order).
-	sort.Sort(cache)
-
-	// Build a copy without redundant entries.
-	var out pcToLineEntries
-	for i, pclf := range cache {
-		if i > 0 && pclf.pc == cache[i-1].pc {
-			// This entry is for the same PC as the previous entry.
-			continue
-		}
-		if i > 0 && pclf.file == cache[i-1].file && pclf.line == cache[i-1].line {
-			// This entry is for the same file and line as the previous entry.
-			continue
-		}
-		out = append(out, pclf)
-	}
-	d.pcToLineEntries = out
-}
-
-// buildLineCaches constructs d.sourceFiles, d.lineToPCEntries, d.pcToLineEntries.
-func (d *Data) buildLineCaches() {
-	if len(d.line) == 0 {
-		return
-	}
-	var m lineMachine
-	// Assume the address_size in the first unit applies to the whole program.
-	// TODO: we could handle executables containing code for multiple address
-	// sizes using DW_AT_stmt_list attributes.
-	if len(d.unit) == 0 {
-		return
-	}
-	buf := makeBuf(d, &d.unit[0], "line", 0, d.line)
-	if err := m.parseHeader(&buf); err != nil {
-		return
-	}
-	for _, f := range m.header.file {
-		d.sourceFiles = append(d.sourceFiles, f.name)
-	}
-	var cache pcToLineEntries
-	fn := func(m *lineMachine) bool {
-		if m.endSequence {
-			cache = append(cache, pcToLineEntry{
-				pc:   m.address,
-				line: 0,
-				file: 0,
-			})
-		} else {
-			cache = append(cache, pcToLineEntry{
-				pc:   m.address,
-				line: m.line,
-				file: m.file,
-			})
-		}
-		return true
-	}
-	m.evalCompilationUnit(&buf, fn)
-	d.buildLineToPCCache(cache)
-	d.buildPCToLineCache(cache)
-}
-
-// buildInfoCaches initializes nameCache and pcToFuncEntries by walking the
-// top-level entries under each compile unit. It swallows any errors in parsing.
-func (d *Data) buildInfoCaches() {
-	// TODO: record errors somewhere?
-	d.nameCache = make(map[string]*nameCacheEntry)
-
-	var pcToFuncEntries pcToFuncEntries
-
-	r := d.Reader()
-loop:
-	for {
-		entry, err := r.Next()
-		if entry == nil || err != nil {
-			break loop
-		}
-		if entry.Tag != TagCompileUnit /* DW_TAG_compile_unit */ {
-			r.SkipChildren()
-			continue
-		}
-		for {
-			entry, err := r.Next()
-			if entry == nil || err != nil {
-				break loop
-			}
-			if entry.Tag == 0 {
-				// End of children of current compile unit.
-				break
-			}
-			r.SkipChildren()
-			// Update name-to-entry cache.
-			if name, ok := entry.Val(AttrName).(string); ok {
-				d.nameCache[name] = &nameCacheEntry{entry: entry, link: d.nameCache[name]}
-			}
-
-			// If this entry is a function, update PC-to-containing-function cache.
-			if entry.Tag != TagSubprogram /* DW_TAG_subprogram */ {
-				continue
-			}
-
-			// DW_AT_low_pc, if present, is the address of the first instruction of
-			// the function.
-			lowpc, ok := entry.Val(AttrLowpc).(uint64)
-			if !ok {
-				continue
-			}
-			pcToFuncEntries = append(pcToFuncEntries, pcToFuncEntry{lowpc, entry})
-
-			// DW_AT_high_pc, if present (TODO: and of class address) is the address
-			// one past the last instruction of the function.
-			highpc, ok := entry.Val(AttrHighpc).(uint64)
-			if !ok {
-				continue
-			}
-			pcToFuncEntries = append(pcToFuncEntries, pcToFuncEntry{highpc, nil})
-		}
-	}
-	// Sort elements by PC.  If there are multiple elements with the same PC,
-	// those with non-nil *Entry are placed earlier.
-	sort.Sort(pcToFuncEntries)
-
-	// Copy only the first element for each PC to out.
-	n := 0
-	for i, ce := range pcToFuncEntries {
-		if i == 0 || ce.pc != pcToFuncEntries[i-1].pc {
-			n++
-		}
-	}
-	out := make([]pcToFuncEntry, 0, n)
-	for i, ce := range pcToFuncEntries {
-		if i == 0 || ce.pc != pcToFuncEntries[i-1].pc {
-			out = append(out, ce)
-		}
-	}
-	d.pcToFuncEntries = out
-}
diff --git a/dwarf/const.go b/dwarf/const.go
deleted file mode 100644
index b2debfb..0000000
--- a/dwarf/const.go
+++ /dev/null
@@ -1,470 +0,0 @@
-// Copyright 2009 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.
-
-// Constants
-
-package dwarf
-
-import "strconv"
-
-// An Attr identifies the attribute type in a DWARF Entry's Field.
-type Attr uint32
-
-const (
-	AttrSibling        Attr = 0x01
-	AttrLocation       Attr = 0x02
-	AttrName           Attr = 0x03
-	AttrOrdering       Attr = 0x09
-	AttrByteSize       Attr = 0x0B
-	AttrBitOffset      Attr = 0x0C
-	AttrBitSize        Attr = 0x0D
-	AttrStmtList       Attr = 0x10
-	AttrLowpc          Attr = 0x11
-	AttrHighpc         Attr = 0x12
-	AttrLanguage       Attr = 0x13
-	AttrDiscr          Attr = 0x15
-	AttrDiscrValue     Attr = 0x16
-	AttrVisibility     Attr = 0x17
-	AttrImport         Attr = 0x18
-	AttrStringLength   Attr = 0x19
-	AttrCommonRef      Attr = 0x1A
-	AttrCompDir        Attr = 0x1B
-	AttrConstValue     Attr = 0x1C
-	AttrContainingType Attr = 0x1D
-	AttrDefaultValue   Attr = 0x1E
-	AttrInline         Attr = 0x20
-	AttrIsOptional     Attr = 0x21
-	AttrLowerBound     Attr = 0x22
-	AttrProducer       Attr = 0x25
-	AttrPrototyped     Attr = 0x27
-	AttrReturnAddr     Attr = 0x2A
-	AttrStartScope     Attr = 0x2C
-	AttrStrideSize     Attr = 0x2E
-	AttrUpperBound     Attr = 0x2F
-	AttrAbstractOrigin Attr = 0x31
-	AttrAccessibility  Attr = 0x32
-	AttrAddrClass      Attr = 0x33
-	AttrArtificial     Attr = 0x34
-	AttrBaseTypes      Attr = 0x35
-	AttrCalling        Attr = 0x36
-	AttrCount          Attr = 0x37
-	AttrDataMemberLoc  Attr = 0x38
-	AttrDeclColumn     Attr = 0x39
-	AttrDeclFile       Attr = 0x3A
-	AttrDeclLine       Attr = 0x3B
-	AttrDeclaration    Attr = 0x3C
-	AttrDiscrList      Attr = 0x3D
-	AttrEncoding       Attr = 0x3E
-	AttrExternal       Attr = 0x3F
-	AttrFrameBase      Attr = 0x40
-	AttrFriend         Attr = 0x41
-	AttrIdentifierCase Attr = 0x42
-	AttrMacroInfo      Attr = 0x43
-	AttrNamelistItem   Attr = 0x44
-	AttrPriority       Attr = 0x45
-	AttrSegment        Attr = 0x46
-	AttrSpecification  Attr = 0x47
-	AttrStaticLink     Attr = 0x48
-	AttrType           Attr = 0x49
-	AttrUseLocation    Attr = 0x4A
-	AttrVarParam       Attr = 0x4B
-	AttrVirtuality     Attr = 0x4C
-	AttrVtableElemLoc  Attr = 0x4D
-	AttrAllocated      Attr = 0x4E
-	AttrAssociated     Attr = 0x4F
-	AttrDataLocation   Attr = 0x50
-	AttrStride         Attr = 0x51
-	AttrEntrypc        Attr = 0x52
-	AttrUseUTF8        Attr = 0x53
-	AttrExtension      Attr = 0x54
-	AttrRanges         Attr = 0x55
-	AttrTrampoline     Attr = 0x56
-	AttrCallColumn     Attr = 0x57
-	AttrCallFile       Attr = 0x58
-	AttrCallLine       Attr = 0x59
-	AttrDescription    Attr = 0x5A
-
-	// Go-specific attributes.
-	AttrGoKind          Attr = 0x2900
-	AttrGoKey           Attr = 0x2901
-	AttrGoElem          Attr = 0x2902
-	AttrGoEmbeddedField Attr = 0x2903
-)
-
-var attrNames = [...]string{
-	AttrSibling:        "Sibling",
-	AttrLocation:       "Location",
-	AttrName:           "Name",
-	AttrOrdering:       "Ordering",
-	AttrByteSize:       "ByteSize",
-	AttrBitOffset:      "BitOffset",
-	AttrBitSize:        "BitSize",
-	AttrStmtList:       "StmtList",
-	AttrLowpc:          "Lowpc",
-	AttrHighpc:         "Highpc",
-	AttrLanguage:       "Language",
-	AttrDiscr:          "Discr",
-	AttrDiscrValue:     "DiscrValue",
-	AttrVisibility:     "Visibility",
-	AttrImport:         "Import",
-	AttrStringLength:   "StringLength",
-	AttrCommonRef:      "CommonRef",
-	AttrCompDir:        "CompDir",
-	AttrConstValue:     "ConstValue",
-	AttrContainingType: "ContainingType",
-	AttrDefaultValue:   "DefaultValue",
-	AttrInline:         "Inline",
-	AttrIsOptional:     "IsOptional",
-	AttrLowerBound:     "LowerBound",
-	AttrProducer:       "Producer",
-	AttrPrototyped:     "Prototyped",
-	AttrReturnAddr:     "ReturnAddr",
-	AttrStartScope:     "StartScope",
-	AttrStrideSize:     "StrideSize",
-	AttrUpperBound:     "UpperBound",
-	AttrAbstractOrigin: "AbstractOrigin",
-	AttrAccessibility:  "Accessibility",
-	AttrAddrClass:      "AddrClass",
-	AttrArtificial:     "Artificial",
-	AttrBaseTypes:      "BaseTypes",
-	AttrCalling:        "Calling",
-	AttrCount:          "Count",
-	AttrDataMemberLoc:  "DataMemberLoc",
-	AttrDeclColumn:     "DeclColumn",
-	AttrDeclFile:       "DeclFile",
-	AttrDeclLine:       "DeclLine",
-	AttrDeclaration:    "Declaration",
-	AttrDiscrList:      "DiscrList",
-	AttrEncoding:       "Encoding",
-	AttrExternal:       "External",
-	AttrFrameBase:      "FrameBase",
-	AttrFriend:         "Friend",
-	AttrIdentifierCase: "IdentifierCase",
-	AttrMacroInfo:      "MacroInfo",
-	AttrNamelistItem:   "NamelistItem",
-	AttrPriority:       "Priority",
-	AttrSegment:        "Segment",
-	AttrSpecification:  "Specification",
-	AttrStaticLink:     "StaticLink",
-	AttrType:           "Type",
-	AttrUseLocation:    "UseLocation",
-	AttrVarParam:       "VarParam",
-	AttrVirtuality:     "Virtuality",
-	AttrVtableElemLoc:  "VtableElemLoc",
-	AttrAllocated:      "Allocated",
-	AttrAssociated:     "Associated",
-	AttrDataLocation:   "DataLocation",
-	AttrStride:         "Stride",
-	AttrEntrypc:        "Entrypc",
-	AttrUseUTF8:        "UseUTF8",
-	AttrExtension:      "Extension",
-	AttrRanges:         "Ranges",
-	AttrTrampoline:     "Trampoline",
-	AttrCallColumn:     "CallColumn",
-	AttrCallFile:       "CallFile",
-	AttrCallLine:       "CallLine",
-	AttrDescription:    "Description",
-}
-
-func (a Attr) String() string {
-	if int(a) < len(attrNames) {
-		s := attrNames[a]
-		if s != "" {
-			return s
-		}
-	}
-	switch a {
-	case AttrGoKind:
-		return "GoKind"
-	case AttrGoKey:
-		return "GoKey"
-	case AttrGoElem:
-		return "GoElem"
-	case AttrGoEmbeddedField:
-		return "GoEmbeddedField"
-	}
-	return strconv.Itoa(int(a))
-}
-
-func (a Attr) GoString() string {
-	if int(a) < len(attrNames) {
-		s := attrNames[a]
-		if s != "" {
-			return "dwarf.Attr" + s
-		}
-	}
-	return "dwarf.Attr(" + strconv.FormatInt(int64(a), 10) + ")"
-}
-
-// A format is a DWARF data encoding format.
-type format uint32
-
-const (
-	// value formats
-	formAddr        format = 0x01
-	formDwarfBlock2 format = 0x03
-	formDwarfBlock4 format = 0x04
-	formData2       format = 0x05
-	formData4       format = 0x06
-	formData8       format = 0x07
-	formString      format = 0x08
-	formDwarfBlock  format = 0x09
-	formDwarfBlock1 format = 0x0A
-	formData1       format = 0x0B
-	formFlag        format = 0x0C
-	formSdata       format = 0x0D
-	formStrp        format = 0x0E
-	formUdata       format = 0x0F
-	formRefAddr     format = 0x10
-	formRef1        format = 0x11
-	formRef2        format = 0x12
-	formRef4        format = 0x13
-	formRef8        format = 0x14
-	formRefUdata    format = 0x15
-	formIndirect    format = 0x16
-	// The following are new in DWARF 4.
-	formSecOffset   format = 0x17
-	formExprloc     format = 0x18
-	formFlagPresent format = 0x19
-	formRefSig8     format = 0x20
-	// Extensions for multi-file compression (.dwz)
-	// http://www.dwarfstd.org/ShowIssue.php?issue=120604.1
-	formGnuRefAlt  format = 0x1f20
-	formGnuStrpAlt format = 0x1f21
-)
-
-// A Tag is the classification (the type) of an Entry.
-type Tag uint32
-
-const (
-	TagArrayType              Tag = 0x01
-	TagClassType              Tag = 0x02
-	TagEntryPoint             Tag = 0x03
-	TagEnumerationType        Tag = 0x04
-	TagFormalParameter        Tag = 0x05
-	TagImportedDeclaration    Tag = 0x08
-	TagLabel                  Tag = 0x0A
-	TagLexDwarfBlock          Tag = 0x0B
-	TagMember                 Tag = 0x0D
-	TagPointerType            Tag = 0x0F
-	TagReferenceType          Tag = 0x10
-	TagCompileUnit            Tag = 0x11
-	TagStringType             Tag = 0x12
-	TagStructType             Tag = 0x13
-	TagSubroutineType         Tag = 0x15
-	TagTypedef                Tag = 0x16
-	TagUnionType              Tag = 0x17
-	TagUnspecifiedParameters  Tag = 0x18
-	TagVariant                Tag = 0x19
-	TagCommonDwarfBlock       Tag = 0x1A
-	TagCommonInclusion        Tag = 0x1B
-	TagInheritance            Tag = 0x1C
-	TagInlinedSubroutine      Tag = 0x1D
-	TagModule                 Tag = 0x1E
-	TagPtrToMemberType        Tag = 0x1F
-	TagSetType                Tag = 0x20
-	TagSubrangeType           Tag = 0x21
-	TagWithStmt               Tag = 0x22
-	TagAccessDeclaration      Tag = 0x23
-	TagBaseType               Tag = 0x24
-	TagCatchDwarfBlock        Tag = 0x25
-	TagConstType              Tag = 0x26
-	TagConstant               Tag = 0x27
-	TagEnumerator             Tag = 0x28
-	TagFileType               Tag = 0x29
-	TagFriend                 Tag = 0x2A
-	TagNamelist               Tag = 0x2B
-	TagNamelistItem           Tag = 0x2C
-	TagPackedType             Tag = 0x2D
-	TagSubprogram             Tag = 0x2E
-	TagTemplateTypeParameter  Tag = 0x2F
-	TagTemplateValueParameter Tag = 0x30
-	TagThrownType             Tag = 0x31
-	TagTryDwarfBlock          Tag = 0x32
-	TagVariantPart            Tag = 0x33
-	TagVariable               Tag = 0x34
-	TagVolatileType           Tag = 0x35
-	// The following are new in DWARF 3.
-	TagDwarfProcedure  Tag = 0x36
-	TagRestrictType    Tag = 0x37
-	TagInterfaceType   Tag = 0x38
-	TagNamespace       Tag = 0x39
-	TagImportedModule  Tag = 0x3A
-	TagUnspecifiedType Tag = 0x3B
-	TagPartialUnit     Tag = 0x3C
-	TagImportedUnit    Tag = 0x3D
-	TagMutableType     Tag = 0x3E // Later removed from DWARF.
-	TagCondition       Tag = 0x3F
-	TagSharedType      Tag = 0x40
-	// The following are new in DWARF 4.
-	TagTypeUnit            Tag = 0x41
-	TagRvalueReferenceType Tag = 0x42
-	TagTemplateAlias       Tag = 0x43
-)
-
-var tagNames = [...]string{
-	TagArrayType:              "ArrayType",
-	TagClassType:              "ClassType",
-	TagEntryPoint:             "EntryPoint",
-	TagEnumerationType:        "EnumerationType",
-	TagFormalParameter:        "FormalParameter",
-	TagImportedDeclaration:    "ImportedDeclaration",
-	TagLabel:                  "Label",
-	TagLexDwarfBlock:          "LexDwarfBlock",
-	TagMember:                 "Member",
-	TagPointerType:            "PointerType",
-	TagReferenceType:          "ReferenceType",
-	TagCompileUnit:            "CompileUnit",
-	TagStringType:             "StringType",
-	TagStructType:             "StructType",
-	TagSubroutineType:         "SubroutineType",
-	TagTypedef:                "Typedef",
-	TagUnionType:              "UnionType",
-	TagUnspecifiedParameters:  "UnspecifiedParameters",
-	TagVariant:                "Variant",
-	TagCommonDwarfBlock:       "CommonDwarfBlock",
-	TagCommonInclusion:        "CommonInclusion",
-	TagInheritance:            "Inheritance",
-	TagInlinedSubroutine:      "InlinedSubroutine",
-	TagModule:                 "Module",
-	TagPtrToMemberType:        "PtrToMemberType",
-	TagSetType:                "SetType",
-	TagSubrangeType:           "SubrangeType",
-	TagWithStmt:               "WithStmt",
-	TagAccessDeclaration:      "AccessDeclaration",
-	TagBaseType:               "BaseType",
-	TagCatchDwarfBlock:        "CatchDwarfBlock",
-	TagConstType:              "ConstType",
-	TagConstant:               "Constant",
-	TagEnumerator:             "Enumerator",
-	TagFileType:               "FileType",
-	TagFriend:                 "Friend",
-	TagNamelist:               "Namelist",
-	TagNamelistItem:           "NamelistItem",
-	TagPackedType:             "PackedType",
-	TagSubprogram:             "Subprogram",
-	TagTemplateTypeParameter:  "TemplateTypeParameter",
-	TagTemplateValueParameter: "TemplateValueParameter",
-	TagThrownType:             "ThrownType",
-	TagTryDwarfBlock:          "TryDwarfBlock",
-	TagVariantPart:            "VariantPart",
-	TagVariable:               "Variable",
-	TagVolatileType:           "VolatileType",
-	TagDwarfProcedure:         "DwarfProcedure",
-	TagRestrictType:           "RestrictType",
-	TagInterfaceType:          "InterfaceType",
-	TagNamespace:              "Namespace",
-	TagImportedModule:         "ImportedModule",
-	TagUnspecifiedType:        "UnspecifiedType",
-	TagPartialUnit:            "PartialUnit",
-	TagImportedUnit:           "ImportedUnit",
-	TagMutableType:            "MutableType",
-	TagCondition:              "Condition",
-	TagSharedType:             "SharedType",
-	TagTypeUnit:               "TypeUnit",
-	TagRvalueReferenceType:    "RvalueReferenceType",
-	TagTemplateAlias:          "TemplateAlias",
-}
-
-func (t Tag) String() string {
-	if int(t) < len(tagNames) {
-		s := tagNames[t]
-		if s != "" {
-			return s
-		}
-	}
-	return strconv.Itoa(int(t))
-}
-
-func (t Tag) GoString() string {
-	if int(t) < len(tagNames) {
-		s := tagNames[t]
-		if s != "" {
-			return "dwarf.Tag" + s
-		}
-	}
-	return "dwarf.Tag(" + strconv.FormatInt(int64(t), 10) + ")"
-}
-
-// Location expression operators.
-// The debug info encodes value locations like 8(R3)
-// as a sequence of these op codes.
-// This package does not implement full expressions;
-// the opPlusUconst operator is expected by the type parser.
-const (
-	opAddr       = 0x03 /* 1 op, const addr */
-	opDeref      = 0x06
-	opConst1u    = 0x08 /* 1 op, 1 byte const */
-	opConst1s    = 0x09 /*	" signed */
-	opConst2u    = 0x0A /* 1 op, 2 byte const  */
-	opConst2s    = 0x0B /*	" signed */
-	opConst4u    = 0x0C /* 1 op, 4 byte const */
-	opConst4s    = 0x0D /*	" signed */
-	opConst8u    = 0x0E /* 1 op, 8 byte const */
-	opConst8s    = 0x0F /*	" signed */
-	opConstu     = 0x10 /* 1 op, LEB128 const */
-	opConsts     = 0x11 /*	" signed */
-	opDup        = 0x12
-	opDrop       = 0x13
-	opOver       = 0x14
-	opPick       = 0x15 /* 1 op, 1 byte stack index */
-	opSwap       = 0x16
-	opRot        = 0x17
-	opXderef     = 0x18
-	opAbs        = 0x19
-	opAnd        = 0x1A
-	opDiv        = 0x1B
-	opMinus      = 0x1C
-	opMod        = 0x1D
-	opMul        = 0x1E
-	opNeg        = 0x1F
-	opNot        = 0x20
-	opOr         = 0x21
-	opPlus       = 0x22
-	opPlusUconst = 0x23 /* 1 op, ULEB128 addend */
-	opShl        = 0x24
-	opShr        = 0x25
-	opShra       = 0x26
-	opXor        = 0x27
-	opSkip       = 0x2F /* 1 op, signed 2-byte constant */
-	opBra        = 0x28 /* 1 op, signed 2-byte constant */
-	opEq         = 0x29
-	opGe         = 0x2A
-	opGt         = 0x2B
-	opLe         = 0x2C
-	opLt         = 0x2D
-	opNe         = 0x2E
-	opLit0       = 0x30
-	/* OpLitN = OpLit0 + N for N = 0..31 */
-	opReg0 = 0x50
-	/* OpRegN = OpReg0 + N for N = 0..31 */
-	opBreg0 = 0x70 /* 1 op, signed LEB128 constant */
-	/* OpBregN = OpBreg0 + N for N = 0..31 */
-	opRegx       = 0x90 /* 1 op, ULEB128 register */
-	opFbreg      = 0x91 /* 1 op, SLEB128 offset */
-	opBregx      = 0x92 /* 2 op, ULEB128 reg; SLEB128 off */
-	opPiece      = 0x93 /* 1 op, ULEB128 size of piece */
-	opDerefSize  = 0x94 /* 1-byte size of data retrieved */
-	opXderefSize = 0x95 /* 1-byte size of data retrieved */
-	opNop        = 0x96
-	/* next four new in Dwarf v3 */
-	opPushObjAddr = 0x97
-	opCall2       = 0x98 /* 2-byte offset of DIE */
-	opCall4       = 0x99 /* 4-byte offset of DIE */
-	opCallRef     = 0x9A /* 4- or 8- byte offset of DIE */
-	/* 0xE0-0xFF reserved for user-specific */
-)
-
-// Basic type encodings -- the value for AttrEncoding in a TagBaseType Entry.
-const (
-	encAddress        = 0x01
-	encBoolean        = 0x02
-	encComplexFloat   = 0x03
-	encFloat          = 0x04
-	encSigned         = 0x05
-	encSignedChar     = 0x06
-	encUnsigned       = 0x07
-	encUnsignedChar   = 0x08
-	encImaginaryFloat = 0x09
-)
diff --git a/dwarf/entry.go b/dwarf/entry.go
deleted file mode 100644
index 4076ec1..0000000
--- a/dwarf/entry.go
+++ /dev/null
@@ -1,407 +0,0 @@
-// Copyright 2009 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.
-
-// DWARF debug information entry parser.
-// An entry is a sequence of data items of a given format.
-// The first word in the entry is an index into what DWARF
-// calls the ``abbreviation table.''  An abbreviation is really
-// just a type descriptor: it's an array of attribute tag/value format pairs.
-
-package dwarf
-
-import (
-	"errors"
-	"strconv"
-)
-
-// a single entry's description: a sequence of attributes
-type abbrev struct {
-	tag      Tag
-	children bool
-	field    []afield
-}
-
-type afield struct {
-	attr Attr
-	fmt  format
-}
-
-// a map from entry format ids to their descriptions
-type abbrevTable map[uint32]abbrev
-
-// ParseAbbrev returns the abbreviation table that starts at byte off
-// in the .debug_abbrev section.
-func (d *Data) parseAbbrev(off uint32) (abbrevTable, error) {
-	if m, ok := d.abbrevCache[off]; ok {
-		return m, nil
-	}
-
-	data := d.abbrev
-	if off > uint32(len(data)) {
-		data = nil
-	} else {
-		data = data[off:]
-	}
-	b := makeBuf(d, unknownFormat{}, "abbrev", 0, data)
-
-	// Error handling is simplified by the buf getters
-	// returning an endless stream of 0s after an error.
-	m := make(abbrevTable)
-	for {
-		// Table ends with id == 0.
-		id := uint32(b.uint())
-		if id == 0 {
-			break
-		}
-
-		// Walk over attributes, counting.
-		n := 0
-		b1 := b // Read from copy of b.
-		b1.uint()
-		b1.uint8()
-		for {
-			tag := b1.uint()
-			fmt := b1.uint()
-			if tag == 0 && fmt == 0 {
-				break
-			}
-			n++
-		}
-		if b1.err != nil {
-			return nil, b1.err
-		}
-
-		// Walk over attributes again, this time writing them down.
-		var a abbrev
-		a.tag = Tag(b.uint())
-		a.children = b.uint8() != 0
-		a.field = make([]afield, n)
-		for i := range a.field {
-			a.field[i].attr = Attr(b.uint())
-			a.field[i].fmt = format(b.uint())
-		}
-		b.uint()
-		b.uint()
-
-		m[id] = a
-	}
-	if b.err != nil {
-		return nil, b.err
-	}
-	d.abbrevCache[off] = m
-	return m, nil
-}
-
-// An entry is a sequence of attribute/value pairs.
-type Entry struct {
-	Offset   Offset // offset of Entry in DWARF info
-	Tag      Tag    // tag (kind of Entry)
-	Children bool   // whether Entry is followed by children
-	Field    []Field
-}
-
-// A Field is a single attribute/value pair in an Entry.
-type Field struct {
-	Attr Attr
-	Val  interface{}
-}
-
-// Val returns the value associated with attribute Attr in Entry,
-// or nil if there is no such attribute.
-//
-// A common idiom is to merge the check for nil return with
-// the check that the value has the expected dynamic type, as in:
-//	v, ok := e.Val(AttrSibling).(int64);
-//
-func (e *Entry) Val(a Attr) interface{} {
-	for _, f := range e.Field {
-		if f.Attr == a {
-			return f.Val
-		}
-	}
-	return nil
-}
-
-// An Offset represents the location of an Entry within the DWARF info.
-// (See Reader.Seek.)
-type Offset uint32
-
-// Entry reads a single entry from buf, decoding
-// according to the given abbreviation table.
-func (b *buf) entry(atab abbrevTable, ubase Offset) *Entry {
-	off := b.off
-	id := uint32(b.uint())
-	if id == 0 {
-		return &Entry{}
-	}
-	a, ok := atab[id]
-	if !ok {
-		b.error("unknown abbreviation table index")
-		return nil
-	}
-	e := &Entry{
-		Offset:   off,
-		Tag:      a.tag,
-		Children: a.children,
-		Field:    make([]Field, len(a.field)),
-	}
-	for i := range e.Field {
-		e.Field[i].Attr = a.field[i].attr
-		fmt := a.field[i].fmt
-		if fmt == formIndirect {
-			fmt = format(b.uint())
-		}
-		var val interface{}
-		switch fmt {
-		default:
-			b.error("unknown entry attr format 0x" + strconv.FormatInt(int64(fmt), 16))
-
-		// address
-		case formAddr:
-			val = b.addr()
-
-		// block
-		case formDwarfBlock1:
-			val = b.bytes(int(b.uint8()))
-		case formDwarfBlock2:
-			val = b.bytes(int(b.uint16()))
-		case formDwarfBlock4:
-			val = b.bytes(int(b.uint32()))
-		case formDwarfBlock:
-			val = b.bytes(int(b.uint()))
-
-		// constant
-		case formData1:
-			val = int64(b.uint8())
-		case formData2:
-			val = int64(b.uint16())
-		case formData4:
-			val = int64(b.uint32())
-		case formData8:
-			val = int64(b.uint64())
-		case formSdata:
-			val = int64(b.int())
-		case formUdata:
-			val = int64(b.uint())
-
-		// flag
-		case formFlag:
-			val = b.uint8() == 1
-		// New in DWARF 4.
-		case formFlagPresent:
-			// The attribute is implicitly indicated as present, and no value is
-			// encoded in the debugging information entry itself.
-			val = true
-
-		// reference to other entry
-		case formRefAddr:
-			vers := b.format.version()
-			if vers == 0 {
-				b.error("unknown version for DW_FORM_ref_addr")
-			} else if vers == 2 {
-				val = Offset(b.addr())
-			} else {
-				is64, known := b.format.dwarf64()
-				if !known {
-					b.error("unknown size for DW_FORM_ref_addr")
-				} else if is64 {
-					val = Offset(b.uint64())
-				} else {
-					val = Offset(b.uint32())
-				}
-			}
-		case formRef1:
-			val = Offset(b.uint8()) + ubase
-		case formRef2:
-			val = Offset(b.uint16()) + ubase
-		case formRef4:
-			val = Offset(b.uint32()) + ubase
-		case formRef8:
-			val = Offset(b.uint64()) + ubase
-		case formRefUdata:
-			val = Offset(b.uint()) + ubase
-
-		// string
-		case formString:
-			val = b.string()
-		case formStrp:
-			off := b.uint32() // offset into .debug_str
-			if b.err != nil {
-				return nil
-			}
-			b1 := makeBuf(b.dwarf, unknownFormat{}, "str", 0, b.dwarf.str)
-			b1.skip(int(off))
-			val = b1.string()
-			if b1.err != nil {
-				b.err = b1.err
-				return nil
-			}
-
-		// lineptr, loclistptr, macptr, rangelistptr
-		// New in DWARF 4, but clang can generate them with -gdwarf-2.
-		// Section reference, replacing use of formData4 and formData8.
-		case formSecOffset, formGnuRefAlt, formGnuStrpAlt:
-			is64, known := b.format.dwarf64()
-			if !known {
-				b.error("unknown size for form 0x" + strconv.FormatInt(int64(fmt), 16))
-			} else if is64 {
-				val = int64(b.uint64())
-			} else {
-				val = int64(b.uint32())
-			}
-
-		// exprloc
-		// New in DWARF 4.
-		case formExprloc:
-			val = b.bytes(int(b.uint()))
-
-		// reference
-		// New in DWARF 4.
-		case formRefSig8:
-			// 64-bit type signature.
-			val = b.uint64()
-		}
-		e.Field[i].Val = val
-	}
-	if b.err != nil {
-		return nil
-	}
-	return e
-}
-
-// A Reader allows reading Entry structures from a DWARF ``info'' section.
-// The Entry structures are arranged in a tree.  The Reader's Next function
-// return successive entries from a pre-order traversal of the tree.
-// If an entry has children, its Children field will be true, and the children
-// follow, terminated by an Entry with Tag 0.
-type Reader struct {
-	b            buf
-	d            *Data
-	err          error
-	unit         int
-	lastChildren bool   // .Children of last entry returned by Next
-	lastSibling  Offset // .Val(AttrSibling) of last entry returned by Next
-}
-
-// Reader returns a new Reader for Data.
-// The reader is positioned at byte offset 0 in the DWARF ``info'' section.
-func (d *Data) Reader() *Reader {
-	r := &Reader{d: d}
-	r.Seek(0)
-	return r
-}
-
-// AddressSize returns the size in bytes of addresses in the current compilation
-// unit.
-func (r *Reader) AddressSize() int {
-	return r.d.unit[r.unit].asize
-}
-
-// Seek positions the Reader at offset off in the encoded entry stream.
-// Offset 0 can be used to denote the first entry.
-func (r *Reader) Seek(off Offset) {
-	d := r.d
-	r.err = nil
-	r.lastChildren = false
-	if off == 0 {
-		if len(d.unit) == 0 {
-			return
-		}
-		u := &d.unit[0]
-		r.unit = 0
-		r.b = makeBuf(r.d, u, "info", u.off, u.data)
-		return
-	}
-
-	// TODO(rsc): binary search (maybe a new package)
-	var i int
-	var u *unit
-	for i = range d.unit {
-		u = &d.unit[i]
-		if u.off <= off && off < u.off+Offset(len(u.data)) {
-			r.unit = i
-			r.b = makeBuf(r.d, u, "info", off, u.data[off-u.off:])
-			return
-		}
-	}
-	r.err = errors.New("offset out of range")
-}
-
-// maybeNextUnit advances to the next unit if this one is finished.
-func (r *Reader) maybeNextUnit() {
-	for len(r.b.data) == 0 && r.unit+1 < len(r.d.unit) {
-		r.unit++
-		u := &r.d.unit[r.unit]
-		r.b = makeBuf(r.d, u, "info", u.off, u.data)
-	}
-}
-
-// Next reads the next entry from the encoded entry stream.
-// It returns nil, nil when it reaches the end of the section.
-// It returns an error if the current offset is invalid or the data at the
-// offset cannot be decoded as a valid Entry.
-func (r *Reader) Next() (*Entry, error) {
-	if r.err != nil {
-		return nil, r.err
-	}
-	r.maybeNextUnit()
-	if len(r.b.data) == 0 {
-		return nil, nil
-	}
-	u := &r.d.unit[r.unit]
-	e := r.b.entry(u.atable, u.base)
-	if r.b.err != nil {
-		r.err = r.b.err
-		return nil, r.err
-	}
-	if e != nil {
-		r.lastChildren = e.Children
-		if r.lastChildren {
-			r.lastSibling, _ = e.Val(AttrSibling).(Offset)
-		}
-	} else {
-		r.lastChildren = false
-	}
-	return e, nil
-}
-
-// SkipChildren skips over the child entries associated with
-// the last Entry returned by Next.  If that Entry did not have
-// children or Next has not been called, SkipChildren is a no-op.
-func (r *Reader) SkipChildren() {
-	if r.err != nil || !r.lastChildren {
-		return
-	}
-
-	// If the last entry had a sibling attribute,
-	// that attribute gives the offset of the next
-	// sibling, so we can avoid decoding the
-	// child subtrees.
-	if r.lastSibling >= r.b.off {
-		r.Seek(r.lastSibling)
-		return
-	}
-
-	for {
-		e, err := r.Next()
-		if err != nil || e == nil || e.Tag == 0 {
-			break
-		}
-		if e.Children {
-			r.SkipChildren()
-		}
-	}
-}
-
-// clone returns a copy of the reader.  This is used by the typeReader
-// interface.
-func (r *Reader) clone() typeReader {
-	return r.d.Reader()
-}
-
-// offset returns the current buffer offset.  This is used by the
-// typeReader interface.
-func (r *Reader) offset() Offset {
-	return r.b.off
-}
diff --git a/dwarf/frame.go b/dwarf/frame.go
deleted file mode 100644
index c112c02..0000000
--- a/dwarf/frame.go
+++ /dev/null
@@ -1,299 +0,0 @@
-// Copyright 2014 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.
-
-// Mapping from PC to SP offset (called CFA - Canonical Frame Address - in DWARF).
-// This value is the offset from the stack pointer to the virtual frame pointer
-// (address of zeroth argument) at each PC value in the program.
-
-package dwarf
-
-import "fmt"
-
-// http://www.dwarfstd.org/doc/DWARF4.pdf Section 6.4 page 126
-// We implement only the CFA column of the table, not the location
-// information about other registers. In other words, we implement
-// only what we need to understand Go programs compiled by gc.
-
-// PCToSPOffset returns the offset, at the specified PC, to add to the
-// SP to reach the virtual frame pointer, which corresponds to the
-// address of the zeroth argument of the function, the word on the
-// stack immediately above the return PC.
-func (d *Data) PCToSPOffset(pc uint64) (offset int64, err error) {
-	if len(d.frame) == 0 {
-		return 0, fmt.Errorf("PCToSPOffset: no frame table")
-	}
-	var m frameMachine
-	// Assume the first info unit is the same as us. Extremely likely. TODO?
-	if len(d.unit) == 0 {
-		return 0, fmt.Errorf("PCToSPOffset: no info section")
-	}
-	buf := makeBuf(d, &d.unit[0], "frame", 0, d.frame)
-	for len(buf.data) > 0 {
-		offset, err := m.evalCompilationUnit(&buf, pc)
-		if err != nil {
-			return 0, err
-		}
-		return offset, nil
-	}
-	return 0, fmt.Errorf("PCToSPOffset: no frame defined for PC %#x", pc)
-}
-
-// Call Frame instructions. Figure 40, page 181.
-// Structure is high two bits plus low 6 bits specified by + in comment.
-// Some take one or two operands.
-const (
-	frameNop              = 0<<6 + 0x00
-	frameAdvanceLoc       = 1<<6 + 0x00 // + delta
-	frameOffset           = 2<<6 + 0x00 // + register op: ULEB128 offset
-	frameRestore          = 3<<6 + 0x00 // + register
-	frameSetLoc           = 0<<6 + 0x01 // op: address
-	frameAdvanceLoc1      = 0<<6 + 0x02 // op: 1-byte delta
-	frameAdvanceLoc2      = 0<<6 + 0x03 // op: 2-byte delta
-	frameAdvanceLoc4      = 0<<6 + 0x04 // op: 4-byte delta
-	frameOffsetExtended   = 0<<6 + 0x05 // ops: ULEB128 register ULEB128 offset
-	frameRestoreExtended  = 0<<6 + 0x06 // op: ULEB128 register
-	frameUndefined        = 0<<6 + 0x07 // op: ULEB128 register
-	frameSameValue        = 0<<6 + 0x08 // op: ULEB128 register
-	frameRegister         = 0<<6 + 0x09 // op: ULEB128 register ULEB128 register
-	frameRememberState    = 0<<6 + 0x0a
-	frameRestoreState     = 0<<6 + 0x0b
-	frameDefCFA           = 0<<6 + 0x0c // op: ULEB128 register ULEB128 offset
-	frameDefCFARegister   = 0<<6 + 0x0d // op: ULEB128 register
-	frameDefCFAOffset     = 0<<6 + 0x0e // op: ULEB128 offset
-	frameDefCFAExpression = 0<<6 + 0x0f // op: BLOCK
-	frameExpression       = 0<<6 + 0x10 // op: ULEB128 register BLOCK
-	frameOffsetExtendedSf = 0<<6 + 0x11 // op: ULEB128 register SLEB128 offset
-	frameDefCFASf         = 0<<6 + 0x12 // op: ULEB128 register SLEB128 offset
-	frameDefCFAOffsetSf   = 0<<6 + 0x13 // op: SLEB128 offset
-	frameValOffset        = 0<<6 + 0x14 // op: ULEB128 ULEB128
-	frameValOffsetSf      = 0<<6 + 0x15 // op: ULEB128 SLEB128
-	frameValExpression    = 0<<6 + 0x16 // op: ULEB128 BLOCK
-	frameLoUser           = 0<<6 + 0x1c
-	frameHiUser           = 0<<6 + 0x3f
-)
-
-// frameMachine represents the PC/SP engine.
-// Section 6.4, page 129.
-type frameMachine struct {
-	// Initial values from CIE.
-	version               uint8  // Version number, "independent of DWARF version"
-	augmentation          string // Augmentation; treated as unexpected for now. TODO.
-	addressSize           uint8  // In DWARF v4 and above. Size of a target address.
-	segmentSize           uint8  // In DWARF v4 and above. Size of a segment selector.
-	codeAlignmentFactor   uint64 // Unit of code size in advance instructions.
-	dataAlignmentFactor   int64  // Unit of data size in certain offset instructions.
-	returnAddressRegister int    // Pseudo-register (actually data column) representing return address.
-	returnRegisterOffset  int64  // Offset to saved PC from CFA in bytes.
-	// CFA definition.
-	cfaRegister int   // Which register represents the SP.
-	cfaOffset   int64 // CFA offset value.
-	// Running machine.
-	location uint64
-}
-
-// evalCompilationUnit scans the frame data for one compilation unit to retrieve
-// the offset information for the specified pc.
-func (m *frameMachine) evalCompilationUnit(b *buf, pc uint64) (int64, error) {
-	err := m.parseCIE(b)
-	if err != nil {
-		return 0, err
-	}
-	for {
-		offset, found, err := m.scanFDE(b, pc)
-		if err != nil {
-			return 0, err
-		}
-		if found {
-			return offset, nil
-		}
-	}
-}
-
-// parseCIE assumes the incoming buffer starts with a CIE block and parses it
-// to initialize a frameMachine.
-func (m *frameMachine) parseCIE(allBuf *buf) error {
-	length := int(allBuf.uint32())
-	if len(allBuf.data) < length {
-		return fmt.Errorf("CIE parse error: too short")
-	}
-	// Create buffer for just this section.
-	b := allBuf.slice(length)
-	cie := b.uint32()
-	if cie != 0xFFFFFFFF {
-		return fmt.Errorf("CIE parse error: not CIE: %x", cie)
-	}
-	m.version = b.uint8()
-	if m.version != 3 && m.version != 4 {
-		return fmt.Errorf("CIE parse error: unsupported version %d", m.version)
-	}
-	m.augmentation = b.string()
-	if len(m.augmentation) > 0 {
-		return fmt.Errorf("CIE: can't handled augmentation string %q", m.augmentation)
-	}
-	if m.version >= 4 {
-		m.addressSize = b.uint8()
-		m.segmentSize = b.uint8()
-	} else {
-		// Unused. Gc generates version 3, so these values will not be
-		// set, but they are also not used so it's OK.
-	}
-	m.codeAlignmentFactor = b.uint()
-	m.dataAlignmentFactor = b.int()
-	m.returnAddressRegister = int(b.uint())
-
-	// Initial instructions. At least for Go, establishes SP register number
-	// and initial value of CFA offset at start of function.
-	_, err := m.run(&b, ^uint64(0))
-	if err != nil {
-		return err
-	}
-
-	// There's padding, but we can ignore it.
-	return nil
-}
-
-// scanFDE assumes the incoming buffer starts with a FDE block and parses it
-// to run a frameMachine and, if the PC is represented in its range, return
-// the CFA offset for that PC. The boolean returned reports whether the
-// PC is in range for this FDE.
-func (m *frameMachine) scanFDE(allBuf *buf, pc uint64) (int64, bool, error) {
-	length := int(allBuf.uint32())
-	if len(allBuf.data) < length {
-		return 0, false, fmt.Errorf("FDE parse error: too short")
-	}
-	if length <= 0 {
-		if length == 0 {
-			// EOF.
-			return 0, false, fmt.Errorf("PC %#x not found in PC/SP table", pc)
-		}
-		return 0, false, fmt.Errorf("bad FDE length %d", length)
-	}
-	// Create buffer for just this section.
-	b := allBuf.slice(length)
-	cieOffset := b.uint32() // TODO assumes 32 bits.
-	// Expect 0: first CIE in this segment. TODO.
-	if cieOffset != 0 {
-		return 0, false, fmt.Errorf("FDE parse error: bad CIE offset: %.2x", cieOffset)
-	}
-	// Initial location.
-	m.location = b.addr()
-	addressRange := b.addr()
-	// If the PC is not in this function, there's no point in executing the instructions.
-	if pc < m.location || m.location+addressRange <= pc {
-		return 0, false, nil
-	}
-	// The PC appears in this FDE. Scan to find the location.
-	offset, err := m.run(&b, pc)
-	if err != nil {
-		return 0, false, err
-	}
-
-	// There's padding, but we can ignore it.
-	return offset, true, nil
-}
-
-// run executes the instructions in the buffer, which has been sliced to contain
-// only the data for this block. When we run out of data, we return.
-// Since we are only called when we know the PC is in this block, reaching
-// EOF is not an error, it just means the final CFA definition matches the
-// tail of the block that holds the PC.
-// The return value is the CFA at the end of the block or the PC, whichever
-// comes first.
-func (m *frameMachine) run(b *buf, pc uint64) (int64, error) {
-	// We run the machine at location == PC because if the PC is at the first
-	// instruction of a block, the definition of its offset arrives as an
-	// offset-defining operand after the PC is set to that location.
-	for m.location <= pc && len(b.data) > 0 {
-		op := b.uint8()
-		// Ops with embedded operands
-		switch op & 0xC0 {
-		case frameAdvanceLoc: // (6.4.2.1)
-			// delta in low bits
-			m.location += uint64(op & 0x3F)
-			continue
-		case frameOffset: // (6.4.2.3)
-			// Register in low bits; ULEB128 offset.
-			// For Go binaries we only see this in the CIE for the return address register.
-			if int(op&0x3F) != m.returnAddressRegister {
-				return 0, fmt.Errorf("invalid frameOffset register R%d should be R%d", op&0x3f, m.returnAddressRegister)
-			}
-			m.returnRegisterOffset = int64(b.uint()) * m.dataAlignmentFactor
-			continue
-		case frameRestore: // (6.4.2.3)
-			// register in low bits
-			return 0, fmt.Errorf("unimplemented frameRestore(R%d)\n", op&0x3F)
-		}
-
-		// The remaining ops do not have embedded operands.
-
-		switch op {
-		// Row creation instructions (6.4.2.1)
-		case frameNop:
-		case frameSetLoc: // op: address
-			return 0, fmt.Errorf("unimplemented setloc") // what size is operand?
-		case frameAdvanceLoc1: // op: 1-byte delta
-			m.location += uint64(b.uint8())
-		case frameAdvanceLoc2: // op: 2-byte delta
-			m.location += uint64(b.uint16())
-		case frameAdvanceLoc4: // op: 4-byte delta
-			m.location += uint64(b.uint32())
-
-		// CFA definition instructions (6.4.2.2)
-		case frameDefCFA: // op: ULEB128 register ULEB128 offset
-			m.cfaRegister = int(b.int())
-			m.cfaOffset = int64(b.uint())
-		case frameDefCFASf: // op: ULEB128 register SLEB128 offset
-			return 0, fmt.Errorf("unimplemented frameDefCFASf")
-		case frameDefCFARegister: // op: ULEB128 register
-			return 0, fmt.Errorf("unimplemented frameDefCFARegister")
-		case frameDefCFAOffset: // op: ULEB128 offset
-			return 0, fmt.Errorf("unimplemented frameDefCFAOffset")
-		case frameDefCFAOffsetSf: // op: SLEB128 offset
-			offset := b.int()
-			m.cfaOffset = offset * m.dataAlignmentFactor
-			// TODO: Verify we are using a factored offset.
-		case frameDefCFAExpression: // op: BLOCK
-			return 0, fmt.Errorf("unimplemented frameDefCFAExpression")
-
-		// Register Rule instructions (6.4.2.3)
-		case frameOffsetExtended: // ops: ULEB128 register ULEB128 offset
-			// The same as frameOffset, but with the register specified in an operand.
-			reg := b.uint()
-			// For Go binaries we only see this in the CIE for the return address register.
-			if reg != uint64(m.returnAddressRegister) {
-				return 0, fmt.Errorf("invalid frameOffsetExtended: register R%d should be R%d", reg, m.returnAddressRegister)
-			}
-			m.returnRegisterOffset = int64(b.uint()) * m.dataAlignmentFactor
-		case frameRestoreExtended: // op: ULEB128 register
-			return 0, fmt.Errorf("unimplemented frameRestoreExtended")
-		case frameUndefined: // op: ULEB128 register; unimplemented
-			return 0, fmt.Errorf("unimplemented frameUndefined")
-		case frameSameValue: // op: ULEB128 register
-			return 0, fmt.Errorf("unimplemented frameSameValue")
-		case frameRegister: // op: ULEB128 register ULEB128 register
-			return 0, fmt.Errorf("unimplemented frameRegister")
-		case frameRememberState:
-			return 0, fmt.Errorf("unimplemented frameRememberState")
-		case frameRestoreState:
-			return 0, fmt.Errorf("unimplemented frameRestoreState")
-		case frameExpression: // op: ULEB128 register BLOCK
-			return 0, fmt.Errorf("unimplemented frameExpression")
-		case frameOffsetExtendedSf: // op: ULEB128 register SLEB128 offset
-			return 0, fmt.Errorf("unimplemented frameOffsetExtended_sf")
-		case frameValOffset: // op: ULEB128 ULEB128
-			return 0, fmt.Errorf("unimplemented frameValOffset")
-		case frameValOffsetSf: // op: ULEB128 SLEB128
-			return 0, fmt.Errorf("unimplemented frameValOffsetSf")
-		case frameValExpression: // op: ULEB128 BLOCK
-			return 0, fmt.Errorf("unimplemented frameValExpression")
-
-		default:
-			if frameLoUser <= op && op <= frameHiUser {
-				return 0, fmt.Errorf("unknown user-defined frame op %#x", op)
-			}
-			return 0, fmt.Errorf("unknown frame op %#x", op)
-		}
-	}
-	return m.cfaOffset, nil
-}
diff --git a/dwarf/frame_test.go b/dwarf/frame_test.go
deleted file mode 100644
index 2bf41f5..0000000
--- a/dwarf/frame_test.go
+++ /dev/null
@@ -1,128 +0,0 @@
-// Copyright 2014 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 dwarf_test
-
-import (
-	"fmt"
-	"io/ioutil"
-	"os"
-	"os/exec"
-	"path/filepath"
-	"runtime"
-	"strings"
-	"testing"
-
-	"golang.org/x/debug/dwarf"
-)
-
-var (
-	pcspTempDir    string
-	pcsptestBinary string
-)
-
-func doPCToSPTest(self bool) bool {
-	// For now, only works on amd64 platforms.
-	if runtime.GOARCH != "amd64" {
-		return false
-	}
-	// Self test reads test binary; only works on Linux or Mac.
-	if self {
-		if runtime.GOOS != "linux" && runtime.GOOS != "darwin" {
-			return false
-		}
-	}
-	// Command below expects "sh", so Unix.
-	if runtime.GOOS == "windows" || runtime.GOOS == "plan9" {
-		return false
-	}
-	if pcsptestBinary != "" {
-		return true
-	}
-	var err error
-	pcspTempDir, err = ioutil.TempDir("", "pcsptest")
-	if err != nil {
-		panic(err)
-	}
-	if strings.Contains(pcspTempDir, " ") {
-		panic("unexpected space in tempdir")
-	}
-	// This command builds pcsptest from testdata/pcsptest.go.
-	pcsptestBinary = filepath.Join(pcspTempDir, "pcsptest")
-	command := fmt.Sprintf("go tool compile -o %s.6 testdata/pcsptest.go && go tool link -H %s -o %s %s.6",
-		pcsptestBinary, runtime.GOOS, pcsptestBinary, pcsptestBinary)
-	cmd := exec.Command("sh", "-c", command)
-	cmd.Stdout = os.Stdout
-	cmd.Stderr = os.Stderr
-	if err := cmd.Run(); err != nil {
-		panic(err)
-	}
-	return true
-}
-
-func endPCToSPTest() {
-	if pcspTempDir != "" {
-		os.RemoveAll(pcspTempDir)
-		pcspTempDir = ""
-		pcsptestBinary = ""
-	}
-}
-
-func TestPCToSPOffset(t *testing.T) {
-	if !doPCToSPTest(false) {
-		return
-	}
-	defer endPCToSPTest()
-
-	data, err := getData(pcsptestBinary)
-	if err != nil {
-		t.Fatal(err)
-	}
-	entry, err := data.LookupFunction("main.test")
-	if err != nil {
-		t.Fatal("lookup startPC:", err)
-	}
-	startPC, ok := entry.Val(dwarf.AttrLowpc).(uint64)
-	if !ok {
-		t.Fatal(`DWARF data for function "main.test" has no low PC`)
-	}
-	endPC, ok := entry.Val(dwarf.AttrHighpc).(uint64)
-	if !ok {
-		t.Fatal(`DWARF data for function "main.test" has no high PC`)
-	}
-
-	const addrSize = 8 // TODO: Assumes amd64.
-	const argSize = 8  // Defined by int64 arguments in test binary.
-
-	// On 64-bit machines, the first offset must be one address size,
-	// for the return PC.
-	offset, err := data.PCToSPOffset(startPC)
-	if err != nil {
-		t.Fatal("startPC:", err)
-	}
-	if offset != addrSize {
-		t.Fatalf("expected %d at start of function; got %d", addrSize, offset)
-	}
-	// On 64-bit machines, expect some 8s and some 32s. (See the
-	// comments in testdata/pcsptest.go.
-	// TODO: The test could be stronger, but not much unless we
-	// disassemble the binary.
-	count := make(map[int64]int)
-	for pc := startPC; pc < endPC; pc++ {
-		offset, err := data.PCToSPOffset(pc)
-		if err != nil {
-			t.Fatal("scanning function:", err)
-		}
-		count[offset]++
-	}
-	if len(count) != 2 {
-		t.Errorf("expected 2 offset values, got %d; counts are: %v", len(count), count)
-	}
-	if count[addrSize] == 0 {
-		t.Errorf("expected some values at offset %d; got %v", addrSize, count)
-	}
-	if count[addrSize+3*argSize] == 0 {
-		t.Errorf("expected some values at offset %d; got %v", addrSize+3*argSize, count)
-	}
-}
diff --git a/dwarf/line.go b/dwarf/line.go
deleted file mode 100644
index 2f47739..0000000
--- a/dwarf/line.go
+++ /dev/null
@@ -1,448 +0,0 @@
-// Copyright 2014 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 dwarf
-
-// This file implements the mapping from PC to lines.
-// TODO: Find a way to test this properly.
-
-// http://www.dwarfstd.org/doc/DWARF4.pdf Section 6.2 page 108
-
-import (
-	"fmt"
-	"sort"
-	"strings"
-)
-
-// PCToLine returns the file and line number corresponding to the PC value.
-// It returns an error if a correspondence cannot be found.
-func (d *Data) PCToLine(pc uint64) (file string, line uint64, err error) {
-	c := d.pcToLineEntries
-	if len(c) == 0 {
-		return "", 0, fmt.Errorf("PCToLine: no line table")
-	}
-	i := sort.Search(len(c), func(i int) bool { return c[i].pc > pc }) - 1
-	// c[i] is now the entry in pcToLineEntries with the largest pc that is not
-	// larger than the query pc.
-	// The search has failed if:
-	// - All pcs in c were larger than the query pc (i == -1).
-	// - c[i] marked the end of a sequence of instructions (c[i].file == 0).
-	// - c[i] is the last element of c, and isn't the end of a sequence of
-	//   instructions, and the search pc is much larger than c[i].pc.  In this
-	//   case, we don't know the range of the last instruction, but the search
-	//   pc is probably past it.
-	if i == -1 || c[i].file == 0 || (i+1 == len(c) && pc-c[i].pc > 1024) {
-		return "", 0, fmt.Errorf("no source line defined for PC %#x", pc)
-	}
-	if c[i].file >= uint64(len(d.sourceFiles)) {
-		return "", 0, fmt.Errorf("invalid file number in DWARF data")
-	}
-	return d.sourceFiles[c[i].file], c[i].line, nil
-}
-
-// LineToBreakpointPCs returns the PCs that should be used as breakpoints
-// corresponding to the given file and line number.
-// It returns an empty slice if no PCs were found.
-func (d *Data) LineToBreakpointPCs(file string, line uint64) ([]uint64, error) {
-	compDir := d.compilationDirectory()
-
-	// Find the closest match in the executable for the specified file.
-	// We choose the file with the largest number of path components matching
-	// at the end of the name. If there is a tie, we prefer files that are
-	// under the compilation directory.  If there is still a tie, we choose
-	// the file with the shortest name.
-	// TODO: handle duplicate file names in the DWARF?
-	var bestFile struct {
-		fileNum    uint64 // Index of the file in the DWARF data.
-		components int    // Number of matching path components.
-		length     int    // Length of the filename.
-		underComp  bool   // File is under the compilation directory.
-	}
-	for filenum, filename := range d.sourceFiles {
-		c := matchingPathComponentSuffixSize(filename, file)
-		underComp := strings.HasPrefix(filename, compDir)
-		better := false
-		if c != bestFile.components {
-			better = c > bestFile.components
-		} else if underComp != bestFile.underComp {
-			better = underComp
-		} else {
-			better = len(filename) < bestFile.length
-		}
-		if better {
-			bestFile.fileNum = uint64(filenum)
-			bestFile.components = c
-			bestFile.length = len(filename)
-			bestFile.underComp = underComp
-		}
-	}
-	if bestFile.components == 0 {
-		return nil, fmt.Errorf("couldn't find file %q", file)
-	}
-
-	c := d.lineToPCEntries[bestFile.fileNum]
-	// c contains all (pc, line) pairs for the appropriate file.
-	start := sort.Search(len(c), func(i int) bool { return c[i].line >= line })
-	end := sort.Search(len(c), func(i int) bool { return c[i].line > line })
-	// c[i].line == line for all i in the range [start, end).
-	pcs := make([]uint64, 0, end-start)
-	for i := start; i < end; i++ {
-		pcs = append(pcs, c[i].pc)
-	}
-	return pcs, nil
-}
-
-// compilationDirectory finds the first compilation unit entry in d and returns
-// the compilation directory contained in it.
-// If it fails, it returns the empty string.
-func (d *Data) compilationDirectory() string {
-	r := d.Reader()
-	for {
-		entry, err := r.Next()
-		if entry == nil || err != nil {
-			return ""
-		}
-		if entry.Tag == TagCompileUnit {
-			name, _ := entry.Val(AttrCompDir).(string)
-			return name
-		}
-	}
-}
-
-// matchingPathComponentSuffixSize returns the largest n such that the last n
-// components of the paths p1 and p2 are equal.
-// e.g. matchingPathComponentSuffixSize("a/b/x/y.go", "b/a/x/y.go") returns 2.
-func matchingPathComponentSuffixSize(p1, p2 string) int {
-	// TODO: deal with other path separators.
-	c1 := strings.Split(p1, "/")
-	c2 := strings.Split(p2, "/")
-	min := len(c1)
-	if len(c2) < min {
-		min = len(c2)
-	}
-	var n int
-	for n = 0; n < min; n++ {
-		if c1[len(c1)-1-n] != c2[len(c2)-1-n] {
-			break
-		}
-	}
-	return n
-}
-
-// Standard opcodes. Figure 37, page 178.
-// If an opcode >= lineMachine.prologue.opcodeBase, it is a special
-// opcode rather than the opcode defined in this table.
-const (
-	lineStdCopy             = 0x01
-	lineStdAdvancePC        = 0x02
-	lineStdAdvanceLine      = 0x03
-	lineStdSetFile          = 0x04
-	lineStdSetColumn        = 0x05
-	lineStdNegateStmt       = 0x06
-	lineStdSetBasicBlock    = 0x07
-	lineStdConstAddPC       = 0x08
-	lineStdFixedAdvancePC   = 0x09
-	lineStdSetPrologueEnd   = 0x0a
-	lineStdSetEpilogueBegin = 0x0b
-	lineStdSetISA           = 0x0c
-)
-
-// Extended opcodes. Figure 38, page 179.
-const (
-	lineStartExtendedOpcode = 0x00 // Not defined as a named constant in the spec.
-	lineExtEndSequence      = 0x01
-	lineExtSetAddress       = 0x02
-	lineExtDefineFile       = 0x03
-	lineExtSetDiscriminator = 0x04 // New in version 4.
-	lineExtLoUser           = 0x80
-	lineExtHiUser           = 0xff
-)
-
-// lineHeader holds the information stored in the header of the line table for a
-// single compilation unit.
-// Section 6.2.4, page 112.
-type lineHeader struct {
-	unitLength           int
-	version              int
-	headerLength         int
-	minInstructionLength int
-	maxOpsPerInstruction int
-	defaultIsStmt        bool
-	lineBase             int
-	lineRange            int
-	opcodeBase           byte
-	stdOpcodeLengths     []byte
-	include              []string   // entry 0 is empty; means current directory
-	file                 []lineFile // entry 0 is empty.
-}
-
-// lineFile represents a file name stored in the PC/line table, usually in the header.
-type lineFile struct {
-	name   string
-	index  int // index into include directories
-	time   int // implementation-defined time of last modification
-	length int // length in bytes, 0 if not available.
-}
-
-// lineMachine holds the registers evaluated during executing of the PC/line mapping engine.
-// Section 6.2.2, page 109.
-type lineMachine struct {
-	// The program-counter value corresponding to a machine instruction generated by the compiler.
-	address uint64
-
-	// An unsigned integer representing the index of an operation within a VLIW
-	// instruction. The index of the first operation is 0. For non-VLIW
-	// architectures, this register will always be 0.
-	// The address and op_index registers, taken together, form an operation
-	// pointer that can reference any individual operation with the instruction
-	// stream.
-	opIndex uint64
-
-	// An unsigned integer indicating the identity of the source file corresponding to a machine instruction.
-	file uint64
-
-	// An unsigned integer indicating a source line number. Lines are numbered
-	// beginning at 1. The compiler may emit the value 0 in cases where an
-	// instruction cannot be attributed to any source line.
-	line uint64
-
-	// An unsigned integer indicating a column number within a source line.
-	// Columns are numbered beginning at 1. The value 0 is reserved to indicate
-	// that a statement begins at the “left edge” of the line.
-	column uint64
-
-	// A boolean indicating that the current instruction is a recommended
-	// breakpoint location. A recommended breakpoint location is intended to
-	// “represent” a line, a statement and/or a semantically distinct subpart of a
-	// statement.
-	isStmt bool
-
-	// A boolean indicating that the current instruction is the beginning of a basic
-	// block.
-	basicBlock bool
-
-	// A boolean indicating that the current address is that of the first byte after
-	// the end of a sequence of target machine instructions. end_sequence
-	// terminates a sequence of lines; therefore other information in the same
-	// row is not meaningful.
-	endSequence bool
-
-	// A boolean indicating that the current address is one (of possibly many)
-	// where execution should be suspended for an entry breakpoint of a
-	// function.
-	prologueEnd bool
-
-	// A boolean indicating that the current address is one (of possibly many)
-	// where execution should be suspended for an exit breakpoint of a function.
-	epilogueBegin bool
-
-	// An unsigned integer whose value encodes the applicable instruction set
-	// architecture for the current instruction.
-	// The encoding of instruction sets should be shared by all users of a given
-	// architecture. It is recommended that this encoding be defined by the ABI
-	// authoring committee for each architecture.
-	isa uint64
-
-	// An unsigned integer identifying the block to which the current instruction
-	// belongs. Discriminator values are assigned arbitrarily by the DWARF
-	// producer and serve to distinguish among multiple blocks that may all be
-	// associated with the same source file, line, and column. Where only one
-	// block exists for a given source position, the discriminator value should be
-	// zero.
-	discriminator uint64
-
-	// The header for the current compilation unit.
-	// Not an actual register, but stored here for cleanliness.
-	header lineHeader
-}
-
-// parseHeader parses the header describing the compilation unit in the line
-// table starting at the specified offset.
-func (m *lineMachine) parseHeader(b *buf) error {
-	m.header = lineHeader{}
-	m.header.unitLength = int(b.uint32()) // Note: We are assuming 32-bit DWARF format.
-	if m.header.unitLength > len(b.data) {
-		return fmt.Errorf("DWARF: bad PC/line header length")
-	}
-	m.header.version = int(b.uint16())
-	m.header.headerLength = int(b.uint32())
-	m.header.minInstructionLength = int(b.uint8())
-	if m.header.version >= 4 {
-		m.header.maxOpsPerInstruction = int(b.uint8())
-	} else {
-		m.header.maxOpsPerInstruction = 1
-	}
-	m.header.defaultIsStmt = b.uint8() != 0
-	m.header.lineBase = int(int8(b.uint8()))
-	m.header.lineRange = int(b.uint8())
-	m.header.opcodeBase = b.uint8()
-	m.header.stdOpcodeLengths = make([]byte, m.header.opcodeBase-1)
-	copy(m.header.stdOpcodeLengths, b.bytes(int(m.header.opcodeBase-1)))
-	m.header.include = make([]string, 1) // First entry is empty; file index entries are 1-indexed.
-	// Includes
-	for {
-		name := b.string()
-		if name == "" {
-			break
-		}
-		m.header.include = append(m.header.include, name)
-	}
-	// Files
-	m.header.file = make([]lineFile, 1, 10) // entries are 1-indexed in line number program.
-	for {
-		name := b.string()
-		if name == "" {
-			break
-		}
-		index := b.uint()
-		time := b.uint()
-		length := b.uint()
-		f := lineFile{
-			name:   name,
-			index:  int(index),
-			time:   int(time),
-			length: int(length),
-		}
-		m.header.file = append(m.header.file, f)
-	}
-	return nil
-}
-
-// Special opcodes, page 117.
-// There are seven steps to processing special opcodes.  We break them up here
-// because the caller needs to output a row between steps 2 and 4, and because
-// we need to perform just step 2 for the opcode DW_LNS_const_add_pc.
-
-func (m *lineMachine) specialOpcodeStep1(opcode byte) {
-	adjustedOpcode := int(opcode - m.header.opcodeBase)
-	lineAdvance := m.header.lineBase + (adjustedOpcode % m.header.lineRange)
-	m.line += uint64(lineAdvance)
-}
-
-func (m *lineMachine) specialOpcodeStep2(opcode byte) {
-	adjustedOpcode := int(opcode - m.header.opcodeBase)
-	advance := adjustedOpcode / m.header.lineRange
-	delta := (int(m.opIndex) + advance) / m.header.maxOpsPerInstruction
-	m.address += uint64(m.header.minInstructionLength * delta)
-	m.opIndex = (m.opIndex + uint64(advance)) % uint64(m.header.maxOpsPerInstruction)
-}
-
-func (m *lineMachine) specialOpcodeSteps4To7() {
-	m.basicBlock = false
-	m.prologueEnd = false
-	m.epilogueBegin = false
-	m.discriminator = 0
-}
-
-// evalCompilationUnit reads the next compilation unit and calls f at each output row.
-// Line machine execution continues while f returns true.
-func (m *lineMachine) evalCompilationUnit(b *buf, f func(m *lineMachine) (cont bool)) error {
-	m.reset()
-	for len(b.data) > 0 {
-		op := b.uint8()
-		if op >= m.header.opcodeBase {
-			m.specialOpcodeStep1(op)
-			m.specialOpcodeStep2(op)
-			// Step 3 is to output a row, so we call f here.
-			if !f(m) {
-				return nil
-			}
-			m.specialOpcodeSteps4To7()
-			continue
-		}
-		switch op {
-		case lineStartExtendedOpcode:
-			if len(b.data) == 0 {
-				return fmt.Errorf("DWARF: short extended opcode (1)")
-			}
-			size := b.uint()
-			if uint64(len(b.data)) < size {
-				return fmt.Errorf("DWARF: short extended opcode (2)")
-			}
-			op = b.uint8()
-			switch op {
-			case lineExtEndSequence:
-				m.endSequence = true
-				if !f(m) {
-					return nil
-				}
-				if len(b.data) == 0 {
-					return nil
-				}
-				m.reset()
-			case lineExtSetAddress:
-				m.address = b.addr()
-				m.opIndex = 0
-			case lineExtDefineFile:
-				return fmt.Errorf("DWARF: unimplemented define_file op")
-			case lineExtSetDiscriminator:
-				discriminator := b.uint()
-				m.discriminator = discriminator
-			default:
-				return fmt.Errorf("DWARF: unknown extended opcode %#x", op)
-			}
-		case lineStdCopy:
-			if !f(m) {
-				return nil
-			}
-			m.discriminator = 0
-			m.basicBlock = false
-			m.prologueEnd = false
-			m.epilogueBegin = false
-		case lineStdAdvancePC:
-			advance := b.uint()
-			delta := (int(m.opIndex) + int(advance)) / m.header.maxOpsPerInstruction
-			m.address += uint64(m.header.minInstructionLength * delta)
-			m.opIndex = (m.opIndex + uint64(advance)) % uint64(m.header.maxOpsPerInstruction)
-			m.basicBlock = false
-			m.prologueEnd = false
-			m.epilogueBegin = false
-			m.discriminator = 0
-		case lineStdAdvanceLine:
-			advance := b.int()
-			m.line = uint64(int64(m.line) + advance)
-		case lineStdSetFile:
-			index := b.uint()
-			m.file = index
-		case lineStdSetColumn:
-			column := b.uint()
-			m.column = column
-		case lineStdNegateStmt:
-			m.isStmt = !m.isStmt
-		case lineStdSetBasicBlock:
-			m.basicBlock = true
-		case lineStdFixedAdvancePC:
-			m.address += uint64(b.uint16())
-			m.opIndex = 0
-		case lineStdSetPrologueEnd:
-			m.prologueEnd = true
-		case lineStdSetEpilogueBegin:
-			m.epilogueBegin = true
-		case lineStdSetISA:
-			m.isa = b.uint()
-		case lineStdConstAddPC:
-			// Update the the address and op_index registers.
-			m.specialOpcodeStep2(255)
-		default:
-			panic("not reached")
-		}
-	}
-	return fmt.Errorf("DWARF: unexpected end of line number information")
-}
-
-// reset sets the machine's registers to the initial state. Page 111.
-func (m *lineMachine) reset() {
-	m.address = 0
-	m.opIndex = 0
-	m.file = 1
-	m.line = 1
-	m.column = 0
-	m.isStmt = m.header.defaultIsStmt
-	m.basicBlock = false
-	m.endSequence = false
-	m.prologueEnd = false
-	m.epilogueBegin = false
-	m.isa = 0
-	m.discriminator = 0
-}
diff --git a/dwarf/open.go b/dwarf/open.go
deleted file mode 100644
index a13c6ed..0000000
--- a/dwarf/open.go
+++ /dev/null
@@ -1,94 +0,0 @@
-// Copyright 2009 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 dwarf provides access to DWARF debugging information loaded from
-// executable files, as defined in the DWARF 2.0 Standard at
-// http://dwarfstd.org/doc/dwarf-2.0.0.pdf
-package dwarf // import "golang.org/x/debug/dwarf"
-
-import "encoding/binary"
-
-// Data represents the DWARF debugging information
-// loaded from an executable file (for example, an ELF or Mach-O executable).
-type Data struct {
-	// raw data
-	abbrev   []byte
-	aranges  []byte
-	frame    []byte
-	info     []byte
-	line     []byte
-	pubnames []byte
-	ranges   []byte
-	str      []byte
-
-	// parsed data
-	abbrevCache     map[uint32]abbrevTable
-	order           binary.ByteOrder
-	typeCache       map[Offset]Type
-	typeSigs        map[uint64]*typeUnit
-	unit            []unit
-	sourceFiles     []string // source files listed in .debug_line.
-	nameCache                // map from name to top-level entries in .debug_info.
-	pcToFuncEntries          // cache of .debug_info data for function bounds.
-	pcToLineEntries          // cache of .debug_line data, used for efficient PC-to-line mapping.
-	lineToPCEntries          // cache of .debug_line data, used for efficient line-to-[]PC mapping.
-}
-
-// New returns a new Data object initialized from the given parameters.
-// Rather than calling this function directly, clients should typically use
-// the DWARF method of the File type of the appropriate package debug/elf,
-// debug/macho, or debug/pe.
-//
-// The []byte arguments are the data from the corresponding debug section
-// in the object file; for example, for an ELF object, abbrev is the contents of
-// the ".debug_abbrev" section.
-func New(abbrev, aranges, frame, info, line, pubnames, ranges, str []byte) (*Data, error) {
-	d := &Data{
-		abbrev:      abbrev,
-		aranges:     aranges,
-		frame:       frame,
-		info:        info,
-		line:        line,
-		pubnames:    pubnames,
-		ranges:      ranges,
-		str:         str,
-		abbrevCache: make(map[uint32]abbrevTable),
-		typeCache:   make(map[Offset]Type),
-		typeSigs:    make(map[uint64]*typeUnit),
-	}
-
-	// Sniff .debug_info to figure out byte order.
-	// bytes 4:6 are the version, a tiny 16-bit number (1, 2, 3).
-	if len(d.info) < 6 {
-		return nil, DecodeError{"info", Offset(len(d.info)), "too short"}
-	}
-	x, y := d.info[4], d.info[5]
-	switch {
-	case x == 0 && y == 0:
-		return nil, DecodeError{"info", 4, "unsupported version 0"}
-	case x == 0:
-		d.order = binary.BigEndian
-	case y == 0:
-		d.order = binary.LittleEndian
-	default:
-		return nil, DecodeError{"info", 4, "cannot determine byte order"}
-	}
-
-	u, err := d.parseUnits()
-	if err != nil {
-		return nil, err
-	}
-	d.unit = u
-	d.buildInfoCaches()
-	d.buildLineCaches()
-	return d, nil
-}
-
-// AddTypes will add one .debug_types section to the DWARF data.  A
-// typical object with DWARF version 4 debug info will have multiple
-// .debug_types sections.  The name is used for error reporting only,
-// and serves to distinguish one .debug_types section from another.
-func (d *Data) AddTypes(name string, types []byte) error {
-	return d.parseTypes(name, types)
-}
diff --git a/dwarf/pclntab_test.go b/dwarf/pclntab_test.go
deleted file mode 100644
index 31ceb78..0000000
--- a/dwarf/pclntab_test.go
+++ /dev/null
@@ -1,156 +0,0 @@
-// Copyright 2009 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 dwarf_test
-
-// Stripped-down, simplified version of ../../gosym/pclntab_test.go
-
-import (
-	"fmt"
-	"io/ioutil"
-	"os"
-	"os/exec"
-	"path/filepath"
-	"runtime"
-	"strings"
-	"testing"
-
-	. "golang.org/x/debug/dwarf"
-	"golang.org/x/debug/elf"
-	"golang.org/x/debug/macho"
-)
-
-var (
-	pclineTempDir    string
-	pclinetestBinary string
-)
-
-func dotest(self bool) bool {
-	// For now, only works on amd64 platforms.
-	if runtime.GOARCH != "amd64" {
-		return false
-	}
-	// Self test reads test binary; only works on Linux or Mac.
-	if self {
-		if runtime.GOOS != "linux" && runtime.GOOS != "darwin" {
-			return false
-		}
-	}
-	// Command below expects "sh", so Unix.
-	if runtime.GOOS == "windows" || runtime.GOOS == "plan9" {
-		return false
-	}
-	if pclinetestBinary != "" {
-		return true
-	}
-	var err error
-	pclineTempDir, err = ioutil.TempDir("", "pclinetest")
-	if err != nil {
-		panic(err)
-	}
-	if strings.Contains(pclineTempDir, " ") {
-		panic("unexpected space in tempdir")
-	}
-	// This command builds pclinetest from ../../gosym/pclinetest.asm;
-	// the resulting binary looks like it was built from pclinetest.s,
-	// but we have renamed it to keep it away from the go tool.
-	pclinetestBinary = filepath.Join(pclineTempDir, "pclinetest")
-	command := fmt.Sprintf("go tool asm -o %s.6 ../gosym/pclinetest.asm && go tool link -H %s -E main -o %s %s.6",
-		pclinetestBinary, runtime.GOOS, pclinetestBinary, pclinetestBinary)
-	cmd := exec.Command("sh", "-c", command)
-	cmd.Stdout = os.Stdout
-	cmd.Stderr = os.Stderr
-	if err := cmd.Run(); err != nil {
-		panic(err)
-	}
-	return true
-}
-
-func endtest() {
-	if pclineTempDir != "" {
-		os.RemoveAll(pclineTempDir)
-		pclineTempDir = ""
-		pclinetestBinary = ""
-	}
-}
-
-func getData(file string) (*Data, error) {
-	switch runtime.GOOS {
-	case "linux":
-		f, err := elf.Open(file)
-		if err != nil {
-			return nil, err
-		}
-		dwarf, err := f.DWARF()
-		if err != nil {
-			return nil, err
-		}
-		f.Close()
-		return dwarf, nil
-	case "darwin":
-		f, err := macho.Open(file)
-		if err != nil {
-			return nil, err
-		}
-		dwarf, err := f.DWARF()
-		if err != nil {
-			return nil, err
-		}
-		f.Close()
-		return dwarf, nil
-	}
-	panic("unimplemented DWARF for GOOS=" + runtime.GOOS)
-}
-
-func TestPCToLine(t *testing.T) {
-	if !dotest(false) {
-		return
-	}
-	defer endtest()
-
-	data, err := getData(pclinetestBinary)
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	// Test PCToLine.
-	entry, err := data.LookupFunction("linefrompc")
-	if err != nil {
-		t.Fatal(err)
-	}
-	pc, ok := entry.Val(AttrLowpc).(uint64)
-	if !ok {
-		t.Fatal(`DWARF data for function "linefrompc" has no PC`)
-	}
-	for _, tt := range []struct {
-		offset, want uint64
-	}{
-		{0, 2},
-		{1, 3},
-		{2, 4},
-		{3, 4},
-		{4, 5},
-		{6, 5},
-		{7, 6},
-		{11, 6},
-		{12, 7},
-		{19, 7},
-		{20, 8},
-		{32, 8},
-		{33, 9},
-		{53, 9},
-		{54, 10},
-	} {
-		file, line, err := data.PCToLine(pc + tt.offset)
-		if err != nil {
-			t.Fatal(err)
-		}
-		if !strings.HasSuffix(file, "/pclinetest.asm") {
-			t.Errorf("got %s; want %s", file, ".../pclinetest.asm")
-		}
-		if line != tt.want {
-			t.Errorf("line for offset %d: got %d; want %d", tt.offset, line, tt.want)
-		}
-	}
-}
diff --git a/dwarf/symbol.go b/dwarf/symbol.go
deleted file mode 100644
index 52d6829..0000000
--- a/dwarf/symbol.go
+++ /dev/null
@@ -1,119 +0,0 @@
-// Copyright 2014 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 dwarf
-
-// This file provides simple methods to access the symbol table by name and address.
-
-import (
-	"fmt"
-	"regexp"
-	"sort"
-)
-
-// lookupEntry returns the first Entry for the name.
-// If tag is non-zero, only entries with that tag are considered.
-func (d *Data) lookupEntry(name string, tag Tag) (*Entry, error) {
-	x, ok := d.nameCache[name]
-	if !ok {
-		return nil, fmt.Errorf("DWARF entry for %q not found", name)
-	}
-	for ; x != nil; x = x.link {
-		if tag == 0 || x.entry.Tag == tag {
-			return x.entry, nil
-		}
-	}
-	return nil, fmt.Errorf("no DWARF entry for %q with tag %s", name, tag)
-}
-
-// LookupMatchingSymbols returns the names of all top-level entries matching
-// the given regular expression.
-func (d *Data) LookupMatchingSymbols(nameRE *regexp.Regexp) (result []string, err error) {
-	for name := range d.nameCache {
-		if nameRE.MatchString(name) {
-			result = append(result, name)
-		}
-	}
-	return result, nil
-}
-
-// LookupEntry returns the Entry for the named symbol.
-func (d *Data) LookupEntry(name string) (*Entry, error) {
-	return d.lookupEntry(name, 0)
-}
-
-// LookupFunction returns the entry for a function.
-func (d *Data) LookupFunction(name string) (*Entry, error) {
-	return d.lookupEntry(name, TagSubprogram)
-}
-
-// LookupVariable returns the entry for a (global) variable.
-func (d *Data) LookupVariable(name string) (*Entry, error) {
-	return d.lookupEntry(name, TagVariable)
-}
-
-// EntryLocation returns the address of the object referred to by the given Entry.
-func (d *Data) EntryLocation(e *Entry) (uint64, error) {
-	loc, _ := e.Val(AttrLocation).([]byte)
-	if len(loc) == 0 {
-		return 0, fmt.Errorf("DWARF entry has no Location attribute")
-	}
-	// TODO: implement the DWARF Location bytecode. What we have here only
-	// recognizes a program with a single literal opAddr bytecode.
-	if asize := d.unit[0].asize; loc[0] == opAddr && len(loc) == 1+asize {
-		switch asize {
-		case 1:
-			return uint64(loc[1]), nil
-		case 2:
-			return uint64(d.order.Uint16(loc[1:])), nil
-		case 4:
-			return uint64(d.order.Uint32(loc[1:])), nil
-		case 8:
-			return d.order.Uint64(loc[1:]), nil
-		}
-	}
-	return 0, fmt.Errorf("DWARF entry has an unimplemented Location op")
-}
-
-// EntryType returns the Type for an Entry.
-func (d *Data) EntryType(e *Entry) (Type, error) {
-	off, err := d.EntryTypeOffset(e)
-	if err != nil {
-		return nil, err
-	}
-	return d.Type(off)
-}
-
-// EntryTypeOffset returns the offset in the given Entry's type attribute.
-func (d *Data) EntryTypeOffset(e *Entry) (Offset, error) {
-	v := e.Val(AttrType)
-	if v == nil {
-		return 0, fmt.Errorf("DWARF entry has no Type attribute")
-	}
-	off, ok := v.(Offset)
-	if !ok {
-		return 0, fmt.Errorf("DWARF entry has an invalid Type attribute")
-	}
-	return off, nil
-}
-
-// PCToFunction returns the entry and address for the function containing the
-// specified PC.
-func (d *Data) PCToFunction(pc uint64) (entry *Entry, lowpc uint64, err error) {
-	p := d.pcToFuncEntries
-	if len(p) == 0 {
-		return nil, 0, fmt.Errorf("no function addresses loaded")
-	}
-	i := sort.Search(len(p), func(i int) bool { return p[i].pc > pc }) - 1
-	// The search failed if:
-	// - pc was before the start of any function.
-	// - The largest function bound not larger than pc was the end of a function,
-	//   not the start of one.
-	// - The largest function bound not larger than pc was the start of a function
-	//   that we don't know the end of, and the PC is much larger than the start.
-	if i == -1 || p[i].entry == nil || (i+1 == len(p) && pc-p[i].pc >= 1<<20) {
-		return nil, 0, fmt.Errorf("no function at %x", pc)
-	}
-	return p[i].entry, p[i].pc, nil
-}
diff --git a/dwarf/testdata/pcsptest.go b/dwarf/testdata/pcsptest.go
deleted file mode 100644
index f0f2822..0000000
--- a/dwarf/testdata/pcsptest.go
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2014 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 main
-
-import "fmt"
-
-func main() {
-	test(1, 2, 3)
-}
-
-// This is the function we examine. After the preamble its stack should be
-// pulled down 1*addrSize for the return PC plus 3*8 for the three
-// arguments. That will be (1+3)*8=32 on 64-bit machines.
-func test(a, b, c int64) int64 {
-	// Put in enough code that it's not inlined.
-	for a = 0; a < 100; a++ {
-		b += c
-	}
-	afterTest(a, b, c)
-	return b
-}
-
-// This function follows test in the binary. We use it to force arguments
-// onto the stack and as a delimiter in the text we scan in the test.
-func afterTest(a, b, c int64) {
-	fmt.Println(a, b, c)
-}
diff --git a/dwarf/testdata/typedef.c b/dwarf/testdata/typedef.c
deleted file mode 100644
index f05f015..0000000
--- a/dwarf/testdata/typedef.c
+++ /dev/null
@@ -1,85 +0,0 @@
-// Copyright 2009 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.
-
-/*
-Linux ELF:
-gcc -gdwarf-2 -m64 -c typedef.c && gcc -gdwarf-2 -m64 -o typedef.elf typedef.o
-
-OS X Mach-O:
-gcc -gdwarf-2 -m64 -c typedef.c -o typedef.macho
-*/
-#include <complex.h>
-
-typedef volatile int* t_ptr_volatile_int;
-typedef const char *t_ptr_const_char;
-typedef long t_long;
-typedef unsigned short t_ushort;
-typedef int t_func_int_of_float_double(float, double);
-typedef int (*t_ptr_func_int_of_float_double)(float, double);
-typedef int (*t_ptr_func_int_of_float_complex)(float complex);
-typedef int (*t_ptr_func_int_of_double_complex)(double complex);
-typedef int (*t_ptr_func_int_of_long_double_complex)(long double complex);
-typedef int *t_func_ptr_int_of_char_schar_uchar(char, signed char, unsigned char);
-typedef void t_func_void_of_char(char);
-typedef void t_func_void_of_void(void);
-typedef void t_func_void_of_ptr_char_dots(char*, ...);
-typedef struct my_struct {
-	volatile int vi;
-	char x : 1;
-	int y : 4;
-	int z[0];
-	long long array[40];
-	int zz[0];
-} t_my_struct;
-typedef struct my_struct1 {
-	int zz [1];
-} t_my_struct1;
-typedef union my_union {
-	volatile int vi;
-	char x : 1;
-	int y : 4;
-	long long array[40];
-} t_my_union;
-typedef enum my_enum {
-	e1 = 1,
-	e2 = 2,
-	e3 = -5,
-	e4 = 1000000000000000LL,
-} t_my_enum;
-
-typedef struct list t_my_list;
-struct list {
-	short val;
-	t_my_list *next;
-};
-
-typedef struct tree {
-	struct tree *left, *right;
-	unsigned long long val;
-} t_my_tree;
-
-t_ptr_volatile_int *a2;
-t_ptr_const_char **a3a;
-t_long *a4;
-t_ushort *a5;
-t_func_int_of_float_double *a6;
-t_ptr_func_int_of_float_double *a7;
-t_func_ptr_int_of_char_schar_uchar *a8;
-t_func_void_of_char *a9;
-t_func_void_of_void *a10;
-t_func_void_of_ptr_char_dots *a11;
-t_my_struct *a12;
-t_my_struct1 *a12a;
-t_my_union *a12b;
-t_my_enum *a13;
-t_my_list *a14;
-t_my_tree *a15;
-t_ptr_func_int_of_float_complex *a16;
-t_ptr_func_int_of_double_complex *a17;
-t_ptr_func_int_of_long_double_complex *a18;
-
-int main()
-{
-	return 0;
-}
diff --git a/dwarf/testdata/typedef.elf b/dwarf/testdata/typedef.elf
deleted file mode 100755
index b2062d2..0000000
--- a/dwarf/testdata/typedef.elf
+++ /dev/null
Binary files differ
diff --git a/dwarf/testdata/typedef.elf4 b/dwarf/testdata/typedef.elf4
deleted file mode 100644
index 3d5a5a1..0000000
--- a/dwarf/testdata/typedef.elf4
+++ /dev/null
Binary files differ
diff --git a/dwarf/testdata/typedef.macho b/dwarf/testdata/typedef.macho
deleted file mode 100644
index f75afcc..0000000
--- a/dwarf/testdata/typedef.macho
+++ /dev/null
Binary files differ
diff --git a/dwarf/type.go b/dwarf/type.go
deleted file mode 100644
index 04bbdad..0000000
--- a/dwarf/type.go
+++ /dev/null
@@ -1,867 +0,0 @@
-// Copyright 2009 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.
-
-// DWARF type information structures.
-// The format is heavily biased toward C, but for simplicity
-// the String methods use a pseudo-Go syntax.
-
-package dwarf
-
-import (
-	"fmt"
-	"reflect"
-	"strconv"
-)
-
-// A Type conventionally represents a pointer to any of the
-// specific Type structures (CharType, StructType, etc.).
-type Type interface {
-	Common() *CommonType
-	String() string
-	Size() int64
-}
-
-// A CommonType holds fields common to multiple types.
-// If a field is not known or not applicable for a given type,
-// the zero value is used.
-type CommonType struct {
-	ByteSize    int64        // size of value of this type, in bytes
-	Name        string       // name that can be used to refer to type
-	ReflectKind reflect.Kind // the reflect kind of the type.
-	Offset      Offset       // the offset at which this type was read
-}
-
-func (c *CommonType) Common() *CommonType { return c }
-
-func (c *CommonType) Size() int64 { return c.ByteSize }
-
-// Basic types
-
-// A BasicType holds fields common to all basic types.
-type BasicType struct {
-	CommonType
-	BitSize   int64
-	BitOffset int64
-}
-
-func (b *BasicType) Basic() *BasicType { return b }
-
-func (t *BasicType) String() string {
-	if t.Name != "" {
-		return t.Name
-	}
-	return "?"
-}
-
-// A CharType represents a signed character type.
-type CharType struct {
-	BasicType
-}
-
-// A UcharType represents an unsigned character type.
-type UcharType struct {
-	BasicType
-}
-
-// An IntType represents a signed integer type.
-type IntType struct {
-	BasicType
-}
-
-// A UintType represents an unsigned integer type.
-type UintType struct {
-	BasicType
-}
-
-// A FloatType represents a floating point type.
-type FloatType struct {
-	BasicType
-}
-
-// A ComplexType represents a complex floating point type.
-type ComplexType struct {
-	BasicType
-}
-
-// A BoolType represents a boolean type.
-type BoolType struct {
-	BasicType
-}
-
-// An AddrType represents a machine address type.
-type AddrType struct {
-	BasicType
-}
-
-// An UnspecifiedType represents an implicit, unknown, ambiguous or nonexistent type.
-type UnspecifiedType struct {
-	BasicType
-}
-
-// qualifiers
-
-// A QualType represents a type that has the C/C++ "const", "restrict", or "volatile" qualifier.
-type QualType struct {
-	CommonType
-	Qual string
-	Type Type
-}
-
-func (t *QualType) String() string { return t.Qual + " " + t.Type.String() }
-
-func (t *QualType) Size() int64 { return t.Type.Size() }
-
-// An ArrayType represents a fixed size array type.
-type ArrayType struct {
-	CommonType
-	Type          Type
-	StrideBitSize int64 // if > 0, number of bits to hold each element
-	Count         int64 // if == -1, an incomplete array, like char x[].
-}
-
-func (t *ArrayType) String() string {
-	return "[" + strconv.FormatInt(t.Count, 10) + "]" + t.Type.String()
-}
-
-func (t *ArrayType) Size() int64 { return t.Count * t.Type.Size() }
-
-// A VoidType represents the C void type.
-type VoidType struct {
-	CommonType
-}
-
-func (t *VoidType) String() string { return "void" }
-
-// A PtrType represents a pointer type.
-type PtrType struct {
-	CommonType
-	Type Type
-}
-
-func (t *PtrType) String() string { return "*" + t.Type.String() }
-
-// A StructType represents a struct, union, or C++ class type.
-type StructType struct {
-	CommonType
-	StructName string
-	Kind       string // "struct", "union", or "class".
-	Field      []*StructField
-	Incomplete bool // if true, struct, union, class is declared but not defined
-}
-
-// A StructField represents a field in a struct, union, or C++ class type.
-type StructField struct {
-	Name       string
-	Type       Type
-	ByteOffset int64
-	ByteSize   int64
-	BitOffset  int64 // within the ByteSize bytes at ByteOffset
-	BitSize    int64 // zero if not a bit field
-	Embedded   bool
-}
-
-func (t *StructType) String() string {
-	if t.StructName != "" {
-		return t.Kind + " " + t.StructName
-	}
-	return t.Defn()
-}
-
-func (t *StructType) Defn() string {
-	s := t.Kind
-	if t.StructName != "" {
-		s += " " + t.StructName
-	}
-	if t.Incomplete {
-		s += " /*incomplete*/"
-		return s
-	}
-	s += " {"
-	for i, f := range t.Field {
-		if i > 0 {
-			s += "; "
-		}
-		s += f.Name + " " + f.Type.String()
-		s += "@" + strconv.FormatInt(f.ByteOffset, 10)
-		if f.BitSize > 0 {
-			s += " : " + strconv.FormatInt(f.BitSize, 10)
-			s += "@" + strconv.FormatInt(f.BitOffset, 10)
-		}
-	}
-	s += "}"
-	return s
-}
-
-// A SliceType represents a Go slice type. It looks like a StructType, describing
-// the runtime-internal structure, with extra fields.
-type SliceType struct {
-	StructType
-	ElemType Type
-}
-
-func (t *SliceType) String() string {
-	if t.Name != "" {
-		return t.Name
-	}
-	return "[]" + t.ElemType.String()
-}
-
-// A StringType represents a Go string type. It looks like a StructType, describing
-// the runtime-internal structure, but we wrap it for neatness.
-type StringType struct {
-	StructType
-}
-
-func (t *StringType) String() string {
-	if t.Name != "" {
-		return t.Name
-	}
-	return "string"
-}
-
-// An InterfaceType represents a Go interface.
-type InterfaceType struct {
-	TypedefType
-}
-
-func (t *InterfaceType) String() string {
-	if t.Name != "" {
-		return t.Name
-	}
-	return "Interface"
-}
-
-// An EnumType represents an enumerated type.
-// The only indication of its native integer type is its ByteSize
-// (inside CommonType).
-type EnumType struct {
-	CommonType
-	EnumName string
-	Val      []*EnumValue
-}
-
-// An EnumValue represents a single enumeration value.
-type EnumValue struct {
-	Name string
-	Val  int64
-}
-
-func (t *EnumType) String() string {
-	s := "enum"
-	if t.EnumName != "" {
-		s += " " + t.EnumName
-	}
-	s += " {"
-	for i, v := range t.Val {
-		if i > 0 {
-			s += "; "
-		}
-		s += v.Name + "=" + strconv.FormatInt(v.Val, 10)
-	}
-	s += "}"
-	return s
-}
-
-// A FuncType represents a function type.
-type FuncType struct {
-	CommonType
-	ReturnType Type
-	ParamType  []Type
-}
-
-func (t *FuncType) String() string {
-	s := "func("
-	for i, t := range t.ParamType {
-		if i > 0 {
-			s += ", "
-		}
-		s += t.String()
-	}
-	s += ")"
-	if t.ReturnType != nil {
-		s += " " + t.ReturnType.String()
-	}
-	return s
-}
-
-// A DotDotDotType represents the variadic ... function parameter.
-type DotDotDotType struct {
-	CommonType
-}
-
-func (t *DotDotDotType) String() string { return "..." }
-
-// A TypedefType represents a named type.
-type TypedefType struct {
-	CommonType
-	Type Type
-}
-
-func (t *TypedefType) String() string { return t.Name }
-
-func (t *TypedefType) Size() int64 { return t.Type.Size() }
-
-// A MapType represents a Go map type. It looks like a TypedefType, describing
-// the runtime-internal structure, with extra fields.
-type MapType struct {
-	TypedefType
-	KeyType  Type
-	ElemType Type
-}
-
-func (t *MapType) String() string {
-	if t.Name != "" {
-		return t.Name
-	}
-	return "map[" + t.KeyType.String() + "]" + t.ElemType.String()
-}
-
-// A ChanType represents a Go channel type.
-type ChanType struct {
-	TypedefType
-	ElemType Type
-}
-
-func (t *ChanType) String() string {
-	if t.Name != "" {
-		return t.Name
-	}
-	return "chan " + t.ElemType.String()
-}
-
-// typeReader is used to read from either the info section or the
-// types section.
-type typeReader interface {
-	Seek(Offset)
-	Next() (*Entry, error)
-	clone() typeReader
-	offset() Offset
-	// AddressSize returns the size in bytes of addresses in the current
-	// compilation unit.
-	AddressSize() int
-}
-
-// Type reads the type at off in the DWARF ``info'' section.
-func (d *Data) Type(off Offset) (Type, error) {
-	return d.readType("info", d.Reader(), off, d.typeCache)
-}
-
-func getKind(e *Entry) reflect.Kind {
-	integer, _ := e.Val(AttrGoKind).(int64)
-	return reflect.Kind(integer)
-}
-
-// readType reads a type from r at off of name using and updating a
-// type cache.
-func (d *Data) readType(name string, r typeReader, off Offset, typeCache map[Offset]Type) (Type, error) {
-	if t, ok := typeCache[off]; ok {
-		return t, nil
-	}
-	r.Seek(off)
-	e, err := r.Next()
-	if err != nil {
-		return nil, err
-	}
-	addressSize := r.AddressSize()
-	if e == nil || e.Offset != off {
-		return nil, DecodeError{name, off, "no type at offset"}
-	}
-
-	// Parse type from Entry.
-	// Must always set typeCache[off] before calling
-	// d.Type recursively, to handle circular types correctly.
-	var typ Type
-
-	nextDepth := 0
-
-	// Get next child; set err if error happens.
-	next := func() *Entry {
-		if !e.Children {
-			return nil
-		}
-		// Only return direct children.
-		// Skip over composite entries that happen to be nested
-		// inside this one. Most DWARF generators wouldn't generate
-		// such a thing, but clang does.
-		// See golang.org/issue/6472.
-		for {
-			kid, err1 := r.Next()
-			if err1 != nil {
-				err = err1
-				return nil
-			}
-			if kid == nil {
-				err = DecodeError{name, r.offset(), "unexpected end of DWARF entries"}
-				return nil
-			}
-			if kid.Tag == 0 {
-				if nextDepth > 0 {
-					nextDepth--
-					continue
-				}
-				return nil
-			}
-			if kid.Children {
-				nextDepth++
-			}
-			if nextDepth > 0 {
-				continue
-			}
-			return kid
-		}
-	}
-
-	// Get Type referred to by Entry's attr.
-	// Set err if error happens.  Not having a type is an error.
-	typeOf := func(e *Entry, attr Attr) Type {
-		tval := e.Val(attr)
-		var t Type
-		switch toff := tval.(type) {
-		case Offset:
-			if t, err = d.readType(name, r.clone(), toff, typeCache); err != nil {
-				return nil
-			}
-		case uint64:
-			if t, err = d.sigToType(toff); err != nil {
-				return nil
-			}
-		default:
-			// It appears that no Type means "void".
-			return new(VoidType)
-		}
-		return t
-	}
-
-	switch e.Tag {
-	case TagArrayType:
-		// Multi-dimensional array.  (DWARF v2 §5.4)
-		// Attributes:
-		//	AttrType:subtype [required]
-		//	AttrStrideSize: distance in bits between each element of the array
-		//	AttrStride: distance in bytes between each element of the array
-		//	AttrByteSize: size of entire array
-		// Children:
-		//	TagSubrangeType or TagEnumerationType giving one dimension.
-		//	dimensions are in left to right order.
-		t := new(ArrayType)
-		t.Name, _ = e.Val(AttrName).(string)
-		t.ReflectKind = getKind(e)
-		typ = t
-		typeCache[off] = t
-		if t.Type = typeOf(e, AttrType); err != nil {
-			goto Error
-		}
-		if bytes, ok := e.Val(AttrStride).(int64); ok {
-			t.StrideBitSize = 8 * bytes
-		} else if bits, ok := e.Val(AttrStrideSize).(int64); ok {
-			t.StrideBitSize = bits
-		} else {
-			// If there's no stride specified, assume it's the size of the
-			// array's element type.
-			t.StrideBitSize = 8 * t.Type.Size()
-		}
-
-		// Accumulate dimensions,
-		ndim := 0
-		for kid := next(); kid != nil; kid = next() {
-			// TODO(rsc): Can also be TagEnumerationType
-			// but haven't seen that in the wild yet.
-			switch kid.Tag {
-			case TagSubrangeType:
-				count, ok := kid.Val(AttrCount).(int64)
-				if !ok {
-					// Old binaries may have an upper bound instead.
-					count, ok = kid.Val(AttrUpperBound).(int64)
-					if ok {
-						count++ // Length is one more than upper bound.
-					} else {
-						count = -1 // As in x[].
-					}
-				}
-				if ndim == 0 {
-					t.Count = count
-				} else {
-					// Multidimensional array.
-					// Create new array type underneath this one.
-					t.Type = &ArrayType{Type: t.Type, Count: count}
-				}
-				ndim++
-			case TagEnumerationType:
-				err = DecodeError{name, kid.Offset, "cannot handle enumeration type as array bound"}
-				goto Error
-			}
-		}
-		if ndim == 0 {
-			// LLVM generates this for x[].
-			t.Count = -1
-		}
-
-	case TagBaseType:
-		// Basic type.  (DWARF v2 §5.1)
-		// Attributes:
-		//	AttrName: name of base type in programming language of the compilation unit [required]
-		//	AttrEncoding: encoding value for type (encFloat etc) [required]
-		//	AttrByteSize: size of type in bytes [required]
-		//	AttrBitOffset: for sub-byte types, size in bits
-		//	AttrBitSize: for sub-byte types, bit offset of high order bit in the AttrByteSize bytes
-		name, _ := e.Val(AttrName).(string)
-		enc, ok := e.Val(AttrEncoding).(int64)
-		if !ok {
-			err = DecodeError{name, e.Offset, "missing encoding attribute for " + name}
-			goto Error
-		}
-		switch enc {
-		default:
-			err = DecodeError{name, e.Offset, "unrecognized encoding attribute value"}
-			goto Error
-
-		case encAddress:
-			typ = new(AddrType)
-		case encBoolean:
-			typ = new(BoolType)
-		case encComplexFloat:
-			typ = new(ComplexType)
-			if name == "complex" {
-				// clang writes out 'complex' instead of 'complex float' or 'complex double'.
-				// clang also writes out a byte size that we can use to distinguish.
-				// See issue 8694.
-				switch byteSize, _ := e.Val(AttrByteSize).(int64); byteSize {
-				case 8:
-					name = "complex float"
-				case 16:
-					name = "complex double"
-				}
-			}
-		case encFloat:
-			typ = new(FloatType)
-		case encSigned:
-			typ = new(IntType)
-		case encUnsigned:
-			typ = new(UintType)
-		case encSignedChar:
-			typ = new(CharType)
-		case encUnsignedChar:
-			typ = new(UcharType)
-		}
-		typeCache[off] = typ
-		t := typ.(interface {
-			Basic() *BasicType
-		}).Basic()
-		t.Name = name
-		t.BitSize, _ = e.Val(AttrBitSize).(int64)
-		t.BitOffset, _ = e.Val(AttrBitOffset).(int64)
-		t.ReflectKind = getKind(e)
-
-	case TagClassType, TagStructType, TagUnionType:
-		// Structure, union, or class type.  (DWARF v2 §5.5)
-		// Also Slices and Strings (Go-specific).
-		// Attributes:
-		//	AttrName: name of struct, union, or class
-		//	AttrByteSize: byte size [required]
-		//	AttrDeclaration: if true, struct/union/class is incomplete
-		// 	AttrGoElem: present for slices only.
-		// Children:
-		//	TagMember to describe one member.
-		//		AttrName: name of member [required]
-		//		AttrType: type of member [required]
-		//		AttrByteSize: size in bytes
-		//		AttrBitOffset: bit offset within bytes for bit fields
-		//		AttrBitSize: bit size for bit fields
-		//		AttrDataMemberLoc: location within struct [required for struct, class]
-		// There is much more to handle C++, all ignored for now.
-		t := new(StructType)
-		t.ReflectKind = getKind(e)
-		switch t.ReflectKind {
-		case reflect.Slice:
-			slice := new(SliceType)
-			slice.ElemType = typeOf(e, AttrGoElem)
-			t = &slice.StructType
-			typ = slice
-		case reflect.String:
-			str := new(StringType)
-			t = &str.StructType
-			typ = str
-		default:
-			typ = t
-		}
-		typeCache[off] = typ
-		switch e.Tag {
-		case TagClassType:
-			t.Kind = "class"
-		case TagStructType:
-			t.Kind = "struct"
-		case TagUnionType:
-			t.Kind = "union"
-		}
-		t.Name, _ = e.Val(AttrName).(string)
-		t.StructName, _ = e.Val(AttrName).(string)
-		t.Incomplete = e.Val(AttrDeclaration) != nil
-		t.Field = make([]*StructField, 0, 8)
-		var lastFieldType Type
-		var lastFieldBitOffset int64
-		for kid := next(); kid != nil; kid = next() {
-			if kid.Tag == TagMember {
-				f := new(StructField)
-				if f.Type = typeOf(kid, AttrType); err != nil {
-					goto Error
-				}
-				switch loc := kid.Val(AttrDataMemberLoc).(type) {
-				case []byte:
-					// TODO: Should have original compilation
-					// unit here, not unknownFormat.
-					if len(loc) == 0 {
-						// Empty exprloc. f.ByteOffset=0.
-						break
-					}
-					b := makeBuf(d, unknownFormat{}, "location", 0, loc)
-					op := b.uint8()
-					switch op {
-					case opPlusUconst:
-						// Handle opcode sequence [DW_OP_plus_uconst <uleb128>]
-						f.ByteOffset = int64(b.uint())
-						b.assertEmpty()
-					case opConsts:
-						// Handle opcode sequence [DW_OP_consts <sleb128> DW_OP_plus]
-						f.ByteOffset = b.int()
-						op = b.uint8()
-						if op != opPlus {
-							err = DecodeError{name, kid.Offset, fmt.Sprintf("unexpected opcode 0x%x", op)}
-							goto Error
-						}
-						b.assertEmpty()
-					default:
-						err = DecodeError{name, kid.Offset, fmt.Sprintf("unexpected opcode 0x%x", op)}
-						goto Error
-					}
-					if b.err != nil {
-						err = b.err
-						goto Error
-					}
-				case int64:
-					f.ByteOffset = loc
-				}
-
-				haveBitOffset := false
-				f.Name, _ = kid.Val(AttrName).(string)
-				f.ByteSize, _ = kid.Val(AttrByteSize).(int64)
-				f.BitOffset, haveBitOffset = kid.Val(AttrBitOffset).(int64)
-				f.BitSize, _ = kid.Val(AttrBitSize).(int64)
-				f.Embedded, _ = kid.Val(AttrGoEmbeddedField).(bool)
-				t.Field = append(t.Field, f)
-
-				bito := f.BitOffset
-				if !haveBitOffset {
-					bito = f.ByteOffset * 8
-				}
-				if bito == lastFieldBitOffset && t.Kind != "union" {
-					// Last field was zero width.  Fix array length.
-					// (DWARF writes out 0-length arrays as if they were 1-length arrays.)
-					zeroArray(lastFieldType)
-				}
-				lastFieldType = f.Type
-				lastFieldBitOffset = bito
-			}
-		}
-		if t.Kind != "union" {
-			b, ok := e.Val(AttrByteSize).(int64)
-			if ok && b*8 == lastFieldBitOffset {
-				// Final field must be zero width.  Fix array length.
-				zeroArray(lastFieldType)
-			}
-		}
-
-	case TagConstType, TagVolatileType, TagRestrictType:
-		// Type modifier (DWARF v2 §5.2)
-		// Attributes:
-		//	AttrType: subtype
-		t := new(QualType)
-		t.Name, _ = e.Val(AttrName).(string)
-		t.ReflectKind = getKind(e)
-		typ = t
-		typeCache[off] = t
-		if t.Type = typeOf(e, AttrType); err != nil {
-			goto Error
-		}
-		switch e.Tag {
-		case TagConstType:
-			t.Qual = "const"
-		case TagRestrictType:
-			t.Qual = "restrict"
-		case TagVolatileType:
-			t.Qual = "volatile"
-		}
-
-	case TagEnumerationType:
-		// Enumeration type (DWARF v2 §5.6)
-		// Attributes:
-		//	AttrName: enum name if any
-		//	AttrByteSize: bytes required to represent largest value
-		// Children:
-		//	TagEnumerator:
-		//		AttrName: name of constant
-		//		AttrConstValue: value of constant
-		t := new(EnumType)
-		t.ReflectKind = getKind(e)
-		typ = t
-		typeCache[off] = t
-		t.Name, _ = e.Val(AttrName).(string)
-		t.EnumName, _ = e.Val(AttrName).(string)
-		t.Val = make([]*EnumValue, 0, 8)
-		for kid := next(); kid != nil; kid = next() {
-			if kid.Tag == TagEnumerator {
-				f := new(EnumValue)
-				f.Name, _ = kid.Val(AttrName).(string)
-				f.Val, _ = kid.Val(AttrConstValue).(int64)
-				n := len(t.Val)
-				if n >= cap(t.Val) {
-					val := make([]*EnumValue, n, n*2)
-					copy(val, t.Val)
-					t.Val = val
-				}
-				t.Val = t.Val[0 : n+1]
-				t.Val[n] = f
-			}
-		}
-
-	case TagPointerType:
-		// Type modifier (DWARF v2 §5.2)
-		// Attributes:
-		//	AttrType: subtype [not required!  void* has no AttrType]
-		//	AttrAddrClass: address class [ignored]
-		t := new(PtrType)
-		t.Name, _ = e.Val(AttrName).(string)
-		t.ReflectKind = getKind(e)
-		typ = t
-		typeCache[off] = t
-		if e.Val(AttrType) == nil {
-			t.Type = &VoidType{}
-			break
-		}
-		t.Type = typeOf(e, AttrType)
-
-	case TagSubroutineType:
-		// Subroutine type.  (DWARF v2 §5.7)
-		// Attributes:
-		//	AttrType: type of return value if any
-		//	AttrName: possible name of type [ignored]
-		//	AttrPrototyped: whether used ANSI C prototype [ignored]
-		// Children:
-		//	TagFormalParameter: typed parameter
-		//		AttrType: type of parameter
-		//	TagUnspecifiedParameter: final ...
-		t := new(FuncType)
-		t.Name, _ = e.Val(AttrName).(string)
-		t.ReflectKind = getKind(e)
-		typ = t
-		typeCache[off] = t
-		if t.ReturnType = typeOf(e, AttrType); err != nil {
-			goto Error
-		}
-		t.ParamType = make([]Type, 0, 8)
-		for kid := next(); kid != nil; kid = next() {
-			var tkid Type
-			switch kid.Tag {
-			default:
-				continue
-			case TagFormalParameter:
-				if tkid = typeOf(kid, AttrType); err != nil {
-					goto Error
-				}
-			case TagUnspecifiedParameters:
-				tkid = &DotDotDotType{}
-			}
-			t.ParamType = append(t.ParamType, tkid)
-		}
-
-	case TagTypedef:
-		// Typedef (DWARF v2 §5.3)
-		// Also maps and channels (Go-specific).
-		// Attributes:
-		//	AttrName: name [required]
-		//	AttrType: type definition [required]
-		//	AttrGoKey: present for maps.
-		//	AttrGoElem: present for maps and channels.
-		t := new(TypedefType)
-		t.ReflectKind = getKind(e)
-		switch t.ReflectKind {
-		case reflect.Map:
-			m := new(MapType)
-			m.KeyType = typeOf(e, AttrGoKey)
-			m.ElemType = typeOf(e, AttrGoElem)
-			t = &m.TypedefType
-			typ = m
-		case reflect.Chan:
-			c := new(ChanType)
-			c.ElemType = typeOf(e, AttrGoElem)
-			t = &c.TypedefType
-			typ = c
-		case reflect.Interface:
-			it := new(InterfaceType)
-			t = &it.TypedefType
-			typ = it
-		default:
-			typ = t
-		}
-		typeCache[off] = typ
-		t.Name, _ = e.Val(AttrName).(string)
-		t.Type = typeOf(e, AttrType)
-
-	case TagUnspecifiedType:
-		// Unspecified type (DWARF v3 §5.2)
-		// Attributes:
-		//      AttrName: name
-		t := new(UnspecifiedType)
-		typ = t
-		typeCache[off] = t
-		t.Name, _ = e.Val(AttrName).(string)
-
-	default:
-		err = DecodeError{name, off, "unsupported type tag"}
-	}
-
-	if err != nil {
-		goto Error
-	}
-
-	typ.Common().Offset = off
-
-	{
-		b, ok := e.Val(AttrByteSize).(int64)
-		if !ok {
-			b = -1
-			switch t := typ.(type) {
-			case *TypedefType:
-				b = t.Type.Size()
-			case *MapType:
-				b = t.Type.Size()
-			case *ChanType:
-				b = t.Type.Size()
-			case *InterfaceType:
-				b = t.Type.Size()
-			case *PtrType:
-				b = int64(addressSize)
-			}
-		}
-		typ.Common().ByteSize = b
-	}
-	return typ, nil
-
-Error:
-	// If the parse fails, take the type out of the cache
-	// so that the next call with this offset doesn't hit
-	// the cache and return success.
-	delete(typeCache, off)
-	return nil, err
-}
-
-func zeroArray(t Type) {
-	for {
-		at, ok := t.(*ArrayType)
-		if !ok {
-			break
-		}
-		at.Count = 0
-		t = at.Type
-	}
-}
diff --git a/dwarf/type_test.go b/dwarf/type_test.go
deleted file mode 100644
index aeb954c..0000000
--- a/dwarf/type_test.go
+++ /dev/null
@@ -1,138 +0,0 @@
-// Copyright 2009 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 dwarf_test
-
-import (
-	"testing"
-
-	. "golang.org/x/debug/dwarf"
-	"golang.org/x/debug/elf"
-	"golang.org/x/debug/macho"
-)
-
-var typedefTests = map[string]string{
-	"t_ptr_volatile_int":                    "*volatile int",
-	"t_ptr_const_char":                      "*const char",
-	"t_long":                                "long int",
-	"t_ushort":                              "short unsigned int",
-	"t_func_int_of_float_double":            "func(float, double) int",
-	"t_ptr_func_int_of_float_double":        "*func(float, double) int",
-	"t_ptr_func_int_of_float_complex":       "*func(complex float) int",
-	"t_ptr_func_int_of_double_complex":      "*func(complex double) int",
-	"t_ptr_func_int_of_long_double_complex": "*func(complex long double) int",
-	"t_func_ptr_int_of_char_schar_uchar":    "func(char, signed char, unsigned char) *int",
-	"t_func_void_of_char":                   "func(char) void",
-	"t_func_void_of_void":                   "func() void",
-	"t_func_void_of_ptr_char_dots":          "func(*char, ...) void",
-	"t_my_struct":                           "struct my_struct {vi volatile int@0; x char@4 : 1@7; y int@4 : 4@27; z [0]int@8; array [40]long long int@8; zz [0]int@328}",
-	"t_my_struct1":                          "struct my_struct1 {zz [1]int@0}",
-	"t_my_union":                            "union my_union {vi volatile int@0; x char@0 : 1@7; y int@0 : 4@28; array [40]long long int@0}",
-	"t_my_enum":                             "enum my_enum {e1=1; e2=2; e3=-5; e4=1000000000000000}",
-	"t_my_list":                             "struct list {val short int@0; next *t_my_list@8}",
-	"t_my_tree":                             "struct tree {left *struct tree@0; right *struct tree@8; val long long unsigned int@16}",
-}
-
-// As Apple converts gcc to a clang-based front end
-// they keep breaking the DWARF output.  This map lists the
-// conversion from real answer to Apple answer.
-var machoBug = map[string]string{
-	"func(*char, ...) void":                                 "func(*char) void",
-	"enum my_enum {e1=1; e2=2; e3=-5; e4=1000000000000000}": "enum my_enum {e1=1; e2=2; e3=-5; e4=-1530494976}",
-}
-
-func elfData(t *testing.T, name string) *Data {
-	f, err := elf.Open(name)
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	d, err := f.DWARF()
-	if err != nil {
-		t.Fatal(err)
-	}
-	return d
-}
-
-func machoData(t *testing.T, name string) *Data {
-	f, err := macho.Open(name)
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	d, err := f.DWARF()
-	if err != nil {
-		t.Fatal(err)
-	}
-	return d
-}
-
-func TestTypedefsELF(t *testing.T) { testTypedefs(t, elfData(t, "testdata/typedef.elf"), "elf") }
-
-func TestTypedefsMachO(t *testing.T) {
-	testTypedefs(t, machoData(t, "testdata/typedef.macho"), "macho")
-}
-
-func TestTypedefsELFDwarf4(t *testing.T) { testTypedefs(t, elfData(t, "testdata/typedef.elf4"), "elf") }
-
-func testTypedefs(t *testing.T, d *Data, kind string) {
-	r := d.Reader()
-	seen := make(map[string]bool)
-	for {
-		e, err := r.Next()
-		if err != nil {
-			t.Fatal("r.Next:", err)
-		}
-		if e == nil {
-			break
-		}
-		if e.Tag == TagTypedef {
-			typ, err := d.Type(e.Offset)
-			if err != nil {
-				t.Fatal("d.Type:", err)
-			}
-			t1 := typ.(*TypedefType)
-			var typstr string
-			if ts, ok := t1.Type.(*StructType); ok {
-				typstr = ts.Defn()
-			} else {
-				typstr = t1.Type.String()
-			}
-
-			if want, ok := typedefTests[t1.Name]; ok {
-				if seen[t1.Name] {
-					t.Errorf("multiple definitions for %s", t1.Name)
-				}
-				seen[t1.Name] = true
-				if typstr != want && (kind != "macho" || typstr != machoBug[want]) {
-					t.Errorf("%s:\n\thave %s\n\twant %s", t1.Name, typstr, want)
-				}
-			}
-		}
-		if e.Tag != TagCompileUnit {
-			r.SkipChildren()
-		}
-	}
-
-	for k := range typedefTests {
-		if !seen[k] {
-			t.Errorf("missing %s", k)
-		}
-	}
-}
-
-func TestTypeForNonTypeEntry(t *testing.T) {
-	d := elfData(t, "testdata/typedef.elf")
-
-	// The returned entry will be a Subprogram.
-	ent, err := d.LookupFunction("main")
-	if err != nil {
-		t.Fatal("d.LookupFunction:", err)
-	}
-
-	_, err = d.Type(ent.Offset)
-	if err == nil {
-		t.Fatal("nil error for unreadable entry")
-	}
-}
diff --git a/dwarf/typeunit.go b/dwarf/typeunit.go
deleted file mode 100644
index d93b9f5..0000000
--- a/dwarf/typeunit.go
+++ /dev/null
@@ -1,171 +0,0 @@
-// Copyright 2012 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 dwarf
-
-import (
-	"fmt"
-	"strconv"
-)
-
-// Parse the type units stored in a DWARF4 .debug_types section.  Each
-// type unit defines a single primary type and an 8-byte signature.
-// Other sections may then use formRefSig8 to refer to the type.
-
-// The typeUnit format is a single type with a signature.  It holds
-// the same data as a compilation unit.
-type typeUnit struct {
-	unit
-	toff  Offset // Offset to signature type within data.
-	name  string // Name of .debug_type section.
-	cache Type   // Cache the type, nil to start.
-}
-
-// Parse a .debug_types section.
-func (d *Data) parseTypes(name string, types []byte) error {
-	b := makeBuf(d, unknownFormat{}, name, 0, types)
-	for len(b.data) > 0 {
-		base := b.off
-		dwarf64 := false
-		n := b.uint32()
-		if n == 0xffffffff {
-			n64 := b.uint64()
-			if n64 != uint64(uint32(n64)) {
-				b.error("type unit length overflow")
-				return b.err
-			}
-			n = uint32(n64)
-			dwarf64 = true
-		}
-		hdroff := b.off
-		vers := b.uint16()
-		if vers != 4 {
-			b.error("unsupported DWARF version " + strconv.Itoa(int(vers)))
-			return b.err
-		}
-		var ao uint32
-		if !dwarf64 {
-			ao = b.uint32()
-		} else {
-			ao64 := b.uint64()
-			if ao64 != uint64(uint32(ao64)) {
-				b.error("type unit abbrev offset overflow")
-				return b.err
-			}
-			ao = uint32(ao64)
-		}
-		atable, err := d.parseAbbrev(ao)
-		if err != nil {
-			return err
-		}
-		asize := b.uint8()
-		sig := b.uint64()
-
-		var toff uint32
-		if !dwarf64 {
-			toff = b.uint32()
-		} else {
-			to64 := b.uint64()
-			if to64 != uint64(uint32(to64)) {
-				b.error("type unit type offset overflow")
-				return b.err
-			}
-			toff = uint32(to64)
-		}
-
-		boff := b.off
-		d.typeSigs[sig] = &typeUnit{
-			unit: unit{
-				base:   base,
-				off:    boff,
-				data:   b.bytes(int(Offset(n) - (b.off - hdroff))),
-				atable: atable,
-				asize:  int(asize),
-				vers:   int(vers),
-				is64:   dwarf64,
-			},
-			toff: Offset(toff),
-			name: name,
-		}
-		if b.err != nil {
-			return b.err
-		}
-	}
-	return nil
-}
-
-// Return the type for a type signature.
-func (d *Data) sigToType(sig uint64) (Type, error) {
-	tu := d.typeSigs[sig]
-	if tu == nil {
-		return nil, fmt.Errorf("no type unit with signature %v", sig)
-	}
-	if tu.cache != nil {
-		return tu.cache, nil
-	}
-
-	b := makeBuf(d, tu, tu.name, tu.off, tu.data)
-	r := &typeUnitReader{d: d, tu: tu, b: b}
-	t, err := d.readType(tu.name, r, Offset(tu.toff), make(map[Offset]Type))
-	if err != nil {
-		return nil, err
-	}
-
-	tu.cache = t
-	return t, nil
-}
-
-// typeUnitReader is a typeReader for a tagTypeUnit.
-type typeUnitReader struct {
-	d   *Data
-	tu  *typeUnit
-	b   buf
-	err error
-}
-
-// Seek to a new position in the type unit.
-func (tur *typeUnitReader) Seek(off Offset) {
-	tur.err = nil
-	doff := off - tur.tu.off
-	if doff < 0 || doff >= Offset(len(tur.tu.data)) {
-		tur.err = fmt.Errorf("%s: offset %d out of range; max %d", tur.tu.name, doff, len(tur.tu.data))
-		return
-	}
-	tur.b = makeBuf(tur.d, tur.tu, tur.tu.name, off, tur.tu.data[doff:])
-}
-
-// AddressSize returns the size in bytes of addresses in the current type unit.
-func (tur *typeUnitReader) AddressSize() int {
-	return tur.tu.unit.asize
-}
-
-// Next reads the next Entry from the type unit.
-func (tur *typeUnitReader) Next() (*Entry, error) {
-	if tur.err != nil {
-		return nil, tur.err
-	}
-	if len(tur.tu.data) == 0 {
-		return nil, nil
-	}
-	e := tur.b.entry(tur.tu.atable, tur.tu.base)
-	if tur.b.err != nil {
-		tur.err = tur.b.err
-		return nil, tur.err
-	}
-	return e, nil
-}
-
-// clone returns a new reader for the type unit.
-func (tur *typeUnitReader) clone() typeReader {
-	return &typeUnitReader{
-		d:  tur.d,
-		tu: tur.tu,
-		b:  makeBuf(tur.d, tur.tu, tur.tu.name, tur.tu.off, tur.tu.data),
-	}
-}
-
-// offset returns the current offset.
-func (tur *typeUnitReader) offset() Offset {
-	return tur.b.off
-}
diff --git a/dwarf/unit.go b/dwarf/unit.go
deleted file mode 100644
index 0fbc8e0..0000000
--- a/dwarf/unit.go
+++ /dev/null
@@ -1,90 +0,0 @@
-// Copyright 2009 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 dwarf
-
-import "strconv"
-
-// DWARF debug info is split into a sequence of compilation units.
-// Each unit has its own abbreviation table and address size.
-
-type unit struct {
-	base   Offset // byte offset of header within the aggregate info
-	off    Offset // byte offset of data within the aggregate info
-	data   []byte
-	atable abbrevTable
-	asize  int
-	vers   int
-	is64   bool // True for 64-bit DWARF format
-}
-
-// Implement the dataFormat interface.
-
-func (u *unit) version() int {
-	return u.vers
-}
-
-func (u *unit) dwarf64() (bool, bool) {
-	return u.is64, true
-}
-
-func (u *unit) addrsize() int {
-	return u.asize
-}
-
-func (d *Data) parseUnits() ([]unit, error) {
-	// Count units.
-	nunit := 0
-	b := makeBuf(d, unknownFormat{}, "info", 0, d.info)
-	for len(b.data) > 0 {
-		len := b.uint32()
-		if len == 0xffffffff {
-			len64 := b.uint64()
-			if len64 != uint64(uint32(len64)) {
-				b.error("unit length overflow")
-				break
-			}
-			len = uint32(len64)
-		}
-		b.skip(int(len))
-		nunit++
-	}
-	if b.err != nil {
-		return nil, b.err
-	}
-
-	// Again, this time writing them down.
-	b = makeBuf(d, unknownFormat{}, "info", 0, d.info)
-	units := make([]unit, nunit)
-	for i := range units {
-		u := &units[i]
-		u.base = b.off
-		n := b.uint32()
-		if n == 0xffffffff {
-			u.is64 = true
-			n = uint32(b.uint64())
-		}
-		vers := b.uint16()
-		if vers != 2 && vers != 3 && vers != 4 {
-			b.error("unsupported DWARF version " + strconv.Itoa(int(vers)))
-			break
-		}
-		u.vers = int(vers)
-		atable, err := d.parseAbbrev(b.uint32())
-		if err != nil {
-			if b.err == nil {
-				b.err = err
-			}
-			break
-		}
-		u.atable = atable
-		u.asize = int(b.uint8())
-		u.off = b.off
-		u.data = b.bytes(int(n - (2 + 4 + 1)))
-	}
-	if b.err != nil {
-		return nil, b.err
-	}
-	return units, nil
-}
diff --git a/elf/elf.go b/elf/elf.go
deleted file mode 100644
index 4e924dc..0000000
--- a/elf/elf.go
+++ /dev/null
@@ -1,1521 +0,0 @@
-/*
- * ELF constants and data structures
- *
- * Derived from:
- * $FreeBSD: src/sys/sys/elf32.h,v 1.8.14.1 2005/12/30 22:13:58 marcel Exp $
- * $FreeBSD: src/sys/sys/elf64.h,v 1.10.14.1 2005/12/30 22:13:58 marcel Exp $
- * $FreeBSD: src/sys/sys/elf_common.h,v 1.15.8.1 2005/12/30 22:13:58 marcel Exp $
- * $FreeBSD: src/sys/alpha/include/elf.h,v 1.14 2003/09/25 01:10:22 peter Exp $
- * $FreeBSD: src/sys/amd64/include/elf.h,v 1.18 2004/08/03 08:21:48 dfr Exp $
- * $FreeBSD: src/sys/arm/include/elf.h,v 1.5.2.1 2006/06/30 21:42:52 cognet Exp $
- * $FreeBSD: src/sys/i386/include/elf.h,v 1.16 2004/08/02 19:12:17 dfr Exp $
- * $FreeBSD: src/sys/powerpc/include/elf.h,v 1.7 2004/11/02 09:47:01 ssouhlal Exp $
- * $FreeBSD: src/sys/sparc64/include/elf.h,v 1.12 2003/09/25 01:10:26 peter Exp $
- *
- * Copyright (c) 1996-1998 John D. Polstra.  All rights reserved.
- * Copyright (c) 2001 David E. O'Brien
- * Portions Copyright 2009 The Go Authors.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-package elf // import "golang.org/x/debug/elf"
-
-import "strconv"
-
-/*
- * Constants
- */
-
-// Indexes into the Header.Ident array.
-const (
-	EI_CLASS      = 4  /* Class of machine. */
-	EI_DATA       = 5  /* Data format. */
-	EI_VERSION    = 6  /* ELF format version. */
-	EI_OSABI      = 7  /* Operating system / ABI identification */
-	EI_ABIVERSION = 8  /* ABI version */
-	EI_PAD        = 9  /* Start of padding (per SVR4 ABI). */
-	EI_NIDENT     = 16 /* Size of e_ident array. */
-)
-
-// Initial magic number for ELF files.
-const ELFMAG = "\177ELF"
-
-// Version is found in Header.Ident[EI_VERSION] and Header.Version.
-type Version byte
-
-const (
-	EV_NONE    Version = 0
-	EV_CURRENT Version = 1
-)
-
-var versionStrings = []intName{
-	{0, "EV_NONE"},
-	{1, "EV_CURRENT"},
-}
-
-func (i Version) String() string   { return stringName(uint32(i), versionStrings, false) }
-func (i Version) GoString() string { return stringName(uint32(i), versionStrings, true) }
-
-// Class is found in Header.Ident[EI_CLASS] and Header.Class.
-type Class byte
-
-const (
-	ELFCLASSNONE Class = 0 /* Unknown class. */
-	ELFCLASS32   Class = 1 /* 32-bit architecture. */
-	ELFCLASS64   Class = 2 /* 64-bit architecture. */
-)
-
-var classStrings = []intName{
-	{0, "ELFCLASSNONE"},
-	{1, "ELFCLASS32"},
-	{2, "ELFCLASS64"},
-}
-
-func (i Class) String() string   { return stringName(uint32(i), classStrings, false) }
-func (i Class) GoString() string { return stringName(uint32(i), classStrings, true) }
-
-// Data is found in Header.Ident[EI_DATA] and Header.Data.
-type Data byte
-
-const (
-	ELFDATANONE Data = 0 /* Unknown data format. */
-	ELFDATA2LSB Data = 1 /* 2's complement little-endian. */
-	ELFDATA2MSB Data = 2 /* 2's complement big-endian. */
-)
-
-var dataStrings = []intName{
-	{0, "ELFDATANONE"},
-	{1, "ELFDATA2LSB"},
-	{2, "ELFDATA2MSB"},
-}
-
-func (i Data) String() string   { return stringName(uint32(i), dataStrings, false) }
-func (i Data) GoString() string { return stringName(uint32(i), dataStrings, true) }
-
-// OSABI is found in Header.Ident[EI_OSABI] and Header.OSABI.
-type OSABI byte
-
-const (
-	ELFOSABI_NONE       OSABI = 0   /* UNIX System V ABI */
-	ELFOSABI_HPUX       OSABI = 1   /* HP-UX operating system */
-	ELFOSABI_NETBSD     OSABI = 2   /* NetBSD */
-	ELFOSABI_LINUX      OSABI = 3   /* GNU/Linux */
-	ELFOSABI_HURD       OSABI = 4   /* GNU/Hurd */
-	ELFOSABI_86OPEN     OSABI = 5   /* 86Open common IA32 ABI */
-	ELFOSABI_SOLARIS    OSABI = 6   /* Solaris */
-	ELFOSABI_AIX        OSABI = 7   /* AIX */
-	ELFOSABI_IRIX       OSABI = 8   /* IRIX */
-	ELFOSABI_FREEBSD    OSABI = 9   /* FreeBSD */
-	ELFOSABI_TRU64      OSABI = 10  /* TRU64 UNIX */
-	ELFOSABI_MODESTO    OSABI = 11  /* Novell Modesto */
-	ELFOSABI_OPENBSD    OSABI = 12  /* OpenBSD */
-	ELFOSABI_OPENVMS    OSABI = 13  /* Open VMS */
-	ELFOSABI_NSK        OSABI = 14  /* HP Non-Stop Kernel */
-	ELFOSABI_ARM        OSABI = 97  /* ARM */
-	ELFOSABI_STANDALONE OSABI = 255 /* Standalone (embedded) application */
-)
-
-var osabiStrings = []intName{
-	{0, "ELFOSABI_NONE"},
-	{1, "ELFOSABI_HPUX"},
-	{2, "ELFOSABI_NETBSD"},
-	{3, "ELFOSABI_LINUX"},
-	{4, "ELFOSABI_HURD"},
-	{5, "ELFOSABI_86OPEN"},
-	{6, "ELFOSABI_SOLARIS"},
-	{7, "ELFOSABI_AIX"},
-	{8, "ELFOSABI_IRIX"},
-	{9, "ELFOSABI_FREEBSD"},
-	{10, "ELFOSABI_TRU64"},
-	{11, "ELFOSABI_MODESTO"},
-	{12, "ELFOSABI_OPENBSD"},
-	{13, "ELFOSABI_OPENVMS"},
-	{14, "ELFOSABI_NSK"},
-	{97, "ELFOSABI_ARM"},
-	{255, "ELFOSABI_STANDALONE"},
-}
-
-func (i OSABI) String() string   { return stringName(uint32(i), osabiStrings, false) }
-func (i OSABI) GoString() string { return stringName(uint32(i), osabiStrings, true) }
-
-// Type is found in Header.Type.
-type Type uint16
-
-const (
-	ET_NONE   Type = 0      /* Unknown type. */
-	ET_REL    Type = 1      /* Relocatable. */
-	ET_EXEC   Type = 2      /* Executable. */
-	ET_DYN    Type = 3      /* Shared object. */
-	ET_CORE   Type = 4      /* Core file. */
-	ET_LOOS   Type = 0xfe00 /* First operating system specific. */
-	ET_HIOS   Type = 0xfeff /* Last operating system-specific. */
-	ET_LOPROC Type = 0xff00 /* First processor-specific. */
-	ET_HIPROC Type = 0xffff /* Last processor-specific. */
-)
-
-var typeStrings = []intName{
-	{0, "ET_NONE"},
-	{1, "ET_REL"},
-	{2, "ET_EXEC"},
-	{3, "ET_DYN"},
-	{4, "ET_CORE"},
-	{0xfe00, "ET_LOOS"},
-	{0xfeff, "ET_HIOS"},
-	{0xff00, "ET_LOPROC"},
-	{0xffff, "ET_HIPROC"},
-}
-
-func (i Type) String() string   { return stringName(uint32(i), typeStrings, false) }
-func (i Type) GoString() string { return stringName(uint32(i), typeStrings, true) }
-
-// Machine is found in Header.Machine.
-type Machine uint16
-
-const (
-	EM_NONE        Machine = 0  /* Unknown machine. */
-	EM_M32         Machine = 1  /* AT&T WE32100. */
-	EM_SPARC       Machine = 2  /* Sun SPARC. */
-	EM_386         Machine = 3  /* Intel i386. */
-	EM_68K         Machine = 4  /* Motorola 68000. */
-	EM_88K         Machine = 5  /* Motorola 88000. */
-	EM_860         Machine = 7  /* Intel i860. */
-	EM_MIPS        Machine = 8  /* MIPS R3000 Big-Endian only. */
-	EM_S370        Machine = 9  /* IBM System/370. */
-	EM_MIPS_RS3_LE Machine = 10 /* MIPS R3000 Little-Endian. */
-	EM_PARISC      Machine = 15 /* HP PA-RISC. */
-	EM_VPP500      Machine = 17 /* Fujitsu VPP500. */
-	EM_SPARC32PLUS Machine = 18 /* SPARC v8plus. */
-	EM_960         Machine = 19 /* Intel 80960. */
-	EM_PPC         Machine = 20 /* PowerPC 32-bit. */
-	EM_PPC64       Machine = 21 /* PowerPC 64-bit. */
-	EM_S390        Machine = 22 /* IBM System/390. */
-	EM_V800        Machine = 36 /* NEC V800. */
-	EM_FR20        Machine = 37 /* Fujitsu FR20. */
-	EM_RH32        Machine = 38 /* TRW RH-32. */
-	EM_RCE         Machine = 39 /* Motorola RCE. */
-	EM_ARM         Machine = 40 /* ARM. */
-	EM_SH          Machine = 42 /* Hitachi SH. */
-	EM_SPARCV9     Machine = 43 /* SPARC v9 64-bit. */
-	EM_TRICORE     Machine = 44 /* Siemens TriCore embedded processor. */
-	EM_ARC         Machine = 45 /* Argonaut RISC Core. */
-	EM_H8_300      Machine = 46 /* Hitachi H8/300. */
-	EM_H8_300H     Machine = 47 /* Hitachi H8/300H. */
-	EM_H8S         Machine = 48 /* Hitachi H8S. */
-	EM_H8_500      Machine = 49 /* Hitachi H8/500. */
-	EM_IA_64       Machine = 50 /* Intel IA-64 Processor. */
-	EM_MIPS_X      Machine = 51 /* Stanford MIPS-X. */
-	EM_COLDFIRE    Machine = 52 /* Motorola ColdFire. */
-	EM_68HC12      Machine = 53 /* Motorola M68HC12. */
-	EM_MMA         Machine = 54 /* Fujitsu MMA. */
-	EM_PCP         Machine = 55 /* Siemens PCP. */
-	EM_NCPU        Machine = 56 /* Sony nCPU. */
-	EM_NDR1        Machine = 57 /* Denso NDR1 microprocessor. */
-	EM_STARCORE    Machine = 58 /* Motorola Star*Core processor. */
-	EM_ME16        Machine = 59 /* Toyota ME16 processor. */
-	EM_ST100       Machine = 60 /* STMicroelectronics ST100 processor. */
-	EM_TINYJ       Machine = 61 /* Advanced Logic Corp. TinyJ processor. */
-	EM_X86_64      Machine = 62 /* Advanced Micro Devices x86-64 */
-
-	/* Non-standard or deprecated. */
-	EM_486         Machine = 6      /* Intel i486. */
-	EM_MIPS_RS4_BE Machine = 10     /* MIPS R4000 Big-Endian */
-	EM_ALPHA_STD   Machine = 41     /* Digital Alpha (standard value). */
-	EM_ALPHA       Machine = 0x9026 /* Alpha (written in the absence of an ABI) */
-)
-
-var machineStrings = []intName{
-	{0, "EM_NONE"},
-	{1, "EM_M32"},
-	{2, "EM_SPARC"},
-	{3, "EM_386"},
-	{4, "EM_68K"},
-	{5, "EM_88K"},
-	{7, "EM_860"},
-	{8, "EM_MIPS"},
-	{9, "EM_S370"},
-	{10, "EM_MIPS_RS3_LE"},
-	{15, "EM_PARISC"},
-	{17, "EM_VPP500"},
-	{18, "EM_SPARC32PLUS"},
-	{19, "EM_960"},
-	{20, "EM_PPC"},
-	{21, "EM_PPC64"},
-	{22, "EM_S390"},
-	{36, "EM_V800"},
-	{37, "EM_FR20"},
-	{38, "EM_RH32"},
-	{39, "EM_RCE"},
-	{40, "EM_ARM"},
-	{42, "EM_SH"},
-	{43, "EM_SPARCV9"},
-	{44, "EM_TRICORE"},
-	{45, "EM_ARC"},
-	{46, "EM_H8_300"},
-	{47, "EM_H8_300H"},
-	{48, "EM_H8S"},
-	{49, "EM_H8_500"},
-	{50, "EM_IA_64"},
-	{51, "EM_MIPS_X"},
-	{52, "EM_COLDFIRE"},
-	{53, "EM_68HC12"},
-	{54, "EM_MMA"},
-	{55, "EM_PCP"},
-	{56, "EM_NCPU"},
-	{57, "EM_NDR1"},
-	{58, "EM_STARCORE"},
-	{59, "EM_ME16"},
-	{60, "EM_ST100"},
-	{61, "EM_TINYJ"},
-	{62, "EM_X86_64"},
-
-	/* Non-standard or deprecated. */
-	{6, "EM_486"},
-	{10, "EM_MIPS_RS4_BE"},
-	{41, "EM_ALPHA_STD"},
-	{0x9026, "EM_ALPHA"},
-}
-
-func (i Machine) String() string   { return stringName(uint32(i), machineStrings, false) }
-func (i Machine) GoString() string { return stringName(uint32(i), machineStrings, true) }
-
-// Special section indices.
-type SectionIndex int
-
-const (
-	SHN_UNDEF     SectionIndex = 0      /* Undefined, missing, irrelevant. */
-	SHN_LORESERVE SectionIndex = 0xff00 /* First of reserved range. */
-	SHN_LOPROC    SectionIndex = 0xff00 /* First processor-specific. */
-	SHN_HIPROC    SectionIndex = 0xff1f /* Last processor-specific. */
-	SHN_LOOS      SectionIndex = 0xff20 /* First operating system-specific. */
-	SHN_HIOS      SectionIndex = 0xff3f /* Last operating system-specific. */
-	SHN_ABS       SectionIndex = 0xfff1 /* Absolute values. */
-	SHN_COMMON    SectionIndex = 0xfff2 /* Common data. */
-	SHN_XINDEX    SectionIndex = 0xffff /* Escape -- index stored elsewhere. */
-	SHN_HIRESERVE SectionIndex = 0xffff /* Last of reserved range. */
-)
-
-var shnStrings = []intName{
-	{0, "SHN_UNDEF"},
-	{0xff00, "SHN_LOPROC"},
-	{0xff20, "SHN_LOOS"},
-	{0xfff1, "SHN_ABS"},
-	{0xfff2, "SHN_COMMON"},
-	{0xffff, "SHN_XINDEX"},
-}
-
-func (i SectionIndex) String() string   { return stringName(uint32(i), shnStrings, false) }
-func (i SectionIndex) GoString() string { return stringName(uint32(i), shnStrings, true) }
-
-// Section type.
-type SectionType uint32
-
-const (
-	SHT_NULL           SectionType = 0          /* inactive */
-	SHT_PROGBITS       SectionType = 1          /* program defined information */
-	SHT_SYMTAB         SectionType = 2          /* symbol table section */
-	SHT_STRTAB         SectionType = 3          /* string table section */
-	SHT_RELA           SectionType = 4          /* relocation section with addends */
-	SHT_HASH           SectionType = 5          /* symbol hash table section */
-	SHT_DYNAMIC        SectionType = 6          /* dynamic section */
-	SHT_NOTE           SectionType = 7          /* note section */
-	SHT_NOBITS         SectionType = 8          /* no space section */
-	SHT_REL            SectionType = 9          /* relocation section - no addends */
-	SHT_SHLIB          SectionType = 10         /* reserved - purpose unknown */
-	SHT_DYNSYM         SectionType = 11         /* dynamic symbol table section */
-	SHT_INIT_ARRAY     SectionType = 14         /* Initialization function pointers. */
-	SHT_FINI_ARRAY     SectionType = 15         /* Termination function pointers. */
-	SHT_PREINIT_ARRAY  SectionType = 16         /* Pre-initialization function ptrs. */
-	SHT_GROUP          SectionType = 17         /* Section group. */
-	SHT_SYMTAB_SHNDX   SectionType = 18         /* Section indexes (see SHN_XINDEX). */
-	SHT_LOOS           SectionType = 0x60000000 /* First of OS specific semantics */
-	SHT_GNU_ATTRIBUTES SectionType = 0x6ffffff5 /* GNU object attributes */
-	SHT_GNU_HASH       SectionType = 0x6ffffff6 /* GNU hash table */
-	SHT_GNU_LIBLIST    SectionType = 0x6ffffff7 /* GNU prelink library list */
-	SHT_GNU_VERDEF     SectionType = 0x6ffffffd /* GNU version definition section */
-	SHT_GNU_VERNEED    SectionType = 0x6ffffffe /* GNU version needs section */
-	SHT_GNU_VERSYM     SectionType = 0x6fffffff /* GNU version symbol table */
-	SHT_HIOS           SectionType = 0x6fffffff /* Last of OS specific semantics */
-	SHT_LOPROC         SectionType = 0x70000000 /* reserved range for processor */
-	SHT_HIPROC         SectionType = 0x7fffffff /* specific section header types */
-	SHT_LOUSER         SectionType = 0x80000000 /* reserved range for application */
-	SHT_HIUSER         SectionType = 0xffffffff /* specific indexes */
-)
-
-var shtStrings = []intName{
-	{0, "SHT_NULL"},
-	{1, "SHT_PROGBITS"},
-	{2, "SHT_SYMTAB"},
-	{3, "SHT_STRTAB"},
-	{4, "SHT_RELA"},
-	{5, "SHT_HASH"},
-	{6, "SHT_DYNAMIC"},
-	{7, "SHT_NOTE"},
-	{8, "SHT_NOBITS"},
-	{9, "SHT_REL"},
-	{10, "SHT_SHLIB"},
-	{11, "SHT_DYNSYM"},
-	{14, "SHT_INIT_ARRAY"},
-	{15, "SHT_FINI_ARRAY"},
-	{16, "SHT_PREINIT_ARRAY"},
-	{17, "SHT_GROUP"},
-	{18, "SHT_SYMTAB_SHNDX"},
-	{0x60000000, "SHT_LOOS"},
-	{0x6ffffff5, "SHT_GNU_ATTRIBUTES"},
-	{0x6ffffff6, "SHT_GNU_HASH"},
-	{0x6ffffff7, "SHT_GNU_LIBLIST"},
-	{0x6ffffffd, "SHT_GNU_VERDEF"},
-	{0x6ffffffe, "SHT_GNU_VERNEED"},
-	{0x6fffffff, "SHT_GNU_VERSYM"},
-	{0x70000000, "SHT_LOPROC"},
-	{0x7fffffff, "SHT_HIPROC"},
-	{0x80000000, "SHT_LOUSER"},
-	{0xffffffff, "SHT_HIUSER"},
-}
-
-func (i SectionType) String() string   { return stringName(uint32(i), shtStrings, false) }
-func (i SectionType) GoString() string { return stringName(uint32(i), shtStrings, true) }
-
-// Section flags.
-type SectionFlag uint32
-
-const (
-	SHF_WRITE            SectionFlag = 0x1        /* Section contains writable data. */
-	SHF_ALLOC            SectionFlag = 0x2        /* Section occupies memory. */
-	SHF_EXECINSTR        SectionFlag = 0x4        /* Section contains instructions. */
-	SHF_MERGE            SectionFlag = 0x10       /* Section may be merged. */
-	SHF_STRINGS          SectionFlag = 0x20       /* Section contains strings. */
-	SHF_INFO_LINK        SectionFlag = 0x40       /* sh_info holds section index. */
-	SHF_LINK_ORDER       SectionFlag = 0x80       /* Special ordering requirements. */
-	SHF_OS_NONCONFORMING SectionFlag = 0x100      /* OS-specific processing required. */
-	SHF_GROUP            SectionFlag = 0x200      /* Member of section group. */
-	SHF_TLS              SectionFlag = 0x400      /* Section contains TLS data. */
-	SHF_MASKOS           SectionFlag = 0x0ff00000 /* OS-specific semantics. */
-	SHF_MASKPROC         SectionFlag = 0xf0000000 /* Processor-specific semantics. */
-)
-
-var shfStrings = []intName{
-	{0x1, "SHF_WRITE"},
-	{0x2, "SHF_ALLOC"},
-	{0x4, "SHF_EXECINSTR"},
-	{0x10, "SHF_MERGE"},
-	{0x20, "SHF_STRINGS"},
-	{0x40, "SHF_INFO_LINK"},
-	{0x80, "SHF_LINK_ORDER"},
-	{0x100, "SHF_OS_NONCONFORMING"},
-	{0x200, "SHF_GROUP"},
-	{0x400, "SHF_TLS"},
-}
-
-func (i SectionFlag) String() string   { return flagName(uint32(i), shfStrings, false) }
-func (i SectionFlag) GoString() string { return flagName(uint32(i), shfStrings, true) }
-
-// Prog.Type
-type ProgType int
-
-const (
-	PT_NULL    ProgType = 0          /* Unused entry. */
-	PT_LOAD    ProgType = 1          /* Loadable segment. */
-	PT_DYNAMIC ProgType = 2          /* Dynamic linking information segment. */
-	PT_INTERP  ProgType = 3          /* Pathname of interpreter. */
-	PT_NOTE    ProgType = 4          /* Auxiliary information. */
-	PT_SHLIB   ProgType = 5          /* Reserved (not used). */
-	PT_PHDR    ProgType = 6          /* Location of program header itself. */
-	PT_TLS     ProgType = 7          /* Thread local storage segment */
-	PT_LOOS    ProgType = 0x60000000 /* First OS-specific. */
-	PT_HIOS    ProgType = 0x6fffffff /* Last OS-specific. */
-	PT_LOPROC  ProgType = 0x70000000 /* First processor-specific type. */
-	PT_HIPROC  ProgType = 0x7fffffff /* Last processor-specific type. */
-)
-
-var ptStrings = []intName{
-	{0, "PT_NULL"},
-	{1, "PT_LOAD"},
-	{2, "PT_DYNAMIC"},
-	{3, "PT_INTERP"},
-	{4, "PT_NOTE"},
-	{5, "PT_SHLIB"},
-	{6, "PT_PHDR"},
-	{7, "PT_TLS"},
-	{0x60000000, "PT_LOOS"},
-	{0x6fffffff, "PT_HIOS"},
-	{0x70000000, "PT_LOPROC"},
-	{0x7fffffff, "PT_HIPROC"},
-}
-
-func (i ProgType) String() string   { return stringName(uint32(i), ptStrings, false) }
-func (i ProgType) GoString() string { return stringName(uint32(i), ptStrings, true) }
-
-// Prog.Flag
-type ProgFlag uint32
-
-const (
-	PF_X        ProgFlag = 0x1        /* Executable. */
-	PF_W        ProgFlag = 0x2        /* Writable. */
-	PF_R        ProgFlag = 0x4        /* Readable. */
-	PF_MASKOS   ProgFlag = 0x0ff00000 /* Operating system-specific. */
-	PF_MASKPROC ProgFlag = 0xf0000000 /* Processor-specific. */
-)
-
-var pfStrings = []intName{
-	{0x1, "PF_X"},
-	{0x2, "PF_W"},
-	{0x4, "PF_R"},
-}
-
-func (i ProgFlag) String() string   { return flagName(uint32(i), pfStrings, false) }
-func (i ProgFlag) GoString() string { return flagName(uint32(i), pfStrings, true) }
-
-// Dyn.Tag
-type DynTag int
-
-const (
-	DT_NULL         DynTag = 0  /* Terminating entry. */
-	DT_NEEDED       DynTag = 1  /* String table offset of a needed shared library. */
-	DT_PLTRELSZ     DynTag = 2  /* Total size in bytes of PLT relocations. */
-	DT_PLTGOT       DynTag = 3  /* Processor-dependent address. */
-	DT_HASH         DynTag = 4  /* Address of symbol hash table. */
-	DT_STRTAB       DynTag = 5  /* Address of string table. */
-	DT_SYMTAB       DynTag = 6  /* Address of symbol table. */
-	DT_RELA         DynTag = 7  /* Address of ElfNN_Rela relocations. */
-	DT_RELASZ       DynTag = 8  /* Total size of ElfNN_Rela relocations. */
-	DT_RELAENT      DynTag = 9  /* Size of each ElfNN_Rela relocation entry. */
-	DT_STRSZ        DynTag = 10 /* Size of string table. */
-	DT_SYMENT       DynTag = 11 /* Size of each symbol table entry. */
-	DT_INIT         DynTag = 12 /* Address of initialization function. */
-	DT_FINI         DynTag = 13 /* Address of finalization function. */
-	DT_SONAME       DynTag = 14 /* String table offset of shared object name. */
-	DT_RPATH        DynTag = 15 /* String table offset of library path. [sup] */
-	DT_SYMBOLIC     DynTag = 16 /* Indicates "symbolic" linking. [sup] */
-	DT_REL          DynTag = 17 /* Address of ElfNN_Rel relocations. */
-	DT_RELSZ        DynTag = 18 /* Total size of ElfNN_Rel relocations. */
-	DT_RELENT       DynTag = 19 /* Size of each ElfNN_Rel relocation. */
-	DT_PLTREL       DynTag = 20 /* Type of relocation used for PLT. */
-	DT_DEBUG        DynTag = 21 /* Reserved (not used). */
-	DT_TEXTREL      DynTag = 22 /* Indicates there may be relocations in non-writable segments. [sup] */
-	DT_JMPREL       DynTag = 23 /* Address of PLT relocations. */
-	DT_BIND_NOW     DynTag = 24 /* [sup] */
-	DT_INIT_ARRAY   DynTag = 25 /* Address of the array of pointers to initialization functions */
-	DT_FINI_ARRAY   DynTag = 26 /* Address of the array of pointers to termination functions */
-	DT_INIT_ARRAYSZ DynTag = 27 /* Size in bytes of the array of initialization functions. */
-	DT_FINI_ARRAYSZ DynTag = 28 /* Size in bytes of the array of terminationfunctions. */
-	DT_RUNPATH      DynTag = 29 /* String table offset of a null-terminated library search path string. */
-	DT_FLAGS        DynTag = 30 /* Object specific flag values. */
-	DT_ENCODING     DynTag = 32 /* Values greater than or equal to DT_ENCODING
-	   and less than DT_LOOS follow the rules for
-	   the interpretation of the d_un union
-	   as follows: even == 'd_ptr', even == 'd_val'
-	   or none */
-	DT_PREINIT_ARRAY   DynTag = 32         /* Address of the array of pointers to pre-initialization functions. */
-	DT_PREINIT_ARRAYSZ DynTag = 33         /* Size in bytes of the array of pre-initialization functions. */
-	DT_LOOS            DynTag = 0x6000000d /* First OS-specific */
-	DT_HIOS            DynTag = 0x6ffff000 /* Last OS-specific */
-	DT_VERSYM          DynTag = 0x6ffffff0
-	DT_VERNEED         DynTag = 0x6ffffffe
-	DT_VERNEEDNUM      DynTag = 0x6fffffff
-	DT_LOPROC          DynTag = 0x70000000 /* First processor-specific type. */
-	DT_HIPROC          DynTag = 0x7fffffff /* Last processor-specific type. */
-)
-
-var dtStrings = []intName{
-	{0, "DT_NULL"},
-	{1, "DT_NEEDED"},
-	{2, "DT_PLTRELSZ"},
-	{3, "DT_PLTGOT"},
-	{4, "DT_HASH"},
-	{5, "DT_STRTAB"},
-	{6, "DT_SYMTAB"},
-	{7, "DT_RELA"},
-	{8, "DT_RELASZ"},
-	{9, "DT_RELAENT"},
-	{10, "DT_STRSZ"},
-	{11, "DT_SYMENT"},
-	{12, "DT_INIT"},
-	{13, "DT_FINI"},
-	{14, "DT_SONAME"},
-	{15, "DT_RPATH"},
-	{16, "DT_SYMBOLIC"},
-	{17, "DT_REL"},
-	{18, "DT_RELSZ"},
-	{19, "DT_RELENT"},
-	{20, "DT_PLTREL"},
-	{21, "DT_DEBUG"},
-	{22, "DT_TEXTREL"},
-	{23, "DT_JMPREL"},
-	{24, "DT_BIND_NOW"},
-	{25, "DT_INIT_ARRAY"},
-	{26, "DT_FINI_ARRAY"},
-	{27, "DT_INIT_ARRAYSZ"},
-	{28, "DT_FINI_ARRAYSZ"},
-	{29, "DT_RUNPATH"},
-	{30, "DT_FLAGS"},
-	{32, "DT_ENCODING"},
-	{32, "DT_PREINIT_ARRAY"},
-	{33, "DT_PREINIT_ARRAYSZ"},
-	{0x6000000d, "DT_LOOS"},
-	{0x6ffff000, "DT_HIOS"},
-	{0x6ffffff0, "DT_VERSYM"},
-	{0x6ffffffe, "DT_VERNEED"},
-	{0x6fffffff, "DT_VERNEEDNUM"},
-	{0x70000000, "DT_LOPROC"},
-	{0x7fffffff, "DT_HIPROC"},
-}
-
-func (i DynTag) String() string   { return stringName(uint32(i), dtStrings, false) }
-func (i DynTag) GoString() string { return stringName(uint32(i), dtStrings, true) }
-
-// DT_FLAGS values.
-type DynFlag int
-
-const (
-	DF_ORIGIN DynFlag = 0x0001 /* Indicates that the object being loaded may
-	   make reference to the
-	   $ORIGIN substitution string */
-	DF_SYMBOLIC DynFlag = 0x0002 /* Indicates "symbolic" linking. */
-	DF_TEXTREL  DynFlag = 0x0004 /* Indicates there may be relocations in non-writable segments. */
-	DF_BIND_NOW DynFlag = 0x0008 /* Indicates that the dynamic linker should
-	   process all relocations for the object
-	   containing this entry before transferring
-	   control to the program. */
-	DF_STATIC_TLS DynFlag = 0x0010 /* Indicates that the shared object or
-	   executable contains code using a static
-	   thread-local storage scheme. */
-)
-
-var dflagStrings = []intName{
-	{0x0001, "DF_ORIGIN"},
-	{0x0002, "DF_SYMBOLIC"},
-	{0x0004, "DF_TEXTREL"},
-	{0x0008, "DF_BIND_NOW"},
-	{0x0010, "DF_STATIC_TLS"},
-}
-
-func (i DynFlag) String() string   { return flagName(uint32(i), dflagStrings, false) }
-func (i DynFlag) GoString() string { return flagName(uint32(i), dflagStrings, true) }
-
-// NType values; used in core files.
-type NType int
-
-const (
-	NT_PRSTATUS NType = 1 /* Process status. */
-	NT_FPREGSET NType = 2 /* Floating point registers. */
-	NT_PRPSINFO NType = 3 /* Process state info. */
-)
-
-var ntypeStrings = []intName{
-	{1, "NT_PRSTATUS"},
-	{2, "NT_FPREGSET"},
-	{3, "NT_PRPSINFO"},
-}
-
-func (i NType) String() string   { return stringName(uint32(i), ntypeStrings, false) }
-func (i NType) GoString() string { return stringName(uint32(i), ntypeStrings, true) }
-
-/* Symbol Binding - ELFNN_ST_BIND - st_info */
-type SymBind int
-
-const (
-	STB_LOCAL  SymBind = 0  /* Local symbol */
-	STB_GLOBAL SymBind = 1  /* Global symbol */
-	STB_WEAK   SymBind = 2  /* like global - lower precedence */
-	STB_LOOS   SymBind = 10 /* Reserved range for operating system */
-	STB_HIOS   SymBind = 12 /*   specific semantics. */
-	STB_LOPROC SymBind = 13 /* reserved range for processor */
-	STB_HIPROC SymBind = 15 /*   specific semantics. */
-)
-
-var stbStrings = []intName{
-	{0, "STB_LOCAL"},
-	{1, "STB_GLOBAL"},
-	{2, "STB_WEAK"},
-	{10, "STB_LOOS"},
-	{12, "STB_HIOS"},
-	{13, "STB_LOPROC"},
-	{15, "STB_HIPROC"},
-}
-
-func (i SymBind) String() string   { return stringName(uint32(i), stbStrings, false) }
-func (i SymBind) GoString() string { return stringName(uint32(i), stbStrings, true) }
-
-/* Symbol type - ELFNN_ST_TYPE - st_info */
-type SymType int
-
-const (
-	STT_NOTYPE  SymType = 0  /* Unspecified type. */
-	STT_OBJECT  SymType = 1  /* Data object. */
-	STT_FUNC    SymType = 2  /* Function. */
-	STT_SECTION SymType = 3  /* Section. */
-	STT_FILE    SymType = 4  /* Source file. */
-	STT_COMMON  SymType = 5  /* Uninitialized common block. */
-	STT_TLS     SymType = 6  /* TLS object. */
-	STT_LOOS    SymType = 10 /* Reserved range for operating system */
-	STT_HIOS    SymType = 12 /*   specific semantics. */
-	STT_LOPROC  SymType = 13 /* reserved range for processor */
-	STT_HIPROC  SymType = 15 /*   specific semantics. */
-)
-
-var sttStrings = []intName{
-	{0, "STT_NOTYPE"},
-	{1, "STT_OBJECT"},
-	{2, "STT_FUNC"},
-	{3, "STT_SECTION"},
-	{4, "STT_FILE"},
-	{5, "STT_COMMON"},
-	{6, "STT_TLS"},
-	{10, "STT_LOOS"},
-	{12, "STT_HIOS"},
-	{13, "STT_LOPROC"},
-	{15, "STT_HIPROC"},
-}
-
-func (i SymType) String() string   { return stringName(uint32(i), sttStrings, false) }
-func (i SymType) GoString() string { return stringName(uint32(i), sttStrings, true) }
-
-/* Symbol visibility - ELFNN_ST_VISIBILITY - st_other */
-type SymVis int
-
-const (
-	STV_DEFAULT   SymVis = 0x0 /* Default visibility (see binding). */
-	STV_INTERNAL  SymVis = 0x1 /* Special meaning in relocatable objects. */
-	STV_HIDDEN    SymVis = 0x2 /* Not visible. */
-	STV_PROTECTED SymVis = 0x3 /* Visible but not preemptible. */
-)
-
-var stvStrings = []intName{
-	{0x0, "STV_DEFAULT"},
-	{0x1, "STV_INTERNAL"},
-	{0x2, "STV_HIDDEN"},
-	{0x3, "STV_PROTECTED"},
-}
-
-func (i SymVis) String() string   { return stringName(uint32(i), stvStrings, false) }
-func (i SymVis) GoString() string { return stringName(uint32(i), stvStrings, true) }
-
-/*
- * Relocation types.
- */
-
-// Relocation types for x86-64.
-type R_X86_64 int
-
-const (
-	R_X86_64_NONE     R_X86_64 = 0  /* No relocation. */
-	R_X86_64_64       R_X86_64 = 1  /* Add 64 bit symbol value. */
-	R_X86_64_PC32     R_X86_64 = 2  /* PC-relative 32 bit signed sym value. */
-	R_X86_64_GOT32    R_X86_64 = 3  /* PC-relative 32 bit GOT offset. */
-	R_X86_64_PLT32    R_X86_64 = 4  /* PC-relative 32 bit PLT offset. */
-	R_X86_64_COPY     R_X86_64 = 5  /* Copy data from shared object. */
-	R_X86_64_GLOB_DAT R_X86_64 = 6  /* Set GOT entry to data address. */
-	R_X86_64_JMP_SLOT R_X86_64 = 7  /* Set GOT entry to code address. */
-	R_X86_64_RELATIVE R_X86_64 = 8  /* Add load address of shared object. */
-	R_X86_64_GOTPCREL R_X86_64 = 9  /* Add 32 bit signed pcrel offset to GOT. */
-	R_X86_64_32       R_X86_64 = 10 /* Add 32 bit zero extended symbol value */
-	R_X86_64_32S      R_X86_64 = 11 /* Add 32 bit sign extended symbol value */
-	R_X86_64_16       R_X86_64 = 12 /* Add 16 bit zero extended symbol value */
-	R_X86_64_PC16     R_X86_64 = 13 /* Add 16 bit signed extended pc relative symbol value */
-	R_X86_64_8        R_X86_64 = 14 /* Add 8 bit zero extended symbol value */
-	R_X86_64_PC8      R_X86_64 = 15 /* Add 8 bit signed extended pc relative symbol value */
-	R_X86_64_DTPMOD64 R_X86_64 = 16 /* ID of module containing symbol */
-	R_X86_64_DTPOFF64 R_X86_64 = 17 /* Offset in TLS block */
-	R_X86_64_TPOFF64  R_X86_64 = 18 /* Offset in static TLS block */
-	R_X86_64_TLSGD    R_X86_64 = 19 /* PC relative offset to GD GOT entry */
-	R_X86_64_TLSLD    R_X86_64 = 20 /* PC relative offset to LD GOT entry */
-	R_X86_64_DTPOFF32 R_X86_64 = 21 /* Offset in TLS block */
-	R_X86_64_GOTTPOFF R_X86_64 = 22 /* PC relative offset to IE GOT entry */
-	R_X86_64_TPOFF32  R_X86_64 = 23 /* Offset in static TLS block */
-)
-
-var rx86_64Strings = []intName{
-	{0, "R_X86_64_NONE"},
-	{1, "R_X86_64_64"},
-	{2, "R_X86_64_PC32"},
-	{3, "R_X86_64_GOT32"},
-	{4, "R_X86_64_PLT32"},
-	{5, "R_X86_64_COPY"},
-	{6, "R_X86_64_GLOB_DAT"},
-	{7, "R_X86_64_JMP_SLOT"},
-	{8, "R_X86_64_RELATIVE"},
-	{9, "R_X86_64_GOTPCREL"},
-	{10, "R_X86_64_32"},
-	{11, "R_X86_64_32S"},
-	{12, "R_X86_64_16"},
-	{13, "R_X86_64_PC16"},
-	{14, "R_X86_64_8"},
-	{15, "R_X86_64_PC8"},
-	{16, "R_X86_64_DTPMOD64"},
-	{17, "R_X86_64_DTPOFF64"},
-	{18, "R_X86_64_TPOFF64"},
-	{19, "R_X86_64_TLSGD"},
-	{20, "R_X86_64_TLSLD"},
-	{21, "R_X86_64_DTPOFF32"},
-	{22, "R_X86_64_GOTTPOFF"},
-	{23, "R_X86_64_TPOFF32"},
-}
-
-func (i R_X86_64) String() string   { return stringName(uint32(i), rx86_64Strings, false) }
-func (i R_X86_64) GoString() string { return stringName(uint32(i), rx86_64Strings, true) }
-
-// Relocation types for Alpha.
-type R_ALPHA int
-
-const (
-	R_ALPHA_NONE           R_ALPHA = 0  /* No reloc */
-	R_ALPHA_REFLONG        R_ALPHA = 1  /* Direct 32 bit */
-	R_ALPHA_REFQUAD        R_ALPHA = 2  /* Direct 64 bit */
-	R_ALPHA_GPREL32        R_ALPHA = 3  /* GP relative 32 bit */
-	R_ALPHA_LITERAL        R_ALPHA = 4  /* GP relative 16 bit w/optimization */
-	R_ALPHA_LITUSE         R_ALPHA = 5  /* Optimization hint for LITERAL */
-	R_ALPHA_GPDISP         R_ALPHA = 6  /* Add displacement to GP */
-	R_ALPHA_BRADDR         R_ALPHA = 7  /* PC+4 relative 23 bit shifted */
-	R_ALPHA_HINT           R_ALPHA = 8  /* PC+4 relative 16 bit shifted */
-	R_ALPHA_SREL16         R_ALPHA = 9  /* PC relative 16 bit */
-	R_ALPHA_SREL32         R_ALPHA = 10 /* PC relative 32 bit */
-	R_ALPHA_SREL64         R_ALPHA = 11 /* PC relative 64 bit */
-	R_ALPHA_OP_PUSH        R_ALPHA = 12 /* OP stack push */
-	R_ALPHA_OP_STORE       R_ALPHA = 13 /* OP stack pop and store */
-	R_ALPHA_OP_PSUB        R_ALPHA = 14 /* OP stack subtract */
-	R_ALPHA_OP_PRSHIFT     R_ALPHA = 15 /* OP stack right shift */
-	R_ALPHA_GPVALUE        R_ALPHA = 16
-	R_ALPHA_GPRELHIGH      R_ALPHA = 17
-	R_ALPHA_GPRELLOW       R_ALPHA = 18
-	R_ALPHA_IMMED_GP_16    R_ALPHA = 19
-	R_ALPHA_IMMED_GP_HI32  R_ALPHA = 20
-	R_ALPHA_IMMED_SCN_HI32 R_ALPHA = 21
-	R_ALPHA_IMMED_BR_HI32  R_ALPHA = 22
-	R_ALPHA_IMMED_LO32     R_ALPHA = 23
-	R_ALPHA_COPY           R_ALPHA = 24 /* Copy symbol at runtime */
-	R_ALPHA_GLOB_DAT       R_ALPHA = 25 /* Create GOT entry */
-	R_ALPHA_JMP_SLOT       R_ALPHA = 26 /* Create PLT entry */
-	R_ALPHA_RELATIVE       R_ALPHA = 27 /* Adjust by program base */
-)
-
-var ralphaStrings = []intName{
-	{0, "R_ALPHA_NONE"},
-	{1, "R_ALPHA_REFLONG"},
-	{2, "R_ALPHA_REFQUAD"},
-	{3, "R_ALPHA_GPREL32"},
-	{4, "R_ALPHA_LITERAL"},
-	{5, "R_ALPHA_LITUSE"},
-	{6, "R_ALPHA_GPDISP"},
-	{7, "R_ALPHA_BRADDR"},
-	{8, "R_ALPHA_HINT"},
-	{9, "R_ALPHA_SREL16"},
-	{10, "R_ALPHA_SREL32"},
-	{11, "R_ALPHA_SREL64"},
-	{12, "R_ALPHA_OP_PUSH"},
-	{13, "R_ALPHA_OP_STORE"},
-	{14, "R_ALPHA_OP_PSUB"},
-	{15, "R_ALPHA_OP_PRSHIFT"},
-	{16, "R_ALPHA_GPVALUE"},
-	{17, "R_ALPHA_GPRELHIGH"},
-	{18, "R_ALPHA_GPRELLOW"},
-	{19, "R_ALPHA_IMMED_GP_16"},
-	{20, "R_ALPHA_IMMED_GP_HI32"},
-	{21, "R_ALPHA_IMMED_SCN_HI32"},
-	{22, "R_ALPHA_IMMED_BR_HI32"},
-	{23, "R_ALPHA_IMMED_LO32"},
-	{24, "R_ALPHA_COPY"},
-	{25, "R_ALPHA_GLOB_DAT"},
-	{26, "R_ALPHA_JMP_SLOT"},
-	{27, "R_ALPHA_RELATIVE"},
-}
-
-func (i R_ALPHA) String() string   { return stringName(uint32(i), ralphaStrings, false) }
-func (i R_ALPHA) GoString() string { return stringName(uint32(i), ralphaStrings, true) }
-
-// Relocation types for ARM.
-type R_ARM int
-
-const (
-	R_ARM_NONE          R_ARM = 0 /* No relocation. */
-	R_ARM_PC24          R_ARM = 1
-	R_ARM_ABS32         R_ARM = 2
-	R_ARM_REL32         R_ARM = 3
-	R_ARM_PC13          R_ARM = 4
-	R_ARM_ABS16         R_ARM = 5
-	R_ARM_ABS12         R_ARM = 6
-	R_ARM_THM_ABS5      R_ARM = 7
-	R_ARM_ABS8          R_ARM = 8
-	R_ARM_SBREL32       R_ARM = 9
-	R_ARM_THM_PC22      R_ARM = 10
-	R_ARM_THM_PC8       R_ARM = 11
-	R_ARM_AMP_VCALL9    R_ARM = 12
-	R_ARM_SWI24         R_ARM = 13
-	R_ARM_THM_SWI8      R_ARM = 14
-	R_ARM_XPC25         R_ARM = 15
-	R_ARM_THM_XPC22     R_ARM = 16
-	R_ARM_COPY          R_ARM = 20 /* Copy data from shared object. */
-	R_ARM_GLOB_DAT      R_ARM = 21 /* Set GOT entry to data address. */
-	R_ARM_JUMP_SLOT     R_ARM = 22 /* Set GOT entry to code address. */
-	R_ARM_RELATIVE      R_ARM = 23 /* Add load address of shared object. */
-	R_ARM_GOTOFF        R_ARM = 24 /* Add GOT-relative symbol address. */
-	R_ARM_GOTPC         R_ARM = 25 /* Add PC-relative GOT table address. */
-	R_ARM_GOT32         R_ARM = 26 /* Add PC-relative GOT offset. */
-	R_ARM_PLT32         R_ARM = 27 /* Add PC-relative PLT offset. */
-	R_ARM_GNU_VTENTRY   R_ARM = 100
-	R_ARM_GNU_VTINHERIT R_ARM = 101
-	R_ARM_RSBREL32      R_ARM = 250
-	R_ARM_THM_RPC22     R_ARM = 251
-	R_ARM_RREL32        R_ARM = 252
-	R_ARM_RABS32        R_ARM = 253
-	R_ARM_RPC24         R_ARM = 254
-	R_ARM_RBASE         R_ARM = 255
-)
-
-var rarmStrings = []intName{
-	{0, "R_ARM_NONE"},
-	{1, "R_ARM_PC24"},
-	{2, "R_ARM_ABS32"},
-	{3, "R_ARM_REL32"},
-	{4, "R_ARM_PC13"},
-	{5, "R_ARM_ABS16"},
-	{6, "R_ARM_ABS12"},
-	{7, "R_ARM_THM_ABS5"},
-	{8, "R_ARM_ABS8"},
-	{9, "R_ARM_SBREL32"},
-	{10, "R_ARM_THM_PC22"},
-	{11, "R_ARM_THM_PC8"},
-	{12, "R_ARM_AMP_VCALL9"},
-	{13, "R_ARM_SWI24"},
-	{14, "R_ARM_THM_SWI8"},
-	{15, "R_ARM_XPC25"},
-	{16, "R_ARM_THM_XPC22"},
-	{20, "R_ARM_COPY"},
-	{21, "R_ARM_GLOB_DAT"},
-	{22, "R_ARM_JUMP_SLOT"},
-	{23, "R_ARM_RELATIVE"},
-	{24, "R_ARM_GOTOFF"},
-	{25, "R_ARM_GOTPC"},
-	{26, "R_ARM_GOT32"},
-	{27, "R_ARM_PLT32"},
-	{100, "R_ARM_GNU_VTENTRY"},
-	{101, "R_ARM_GNU_VTINHERIT"},
-	{250, "R_ARM_RSBREL32"},
-	{251, "R_ARM_THM_RPC22"},
-	{252, "R_ARM_RREL32"},
-	{253, "R_ARM_RABS32"},
-	{254, "R_ARM_RPC24"},
-	{255, "R_ARM_RBASE"},
-}
-
-func (i R_ARM) String() string   { return stringName(uint32(i), rarmStrings, false) }
-func (i R_ARM) GoString() string { return stringName(uint32(i), rarmStrings, true) }
-
-// Relocation types for 386.
-type R_386 int
-
-const (
-	R_386_NONE         R_386 = 0  /* No relocation. */
-	R_386_32           R_386 = 1  /* Add symbol value. */
-	R_386_PC32         R_386 = 2  /* Add PC-relative symbol value. */
-	R_386_GOT32        R_386 = 3  /* Add PC-relative GOT offset. */
-	R_386_PLT32        R_386 = 4  /* Add PC-relative PLT offset. */
-	R_386_COPY         R_386 = 5  /* Copy data from shared object. */
-	R_386_GLOB_DAT     R_386 = 6  /* Set GOT entry to data address. */
-	R_386_JMP_SLOT     R_386 = 7  /* Set GOT entry to code address. */
-	R_386_RELATIVE     R_386 = 8  /* Add load address of shared object. */
-	R_386_GOTOFF       R_386 = 9  /* Add GOT-relative symbol address. */
-	R_386_GOTPC        R_386 = 10 /* Add PC-relative GOT table address. */
-	R_386_TLS_TPOFF    R_386 = 14 /* Negative offset in static TLS block */
-	R_386_TLS_IE       R_386 = 15 /* Absolute address of GOT for -ve static TLS */
-	R_386_TLS_GOTIE    R_386 = 16 /* GOT entry for negative static TLS block */
-	R_386_TLS_LE       R_386 = 17 /* Negative offset relative to static TLS */
-	R_386_TLS_GD       R_386 = 18 /* 32 bit offset to GOT (index,off) pair */
-	R_386_TLS_LDM      R_386 = 19 /* 32 bit offset to GOT (index,zero) pair */
-	R_386_TLS_GD_32    R_386 = 24 /* 32 bit offset to GOT (index,off) pair */
-	R_386_TLS_GD_PUSH  R_386 = 25 /* pushl instruction for Sun ABI GD sequence */
-	R_386_TLS_GD_CALL  R_386 = 26 /* call instruction for Sun ABI GD sequence */
-	R_386_TLS_GD_POP   R_386 = 27 /* popl instruction for Sun ABI GD sequence */
-	R_386_TLS_LDM_32   R_386 = 28 /* 32 bit offset to GOT (index,zero) pair */
-	R_386_TLS_LDM_PUSH R_386 = 29 /* pushl instruction for Sun ABI LD sequence */
-	R_386_TLS_LDM_CALL R_386 = 30 /* call instruction for Sun ABI LD sequence */
-	R_386_TLS_LDM_POP  R_386 = 31 /* popl instruction for Sun ABI LD sequence */
-	R_386_TLS_LDO_32   R_386 = 32 /* 32 bit offset from start of TLS block */
-	R_386_TLS_IE_32    R_386 = 33 /* 32 bit offset to GOT static TLS offset entry */
-	R_386_TLS_LE_32    R_386 = 34 /* 32 bit offset within static TLS block */
-	R_386_TLS_DTPMOD32 R_386 = 35 /* GOT entry containing TLS index */
-	R_386_TLS_DTPOFF32 R_386 = 36 /* GOT entry containing TLS offset */
-	R_386_TLS_TPOFF32  R_386 = 37 /* GOT entry of -ve static TLS offset */
-)
-
-var r386Strings = []intName{
-	{0, "R_386_NONE"},
-	{1, "R_386_32"},
-	{2, "R_386_PC32"},
-	{3, "R_386_GOT32"},
-	{4, "R_386_PLT32"},
-	{5, "R_386_COPY"},
-	{6, "R_386_GLOB_DAT"},
-	{7, "R_386_JMP_SLOT"},
-	{8, "R_386_RELATIVE"},
-	{9, "R_386_GOTOFF"},
-	{10, "R_386_GOTPC"},
-	{14, "R_386_TLS_TPOFF"},
-	{15, "R_386_TLS_IE"},
-	{16, "R_386_TLS_GOTIE"},
-	{17, "R_386_TLS_LE"},
-	{18, "R_386_TLS_GD"},
-	{19, "R_386_TLS_LDM"},
-	{24, "R_386_TLS_GD_32"},
-	{25, "R_386_TLS_GD_PUSH"},
-	{26, "R_386_TLS_GD_CALL"},
-	{27, "R_386_TLS_GD_POP"},
-	{28, "R_386_TLS_LDM_32"},
-	{29, "R_386_TLS_LDM_PUSH"},
-	{30, "R_386_TLS_LDM_CALL"},
-	{31, "R_386_TLS_LDM_POP"},
-	{32, "R_386_TLS_LDO_32"},
-	{33, "R_386_TLS_IE_32"},
-	{34, "R_386_TLS_LE_32"},
-	{35, "R_386_TLS_DTPMOD32"},
-	{36, "R_386_TLS_DTPOFF32"},
-	{37, "R_386_TLS_TPOFF32"},
-}
-
-func (i R_386) String() string   { return stringName(uint32(i), r386Strings, false) }
-func (i R_386) GoString() string { return stringName(uint32(i), r386Strings, true) }
-
-// Relocation types for PowerPC.
-type R_PPC int
-
-const (
-	R_PPC_NONE            R_PPC = 0 /* No relocation. */
-	R_PPC_ADDR32          R_PPC = 1
-	R_PPC_ADDR24          R_PPC = 2
-	R_PPC_ADDR16          R_PPC = 3
-	R_PPC_ADDR16_LO       R_PPC = 4
-	R_PPC_ADDR16_HI       R_PPC = 5
-	R_PPC_ADDR16_HA       R_PPC = 6
-	R_PPC_ADDR14          R_PPC = 7
-	R_PPC_ADDR14_BRTAKEN  R_PPC = 8
-	R_PPC_ADDR14_BRNTAKEN R_PPC = 9
-	R_PPC_REL24           R_PPC = 10
-	R_PPC_REL14           R_PPC = 11
-	R_PPC_REL14_BRTAKEN   R_PPC = 12
-	R_PPC_REL14_BRNTAKEN  R_PPC = 13
-	R_PPC_GOT16           R_PPC = 14
-	R_PPC_GOT16_LO        R_PPC = 15
-	R_PPC_GOT16_HI        R_PPC = 16
-	R_PPC_GOT16_HA        R_PPC = 17
-	R_PPC_PLTREL24        R_PPC = 18
-	R_PPC_COPY            R_PPC = 19
-	R_PPC_GLOB_DAT        R_PPC = 20
-	R_PPC_JMP_SLOT        R_PPC = 21
-	R_PPC_RELATIVE        R_PPC = 22
-	R_PPC_LOCAL24PC       R_PPC = 23
-	R_PPC_UADDR32         R_PPC = 24
-	R_PPC_UADDR16         R_PPC = 25
-	R_PPC_REL32           R_PPC = 26
-	R_PPC_PLT32           R_PPC = 27
-	R_PPC_PLTREL32        R_PPC = 28
-	R_PPC_PLT16_LO        R_PPC = 29
-	R_PPC_PLT16_HI        R_PPC = 30
-	R_PPC_PLT16_HA        R_PPC = 31
-	R_PPC_SDAREL16        R_PPC = 32
-	R_PPC_SECTOFF         R_PPC = 33
-	R_PPC_SECTOFF_LO      R_PPC = 34
-	R_PPC_SECTOFF_HI      R_PPC = 35
-	R_PPC_SECTOFF_HA      R_PPC = 36
-	R_PPC_TLS             R_PPC = 67
-	R_PPC_DTPMOD32        R_PPC = 68
-	R_PPC_TPREL16         R_PPC = 69
-	R_PPC_TPREL16_LO      R_PPC = 70
-	R_PPC_TPREL16_HI      R_PPC = 71
-	R_PPC_TPREL16_HA      R_PPC = 72
-	R_PPC_TPREL32         R_PPC = 73
-	R_PPC_DTPREL16        R_PPC = 74
-	R_PPC_DTPREL16_LO     R_PPC = 75
-	R_PPC_DTPREL16_HI     R_PPC = 76
-	R_PPC_DTPREL16_HA     R_PPC = 77
-	R_PPC_DTPREL32        R_PPC = 78
-	R_PPC_GOT_TLSGD16     R_PPC = 79
-	R_PPC_GOT_TLSGD16_LO  R_PPC = 80
-	R_PPC_GOT_TLSGD16_HI  R_PPC = 81
-	R_PPC_GOT_TLSGD16_HA  R_PPC = 82
-	R_PPC_GOT_TLSLD16     R_PPC = 83
-	R_PPC_GOT_TLSLD16_LO  R_PPC = 84
-	R_PPC_GOT_TLSLD16_HI  R_PPC = 85
-	R_PPC_GOT_TLSLD16_HA  R_PPC = 86
-	R_PPC_GOT_TPREL16     R_PPC = 87
-	R_PPC_GOT_TPREL16_LO  R_PPC = 88
-	R_PPC_GOT_TPREL16_HI  R_PPC = 89
-	R_PPC_GOT_TPREL16_HA  R_PPC = 90
-	R_PPC_EMB_NADDR32     R_PPC = 101
-	R_PPC_EMB_NADDR16     R_PPC = 102
-	R_PPC_EMB_NADDR16_LO  R_PPC = 103
-	R_PPC_EMB_NADDR16_HI  R_PPC = 104
-	R_PPC_EMB_NADDR16_HA  R_PPC = 105
-	R_PPC_EMB_SDAI16      R_PPC = 106
-	R_PPC_EMB_SDA2I16     R_PPC = 107
-	R_PPC_EMB_SDA2REL     R_PPC = 108
-	R_PPC_EMB_SDA21       R_PPC = 109
-	R_PPC_EMB_MRKREF      R_PPC = 110
-	R_PPC_EMB_RELSEC16    R_PPC = 111
-	R_PPC_EMB_RELST_LO    R_PPC = 112
-	R_PPC_EMB_RELST_HI    R_PPC = 113
-	R_PPC_EMB_RELST_HA    R_PPC = 114
-	R_PPC_EMB_BIT_FLD     R_PPC = 115
-	R_PPC_EMB_RELSDA      R_PPC = 116
-)
-
-var rppcStrings = []intName{
-	{0, "R_PPC_NONE"},
-	{1, "R_PPC_ADDR32"},
-	{2, "R_PPC_ADDR24"},
-	{3, "R_PPC_ADDR16"},
-	{4, "R_PPC_ADDR16_LO"},
-	{5, "R_PPC_ADDR16_HI"},
-	{6, "R_PPC_ADDR16_HA"},
-	{7, "R_PPC_ADDR14"},
-	{8, "R_PPC_ADDR14_BRTAKEN"},
-	{9, "R_PPC_ADDR14_BRNTAKEN"},
-	{10, "R_PPC_REL24"},
-	{11, "R_PPC_REL14"},
-	{12, "R_PPC_REL14_BRTAKEN"},
-	{13, "R_PPC_REL14_BRNTAKEN"},
-	{14, "R_PPC_GOT16"},
-	{15, "R_PPC_GOT16_LO"},
-	{16, "R_PPC_GOT16_HI"},
-	{17, "R_PPC_GOT16_HA"},
-	{18, "R_PPC_PLTREL24"},
-	{19, "R_PPC_COPY"},
-	{20, "R_PPC_GLOB_DAT"},
-	{21, "R_PPC_JMP_SLOT"},
-	{22, "R_PPC_RELATIVE"},
-	{23, "R_PPC_LOCAL24PC"},
-	{24, "R_PPC_UADDR32"},
-	{25, "R_PPC_UADDR16"},
-	{26, "R_PPC_REL32"},
-	{27, "R_PPC_PLT32"},
-	{28, "R_PPC_PLTREL32"},
-	{29, "R_PPC_PLT16_LO"},
-	{30, "R_PPC_PLT16_HI"},
-	{31, "R_PPC_PLT16_HA"},
-	{32, "R_PPC_SDAREL16"},
-	{33, "R_PPC_SECTOFF"},
-	{34, "R_PPC_SECTOFF_LO"},
-	{35, "R_PPC_SECTOFF_HI"},
-	{36, "R_PPC_SECTOFF_HA"},
-
-	{67, "R_PPC_TLS"},
-	{68, "R_PPC_DTPMOD32"},
-	{69, "R_PPC_TPREL16"},
-	{70, "R_PPC_TPREL16_LO"},
-	{71, "R_PPC_TPREL16_HI"},
-	{72, "R_PPC_TPREL16_HA"},
-	{73, "R_PPC_TPREL32"},
-	{74, "R_PPC_DTPREL16"},
-	{75, "R_PPC_DTPREL16_LO"},
-	{76, "R_PPC_DTPREL16_HI"},
-	{77, "R_PPC_DTPREL16_HA"},
-	{78, "R_PPC_DTPREL32"},
-	{79, "R_PPC_GOT_TLSGD16"},
-	{80, "R_PPC_GOT_TLSGD16_LO"},
-	{81, "R_PPC_GOT_TLSGD16_HI"},
-	{82, "R_PPC_GOT_TLSGD16_HA"},
-	{83, "R_PPC_GOT_TLSLD16"},
-	{84, "R_PPC_GOT_TLSLD16_LO"},
-	{85, "R_PPC_GOT_TLSLD16_HI"},
-	{86, "R_PPC_GOT_TLSLD16_HA"},
-	{87, "R_PPC_GOT_TPREL16"},
-	{88, "R_PPC_GOT_TPREL16_LO"},
-	{89, "R_PPC_GOT_TPREL16_HI"},
-	{90, "R_PPC_GOT_TPREL16_HA"},
-
-	{101, "R_PPC_EMB_NADDR32"},
-	{102, "R_PPC_EMB_NADDR16"},
-	{103, "R_PPC_EMB_NADDR16_LO"},
-	{104, "R_PPC_EMB_NADDR16_HI"},
-	{105, "R_PPC_EMB_NADDR16_HA"},
-	{106, "R_PPC_EMB_SDAI16"},
-	{107, "R_PPC_EMB_SDA2I16"},
-	{108, "R_PPC_EMB_SDA2REL"},
-	{109, "R_PPC_EMB_SDA21"},
-	{110, "R_PPC_EMB_MRKREF"},
-	{111, "R_PPC_EMB_RELSEC16"},
-	{112, "R_PPC_EMB_RELST_LO"},
-	{113, "R_PPC_EMB_RELST_HI"},
-	{114, "R_PPC_EMB_RELST_HA"},
-	{115, "R_PPC_EMB_BIT_FLD"},
-	{116, "R_PPC_EMB_RELSDA"},
-}
-
-func (i R_PPC) String() string   { return stringName(uint32(i), rppcStrings, false) }
-func (i R_PPC) GoString() string { return stringName(uint32(i), rppcStrings, true) }
-
-// Relocation types for SPARC.
-type R_SPARC int
-
-const (
-	R_SPARC_NONE     R_SPARC = 0
-	R_SPARC_8        R_SPARC = 1
-	R_SPARC_16       R_SPARC = 2
-	R_SPARC_32       R_SPARC = 3
-	R_SPARC_DISP8    R_SPARC = 4
-	R_SPARC_DISP16   R_SPARC = 5
-	R_SPARC_DISP32   R_SPARC = 6
-	R_SPARC_WDISP30  R_SPARC = 7
-	R_SPARC_WDISP22  R_SPARC = 8
-	R_SPARC_HI22     R_SPARC = 9
-	R_SPARC_22       R_SPARC = 10
-	R_SPARC_13       R_SPARC = 11
-	R_SPARC_LO10     R_SPARC = 12
-	R_SPARC_GOT10    R_SPARC = 13
-	R_SPARC_GOT13    R_SPARC = 14
-	R_SPARC_GOT22    R_SPARC = 15
-	R_SPARC_PC10     R_SPARC = 16
-	R_SPARC_PC22     R_SPARC = 17
-	R_SPARC_WPLT30   R_SPARC = 18
-	R_SPARC_COPY     R_SPARC = 19
-	R_SPARC_GLOB_DAT R_SPARC = 20
-	R_SPARC_JMP_SLOT R_SPARC = 21
-	R_SPARC_RELATIVE R_SPARC = 22
-	R_SPARC_UA32     R_SPARC = 23
-	R_SPARC_PLT32    R_SPARC = 24
-	R_SPARC_HIPLT22  R_SPARC = 25
-	R_SPARC_LOPLT10  R_SPARC = 26
-	R_SPARC_PCPLT32  R_SPARC = 27
-	R_SPARC_PCPLT22  R_SPARC = 28
-	R_SPARC_PCPLT10  R_SPARC = 29
-	R_SPARC_10       R_SPARC = 30
-	R_SPARC_11       R_SPARC = 31
-	R_SPARC_64       R_SPARC = 32
-	R_SPARC_OLO10    R_SPARC = 33
-	R_SPARC_HH22     R_SPARC = 34
-	R_SPARC_HM10     R_SPARC = 35
-	R_SPARC_LM22     R_SPARC = 36
-	R_SPARC_PC_HH22  R_SPARC = 37
-	R_SPARC_PC_HM10  R_SPARC = 38
-	R_SPARC_PC_LM22  R_SPARC = 39
-	R_SPARC_WDISP16  R_SPARC = 40
-	R_SPARC_WDISP19  R_SPARC = 41
-	R_SPARC_GLOB_JMP R_SPARC = 42
-	R_SPARC_7        R_SPARC = 43
-	R_SPARC_5        R_SPARC = 44
-	R_SPARC_6        R_SPARC = 45
-	R_SPARC_DISP64   R_SPARC = 46
-	R_SPARC_PLT64    R_SPARC = 47
-	R_SPARC_HIX22    R_SPARC = 48
-	R_SPARC_LOX10    R_SPARC = 49
-	R_SPARC_H44      R_SPARC = 50
-	R_SPARC_M44      R_SPARC = 51
-	R_SPARC_L44      R_SPARC = 52
-	R_SPARC_REGISTER R_SPARC = 53
-	R_SPARC_UA64     R_SPARC = 54
-	R_SPARC_UA16     R_SPARC = 55
-)
-
-var rsparcStrings = []intName{
-	{0, "R_SPARC_NONE"},
-	{1, "R_SPARC_8"},
-	{2, "R_SPARC_16"},
-	{3, "R_SPARC_32"},
-	{4, "R_SPARC_DISP8"},
-	{5, "R_SPARC_DISP16"},
-	{6, "R_SPARC_DISP32"},
-	{7, "R_SPARC_WDISP30"},
-	{8, "R_SPARC_WDISP22"},
-	{9, "R_SPARC_HI22"},
-	{10, "R_SPARC_22"},
-	{11, "R_SPARC_13"},
-	{12, "R_SPARC_LO10"},
-	{13, "R_SPARC_GOT10"},
-	{14, "R_SPARC_GOT13"},
-	{15, "R_SPARC_GOT22"},
-	{16, "R_SPARC_PC10"},
-	{17, "R_SPARC_PC22"},
-	{18, "R_SPARC_WPLT30"},
-	{19, "R_SPARC_COPY"},
-	{20, "R_SPARC_GLOB_DAT"},
-	{21, "R_SPARC_JMP_SLOT"},
-	{22, "R_SPARC_RELATIVE"},
-	{23, "R_SPARC_UA32"},
-	{24, "R_SPARC_PLT32"},
-	{25, "R_SPARC_HIPLT22"},
-	{26, "R_SPARC_LOPLT10"},
-	{27, "R_SPARC_PCPLT32"},
-	{28, "R_SPARC_PCPLT22"},
-	{29, "R_SPARC_PCPLT10"},
-	{30, "R_SPARC_10"},
-	{31, "R_SPARC_11"},
-	{32, "R_SPARC_64"},
-	{33, "R_SPARC_OLO10"},
-	{34, "R_SPARC_HH22"},
-	{35, "R_SPARC_HM10"},
-	{36, "R_SPARC_LM22"},
-	{37, "R_SPARC_PC_HH22"},
-	{38, "R_SPARC_PC_HM10"},
-	{39, "R_SPARC_PC_LM22"},
-	{40, "R_SPARC_WDISP16"},
-	{41, "R_SPARC_WDISP19"},
-	{42, "R_SPARC_GLOB_JMP"},
-	{43, "R_SPARC_7"},
-	{44, "R_SPARC_5"},
-	{45, "R_SPARC_6"},
-	{46, "R_SPARC_DISP64"},
-	{47, "R_SPARC_PLT64"},
-	{48, "R_SPARC_HIX22"},
-	{49, "R_SPARC_LOX10"},
-	{50, "R_SPARC_H44"},
-	{51, "R_SPARC_M44"},
-	{52, "R_SPARC_L44"},
-	{53, "R_SPARC_REGISTER"},
-	{54, "R_SPARC_UA64"},
-	{55, "R_SPARC_UA16"},
-}
-
-func (i R_SPARC) String() string   { return stringName(uint32(i), rsparcStrings, false) }
-func (i R_SPARC) GoString() string { return stringName(uint32(i), rsparcStrings, true) }
-
-// Magic number for the elf trampoline, chosen wisely to be an immediate value.
-const ARM_MAGIC_TRAMP_NUMBER = 0x5c000003
-
-// ELF32 File header.
-type Header32 struct {
-	Ident     [EI_NIDENT]byte /* File identification. */
-	Type      uint16          /* File type. */
-	Machine   uint16          /* Machine architecture. */
-	Version   uint32          /* ELF format version. */
-	Entry     uint32          /* Entry point. */
-	Phoff     uint32          /* Program header file offset. */
-	Shoff     uint32          /* Section header file offset. */
-	Flags     uint32          /* Architecture-specific flags. */
-	Ehsize    uint16          /* Size of ELF header in bytes. */
-	Phentsize uint16          /* Size of program header entry. */
-	Phnum     uint16          /* Number of program header entries. */
-	Shentsize uint16          /* Size of section header entry. */
-	Shnum     uint16          /* Number of section header entries. */
-	Shstrndx  uint16          /* Section name strings section. */
-}
-
-// ELF32 Section header.
-type Section32 struct {
-	Name      uint32 /* Section name (index into the section header string table). */
-	Type      uint32 /* Section type. */
-	Flags     uint32 /* Section flags. */
-	Addr      uint32 /* Address in memory image. */
-	Off       uint32 /* Offset in file. */
-	Size      uint32 /* Size in bytes. */
-	Link      uint32 /* Index of a related section. */
-	Info      uint32 /* Depends on section type. */
-	Addralign uint32 /* Alignment in bytes. */
-	Entsize   uint32 /* Size of each entry in section. */
-}
-
-// ELF32 Program header.
-type Prog32 struct {
-	Type   uint32 /* Entry type. */
-	Off    uint32 /* File offset of contents. */
-	Vaddr  uint32 /* Virtual address in memory image. */
-	Paddr  uint32 /* Physical address (not used). */
-	Filesz uint32 /* Size of contents in file. */
-	Memsz  uint32 /* Size of contents in memory. */
-	Flags  uint32 /* Access permission flags. */
-	Align  uint32 /* Alignment in memory and file. */
-}
-
-// ELF32 Dynamic structure.  The ".dynamic" section contains an array of them.
-type Dyn32 struct {
-	Tag int32  /* Entry type. */
-	Val uint32 /* Integer/Address value. */
-}
-
-/*
- * Relocation entries.
- */
-
-// ELF32 Relocations that don't need an addend field.
-type Rel32 struct {
-	Off  uint32 /* Location to be relocated. */
-	Info uint32 /* Relocation type and symbol index. */
-}
-
-// ELF32 Relocations that need an addend field.
-type Rela32 struct {
-	Off    uint32 /* Location to be relocated. */
-	Info   uint32 /* Relocation type and symbol index. */
-	Addend int32  /* Addend. */
-}
-
-func R_SYM32(info uint32) uint32      { return uint32(info >> 8) }
-func R_TYPE32(info uint32) uint32     { return uint32(info & 0xff) }
-func R_INFO32(sym, typ uint32) uint32 { return sym<<8 | typ }
-
-// ELF32 Symbol.
-type Sym32 struct {
-	Name  uint32
-	Value uint32
-	Size  uint32
-	Info  uint8
-	Other uint8
-	Shndx uint16
-}
-
-const Sym32Size = 16
-
-func ST_BIND(info uint8) SymBind { return SymBind(info >> 4) }
-func ST_TYPE(info uint8) SymType { return SymType(info & 0xF) }
-func ST_INFO(bind SymBind, typ SymType) uint8 {
-	return uint8(bind)<<4 | uint8(typ)&0xf
-}
-func ST_VISIBILITY(other uint8) SymVis { return SymVis(other & 3) }
-
-/*
- * ELF64
- */
-
-// ELF64 file header.
-type Header64 struct {
-	Ident     [EI_NIDENT]byte /* File identification. */
-	Type      uint16          /* File type. */
-	Machine   uint16          /* Machine architecture. */
-	Version   uint32          /* ELF format version. */
-	Entry     uint64          /* Entry point. */
-	Phoff     uint64          /* Program header file offset. */
-	Shoff     uint64          /* Section header file offset. */
-	Flags     uint32          /* Architecture-specific flags. */
-	Ehsize    uint16          /* Size of ELF header in bytes. */
-	Phentsize uint16          /* Size of program header entry. */
-	Phnum     uint16          /* Number of program header entries. */
-	Shentsize uint16          /* Size of section header entry. */
-	Shnum     uint16          /* Number of section header entries. */
-	Shstrndx  uint16          /* Section name strings section. */
-}
-
-// ELF64 Section header.
-type Section64 struct {
-	Name      uint32 /* Section name (index into the section header string table). */
-	Type      uint32 /* Section type. */
-	Flags     uint64 /* Section flags. */
-	Addr      uint64 /* Address in memory image. */
-	Off       uint64 /* Offset in file. */
-	Size      uint64 /* Size in bytes. */
-	Link      uint32 /* Index of a related section. */
-	Info      uint32 /* Depends on section type. */
-	Addralign uint64 /* Alignment in bytes. */
-	Entsize   uint64 /* Size of each entry in section. */
-}
-
-// ELF64 Program header.
-type Prog64 struct {
-	Type   uint32 /* Entry type. */
-	Flags  uint32 /* Access permission flags. */
-	Off    uint64 /* File offset of contents. */
-	Vaddr  uint64 /* Virtual address in memory image. */
-	Paddr  uint64 /* Physical address (not used). */
-	Filesz uint64 /* Size of contents in file. */
-	Memsz  uint64 /* Size of contents in memory. */
-	Align  uint64 /* Alignment in memory and file. */
-}
-
-// ELF64 Dynamic structure.  The ".dynamic" section contains an array of them.
-type Dyn64 struct {
-	Tag int64  /* Entry type. */
-	Val uint64 /* Integer/address value */
-}
-
-/*
- * Relocation entries.
- */
-
-/* ELF64 relocations that don't need an addend field. */
-type Rel64 struct {
-	Off  uint64 /* Location to be relocated. */
-	Info uint64 /* Relocation type and symbol index. */
-}
-
-/* ELF64 relocations that need an addend field. */
-type Rela64 struct {
-	Off    uint64 /* Location to be relocated. */
-	Info   uint64 /* Relocation type and symbol index. */
-	Addend int64  /* Addend. */
-}
-
-func R_SYM64(info uint64) uint32    { return uint32(info >> 32) }
-func R_TYPE64(info uint64) uint32   { return uint32(info) }
-func R_INFO(sym, typ uint32) uint64 { return uint64(sym)<<32 | uint64(typ) }
-
-// ELF64 symbol table entries.
-type Sym64 struct {
-	Name  uint32 /* String table index of name. */
-	Info  uint8  /* Type and binding information. */
-	Other uint8  /* Reserved (not used). */
-	Shndx uint16 /* Section index of symbol. */
-	Value uint64 /* Symbol value. */
-	Size  uint64 /* Size of associated object. */
-}
-
-const Sym64Size = 24
-
-type intName struct {
-	i uint32
-	s string
-}
-
-func stringName(i uint32, names []intName, goSyntax bool) string {
-	for _, n := range names {
-		if n.i == i {
-			if goSyntax {
-				return "elf." + n.s
-			}
-			return n.s
-		}
-	}
-
-	// second pass - look for smaller to add with.
-	// assume sorted already
-	for j := len(names) - 1; j >= 0; j-- {
-		n := names[j]
-		if n.i < i {
-			s := n.s
-			if goSyntax {
-				s = "elf." + s
-			}
-			return s + "+" + strconv.FormatUint(uint64(i-n.i), 10)
-		}
-	}
-
-	return strconv.FormatUint(uint64(i), 10)
-}
-
-func flagName(i uint32, names []intName, goSyntax bool) string {
-	s := ""
-	for _, n := range names {
-		if n.i&i == n.i {
-			if len(s) > 0 {
-				s += "+"
-			}
-			if goSyntax {
-				s += "elf."
-			}
-			s += n.s
-			i -= n.i
-		}
-	}
-	if len(s) == 0 {
-		return "0x" + strconv.FormatUint(uint64(i), 16)
-	}
-	if i != 0 {
-		s += "+0x" + strconv.FormatUint(uint64(i), 16)
-	}
-	return s
-}
diff --git a/elf/elf_test.go b/elf/elf_test.go
deleted file mode 100644
index e3c51bb..0000000
--- a/elf/elf_test.go
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2009 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 elf
-
-import (
-	"fmt"
-	"testing"
-)
-
-type nameTest struct {
-	val interface{}
-	str string
-}
-
-var nameTests = []nameTest{
-	{ELFOSABI_LINUX, "ELFOSABI_LINUX"},
-	{ET_EXEC, "ET_EXEC"},
-	{EM_860, "EM_860"},
-	{SHN_LOPROC, "SHN_LOPROC"},
-	{SHT_PROGBITS, "SHT_PROGBITS"},
-	{SHF_MERGE + SHF_TLS, "SHF_MERGE+SHF_TLS"},
-	{PT_LOAD, "PT_LOAD"},
-	{PF_W + PF_R + 0x50, "PF_W+PF_R+0x50"},
-	{DT_SYMBOLIC, "DT_SYMBOLIC"},
-	{DF_BIND_NOW, "DF_BIND_NOW"},
-	{NT_FPREGSET, "NT_FPREGSET"},
-	{STB_GLOBAL, "STB_GLOBAL"},
-	{STT_COMMON, "STT_COMMON"},
-	{STV_HIDDEN, "STV_HIDDEN"},
-	{R_X86_64_PC32, "R_X86_64_PC32"},
-	{R_ALPHA_OP_PUSH, "R_ALPHA_OP_PUSH"},
-	{R_ARM_THM_ABS5, "R_ARM_THM_ABS5"},
-	{R_386_GOT32, "R_386_GOT32"},
-	{R_PPC_GOT16_HI, "R_PPC_GOT16_HI"},
-	{R_SPARC_GOT22, "R_SPARC_GOT22"},
-	{ET_LOOS + 5, "ET_LOOS+5"},
-	{ProgFlag(0x50), "0x50"},
-}
-
-func TestNames(t *testing.T) {
-	for i, tt := range nameTests {
-		s := fmt.Sprint(tt.val)
-		if s != tt.str {
-			t.Errorf("#%d: Sprint(%d) = %q, want %q", i, tt.val, s, tt.str)
-		}
-	}
-}
diff --git a/elf/file.go b/elf/file.go
deleted file mode 100644
index 6946550..0000000
--- a/elf/file.go
+++ /dev/null
@@ -1,829 +0,0 @@
-// Copyright 2009 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 elf implements access to ELF object files.
-package elf
-
-import (
-	"bytes"
-	"encoding/binary"
-	"errors"
-	"fmt"
-	"io"
-	"os"
-
-	"golang.org/x/debug/dwarf"
-)
-
-// TODO: error reporting detail
-
-/*
- * Internal ELF representation
- */
-
-// A FileHeader represents an ELF file header.
-type FileHeader struct {
-	Class      Class
-	Data       Data
-	Version    Version
-	OSABI      OSABI
-	ABIVersion uint8
-	ByteOrder  binary.ByteOrder
-	Type       Type
-	Machine    Machine
-	Entry      uint64
-}
-
-// A File represents an open ELF file.
-type File struct {
-	FileHeader
-	Sections  []*Section
-	Progs     []*Prog
-	closer    io.Closer
-	gnuNeed   []verneed
-	gnuVersym []byte
-}
-
-// A SectionHeader represents a single ELF section header.
-type SectionHeader struct {
-	Name      string
-	Type      SectionType
-	Flags     SectionFlag
-	Addr      uint64
-	Offset    uint64
-	Size      uint64
-	Link      uint32
-	Info      uint32
-	Addralign uint64
-	Entsize   uint64
-}
-
-// A Section represents a single section in an ELF file.
-type Section struct {
-	SectionHeader
-
-	// Embed ReaderAt for ReadAt method.
-	// Do not embed SectionReader directly
-	// to avoid having Read and Seek.
-	// If a client wants Read and Seek it must use
-	// Open() to avoid fighting over the seek offset
-	// with other clients.
-	io.ReaderAt
-	sr *io.SectionReader
-}
-
-// Data reads and returns the contents of the ELF section.
-func (s *Section) Data() ([]byte, error) {
-	dat := make([]byte, s.sr.Size())
-	n, err := s.sr.ReadAt(dat, 0)
-	if n == len(dat) {
-		err = nil
-	}
-	return dat[0:n], err
-}
-
-// stringTable reads and returns the string table given by the
-// specified link value.
-func (f *File) stringTable(link uint32) ([]byte, error) {
-	if link <= 0 || link >= uint32(len(f.Sections)) {
-		return nil, errors.New("section has invalid string table link")
-	}
-	return f.Sections[link].Data()
-}
-
-// Open returns a new ReadSeeker reading the ELF section.
-func (s *Section) Open() io.ReadSeeker { return io.NewSectionReader(s.sr, 0, 1<<63-1) }
-
-// A ProgHeader represents a single ELF program header.
-type ProgHeader struct {
-	Type   ProgType
-	Flags  ProgFlag
-	Off    uint64
-	Vaddr  uint64
-	Paddr  uint64
-	Filesz uint64
-	Memsz  uint64
-	Align  uint64
-}
-
-// A Prog represents a single ELF program header in an ELF binary.
-type Prog struct {
-	ProgHeader
-
-	// Embed ReaderAt for ReadAt method.
-	// Do not embed SectionReader directly
-	// to avoid having Read and Seek.
-	// If a client wants Read and Seek it must use
-	// Open() to avoid fighting over the seek offset
-	// with other clients.
-	io.ReaderAt
-	sr *io.SectionReader
-}
-
-// Open returns a new ReadSeeker reading the ELF program body.
-func (p *Prog) Open() io.ReadSeeker { return io.NewSectionReader(p.sr, 0, 1<<63-1) }
-
-// A Symbol represents an entry in an ELF symbol table section.
-type Symbol struct {
-	Name        string
-	Info, Other byte
-	Section     SectionIndex
-	Value, Size uint64
-}
-
-/*
- * ELF reader
- */
-
-type FormatError struct {
-	off int64
-	msg string
-	val interface{}
-}
-
-func (e *FormatError) Error() string {
-	msg := e.msg
-	if e.val != nil {
-		msg += fmt.Sprintf(" '%v' ", e.val)
-	}
-	msg += fmt.Sprintf("in record at byte %#x", e.off)
-	return msg
-}
-
-// Open opens the named file using os.Open and prepares it for use as an ELF binary.
-func Open(name string) (*File, error) {
-	f, err := os.Open(name)
-	if err != nil {
-		return nil, err
-	}
-	ff, err := NewFile(f)
-	if err != nil {
-		f.Close()
-		return nil, err
-	}
-	ff.closer = f
-	return ff, nil
-}
-
-// Close closes the File.
-// If the File was created using NewFile directly instead of Open,
-// Close has no effect.
-func (f *File) Close() error {
-	var err error
-	if f.closer != nil {
-		err = f.closer.Close()
-		f.closer = nil
-	}
-	return err
-}
-
-// SectionByType returns the first section in f with the
-// given type, or nil if there is no such section.
-func (f *File) SectionByType(typ SectionType) *Section {
-	for _, s := range f.Sections {
-		if s.Type == typ {
-			return s
-		}
-	}
-	return nil
-}
-
-// NewFile creates a new File for accessing an ELF binary in an underlying reader.
-// The ELF binary is expected to start at position 0 in the ReaderAt.
-func NewFile(r io.ReaderAt) (*File, error) {
-	sr := io.NewSectionReader(r, 0, 1<<63-1)
-	// Read and decode ELF identifier
-	var ident [16]uint8
-	if _, err := r.ReadAt(ident[0:], 0); err != nil {
-		return nil, err
-	}
-	if ident[0] != '\x7f' || ident[1] != 'E' || ident[2] != 'L' || ident[3] != 'F' {
-		return nil, &FormatError{0, "bad magic number", ident[0:4]}
-	}
-
-	f := new(File)
-	f.Class = Class(ident[EI_CLASS])
-	switch f.Class {
-	case ELFCLASS32:
-	case ELFCLASS64:
-		// ok
-	default:
-		return nil, &FormatError{0, "unknown ELF class", f.Class}
-	}
-
-	f.Data = Data(ident[EI_DATA])
-	switch f.Data {
-	case ELFDATA2LSB:
-		f.ByteOrder = binary.LittleEndian
-	case ELFDATA2MSB:
-		f.ByteOrder = binary.BigEndian
-	default:
-		return nil, &FormatError{0, "unknown ELF data encoding", f.Data}
-	}
-
-	f.Version = Version(ident[EI_VERSION])
-	if f.Version != EV_CURRENT {
-		return nil, &FormatError{0, "unknown ELF version", f.Version}
-	}
-
-	f.OSABI = OSABI(ident[EI_OSABI])
-	f.ABIVersion = ident[EI_ABIVERSION]
-
-	// Read ELF file header
-	var phoff int64
-	var phentsize, phnum int
-	var shoff int64
-	var shentsize, shnum, shstrndx int
-	shstrndx = -1
-	switch f.Class {
-	case ELFCLASS32:
-		hdr := new(Header32)
-		sr.Seek(0, os.SEEK_SET)
-		if err := binary.Read(sr, f.ByteOrder, hdr); err != nil {
-			return nil, err
-		}
-		f.Type = Type(hdr.Type)
-		f.Machine = Machine(hdr.Machine)
-		f.Entry = uint64(hdr.Entry)
-		if v := Version(hdr.Version); v != f.Version {
-			return nil, &FormatError{0, "mismatched ELF version", v}
-		}
-		phoff = int64(hdr.Phoff)
-		phentsize = int(hdr.Phentsize)
-		phnum = int(hdr.Phnum)
-		shoff = int64(hdr.Shoff)
-		shentsize = int(hdr.Shentsize)
-		shnum = int(hdr.Shnum)
-		shstrndx = int(hdr.Shstrndx)
-	case ELFCLASS64:
-		hdr := new(Header64)
-		sr.Seek(0, os.SEEK_SET)
-		if err := binary.Read(sr, f.ByteOrder, hdr); err != nil {
-			return nil, err
-		}
-		f.Type = Type(hdr.Type)
-		f.Machine = Machine(hdr.Machine)
-		f.Entry = uint64(hdr.Entry)
-		if v := Version(hdr.Version); v != f.Version {
-			return nil, &FormatError{0, "mismatched ELF version", v}
-		}
-		phoff = int64(hdr.Phoff)
-		phentsize = int(hdr.Phentsize)
-		phnum = int(hdr.Phnum)
-		shoff = int64(hdr.Shoff)
-		shentsize = int(hdr.Shentsize)
-		shnum = int(hdr.Shnum)
-		shstrndx = int(hdr.Shstrndx)
-	}
-
-	if shnum > 0 && shoff > 0 && (shstrndx < 0 || shstrndx >= shnum) {
-		return nil, &FormatError{0, "invalid ELF shstrndx", shstrndx}
-	}
-
-	// Read program headers
-	f.Progs = make([]*Prog, phnum)
-	for i := 0; i < phnum; i++ {
-		off := phoff + int64(i)*int64(phentsize)
-		sr.Seek(off, os.SEEK_SET)
-		p := new(Prog)
-		switch f.Class {
-		case ELFCLASS32:
-			ph := new(Prog32)
-			if err := binary.Read(sr, f.ByteOrder, ph); err != nil {
-				return nil, err
-			}
-			p.ProgHeader = ProgHeader{
-				Type:   ProgType(ph.Type),
-				Flags:  ProgFlag(ph.Flags),
-				Off:    uint64(ph.Off),
-				Vaddr:  uint64(ph.Vaddr),
-				Paddr:  uint64(ph.Paddr),
-				Filesz: uint64(ph.Filesz),
-				Memsz:  uint64(ph.Memsz),
-				Align:  uint64(ph.Align),
-			}
-		case ELFCLASS64:
-			ph := new(Prog64)
-			if err := binary.Read(sr, f.ByteOrder, ph); err != nil {
-				return nil, err
-			}
-			p.ProgHeader = ProgHeader{
-				Type:   ProgType(ph.Type),
-				Flags:  ProgFlag(ph.Flags),
-				Off:    uint64(ph.Off),
-				Vaddr:  uint64(ph.Vaddr),
-				Paddr:  uint64(ph.Paddr),
-				Filesz: uint64(ph.Filesz),
-				Memsz:  uint64(ph.Memsz),
-				Align:  uint64(ph.Align),
-			}
-		}
-		p.sr = io.NewSectionReader(r, int64(p.Off), int64(p.Filesz))
-		p.ReaderAt = p.sr
-		f.Progs[i] = p
-	}
-
-	// Read section headers
-	f.Sections = make([]*Section, shnum)
-	names := make([]uint32, shnum)
-	for i := 0; i < shnum; i++ {
-		off := shoff + int64(i)*int64(shentsize)
-		sr.Seek(off, os.SEEK_SET)
-		s := new(Section)
-		switch f.Class {
-		case ELFCLASS32:
-			sh := new(Section32)
-			if err := binary.Read(sr, f.ByteOrder, sh); err != nil {
-				return nil, err
-			}
-			names[i] = sh.Name
-			s.SectionHeader = SectionHeader{
-				Type:      SectionType(sh.Type),
-				Flags:     SectionFlag(sh.Flags),
-				Addr:      uint64(sh.Addr),
-				Offset:    uint64(sh.Off),
-				Size:      uint64(sh.Size),
-				Link:      uint32(sh.Link),
-				Info:      uint32(sh.Info),
-				Addralign: uint64(sh.Addralign),
-				Entsize:   uint64(sh.Entsize),
-			}
-		case ELFCLASS64:
-			sh := new(Section64)
-			if err := binary.Read(sr, f.ByteOrder, sh); err != nil {
-				return nil, err
-			}
-			names[i] = sh.Name
-			s.SectionHeader = SectionHeader{
-				Type:      SectionType(sh.Type),
-				Flags:     SectionFlag(sh.Flags),
-				Offset:    uint64(sh.Off),
-				Size:      uint64(sh.Size),
-				Addr:      uint64(sh.Addr),
-				Link:      uint32(sh.Link),
-				Info:      uint32(sh.Info),
-				Addralign: uint64(sh.Addralign),
-				Entsize:   uint64(sh.Entsize),
-			}
-		}
-		s.sr = io.NewSectionReader(r, int64(s.Offset), int64(s.Size))
-		s.ReaderAt = s.sr
-		f.Sections[i] = s
-	}
-
-	if len(f.Sections) == 0 {
-		return f, nil
-	}
-
-	// Load section header string table.
-	shstrtab, err := f.Sections[shstrndx].Data()
-	if err != nil {
-		return nil, err
-	}
-	for i, s := range f.Sections {
-		var ok bool
-		s.Name, ok = getString(shstrtab, int(names[i]))
-		if !ok {
-			return nil, &FormatError{shoff + int64(i*shentsize), "bad section name index", names[i]}
-		}
-	}
-
-	return f, nil
-}
-
-// getSymbols returns a slice of Symbols from parsing the symbol table
-// with the given type, along with the associated string table.
-func (f *File) getSymbols(typ SectionType) ([]Symbol, []byte, error) {
-	switch f.Class {
-	case ELFCLASS64:
-		return f.getSymbols64(typ)
-
-	case ELFCLASS32:
-		return f.getSymbols32(typ)
-	}
-
-	return nil, nil, errors.New("not implemented")
-}
-
-func (f *File) getSymbols32(typ SectionType) ([]Symbol, []byte, error) {
-	symtabSection := f.SectionByType(typ)
-	if symtabSection == nil {
-		return nil, nil, errors.New("no symbol section")
-	}
-
-	data, err := symtabSection.Data()
-	if err != nil {
-		return nil, nil, errors.New("cannot load symbol section")
-	}
-	symtab := bytes.NewReader(data)
-	if symtab.Len()%Sym32Size != 0 {
-		return nil, nil, errors.New("length of symbol section is not a multiple of SymSize")
-	}
-
-	strdata, err := f.stringTable(symtabSection.Link)
-	if err != nil {
-		return nil, nil, errors.New("cannot load string table section")
-	}
-
-	// The first entry is all zeros.
-	var skip [Sym32Size]byte
-	symtab.Read(skip[:])
-
-	symbols := make([]Symbol, symtab.Len()/Sym32Size)
-
-	i := 0
-	var sym Sym32
-	for symtab.Len() > 0 {
-		binary.Read(symtab, f.ByteOrder, &sym)
-		str, _ := getString(strdata, int(sym.Name))
-		symbols[i].Name = str
-		symbols[i].Info = sym.Info
-		symbols[i].Other = sym.Other
-		symbols[i].Section = SectionIndex(sym.Shndx)
-		symbols[i].Value = uint64(sym.Value)
-		symbols[i].Size = uint64(sym.Size)
-		i++
-	}
-
-	return symbols, strdata, nil
-}
-
-func (f *File) getSymbols64(typ SectionType) ([]Symbol, []byte, error) {
-	symtabSection := f.SectionByType(typ)
-	if symtabSection == nil {
-		return nil, nil, errors.New("no symbol section")
-	}
-
-	data, err := symtabSection.Data()
-	if err != nil {
-		return nil, nil, errors.New("cannot load symbol section")
-	}
-	symtab := bytes.NewReader(data)
-	if symtab.Len()%Sym64Size != 0 {
-		return nil, nil, errors.New("length of symbol section is not a multiple of Sym64Size")
-	}
-
-	strdata, err := f.stringTable(symtabSection.Link)
-	if err != nil {
-		return nil, nil, errors.New("cannot load string table section")
-	}
-
-	// The first entry is all zeros.
-	var skip [Sym64Size]byte
-	symtab.Read(skip[:])
-
-	symbols := make([]Symbol, symtab.Len()/Sym64Size)
-
-	i := 0
-	var sym Sym64
-	for symtab.Len() > 0 {
-		binary.Read(symtab, f.ByteOrder, &sym)
-		str, _ := getString(strdata, int(sym.Name))
-		symbols[i].Name = str
-		symbols[i].Info = sym.Info
-		symbols[i].Other = sym.Other
-		symbols[i].Section = SectionIndex(sym.Shndx)
-		symbols[i].Value = sym.Value
-		symbols[i].Size = sym.Size
-		i++
-	}
-
-	return symbols, strdata, nil
-}
-
-// getString extracts a string from an ELF string table.
-func getString(section []byte, start int) (string, bool) {
-	if start < 0 || start >= len(section) {
-		return "", false
-	}
-
-	for end := start; end < len(section); end++ {
-		if section[end] == 0 {
-			return string(section[start:end]), true
-		}
-	}
-	return "", false
-}
-
-// Section returns a section with the given name, or nil if no such
-// section exists.
-func (f *File) Section(name string) *Section {
-	for _, s := range f.Sections {
-		if s.Name == name {
-			return s
-		}
-	}
-	return nil
-}
-
-// applyRelocations applies relocations to dst. rels is a relocations section
-// in RELA format.
-func (f *File) applyRelocations(dst []byte, rels []byte) error {
-	if f.Class == ELFCLASS64 && f.Machine == EM_X86_64 {
-		return f.applyRelocationsAMD64(dst, rels)
-	}
-
-	return errors.New("not implemented")
-}
-
-func (f *File) applyRelocationsAMD64(dst []byte, rels []byte) error {
-	if len(rels)%Sym64Size != 0 {
-		return errors.New("length of relocation section is not a multiple of Sym64Size")
-	}
-
-	symbols, _, err := f.getSymbols(SHT_SYMTAB)
-	if err != nil {
-		return err
-	}
-
-	b := bytes.NewReader(rels)
-	var rela Rela64
-
-	for b.Len() > 0 {
-		binary.Read(b, f.ByteOrder, &rela)
-		symNo := rela.Info >> 32
-		t := R_X86_64(rela.Info & 0xffff)
-
-		if symNo == 0 || symNo > uint64(len(symbols)) {
-			continue
-		}
-		sym := &symbols[symNo-1]
-		if SymType(sym.Info&0xf) != STT_SECTION {
-			// We don't handle non-section relocations for now.
-			continue
-		}
-
-		switch t {
-		case R_X86_64_64:
-			if rela.Off+8 >= uint64(len(dst)) || rela.Addend < 0 {
-				continue
-			}
-			f.ByteOrder.PutUint64(dst[rela.Off:rela.Off+8], uint64(rela.Addend))
-		case R_X86_64_32:
-			if rela.Off+4 >= uint64(len(dst)) || rela.Addend < 0 {
-				continue
-			}
-			f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], uint32(rela.Addend))
-		}
-	}
-
-	return nil
-}
-
-func (f *File) DWARF() (*dwarf.Data, error) {
-	// There are many other DWARF sections, but these
-	// are the required ones, and the debug/dwarf package
-	// does not use the others, so don't bother loading them.
-	// r: added line.
-	var names = [...]string{"abbrev", "frame", "info", "line", "str"}
-	var dat [len(names)][]byte
-	for i, name := range names {
-		name = ".debug_" + name
-		s := f.Section(name)
-		if s == nil {
-			continue
-		}
-		b, err := s.Data()
-		if err != nil && uint64(len(b)) < s.Size {
-			return nil, err
-		}
-		dat[i] = b
-	}
-
-	// If there's a relocation table for .debug_info, we have to process it
-	// now otherwise the data in .debug_info is invalid for x86-64 objects.
-	rela := f.Section(".rela.debug_info")
-	if rela != nil && rela.Type == SHT_RELA && f.Machine == EM_X86_64 {
-		data, err := rela.Data()
-		if err != nil {
-			return nil, err
-		}
-		err = f.applyRelocations(dat[2], data)
-		if err != nil {
-			return nil, err
-		}
-	}
-
-	abbrev, frame, info, line, str := dat[0], dat[1], dat[2], dat[3], dat[4]
-	d, err := dwarf.New(abbrev, nil, frame, info, line, nil, nil, str)
-	if err != nil {
-		return nil, err
-	}
-
-	// Look for DWARF4 .debug_types sections.
-	for i, s := range f.Sections {
-		if s.Name == ".debug_types" {
-			b, err := s.Data()
-			if err != nil && uint64(len(b)) < s.Size {
-				return nil, err
-			}
-
-			for _, r := range f.Sections {
-				if r.Type != SHT_RELA && r.Type != SHT_REL {
-					continue
-				}
-				if int(r.Info) != i {
-					continue
-				}
-				rd, err := r.Data()
-				if err != nil {
-					return nil, err
-				}
-				err = f.applyRelocations(b, rd)
-				if err != nil {
-					return nil, err
-				}
-			}
-
-			err = d.AddTypes(fmt.Sprintf("types-%d", i), b)
-			if err != nil {
-				return nil, err
-			}
-		}
-	}
-
-	return d, nil
-}
-
-// Symbols returns the symbol table for f.
-//
-// For compatibility with Go 1.0, Symbols omits the null symbol at index 0.
-// After retrieving the symbols as symtab, an externally supplied index x
-// corresponds to symtab[x-1], not symtab[x].
-func (f *File) Symbols() ([]Symbol, error) {
-	sym, _, err := f.getSymbols(SHT_SYMTAB)
-	return sym, err
-}
-
-type ImportedSymbol struct {
-	Name    string
-	Version string
-	Library string
-}
-
-// ImportedSymbols returns the names of all symbols
-// referred to by the binary f that are expected to be
-// satisfied by other libraries at dynamic load time.
-// It does not return weak symbols.
-func (f *File) ImportedSymbols() ([]ImportedSymbol, error) {
-	sym, str, err := f.getSymbols(SHT_DYNSYM)
-	if err != nil {
-		return nil, err
-	}
-	f.gnuVersionInit(str)
-	var all []ImportedSymbol
-	for i, s := range sym {
-		if ST_BIND(s.Info) == STB_GLOBAL && s.Section == SHN_UNDEF {
-			all = append(all, ImportedSymbol{Name: s.Name})
-			f.gnuVersion(i, &all[len(all)-1])
-		}
-	}
-	return all, nil
-}
-
-type verneed struct {
-	File string
-	Name string
-}
-
-// gnuVersionInit parses the GNU version tables
-// for use by calls to gnuVersion.
-func (f *File) gnuVersionInit(str []byte) {
-	// Accumulate verneed information.
-	vn := f.SectionByType(SHT_GNU_VERNEED)
-	if vn == nil {
-		return
-	}
-	d, _ := vn.Data()
-
-	var need []verneed
-	i := 0
-	for {
-		if i+16 > len(d) {
-			break
-		}
-		vers := f.ByteOrder.Uint16(d[i : i+2])
-		if vers != 1 {
-			break
-		}
-		cnt := f.ByteOrder.Uint16(d[i+2 : i+4])
-		fileoff := f.ByteOrder.Uint32(d[i+4 : i+8])
-		aux := f.ByteOrder.Uint32(d[i+8 : i+12])
-		next := f.ByteOrder.Uint32(d[i+12 : i+16])
-		file, _ := getString(str, int(fileoff))
-
-		var name string
-		j := i + int(aux)
-		for c := 0; c < int(cnt); c++ {
-			if j+16 > len(d) {
-				break
-			}
-			// hash := f.ByteOrder.Uint32(d[j:j+4])
-			// flags := f.ByteOrder.Uint16(d[j+4:j+6])
-			other := f.ByteOrder.Uint16(d[j+6 : j+8])
-			nameoff := f.ByteOrder.Uint32(d[j+8 : j+12])
-			next := f.ByteOrder.Uint32(d[j+12 : j+16])
-			name, _ = getString(str, int(nameoff))
-			ndx := int(other)
-			if ndx >= len(need) {
-				a := make([]verneed, 2*(ndx+1))
-				copy(a, need)
-				need = a
-			}
-
-			need[ndx] = verneed{file, name}
-			if next == 0 {
-				break
-			}
-			j += int(next)
-		}
-
-		if next == 0 {
-			break
-		}
-		i += int(next)
-	}
-
-	// Versym parallels symbol table, indexing into verneed.
-	vs := f.SectionByType(SHT_GNU_VERSYM)
-	if vs == nil {
-		return
-	}
-	d, _ = vs.Data()
-
-	f.gnuNeed = need
-	f.gnuVersym = d
-}
-
-// gnuVersion adds Library and Version information to sym,
-// which came from offset i of the symbol table.
-func (f *File) gnuVersion(i int, sym *ImportedSymbol) {
-	// Each entry is two bytes.
-	i = (i + 1) * 2
-	if i >= len(f.gnuVersym) {
-		return
-	}
-	j := int(f.ByteOrder.Uint16(f.gnuVersym[i:]))
-	if j < 2 || j >= len(f.gnuNeed) {
-		return
-	}
-	n := &f.gnuNeed[j]
-	sym.Library = n.File
-	sym.Version = n.Name
-}
-
-// ImportedLibraries returns the names of all libraries
-// referred to by the binary f that are expected to be
-// linked with the binary at dynamic link time.
-func (f *File) ImportedLibraries() ([]string, error) {
-	return f.DynString(DT_NEEDED)
-}
-
-// DynString returns the strings listed for the given tag in the file's dynamic
-// section.
-//
-// The tag must be one that takes string values: DT_NEEDED, DT_SONAME, DT_RPATH, or
-// DT_RUNPATH.
-func (f *File) DynString(tag DynTag) ([]string, error) {
-	switch tag {
-	case DT_NEEDED, DT_SONAME, DT_RPATH, DT_RUNPATH:
-	default:
-		return nil, fmt.Errorf("non-string-valued tag %v", tag)
-	}
-	ds := f.SectionByType(SHT_DYNAMIC)
-	if ds == nil {
-		// not dynamic, so no libraries
-		return nil, nil
-	}
-	d, err := ds.Data()
-	if err != nil {
-		return nil, err
-	}
-	str, err := f.stringTable(ds.Link)
-	if err != nil {
-		return nil, err
-	}
-	var all []string
-	for len(d) > 0 {
-		var t DynTag
-		var v uint64
-		switch f.Class {
-		case ELFCLASS32:
-			t = DynTag(f.ByteOrder.Uint32(d[0:4]))
-			v = uint64(f.ByteOrder.Uint32(d[4:8]))
-			d = d[8:]
-		case ELFCLASS64:
-			t = DynTag(f.ByteOrder.Uint64(d[0:8]))
-			v = f.ByteOrder.Uint64(d[8:16])
-			d = d[16:]
-		}
-		if t == tag {
-			s, ok := getString(str, int(v))
-			if ok {
-				all = append(all, s)
-			}
-		}
-	}
-	return all, nil
-}
diff --git a/elf/file_test.go b/elf/file_test.go
deleted file mode 100644
index 596dc4e..0000000
--- a/elf/file_test.go
+++ /dev/null
@@ -1,334 +0,0 @@
-// Copyright 2009 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 elf
-
-import (
-	"bytes"
-	"compress/gzip"
-	"encoding/binary"
-	"io"
-	"net"
-	"os"
-	"path"
-	"reflect"
-	"runtime"
-	"testing"
-
-	"golang.org/x/debug/dwarf"
-)
-
-type fileTest struct {
-	file     string
-	hdr      FileHeader
-	sections []SectionHeader
-	progs    []ProgHeader
-	needed   []string
-}
-
-var fileTests = []fileTest{
-	{
-		"testdata/gcc-386-freebsd-exec",
-		FileHeader{ELFCLASS32, ELFDATA2LSB, EV_CURRENT, ELFOSABI_FREEBSD, 0, binary.LittleEndian, ET_EXEC, EM_386, 0x80483cc},
-		[]SectionHeader{
-			{"", SHT_NULL, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
-			{".interp", SHT_PROGBITS, SHF_ALLOC, 0x80480d4, 0xd4, 0x15, 0x0, 0x0, 0x1, 0x0},
-			{".hash", SHT_HASH, SHF_ALLOC, 0x80480ec, 0xec, 0x90, 0x3, 0x0, 0x4, 0x4},
-			{".dynsym", SHT_DYNSYM, SHF_ALLOC, 0x804817c, 0x17c, 0x110, 0x4, 0x1, 0x4, 0x10},
-			{".dynstr", SHT_STRTAB, SHF_ALLOC, 0x804828c, 0x28c, 0xbb, 0x0, 0x0, 0x1, 0x0},
-			{".rel.plt", SHT_REL, SHF_ALLOC, 0x8048348, 0x348, 0x20, 0x3, 0x7, 0x4, 0x8},
-			{".init", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR, 0x8048368, 0x368, 0x11, 0x0, 0x0, 0x4, 0x0},
-			{".plt", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR, 0x804837c, 0x37c, 0x50, 0x0, 0x0, 0x4, 0x4},
-			{".text", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR, 0x80483cc, 0x3cc, 0x180, 0x0, 0x0, 0x4, 0x0},
-			{".fini", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR, 0x804854c, 0x54c, 0xc, 0x0, 0x0, 0x4, 0x0},
-			{".rodata", SHT_PROGBITS, SHF_ALLOC, 0x8048558, 0x558, 0xa3, 0x0, 0x0, 0x1, 0x0},
-			{".data", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x80495fc, 0x5fc, 0xc, 0x0, 0x0, 0x4, 0x0},
-			{".eh_frame", SHT_PROGBITS, SHF_ALLOC, 0x8049608, 0x608, 0x4, 0x0, 0x0, 0x4, 0x0},
-			{".dynamic", SHT_DYNAMIC, SHF_WRITE + SHF_ALLOC, 0x804960c, 0x60c, 0x98, 0x4, 0x0, 0x4, 0x8},
-			{".ctors", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x80496a4, 0x6a4, 0x8, 0x0, 0x0, 0x4, 0x0},
-			{".dtors", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x80496ac, 0x6ac, 0x8, 0x0, 0x0, 0x4, 0x0},
-			{".jcr", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x80496b4, 0x6b4, 0x4, 0x0, 0x0, 0x4, 0x0},
-			{".got", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x80496b8, 0x6b8, 0x1c, 0x0, 0x0, 0x4, 0x4},
-			{".bss", SHT_NOBITS, SHF_WRITE + SHF_ALLOC, 0x80496d4, 0x6d4, 0x20, 0x0, 0x0, 0x4, 0x0},
-			{".comment", SHT_PROGBITS, 0x0, 0x0, 0x6d4, 0x12d, 0x0, 0x0, 0x1, 0x0},
-			{".debug_aranges", SHT_PROGBITS, 0x0, 0x0, 0x801, 0x20, 0x0, 0x0, 0x1, 0x0},
-			{".debug_pubnames", SHT_PROGBITS, 0x0, 0x0, 0x821, 0x1b, 0x0, 0x0, 0x1, 0x0},
-			{".debug_info", SHT_PROGBITS, 0x0, 0x0, 0x83c, 0x11d, 0x0, 0x0, 0x1, 0x0},
-			{".debug_abbrev", SHT_PROGBITS, 0x0, 0x0, 0x959, 0x41, 0x0, 0x0, 0x1, 0x0},
-			{".debug_line", SHT_PROGBITS, 0x0, 0x0, 0x99a, 0x35, 0x0, 0x0, 0x1, 0x0},
-			{".debug_frame", SHT_PROGBITS, 0x0, 0x0, 0x9d0, 0x30, 0x0, 0x0, 0x4, 0x0},
-			{".debug_str", SHT_PROGBITS, 0x0, 0x0, 0xa00, 0xd, 0x0, 0x0, 0x1, 0x0},
-			{".shstrtab", SHT_STRTAB, 0x0, 0x0, 0xa0d, 0xf8, 0x0, 0x0, 0x1, 0x0},
-			{".symtab", SHT_SYMTAB, 0x0, 0x0, 0xfb8, 0x4b0, 0x1d, 0x38, 0x4, 0x10},
-			{".strtab", SHT_STRTAB, 0x0, 0x0, 0x1468, 0x206, 0x0, 0x0, 0x1, 0x0},
-		},
-		[]ProgHeader{
-			{PT_PHDR, PF_R + PF_X, 0x34, 0x8048034, 0x8048034, 0xa0, 0xa0, 0x4},
-			{PT_INTERP, PF_R, 0xd4, 0x80480d4, 0x80480d4, 0x15, 0x15, 0x1},
-			{PT_LOAD, PF_R + PF_X, 0x0, 0x8048000, 0x8048000, 0x5fb, 0x5fb, 0x1000},
-			{PT_LOAD, PF_R + PF_W, 0x5fc, 0x80495fc, 0x80495fc, 0xd8, 0xf8, 0x1000},
-			{PT_DYNAMIC, PF_R + PF_W, 0x60c, 0x804960c, 0x804960c, 0x98, 0x98, 0x4},
-		},
-		[]string{"libc.so.6"},
-	},
-	{
-		"testdata/gcc-amd64-linux-exec",
-		FileHeader{ELFCLASS64, ELFDATA2LSB, EV_CURRENT, ELFOSABI_NONE, 0, binary.LittleEndian, ET_EXEC, EM_X86_64, 0x4003e0},
-		[]SectionHeader{
-			{"", SHT_NULL, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
-			{".interp", SHT_PROGBITS, SHF_ALLOC, 0x400200, 0x200, 0x1c, 0x0, 0x0, 0x1, 0x0},
-			{".note.ABI-tag", SHT_NOTE, SHF_ALLOC, 0x40021c, 0x21c, 0x20, 0x0, 0x0, 0x4, 0x0},
-			{".hash", SHT_HASH, SHF_ALLOC, 0x400240, 0x240, 0x24, 0x5, 0x0, 0x8, 0x4},
-			{".gnu.hash", SHT_LOOS + 268435446, SHF_ALLOC, 0x400268, 0x268, 0x1c, 0x5, 0x0, 0x8, 0x0},
-			{".dynsym", SHT_DYNSYM, SHF_ALLOC, 0x400288, 0x288, 0x60, 0x6, 0x1, 0x8, 0x18},
-			{".dynstr", SHT_STRTAB, SHF_ALLOC, 0x4002e8, 0x2e8, 0x3d, 0x0, 0x0, 0x1, 0x0},
-			{".gnu.version", SHT_HIOS, SHF_ALLOC, 0x400326, 0x326, 0x8, 0x5, 0x0, 0x2, 0x2},
-			{".gnu.version_r", SHT_LOOS + 268435454, SHF_ALLOC, 0x400330, 0x330, 0x20, 0x6, 0x1, 0x8, 0x0},
-			{".rela.dyn", SHT_RELA, SHF_ALLOC, 0x400350, 0x350, 0x18, 0x5, 0x0, 0x8, 0x18},
-			{".rela.plt", SHT_RELA, SHF_ALLOC, 0x400368, 0x368, 0x30, 0x5, 0xc, 0x8, 0x18},
-			{".init", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR, 0x400398, 0x398, 0x18, 0x0, 0x0, 0x4, 0x0},
-			{".plt", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR, 0x4003b0, 0x3b0, 0x30, 0x0, 0x0, 0x4, 0x10},
-			{".text", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR, 0x4003e0, 0x3e0, 0x1b4, 0x0, 0x0, 0x10, 0x0},
-			{".fini", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR, 0x400594, 0x594, 0xe, 0x0, 0x0, 0x4, 0x0},
-			{".rodata", SHT_PROGBITS, SHF_ALLOC, 0x4005a4, 0x5a4, 0x11, 0x0, 0x0, 0x4, 0x0},
-			{".eh_frame_hdr", SHT_PROGBITS, SHF_ALLOC, 0x4005b8, 0x5b8, 0x24, 0x0, 0x0, 0x4, 0x0},
-			{".eh_frame", SHT_PROGBITS, SHF_ALLOC, 0x4005e0, 0x5e0, 0xa4, 0x0, 0x0, 0x8, 0x0},
-			{".ctors", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x600688, 0x688, 0x10, 0x0, 0x0, 0x8, 0x0},
-			{".dtors", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x600698, 0x698, 0x10, 0x0, 0x0, 0x8, 0x0},
-			{".jcr", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x6006a8, 0x6a8, 0x8, 0x0, 0x0, 0x8, 0x0},
-			{".dynamic", SHT_DYNAMIC, SHF_WRITE + SHF_ALLOC, 0x6006b0, 0x6b0, 0x1a0, 0x6, 0x0, 0x8, 0x10},
-			{".got", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x600850, 0x850, 0x8, 0x0, 0x0, 0x8, 0x8},
-			{".got.plt", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x600858, 0x858, 0x28, 0x0, 0x0, 0x8, 0x8},
-			{".data", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x600880, 0x880, 0x18, 0x0, 0x0, 0x8, 0x0},
-			{".bss", SHT_NOBITS, SHF_WRITE + SHF_ALLOC, 0x600898, 0x898, 0x8, 0x0, 0x0, 0x4, 0x0},
-			{".comment", SHT_PROGBITS, 0x0, 0x0, 0x898, 0x126, 0x0, 0x0, 0x1, 0x0},
-			{".debug_aranges", SHT_PROGBITS, 0x0, 0x0, 0x9c0, 0x90, 0x0, 0x0, 0x10, 0x0},
-			{".debug_pubnames", SHT_PROGBITS, 0x0, 0x0, 0xa50, 0x25, 0x0, 0x0, 0x1, 0x0},
-			{".debug_info", SHT_PROGBITS, 0x0, 0x0, 0xa75, 0x1a7, 0x0, 0x0, 0x1, 0x0},
-			{".debug_abbrev", SHT_PROGBITS, 0x0, 0x0, 0xc1c, 0x6f, 0x0, 0x0, 0x1, 0x0},
-			{".debug_line", SHT_PROGBITS, 0x0, 0x0, 0xc8b, 0x13f, 0x0, 0x0, 0x1, 0x0},
-			{".debug_str", SHT_PROGBITS, SHF_MERGE + SHF_STRINGS, 0x0, 0xdca, 0xb1, 0x0, 0x0, 0x1, 0x1},
-			{".debug_ranges", SHT_PROGBITS, 0x0, 0x0, 0xe80, 0x90, 0x0, 0x0, 0x10, 0x0},
-			{".shstrtab", SHT_STRTAB, 0x0, 0x0, 0xf10, 0x149, 0x0, 0x0, 0x1, 0x0},
-			{".symtab", SHT_SYMTAB, 0x0, 0x0, 0x19a0, 0x6f0, 0x24, 0x39, 0x8, 0x18},
-			{".strtab", SHT_STRTAB, 0x0, 0x0, 0x2090, 0x1fc, 0x0, 0x0, 0x1, 0x0},
-		},
-		[]ProgHeader{
-			{PT_PHDR, PF_R + PF_X, 0x40, 0x400040, 0x400040, 0x1c0, 0x1c0, 0x8},
-			{PT_INTERP, PF_R, 0x200, 0x400200, 0x400200, 0x1c, 0x1c, 1},
-			{PT_LOAD, PF_R + PF_X, 0x0, 0x400000, 0x400000, 0x684, 0x684, 0x200000},
-			{PT_LOAD, PF_R + PF_W, 0x688, 0x600688, 0x600688, 0x210, 0x218, 0x200000},
-			{PT_DYNAMIC, PF_R + PF_W, 0x6b0, 0x6006b0, 0x6006b0, 0x1a0, 0x1a0, 0x8},
-			{PT_NOTE, PF_R, 0x21c, 0x40021c, 0x40021c, 0x20, 0x20, 0x4},
-			{PT_LOOS + 0x474E550, PF_R, 0x5b8, 0x4005b8, 0x4005b8, 0x24, 0x24, 0x4},
-			{PT_LOOS + 0x474E551, PF_R + PF_W, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8},
-		},
-		[]string{"libc.so.6"},
-	},
-	{
-		"testdata/hello-world-core.gz",
-		FileHeader{ELFCLASS64, ELFDATA2LSB, EV_CURRENT, ELFOSABI_NONE, 0x0, binary.LittleEndian, ET_CORE, EM_X86_64, 0x0},
-		[]SectionHeader{},
-		[]ProgHeader{
-			{Type: PT_NOTE, Flags: 0x0, Off: 0x3f8, Vaddr: 0x0, Paddr: 0x0, Filesz: 0x8ac, Memsz: 0x0, Align: 0x0},
-			{Type: PT_LOAD, Flags: PF_X + PF_R, Off: 0x1000, Vaddr: 0x400000, Paddr: 0x0, Filesz: 0x0, Memsz: 0x1000, Align: 0x1000},
-			{Type: PT_LOAD, Flags: PF_R, Off: 0x1000, Vaddr: 0x401000, Paddr: 0x0, Filesz: 0x1000, Memsz: 0x1000, Align: 0x1000},
-			{Type: PT_LOAD, Flags: PF_W + PF_R, Off: 0x2000, Vaddr: 0x402000, Paddr: 0x0, Filesz: 0x1000, Memsz: 0x1000, Align: 0x1000},
-			{Type: PT_LOAD, Flags: PF_X + PF_R, Off: 0x3000, Vaddr: 0x7f54078b8000, Paddr: 0x0, Filesz: 0x0, Memsz: 0x1b5000, Align: 0x1000},
-			{Type: PT_LOAD, Flags: 0x0, Off: 0x3000, Vaddr: 0x7f5407a6d000, Paddr: 0x0, Filesz: 0x0, Memsz: 0x1ff000, Align: 0x1000},
-			{Type: PT_LOAD, Flags: PF_R, Off: 0x3000, Vaddr: 0x7f5407c6c000, Paddr: 0x0, Filesz: 0x4000, Memsz: 0x4000, Align: 0x1000},
-			{Type: PT_LOAD, Flags: PF_W + PF_R, Off: 0x7000, Vaddr: 0x7f5407c70000, Paddr: 0x0, Filesz: 0x2000, Memsz: 0x2000, Align: 0x1000},
-			{Type: PT_LOAD, Flags: PF_W + PF_R, Off: 0x9000, Vaddr: 0x7f5407c72000, Paddr: 0x0, Filesz: 0x5000, Memsz: 0x5000, Align: 0x1000},
-			{Type: PT_LOAD, Flags: PF_X + PF_R, Off: 0xe000, Vaddr: 0x7f5407c77000, Paddr: 0x0, Filesz: 0x0, Memsz: 0x22000, Align: 0x1000},
-			{Type: PT_LOAD, Flags: PF_W + PF_R, Off: 0xe000, Vaddr: 0x7f5407e81000, Paddr: 0x0, Filesz: 0x3000, Memsz: 0x3000, Align: 0x1000},
-			{Type: PT_LOAD, Flags: PF_W + PF_R, Off: 0x11000, Vaddr: 0x7f5407e96000, Paddr: 0x0, Filesz: 0x3000, Memsz: 0x3000, Align: 0x1000},
-			{Type: PT_LOAD, Flags: PF_R, Off: 0x14000, Vaddr: 0x7f5407e99000, Paddr: 0x0, Filesz: 0x1000, Memsz: 0x1000, Align: 0x1000},
-			{Type: PT_LOAD, Flags: PF_W + PF_R, Off: 0x15000, Vaddr: 0x7f5407e9a000, Paddr: 0x0, Filesz: 0x2000, Memsz: 0x2000, Align: 0x1000},
-			{Type: PT_LOAD, Flags: PF_W + PF_R, Off: 0x17000, Vaddr: 0x7fff79972000, Paddr: 0x0, Filesz: 0x23000, Memsz: 0x23000, Align: 0x1000},
-			{Type: PT_LOAD, Flags: PF_X + PF_R, Off: 0x3a000, Vaddr: 0x7fff799f8000, Paddr: 0x0, Filesz: 0x1000, Memsz: 0x1000, Align: 0x1000},
-			{Type: PT_LOAD, Flags: PF_X + PF_R, Off: 0x3b000, Vaddr: 0xffffffffff600000, Paddr: 0x0, Filesz: 0x1000, Memsz: 0x1000, Align: 0x1000},
-		},
-		nil,
-	},
-}
-
-func TestOpen(t *testing.T) {
-	for i := range fileTests {
-		tt := &fileTests[i]
-
-		var f *File
-		var err error
-		if path.Ext(tt.file) == ".gz" {
-			var r io.ReaderAt
-			if r, err = decompress(tt.file); err == nil {
-				f, err = NewFile(r)
-			}
-		} else {
-			f, err = Open(tt.file)
-		}
-		if err != nil {
-			t.Errorf("cannot open file %s: %v", tt.file, err)
-			continue
-		}
-		defer f.Close()
-		if !reflect.DeepEqual(f.FileHeader, tt.hdr) {
-			t.Errorf("open %s:\n\thave %#v\n\twant %#v\n", tt.file, f.FileHeader, tt.hdr)
-			continue
-		}
-		for i, s := range f.Sections {
-			if i >= len(tt.sections) {
-				break
-			}
-			sh := &tt.sections[i]
-			if !reflect.DeepEqual(&s.SectionHeader, sh) {
-				t.Errorf("open %s, section %d:\n\thave %#v\n\twant %#v\n", tt.file, i, &s.SectionHeader, sh)
-			}
-		}
-		for i, p := range f.Progs {
-			if i >= len(tt.progs) {
-				break
-			}
-			ph := &tt.progs[i]
-			if !reflect.DeepEqual(&p.ProgHeader, ph) {
-				t.Errorf("open %s, program %d:\n\thave %#v\n\twant %#v\n", tt.file, i, &p.ProgHeader, ph)
-			}
-		}
-		tn := len(tt.sections)
-		fn := len(f.Sections)
-		if tn != fn {
-			t.Errorf("open %s: len(Sections) = %d, want %d", tt.file, fn, tn)
-		}
-		tn = len(tt.progs)
-		fn = len(f.Progs)
-		if tn != fn {
-			t.Errorf("open %s: len(Progs) = %d, want %d", tt.file, fn, tn)
-		}
-		tl := tt.needed
-		fl, err := f.ImportedLibraries()
-		if err != nil {
-			t.Error(err)
-		}
-		if !reflect.DeepEqual(tl, fl) {
-			t.Errorf("open %s: DT_NEEDED = %v, want %v", tt.file, tl, fl)
-		}
-	}
-}
-
-// elf.NewFile requires io.ReaderAt, which compress/gzip cannot
-// provide. Decompress the file to a bytes.Reader.
-func decompress(gz string) (io.ReaderAt, error) {
-	in, err := os.Open(gz)
-	if err != nil {
-		return nil, err
-	}
-	defer in.Close()
-	r, err := gzip.NewReader(in)
-	if err != nil {
-		return nil, err
-	}
-	var out bytes.Buffer
-	_, err = io.Copy(&out, r)
-	return bytes.NewReader(out.Bytes()), err
-}
-
-type relocationTestEntry struct {
-	entryNumber int
-	entry       *dwarf.Entry
-}
-
-type relocationTest struct {
-	file    string
-	entries []relocationTestEntry
-}
-
-var relocationTests = []relocationTest{
-	{
-		"testdata/go-relocation-test-gcc441-x86-64.obj",
-		[]relocationTestEntry{
-			{0, &dwarf.Entry{Offset: 0xb, Tag: dwarf.TagCompileUnit, Children: true, Field: []dwarf.Field{{Attr: dwarf.AttrProducer, Val: "GNU C 4.4.1"}, {Attr: dwarf.AttrLanguage, Val: int64(1)}, {Attr: dwarf.AttrName, Val: "go-relocation-test.c"}, {Attr: dwarf.AttrCompDir, Val: "/tmp"}, {Attr: dwarf.AttrLowpc, Val: uint64(0x0)}, {Attr: dwarf.AttrHighpc, Val: uint64(0x6)}, {Attr: dwarf.AttrStmtList, Val: int64(0)}}}},
-		},
-	},
-	{
-		"testdata/go-relocation-test-gcc441-x86.obj",
-		[]relocationTestEntry{
-			{0, &dwarf.Entry{Offset: 0xb, Tag: dwarf.TagCompileUnit, Children: true, Field: []dwarf.Field{{Attr: dwarf.AttrProducer, Val: "GNU C 4.4.1"}, {Attr: dwarf.AttrLanguage, Val: int64(1)}, {Attr: dwarf.AttrName, Val: "t.c"}, {Attr: dwarf.AttrCompDir, Val: "/tmp"}, {Attr: dwarf.AttrLowpc, Val: uint64(0x0)}, {Attr: dwarf.AttrHighpc, Val: uint64(0x5)}, {Attr: dwarf.AttrStmtList, Val: int64(0)}}}},
-		},
-	},
-	{
-		"testdata/go-relocation-test-gcc424-x86-64.obj",
-		[]relocationTestEntry{
-			{0, &dwarf.Entry{Offset: 0xb, Tag: dwarf.TagCompileUnit, Children: true, Field: []dwarf.Field{{Attr: dwarf.AttrProducer, Val: "GNU C 4.2.4 (Ubuntu 4.2.4-1ubuntu4)"}, {Attr: dwarf.AttrLanguage, Val: int64(1)}, {Attr: dwarf.AttrName, Val: "go-relocation-test-gcc424.c"}, {Attr: dwarf.AttrCompDir, Val: "/tmp"}, {Attr: dwarf.AttrLowpc, Val: uint64(0x0)}, {Attr: dwarf.AttrHighpc, Val: uint64(0x6)}, {Attr: dwarf.AttrStmtList, Val: int64(0)}}}},
-		},
-	},
-	{
-		"testdata/gcc-amd64-openbsd-debug-with-rela.obj",
-		[]relocationTestEntry{
-			{203, &dwarf.Entry{Offset: 0xc62, Tag: dwarf.TagMember, Children: false, Field: []dwarf.Field{{Attr: dwarf.AttrName, Val: "it_interval"}, {Attr: dwarf.AttrDeclFile, Val: int64(7)}, {Attr: dwarf.AttrDeclLine, Val: int64(236)}, {Attr: dwarf.AttrType, Val: dwarf.Offset(0xb7f)}, {Attr: dwarf.AttrDataMemberLoc, Val: []byte{0x23, 0x0}}}}},
-			{204, &dwarf.Entry{Offset: 0xc70, Tag: dwarf.TagMember, Children: false, Field: []dwarf.Field{{Attr: dwarf.AttrName, Val: "it_value"}, {Attr: dwarf.AttrDeclFile, Val: int64(7)}, {Attr: dwarf.AttrDeclLine, Val: int64(237)}, {Attr: dwarf.AttrType, Val: dwarf.Offset(0xb7f)}, {Attr: dwarf.AttrDataMemberLoc, Val: []byte{0x23, 0x10}}}}},
-		},
-	},
-}
-
-func TestDWARFRelocations(t *testing.T) {
-	for i, test := range relocationTests {
-		f, err := Open(test.file)
-		if err != nil {
-			t.Error(err)
-			continue
-		}
-		dwarf, err := f.DWARF()
-		if err != nil {
-			t.Error(err)
-			continue
-		}
-		for _, testEntry := range test.entries {
-			reader := dwarf.Reader()
-			for j := 0; j < testEntry.entryNumber; j++ {
-				entry, err := reader.Next()
-				if entry == nil || err != nil {
-					t.Errorf("Failed to skip to entry %d: %v", testEntry.entryNumber, err)
-					continue
-				}
-			}
-			entry, err := reader.Next()
-			if err != nil {
-				t.Error(err)
-				continue
-			}
-			if !reflect.DeepEqual(testEntry.entry, entry) {
-				t.Errorf("#%d/%d: mismatch: got:%#v want:%#v", i, testEntry.entryNumber, entry, testEntry.entry)
-				continue
-			}
-		}
-	}
-}
-
-func TestNoSectionOverlaps(t *testing.T) {
-	// Ensure 6l outputs sections without overlaps.
-	if runtime.GOOS != "linux" && runtime.GOOS != "freebsd" {
-		return // not ELF
-	}
-	_ = net.ResolveIPAddr // force dynamic linkage
-	f, err := Open(os.Args[0])
-	if err != nil {
-		t.Error(err)
-		return
-	}
-	for i, si := range f.Sections {
-		sih := si.SectionHeader
-		if sih.Type == SHT_NOBITS {
-			continue
-		}
-		for j, sj := range f.Sections {
-			sjh := sj.SectionHeader
-			if i == j || sjh.Type == SHT_NOBITS || sih.Offset == sjh.Offset && sih.Size == 0 {
-				continue
-			}
-			if sih.Offset >= sjh.Offset && sih.Offset < sjh.Offset+sjh.Size {
-				t.Errorf("ld produced ELF with section %s within %s: 0x%x <= 0x%x..0x%x < 0x%x",
-					sih.Name, sjh.Name, sjh.Offset, sih.Offset, sih.Offset+sih.Size, sjh.Offset+sjh.Size)
-			}
-		}
-	}
-}
diff --git a/elf/testdata/gcc-386-freebsd-exec b/elf/testdata/gcc-386-freebsd-exec
deleted file mode 100755
index 7af9c58..0000000
--- a/elf/testdata/gcc-386-freebsd-exec
+++ /dev/null
Binary files differ
diff --git a/elf/testdata/gcc-amd64-linux-exec b/elf/testdata/gcc-amd64-linux-exec
deleted file mode 100755
index c6cb1de..0000000
--- a/elf/testdata/gcc-amd64-linux-exec
+++ /dev/null
Binary files differ
diff --git a/elf/testdata/gcc-amd64-openbsd-debug-with-rela.obj b/elf/testdata/gcc-amd64-openbsd-debug-with-rela.obj
deleted file mode 100644
index f62b1ea..0000000
--- a/elf/testdata/gcc-amd64-openbsd-debug-with-rela.obj
+++ /dev/null
Binary files differ
diff --git a/elf/testdata/go-relocation-test-gcc424-x86-64.obj b/elf/testdata/go-relocation-test-gcc424-x86-64.obj
deleted file mode 100644
index a7c6d6e..0000000
--- a/elf/testdata/go-relocation-test-gcc424-x86-64.obj
+++ /dev/null
Binary files differ
diff --git a/elf/testdata/go-relocation-test-gcc441-x86-64.obj b/elf/testdata/go-relocation-test-gcc441-x86-64.obj
deleted file mode 100644
index 2d37ab6..0000000
--- a/elf/testdata/go-relocation-test-gcc441-x86-64.obj
+++ /dev/null
Binary files differ
diff --git a/elf/testdata/go-relocation-test-gcc441-x86.obj b/elf/testdata/go-relocation-test-gcc441-x86.obj
deleted file mode 100644
index 0d59fe3..0000000
--- a/elf/testdata/go-relocation-test-gcc441-x86.obj
+++ /dev/null
Binary files differ
diff --git a/elf/testdata/hello-world-core.gz b/elf/testdata/hello-world-core.gz
deleted file mode 100644
index 806af6e..0000000
--- a/elf/testdata/hello-world-core.gz
+++ /dev/null
Binary files differ
diff --git a/elf/testdata/hello.c b/elf/testdata/hello.c
deleted file mode 100644
index 34d9ee7..0000000
--- a/elf/testdata/hello.c
+++ /dev/null
@@ -1,7 +0,0 @@
-#include <stdio.h>
-
-void
-main(int argc, char *argv[])
-{
-	printf("hello, world\n");
-}
diff --git a/gosym/pclinetest.asm b/gosym/pclinetest.asm
deleted file mode 100644
index b9ee9c0..0000000
--- a/gosym/pclinetest.asm
+++ /dev/null
@@ -1,58 +0,0 @@
-TEXT linefrompc(SB),4,$0	// Each byte stores its line delta
-BYTE $2;
-BYTE $1;
-BYTE $1; BYTE $0;
-BYTE $1; BYTE $0; BYTE $0;
-BYTE $1; BYTE $0; BYTE $0; BYTE $0; BYTE $0;
-BYTE $1; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0;
-BYTE $1; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0;
-BYTE $1; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0;
-BYTE $1; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0;
-BYTE $1; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0;
-BYTE $1; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0;
-BYTE $1; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0;
-BYTE $1; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0;
-BYTE $1; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0;
-BYTE $1;
-BYTE $1;
-BYTE $1; BYTE $0;
-BYTE $1; BYTE $0; BYTE $0;
-BYTE $1; BYTE $0; BYTE $0; BYTE $0; BYTE $0;
-BYTE $1; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0;
-BYTE $1; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0;
-BYTE $1; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0;
-BYTE $1; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0;
-#include "pclinetest.h"
-BYTE $2;
-#include "pclinetest.h"
-BYTE $2;
-BYTE $255;
-
-TEXT pcfromline(SB),4,$0	// Each record stores its line delta, then n, then n more bytes
-BYTE $32; BYTE $0;
-BYTE $1; BYTE $1; BYTE $0;
-BYTE $1; BYTE $0;
-
-BYTE $2; BYTE $4; BYTE $0; BYTE $0; BYTE $0; BYTE $0;
-
-
-#include "pclinetest.h"
-BYTE $4; BYTE $0;
-
-
-BYTE $3; BYTE $3; BYTE $0; BYTE $0; BYTE $0;
-#include "pclinetest.h"
-
-
-BYTE $4; BYTE $3; BYTE $0; BYTE $0; BYTE $0;
-BYTE $255;
-
-// Keep the linker happy
-TEXT main·main(SB),4,$0
-	RET
-
-TEXT main·init(SB),4,$0
-	// Prevent GC of our test symbols
-	CALL linefrompc(SB)
-	CALL pcfromline(SB)
-	RET
diff --git a/gosym/pclinetest.h b/gosym/pclinetest.h
deleted file mode 100644
index 156c0b8..0000000
--- a/gosym/pclinetest.h
+++ /dev/null
@@ -1,9 +0,0 @@
-// +build ignore
-
-// Empty include file to generate z symbols
-
-
-
-
-
-// EOF
diff --git a/gosym/pclntab.go b/gosym/pclntab.go
deleted file mode 100644
index a9c2fc7..0000000
--- a/gosym/pclntab.go
+++ /dev/null
@@ -1,462 +0,0 @@
-// Copyright 2009 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.
-
-/*
- * Line tables
- */
-
-package gosym
-
-import (
-	"encoding/binary"
-	"sync"
-)
-
-// A LineTable is a data structure mapping program counters to line numbers.
-//
-// In Go 1.1 and earlier, each function (represented by a Func) had its own LineTable,
-// and the line number corresponded to a numbering of all source lines in the
-// program, across all files. That absolute line number would then have to be
-// converted separately to a file name and line number within the file.
-//
-// In Go 1.2, the format of the data changed so that there is a single LineTable
-// for the entire program, shared by all Funcs, and there are no absolute line
-// numbers, just line numbers within specific files.
-//
-// For the most part, LineTable's methods should be treated as an internal
-// detail of the package; callers should use the methods on Table instead.
-type LineTable struct {
-	Data []byte
-	PC   uint64
-	Line int
-
-	// Go 1.2 state
-	mu       sync.Mutex
-	go12     int // is this in Go 1.2 format? -1 no, 0 unknown, 1 yes
-	binary   binary.ByteOrder
-	quantum  uint32
-	ptrsize  uint32
-	functab  []byte
-	nfunctab uint32
-	filetab  []byte
-	nfiletab uint32
-	fileMap  map[string]uint32
-}
-
-// NOTE(rsc): This is wrong for GOARCH=arm, which uses a quantum of 4,
-// but we have no idea whether we're using arm or not. This only
-// matters in the old (pre-Go 1.2) symbol table format, so it's not worth
-// fixing.
-const oldQuantum = 1
-
-func (t *LineTable) parse(targetPC uint64, targetLine int) (b []byte, pc uint64, line int) {
-	// The PC/line table can be thought of as a sequence of
-	//  <pc update>* <line update>
-	// batches.  Each update batch results in a (pc, line) pair,
-	// where line applies to every PC from pc up to but not
-	// including the pc of the next pair.
-	//
-	// Here we process each update individually, which simplifies
-	// the code, but makes the corner cases more confusing.
-	b, pc, line = t.Data, t.PC, t.Line
-	for pc <= targetPC && line != targetLine && len(b) > 0 {
-		code := b[0]
-		b = b[1:]
-		switch {
-		case code == 0:
-			if len(b) < 4 {
-				b = b[0:0]
-				break
-			}
-			val := binary.BigEndian.Uint32(b)
-			b = b[4:]
-			line += int(val)
-		case code <= 64:
-			line += int(code)
-		case code <= 128:
-			line -= int(code - 64)
-		default:
-			pc += oldQuantum * uint64(code-128)
-			continue
-		}
-		pc += oldQuantum
-	}
-	return b, pc, line
-}
-
-func (t *LineTable) slice(pc uint64) *LineTable {
-	data, pc, line := t.parse(pc, -1)
-	return &LineTable{Data: data, PC: pc, Line: line}
-}
-
-// PCToLine returns the line number for the given program counter.
-// Callers should use Table's PCToLine method instead.
-func (t *LineTable) PCToLine(pc uint64) int {
-	if t.isGo12() {
-		return t.go12PCToLine(pc)
-	}
-	_, _, line := t.parse(pc, -1)
-	return line
-}
-
-// LineToPC returns the program counter for the given line number,
-// considering only program counters before maxpc.
-// Callers should use Table's LineToPC method instead.
-func (t *LineTable) LineToPC(line int, maxpc uint64) uint64 {
-	if t.isGo12() {
-		return 0
-	}
-	_, pc, line1 := t.parse(maxpc, line)
-	if line1 != line {
-		return 0
-	}
-	// Subtract quantum from PC to account for post-line increment
-	return pc - oldQuantum
-}
-
-// NewLineTable returns a new PC/line table
-// corresponding to the encoded data.
-// Text must be the start address of the
-// corresponding text segment.
-func NewLineTable(data []byte, text uint64) *LineTable {
-	return &LineTable{Data: data, PC: text, Line: 0}
-}
-
-// Go 1.2 symbol table format.
-// See golang.org/s/go12symtab.
-//
-// A general note about the methods here: rather than try to avoid
-// index out of bounds errors, we trust Go to detect them, and then
-// we recover from the panics and treat them as indicative of a malformed
-// or incomplete table.
-//
-// The methods called by symtab.go, which begin with "go12" prefixes,
-// are expected to have that recovery logic.
-
-// isGo12 reports whether this is a Go 1.2 (or later) symbol table.
-func (t *LineTable) isGo12() bool {
-	t.go12Init()
-	return t.go12 == 1
-}
-
-const go12magic = 0xfffffffb
-
-// uintptr returns the pointer-sized value encoded at b.
-// The pointer size is dictated by the table being read.
-func (t *LineTable) uintptr(b []byte) uint64 {
-	if t.ptrsize == 4 {
-		return uint64(t.binary.Uint32(b))
-	}
-	return t.binary.Uint64(b)
-}
-
-// go12init initializes the Go 1.2 metadata if t is a Go 1.2 symbol table.
-func (t *LineTable) go12Init() {
-	t.mu.Lock()
-	defer t.mu.Unlock()
-	if t.go12 != 0 {
-		return
-	}
-
-	defer func() {
-		// If we panic parsing, assume it's not a Go 1.2 symbol table.
-		recover()
-	}()
-
-	// Check header: 4-byte magic, two zeros, pc quantum, pointer size.
-	t.go12 = -1 // not Go 1.2 until proven otherwise
-	if len(t.Data) < 16 || t.Data[4] != 0 || t.Data[5] != 0 ||
-		(t.Data[6] != 1 && t.Data[6] != 4) || // pc quantum
-		(t.Data[7] != 4 && t.Data[7] != 8) { // pointer size
-		return
-	}
-
-	switch uint32(go12magic) {
-	case binary.LittleEndian.Uint32(t.Data):
-		t.binary = binary.LittleEndian
-	case binary.BigEndian.Uint32(t.Data):
-		t.binary = binary.BigEndian
-	default:
-		return
-	}
-
-	t.quantum = uint32(t.Data[6])
-	t.ptrsize = uint32(t.Data[7])
-
-	t.nfunctab = uint32(t.uintptr(t.Data[8:]))
-	t.functab = t.Data[8+t.ptrsize:]
-	functabsize := t.nfunctab*2*t.ptrsize + t.ptrsize
-	fileoff := t.binary.Uint32(t.functab[functabsize:])
-	t.functab = t.functab[:functabsize]
-	t.filetab = t.Data[fileoff:]
-	t.nfiletab = t.binary.Uint32(t.filetab)
-	t.filetab = t.filetab[:t.nfiletab*4]
-
-	t.go12 = 1 // so far so good
-}
-
-// go12Funcs returns a slice of Funcs derived from the Go 1.2 pcln table.
-func (t *LineTable) go12Funcs() []Func {
-	// Assume it is malformed and return nil on error.
-	defer func() {
-		recover()
-	}()
-
-	n := len(t.functab) / int(t.ptrsize) / 2
-	funcs := make([]Func, n)
-	for i := range funcs {
-		f := &funcs[i]
-		f.Entry = uint64(t.uintptr(t.functab[2*i*int(t.ptrsize):]))
-		f.End = uint64(t.uintptr(t.functab[(2*i+2)*int(t.ptrsize):]))
-		info := t.Data[t.uintptr(t.functab[(2*i+1)*int(t.ptrsize):]):]
-		f.LineTable = t
-		f.FrameSize = int(t.binary.Uint32(info[t.ptrsize+2*4:]))
-		f.Sym = &Sym{
-			Value:  f.Entry,
-			Type:   'T',
-			Name:   t.string(t.binary.Uint32(info[t.ptrsize:])),
-			GoType: 0,
-			Func:   f,
-		}
-	}
-	return funcs
-}
-
-// findFunc returns the func corresponding to the given program counter.
-func (t *LineTable) findFunc(pc uint64) []byte {
-	if pc < t.uintptr(t.functab) || pc >= t.uintptr(t.functab[len(t.functab)-int(t.ptrsize):]) {
-		return nil
-	}
-
-	// The function table is a list of 2*nfunctab+1 uintptrs,
-	// alternating program counters and offsets to func structures.
-	f := t.functab
-	nf := t.nfunctab
-	for nf > 0 {
-		m := nf / 2
-		fm := f[2*t.ptrsize*m:]
-		if t.uintptr(fm) <= pc && pc < t.uintptr(fm[2*t.ptrsize:]) {
-			return t.Data[t.uintptr(fm[t.ptrsize:]):]
-		} else if pc < t.uintptr(fm) {
-			nf = m
-		} else {
-			f = f[(m+1)*2*t.ptrsize:]
-			nf -= m + 1
-		}
-	}
-	return nil
-}
-
-// readvarint reads, removes, and returns a varint from *pp.
-func (t *LineTable) readvarint(pp *[]byte) uint32 {
-	var v, shift uint32
-	p := *pp
-	for shift = 0; ; shift += 7 {
-		b := p[0]
-		p = p[1:]
-		v |= (uint32(b) & 0x7F) << shift
-		if b&0x80 == 0 {
-			break
-		}
-	}
-	*pp = p
-	return v
-}
-
-// string returns a Go string found at off.
-func (t *LineTable) string(off uint32) string {
-	for i := off; ; i++ {
-		if t.Data[i] == 0 {
-			return string(t.Data[off:i])
-		}
-	}
-}
-
-// step advances to the next pc, value pair in the encoded table.
-func (t *LineTable) step(p *[]byte, pc *uint64, val *int32, first bool) bool {
-	uvdelta := t.readvarint(p)
-	if uvdelta == 0 && !first {
-		return false
-	}
-	if uvdelta&1 != 0 {
-		uvdelta = ^(uvdelta >> 1)
-	} else {
-		uvdelta >>= 1
-	}
-	vdelta := int32(uvdelta)
-	pcdelta := t.readvarint(p) * t.quantum
-	*pc += uint64(pcdelta)
-	*val += vdelta
-	return true
-}
-
-// pcvalue reports the value associated with the target pc.
-// off is the offset to the beginning of the pc-value table,
-// and entry is the start PC for the corresponding function.
-func (t *LineTable) pcvalue(off uint32, entry, targetpc uint64) int32 {
-	if off == 0 {
-		return -1
-	}
-	p := t.Data[off:]
-
-	val := int32(-1)
-	pc := entry
-	for t.step(&p, &pc, &val, pc == entry) {
-		if targetpc < pc {
-			return val
-		}
-	}
-	return -1
-}
-
-// findFileLine scans one function in the binary looking for a
-// program counter in the given file on the given line.
-// It does so by running the pc-value tables mapping program counter
-// to file number. Since most functions come from a single file, these
-// are usually short and quick to scan. If a file match is found, then the
-// code goes to the expense of looking for a simultaneous line number match.
-func (t *LineTable) findFileLine(entry uint64, filetab, linetab uint32, filenum, line int32) uint64 {
-	if filetab == 0 || linetab == 0 {
-		return 0
-	}
-
-	fp := t.Data[filetab:]
-	fl := t.Data[linetab:]
-	fileVal := int32(-1)
-	filePC := entry
-	lineVal := int32(-1)
-	linePC := entry
-	fileStartPC := filePC
-	for t.step(&fp, &filePC, &fileVal, filePC == entry) {
-		if fileVal == filenum && fileStartPC < filePC {
-			// fileVal is in effect starting at fileStartPC up to
-			// but not including filePC, and it's the file we want.
-			// Run the PC table looking for a matching line number
-			// or until we reach filePC.
-			lineStartPC := linePC
-			for linePC < filePC && t.step(&fl, &linePC, &lineVal, linePC == entry) {
-				// lineVal is in effect until linePC, and lineStartPC < filePC.
-				if lineVal == line {
-					if fileStartPC <= lineStartPC {
-						return lineStartPC
-					}
-					if fileStartPC < linePC {
-						return fileStartPC
-					}
-				}
-				lineStartPC = linePC
-			}
-		}
-		fileStartPC = filePC
-	}
-	return 0
-}
-
-// go12PCToLine maps program counter to line number for the Go 1.2 pcln table.
-func (t *LineTable) go12PCToLine(pc uint64) (line int) {
-	return t.go12PCToVal(pc, t.ptrsize+5*4)
-}
-
-// go12PCToSPAdj maps program counter to Stack Pointer adjustment for the Go 1.2 pcln table.
-func (t *LineTable) go12PCToSPAdj(pc uint64) (spadj int) {
-	return t.go12PCToVal(pc, t.ptrsize+3*4)
-}
-
-func (t *LineTable) go12PCToVal(pc uint64, fOffset uint32) (val int) {
-	defer func() {
-		if recover() != nil {
-			val = -1
-		}
-	}()
-
-	f := t.findFunc(pc)
-	if f == nil {
-		return -1
-	}
-	entry := t.uintptr(f)
-	linetab := t.binary.Uint32(f[fOffset:])
-	return int(t.pcvalue(linetab, entry, pc))
-}
-
-// go12PCToFile maps program counter to file name for the Go 1.2 pcln table.
-func (t *LineTable) go12PCToFile(pc uint64) (file string) {
-	defer func() {
-		if recover() != nil {
-			file = ""
-		}
-	}()
-
-	f := t.findFunc(pc)
-	if f == nil {
-		return ""
-	}
-	entry := t.uintptr(f)
-	filetab := t.binary.Uint32(f[t.ptrsize+4*4:])
-	fno := t.pcvalue(filetab, entry, pc)
-	if fno <= 0 {
-		return ""
-	}
-	return t.string(t.binary.Uint32(t.filetab[4*fno:]))
-}
-
-// go12LineToPC maps a (file, line) pair to a program counter for the Go 1.2 pcln table.
-func (t *LineTable) go12LineToPC(file string, line int) (pc uint64) {
-	defer func() {
-		if recover() != nil {
-			pc = 0
-		}
-	}()
-
-	t.initFileMap()
-	filenum := t.fileMap[file]
-	if filenum == 0 {
-		return 0
-	}
-
-	// Scan all functions.
-	// If this turns out to be a bottleneck, we could build a map[int32][]int32
-	// mapping file number to a list of functions with code from that file.
-	for i := uint32(0); i < t.nfunctab; i++ {
-		f := t.Data[t.uintptr(t.functab[2*t.ptrsize*i+t.ptrsize:]):]
-		entry := t.uintptr(f)
-		filetab := t.binary.Uint32(f[t.ptrsize+4*4:])
-		linetab := t.binary.Uint32(f[t.ptrsize+5*4:])
-		pc := t.findFileLine(entry, filetab, linetab, int32(filenum), int32(line))
-		if pc != 0 {
-			return pc
-		}
-	}
-	return 0
-}
-
-// initFileMap initializes the map from file name to file number.
-func (t *LineTable) initFileMap() {
-	t.mu.Lock()
-	defer t.mu.Unlock()
-
-	if t.fileMap != nil {
-		return
-	}
-	m := make(map[string]uint32)
-
-	for i := uint32(1); i < t.nfiletab; i++ {
-		s := t.string(t.binary.Uint32(t.filetab[4*i:]))
-		m[s] = i
-	}
-	t.fileMap = m
-}
-
-// go12MapFiles adds to m a key for every file in the Go 1.2 LineTable.
-// Every key maps to obj. That's not a very interesting map, but it provides
-// a way for callers to obtain the list of files in the program.
-func (t *LineTable) go12MapFiles(m map[string]*Obj, obj *Obj) {
-	defer func() {
-		recover()
-	}()
-
-	t.initFileMap()
-	for file := range t.fileMap {
-		m[file] = obj
-	}
-}
diff --git a/gosym/pclntab_test.go b/gosym/pclntab_test.go
deleted file mode 100644
index 35502e8..0000000
--- a/gosym/pclntab_test.go
+++ /dev/null
@@ -1,274 +0,0 @@
-// Copyright 2009 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 gosym
-
-import (
-	"debug/elf"
-	"fmt"
-	"io/ioutil"
-	"os"
-	"os/exec"
-	"path/filepath"
-	"runtime"
-	"strings"
-	"testing"
-)
-
-var (
-	pclineTempDir    string
-	pclinetestBinary string
-)
-
-func dotest(self bool) bool {
-	// For now, only works on amd64 platforms.
-	if runtime.GOARCH != "amd64" {
-		return false
-	}
-	// Self test reads test binary; only works on Linux.
-	if self && runtime.GOOS != "linux" {
-		return false
-	}
-	// Command below expects "sh", so Unix.
-	if runtime.GOOS == "windows" || runtime.GOOS == "plan9" {
-		return false
-	}
-	if pclinetestBinary != "" {
-		return true
-	}
-	var err error
-	pclineTempDir, err = ioutil.TempDir("", "pclinetest")
-	if err != nil {
-		panic(err)
-	}
-	if strings.Contains(pclineTempDir, " ") {
-		panic("unexpected space in tempdir")
-	}
-	// This command builds pclinetest from pclinetest.asm;
-	// the resulting binary looks like it was built from pclinetest.s,
-	// but we have renamed it to keep it away from the go tool.
-	pclinetestBinary = filepath.Join(pclineTempDir, "pclinetest")
-	command := fmt.Sprintf("go tool 6a -o %s.6 pclinetest.asm && go tool 6l -H linux -E main -o %s %s.6",
-		pclinetestBinary, pclinetestBinary, pclinetestBinary)
-	cmd := exec.Command("sh", "-c", command)
-	cmd.Stdout = os.Stdout
-	cmd.Stderr = os.Stderr
-	if err := cmd.Run(); err != nil {
-		panic(err)
-	}
-	return true
-}
-
-func endtest() {
-	if pclineTempDir != "" {
-		os.RemoveAll(pclineTempDir)
-		pclineTempDir = ""
-		pclinetestBinary = ""
-	}
-}
-
-func getTable(t *testing.T) *Table {
-	f, tab := crack(os.Args[0], t)
-	f.Close()
-	return tab
-}
-
-func crack(file string, t *testing.T) (*elf.File, *Table) {
-	// Open self
-	f, err := elf.Open(file)
-	if err != nil {
-		t.Fatal(err)
-	}
-	return parse(file, f, t)
-}
-
-func parse(file string, f *elf.File, t *testing.T) (*elf.File, *Table) {
-	symdat, err := f.Section(".gosymtab").Data()
-	if err != nil {
-		f.Close()
-		t.Fatalf("reading %s gosymtab: %v", file, err)
-	}
-	pclndat, err := f.Section(".gopclntab").Data()
-	if err != nil {
-		f.Close()
-		t.Fatalf("reading %s gopclntab: %v", file, err)
-	}
-
-	pcln := NewLineTable(pclndat, f.Section(".text").Addr)
-	tab, err := NewTable(symdat, pcln)
-	if err != nil {
-		f.Close()
-		t.Fatalf("parsing %s gosymtab: %v", file, err)
-	}
-
-	return f, tab
-}
-
-var goarch = os.Getenv("O")
-
-func TestLineFromAline(t *testing.T) {
-	if !dotest(true) {
-		return
-	}
-	defer endtest()
-
-	tab := getTable(t)
-	if tab.go12line != nil {
-		// aline's don't exist in the Go 1.2 table.
-		t.Skip("not relevant to Go 1.2 symbol table")
-	}
-
-	// Find the sym package
-	pkg := tab.LookupFunc("debug/gosym.TestLineFromAline").Obj
-	if pkg == nil {
-		t.Fatalf("nil pkg")
-	}
-
-	// Walk every absolute line and ensure that we hit every
-	// source line monotonically
-	lastline := make(map[string]int)
-	final := -1
-	for i := 0; i < 10000; i++ {
-		path, line := pkg.lineFromAline(i)
-		// Check for end of object
-		if path == "" {
-			if final == -1 {
-				final = i - 1
-			}
-			continue
-		} else if final != -1 {
-			t.Fatalf("reached end of package at absolute line %d, but absolute line %d mapped to %s:%d", final, i, path, line)
-		}
-		// It's okay to see files multiple times (e.g., sys.a)
-		if line == 1 {
-			lastline[path] = 1
-			continue
-		}
-		// Check that the is the next line in path
-		ll, ok := lastline[path]
-		if !ok {
-			t.Errorf("file %s starts on line %d", path, line)
-		} else if line != ll+1 {
-			t.Fatalf("expected next line of file %s to be %d, got %d", path, ll+1, line)
-		}
-		lastline[path] = line
-	}
-	if final == -1 {
-		t.Errorf("never reached end of object")
-	}
-}
-
-func TestLineAline(t *testing.T) {
-	if !dotest(true) {
-		return
-	}
-	defer endtest()
-
-	tab := getTable(t)
-	if tab.go12line != nil {
-		// aline's don't exist in the Go 1.2 table.
-		t.Skip("not relevant to Go 1.2 symbol table")
-	}
-
-	for _, o := range tab.Files {
-		// A source file can appear multiple times in a
-		// object.  alineFromLine will always return alines in
-		// the first file, so track which lines we've seen.
-		found := make(map[string]int)
-		for i := 0; i < 1000; i++ {
-			path, line := o.lineFromAline(i)
-			if path == "" {
-				break
-			}
-
-			// cgo files are full of 'Z' symbols, which we don't handle
-			if len(path) > 4 && path[len(path)-4:] == ".cgo" {
-				continue
-			}
-
-			if minline, ok := found[path]; path != "" && ok {
-				if minline >= line {
-					// We've already covered this file
-					continue
-				}
-			}
-			found[path] = line
-
-			a, err := o.alineFromLine(path, line)
-			if err != nil {
-				t.Errorf("absolute line %d in object %s maps to %s:%d, but mapping that back gives error %s", i, o.Paths[0].Name, path, line, err)
-			} else if a != i {
-				t.Errorf("absolute line %d in object %s maps to %s:%d, which maps back to absolute line %d\n", i, o.Paths[0].Name, path, line, a)
-			}
-		}
-	}
-}
-
-func TestPCLine(t *testing.T) {
-	if !dotest(false) {
-		return
-	}
-	defer endtest()
-
-	f, tab := crack(pclinetestBinary, t)
-	text := f.Section(".text")
-	textdat, err := text.Data()
-	if err != nil {
-		t.Fatalf("reading .text: %v", err)
-	}
-
-	// Test PCToLine
-	sym := tab.LookupFunc("linefrompc")
-	wantLine := 0
-	for pc := sym.Entry; pc < sym.End; pc++ {
-		off := pc - text.Addr // TODO(rsc): should not need off; bug in 8g
-		if textdat[off] == 255 {
-			break
-		}
-		wantLine += int(textdat[off])
-		t.Logf("off is %d %#x (max %d)", off, textdat[off], sym.End-pc)
-		file, line, fn := tab.PCToLine(pc)
-		if fn == nil {
-			t.Errorf("failed to get line of PC %#x", pc)
-		} else if !strings.HasSuffix(file, "pclinetest.asm") || line != wantLine || fn != sym {
-			t.Errorf("PCToLine(%#x) = %s:%d (%s), want %s:%d (%s)", pc, file, line, fn.Name, "pclinetest.asm", wantLine, sym.Name)
-		}
-	}
-
-	// Test LineToPC
-	sym = tab.LookupFunc("pcfromline")
-	lookupline := -1
-	wantLine = 0
-	off := uint64(0) // TODO(rsc): should not need off; bug in 8g
-	for pc := sym.Value; pc < sym.End; pc += 2 + uint64(textdat[off]) {
-		file, line, fn := tab.PCToLine(pc)
-		off = pc - text.Addr
-		if textdat[off] == 255 {
-			break
-		}
-		wantLine += int(textdat[off])
-		if line != wantLine {
-			t.Errorf("expected line %d at PC %#x in pcfromline, got %d", wantLine, pc, line)
-			off = pc + 1 - text.Addr
-			continue
-		}
-		if lookupline == -1 {
-			lookupline = line
-		}
-		for ; lookupline <= line; lookupline++ {
-			pc2, fn2, err := tab.LineToPC(file, lookupline)
-			if lookupline != line {
-				// Should be nothing on this line
-				if err == nil {
-					t.Errorf("expected no PC at line %d, got %#x (%s)", lookupline, pc2, fn2.Name)
-				}
-			} else if err != nil {
-				t.Errorf("failed to get PC of line %d: %s", lookupline, err)
-			} else if pc != pc2 {
-				t.Errorf("expected PC %#x (%s) at line %d, got PC %#x (%s)", pc, fn.Name, line, pc2, fn2.Name)
-			}
-		}
-		off = pc + 1 - text.Addr
-	}
-}
diff --git a/gosym/symtab.go b/gosym/symtab.go
deleted file mode 100644
index 9121c37..0000000
--- a/gosym/symtab.go
+++ /dev/null
@@ -1,721 +0,0 @@
-// Copyright 2009 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 gosym implements access to the Go symbol
-// and line number tables embedded in Go binaries generated
-// by the gc compilers.
-package gosym // import "golang.org/x/debug/gosym"
-
-// The table format is a variant of the format used in Plan 9's a.out
-// format, documented at http://plan9.bell-labs.com/magic/man2html/6/a.out.
-// The best reference for the differences between the Plan 9 format
-// and the Go format is the runtime source, specifically ../../runtime/symtab.c.
-
-import (
-	"bytes"
-	"encoding/binary"
-	"fmt"
-	"strconv"
-	"strings"
-)
-
-/*
- * Symbols
- */
-
-// A Sym represents a single symbol table entry.
-type Sym struct {
-	Value  uint64
-	Type   byte
-	Name   string
-	GoType uint64
-	// If this symbol if a function symbol, the corresponding Func
-	Func *Func
-}
-
-// Static reports whether this symbol is static (not visible outside its file).
-func (s *Sym) Static() bool { return s.Type >= 'a' }
-
-// PackageName returns the package part of the symbol name,
-// or the empty string if there is none.
-func (s *Sym) PackageName() string {
-	if i := strings.Index(s.Name, "."); i != -1 {
-		return s.Name[0:i]
-	}
-	return ""
-}
-
-// ReceiverName returns the receiver type name of this symbol,
-// or the empty string if there is none.
-func (s *Sym) ReceiverName() string {
-	l := strings.Index(s.Name, ".")
-	r := strings.LastIndex(s.Name, ".")
-	if l == -1 || r == -1 || l == r {
-		return ""
-	}
-	return s.Name[l+1 : r]
-}
-
-// BaseName returns the symbol name without the package or receiver name.
-func (s *Sym) BaseName() string {
-	if i := strings.LastIndex(s.Name, "."); i != -1 {
-		return s.Name[i+1:]
-	}
-	return s.Name
-}
-
-// A Func collects information about a single function.
-type Func struct {
-	Entry uint64
-	*Sym
-	End       uint64
-	Params    []*Sym
-	Locals    []*Sym
-	FrameSize int
-	LineTable *LineTable
-	Obj       *Obj
-}
-
-// An Obj represents a collection of functions in a symbol table.
-//
-// The exact method of division of a binary into separate Objs is an internal detail
-// of the symbol table format.
-//
-// In early versions of Go each source file became a different Obj.
-//
-// In Go 1 and Go 1.1, each package produced one Obj for all Go sources
-// and one Obj per C source file.
-//
-// In Go 1.2, there is a single Obj for the entire program.
-type Obj struct {
-	// Funcs is a list of functions in the Obj.
-	Funcs []Func
-
-	// In Go 1.1 and earlier, Paths is a list of symbols corresponding
-	// to the source file names that produced the Obj.
-	// In Go 1.2, Paths is nil.
-	// Use the keys of Table.Files to obtain a list of source files.
-	Paths []Sym // meta
-}
-
-/*
- * Symbol tables
- */
-
-// Table represents a Go symbol table.  It stores all of the
-// symbols decoded from the program and provides methods to translate
-// between symbols, names, and addresses.
-type Table struct {
-	Syms  []Sym
-	Funcs []Func
-	Files map[string]*Obj // nil for Go 1.2 and later binaries
-	Objs  []Obj           // nil for Go 1.2 and later binaries
-
-	go12line *LineTable // Go 1.2 line number table
-}
-
-type sym struct {
-	value  uint64
-	gotype uint64
-	typ    byte
-	name   []byte
-}
-
-var (
-	littleEndianSymtab    = []byte{0xFD, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00}
-	bigEndianSymtab       = []byte{0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x00}
-	oldLittleEndianSymtab = []byte{0xFE, 0xFF, 0xFF, 0xFF, 0x00, 0x00}
-)
-
-func walksymtab(data []byte, fn func(sym) error) error {
-	if len(data) == 0 { // missing symtab is okay
-		return nil
-	}
-	var order binary.ByteOrder = binary.BigEndian
-	newTable := false
-	switch {
-	case bytes.HasPrefix(data, oldLittleEndianSymtab):
-		// Same as Go 1.0, but little endian.
-		// Format was used during interim development between Go 1.0 and Go 1.1.
-		// Should not be widespread, but easy to support.
-		data = data[6:]
-		order = binary.LittleEndian
-	case bytes.HasPrefix(data, bigEndianSymtab):
-		newTable = true
-	case bytes.HasPrefix(data, littleEndianSymtab):
-		newTable = true
-		order = binary.LittleEndian
-	}
-	var ptrsz int
-	if newTable {
-		if len(data) < 8 {
-			return &DecodingError{len(data), "unexpected EOF", nil}
-		}
-		ptrsz = int(data[7])
-		if ptrsz != 4 && ptrsz != 8 {
-			return &DecodingError{7, "invalid pointer size", ptrsz}
-		}
-		data = data[8:]
-	}
-	var s sym
-	p := data
-	for len(p) >= 4 {
-		var typ byte
-		if newTable {
-			// Symbol type, value, Go type.
-			typ = p[0] & 0x3F
-			wideValue := p[0]&0x40 != 0
-			goType := p[0]&0x80 != 0
-			if typ < 26 {
-				typ += 'A'
-			} else {
-				typ += 'a' - 26
-			}
-			s.typ = typ
-			p = p[1:]
-			if wideValue {
-				if len(p) < ptrsz {
-					return &DecodingError{len(data), "unexpected EOF", nil}
-				}
-				// fixed-width value
-				if ptrsz == 8 {
-					s.value = order.Uint64(p[0:8])
-					p = p[8:]
-				} else {
-					s.value = uint64(order.Uint32(p[0:4]))
-					p = p[4:]
-				}
-			} else {
-				// varint value
-				s.value = 0
-				shift := uint(0)
-				for len(p) > 0 && p[0]&0x80 != 0 {
-					s.value |= uint64(p[0]&0x7F) << shift
-					shift += 7
-					p = p[1:]
-				}
-				if len(p) == 0 {
-					return &DecodingError{len(data), "unexpected EOF", nil}
-				}
-				s.value |= uint64(p[0]) << shift
-				p = p[1:]
-			}
-			if goType {
-				if len(p) < ptrsz {
-					return &DecodingError{len(data), "unexpected EOF", nil}
-				}
-				// fixed-width go type
-				if ptrsz == 8 {
-					s.gotype = order.Uint64(p[0:8])
-					p = p[8:]
-				} else {
-					s.gotype = uint64(order.Uint32(p[0:4]))
-					p = p[4:]
-				}
-			}
-		} else {
-			// Value, symbol type.
-			s.value = uint64(order.Uint32(p[0:4]))
-			if len(p) < 5 {
-				return &DecodingError{len(data), "unexpected EOF", nil}
-			}
-			typ = p[4]
-			if typ&0x80 == 0 {
-				return &DecodingError{len(data) - len(p) + 4, "bad symbol type", typ}
-			}
-			typ &^= 0x80
-			s.typ = typ
-			p = p[5:]
-		}
-
-		// Name.
-		var i int
-		var nnul int
-		for i = 0; i < len(p); i++ {
-			if p[i] == 0 {
-				nnul = 1
-				break
-			}
-		}
-		switch typ {
-		case 'z', 'Z':
-			p = p[i+nnul:]
-			for i = 0; i+2 <= len(p); i += 2 {
-				if p[i] == 0 && p[i+1] == 0 {
-					nnul = 2
-					break
-				}
-			}
-		}
-		if len(p) < i+nnul {
-			return &DecodingError{len(data), "unexpected EOF", nil}
-		}
-		s.name = p[0:i]
-		i += nnul
-		p = p[i:]
-
-		if !newTable {
-			if len(p) < 4 {
-				return &DecodingError{len(data), "unexpected EOF", nil}
-			}
-			// Go type.
-			s.gotype = uint64(order.Uint32(p[:4]))
-			p = p[4:]
-		}
-		fn(s)
-	}
-	return nil
-}
-
-// NewTable decodes the Go symbol table in data,
-// returning an in-memory representation.
-func NewTable(symtab []byte, pcln *LineTable) (*Table, error) {
-	var n int
-	err := walksymtab(symtab, func(s sym) error {
-		n++
-		return nil
-	})
-	if err != nil {
-		return nil, err
-	}
-
-	var t Table
-	if pcln.isGo12() {
-		t.go12line = pcln
-	}
-	fname := make(map[uint16]string)
-	t.Syms = make([]Sym, 0, n)
-	nf := 0
-	nz := 0
-	lasttyp := uint8(0)
-	err = walksymtab(symtab, func(s sym) error {
-		n := len(t.Syms)
-		t.Syms = t.Syms[0 : n+1]
-		ts := &t.Syms[n]
-		ts.Type = s.typ
-		ts.Value = uint64(s.value)
-		ts.GoType = uint64(s.gotype)
-		switch s.typ {
-		default:
-			// rewrite name to use . instead of · (c2 b7)
-			w := 0
-			b := s.name
-			for i := 0; i < len(b); i++ {
-				if b[i] == 0xc2 && i+1 < len(b) && b[i+1] == 0xb7 {
-					i++
-					b[i] = '.'
-				}
-				b[w] = b[i]
-				w++
-			}
-			ts.Name = string(s.name[0:w])
-		case 'z', 'Z':
-			if lasttyp != 'z' && lasttyp != 'Z' {
-				nz++
-			}
-			for i := 0; i < len(s.name); i += 2 {
-				eltIdx := binary.BigEndian.Uint16(s.name[i : i+2])
-				elt, ok := fname[eltIdx]
-				if !ok {
-					return &DecodingError{-1, "bad filename code", eltIdx}
-				}
-				if n := len(ts.Name); n > 0 && ts.Name[n-1] != '/' {
-					ts.Name += "/"
-				}
-				ts.Name += elt
-			}
-		}
-		switch s.typ {
-		case 'T', 't', 'L', 'l':
-			nf++
-		case 'f':
-			fname[uint16(s.value)] = ts.Name
-		}
-		lasttyp = s.typ
-		return nil
-	})
-	if err != nil {
-		return nil, err
-	}
-
-	t.Funcs = make([]Func, 0, nf)
-	t.Files = make(map[string]*Obj)
-
-	var obj *Obj
-	if t.go12line != nil {
-		// Put all functions into one Obj.
-		t.Objs = make([]Obj, 1)
-		obj = &t.Objs[0]
-		t.go12line.go12MapFiles(t.Files, obj)
-	} else {
-		t.Objs = make([]Obj, 0, nz)
-	}
-
-	// Count text symbols and attach frame sizes, parameters, and
-	// locals to them.  Also, find object file boundaries.
-	lastf := 0
-	for i := 0; i < len(t.Syms); i++ {
-		sym := &t.Syms[i]
-		switch sym.Type {
-		case 'Z', 'z': // path symbol
-			if t.go12line != nil {
-				// Go 1.2 binaries have the file information elsewhere. Ignore.
-				break
-			}
-			// Finish the current object
-			if obj != nil {
-				obj.Funcs = t.Funcs[lastf:]
-			}
-			lastf = len(t.Funcs)
-
-			// Start new object
-			n := len(t.Objs)
-			t.Objs = t.Objs[0 : n+1]
-			obj = &t.Objs[n]
-
-			// Count & copy path symbols
-			var end int
-			for end = i + 1; end < len(t.Syms); end++ {
-				if c := t.Syms[end].Type; c != 'Z' && c != 'z' {
-					break
-				}
-			}
-			obj.Paths = t.Syms[i:end]
-			i = end - 1 // loop will i++
-
-			// Record file names
-			depth := 0
-			for j := range obj.Paths {
-				s := &obj.Paths[j]
-				if s.Name == "" {
-					depth--
-				} else {
-					if depth == 0 {
-						t.Files[s.Name] = obj
-					}
-					depth++
-				}
-			}
-
-		case 'T', 't', 'L', 'l': // text symbol
-			if n := len(t.Funcs); n > 0 {
-				t.Funcs[n-1].End = sym.Value
-			}
-			if sym.Name == "etext" {
-				continue
-			}
-
-			// Count parameter and local (auto) syms
-			var np, na int
-			var end int
-		countloop:
-			for end = i + 1; end < len(t.Syms); end++ {
-				switch t.Syms[end].Type {
-				case 'T', 't', 'L', 'l', 'Z', 'z':
-					break countloop
-				case 'p':
-					np++
-				case 'a':
-					na++
-				}
-			}
-
-			// Fill in the function symbol
-			n := len(t.Funcs)
-			t.Funcs = t.Funcs[0 : n+1]
-			fn := &t.Funcs[n]
-			sym.Func = fn
-			fn.Params = make([]*Sym, 0, np)
-			fn.Locals = make([]*Sym, 0, na)
-			fn.Sym = sym
-			fn.Entry = sym.Value
-			fn.Obj = obj
-			if t.go12line != nil {
-				// All functions share the same line table.
-				// It knows how to narrow down to a specific
-				// function quickly.
-				fn.LineTable = t.go12line
-			} else if pcln != nil {
-				fn.LineTable = pcln.slice(fn.Entry)
-				pcln = fn.LineTable
-			}
-			for j := i; j < end; j++ {
-				s := &t.Syms[j]
-				switch s.Type {
-				case 'm':
-					fn.FrameSize = int(s.Value)
-				case 'p':
-					n := len(fn.Params)
-					fn.Params = fn.Params[0 : n+1]
-					fn.Params[n] = s
-				case 'a':
-					n := len(fn.Locals)
-					fn.Locals = fn.Locals[0 : n+1]
-					fn.Locals[n] = s
-				}
-			}
-			i = end - 1 // loop will i++
-		}
-	}
-
-	if t.go12line != nil && nf == 0 {
-		t.Funcs = t.go12line.go12Funcs()
-	}
-	if obj != nil {
-		obj.Funcs = t.Funcs[lastf:]
-	}
-	return &t, nil
-}
-
-// PCToFunc returns the function containing the program counter pc,
-// or nil if there is no such function.
-func (t *Table) PCToFunc(pc uint64) *Func {
-	funcs := t.Funcs
-	for len(funcs) > 0 {
-		m := len(funcs) / 2
-		fn := &funcs[m]
-		switch {
-		case pc < fn.Entry:
-			funcs = funcs[0:m]
-		case fn.Entry <= pc && pc < fn.End:
-			return fn
-		default:
-			funcs = funcs[m+1:]
-		}
-	}
-	return nil
-}
-
-// PCToLine looks up line number information for a program counter.
-// If there is no information, it returns fn == nil.
-func (t *Table) PCToLine(pc uint64) (file string, line int, fn *Func) {
-	if fn = t.PCToFunc(pc); fn == nil {
-		return
-	}
-	if t.go12line != nil {
-		file = t.go12line.go12PCToFile(pc)
-		line = t.go12line.go12PCToLine(pc)
-	} else {
-		file, line = fn.Obj.lineFromAline(fn.LineTable.PCToLine(pc))
-	}
-	return
-}
-
-// PCToSPAdj returns the stack pointer adjustment for a program counter.
-func (t *Table) PCToSPAdj(pc uint64) (spadj int) {
-	if fn := t.PCToFunc(pc); fn == nil {
-		return 0
-	}
-	if t.go12line != nil {
-		return t.go12line.go12PCToSPAdj(pc)
-	}
-	return 0
-}
-
-// LineToPC looks up the first program counter on the given line in
-// the named file.  It returns UnknownPathError or UnknownLineError if
-// there is an error looking up this line.
-func (t *Table) LineToPC(file string, line int) (pc uint64, fn *Func, err error) {
-	obj, ok := t.Files[file]
-	if !ok {
-		return 0, nil, UnknownFileError(file)
-	}
-
-	if t.go12line != nil {
-		pc := t.go12line.go12LineToPC(file, line)
-		if pc == 0 {
-			return 0, nil, &UnknownLineError{file, line}
-		}
-		return pc, t.PCToFunc(pc), nil
-	}
-
-	abs, err := obj.alineFromLine(file, line)
-	if err != nil {
-		return
-	}
-	for i := range obj.Funcs {
-		f := &obj.Funcs[i]
-		pc := f.LineTable.LineToPC(abs, f.End)
-		if pc != 0 {
-			return pc, f, nil
-		}
-	}
-	return 0, nil, &UnknownLineError{file, line}
-}
-
-// LookupSym returns the text, data, or bss symbol with the given name,
-// or nil if no such symbol is found.
-func (t *Table) LookupSym(name string) *Sym {
-	// TODO(austin) Maybe make a map
-	for i := range t.Syms {
-		s := &t.Syms[i]
-		switch s.Type {
-		case 'T', 't', 'L', 'l', 'D', 'd', 'B', 'b':
-			if s.Name == name {
-				return s
-			}
-		}
-	}
-	return nil
-}
-
-// LookupFunc returns the text, data, or bss symbol with the given name,
-// or nil if no such symbol is found.
-func (t *Table) LookupFunc(name string) *Func {
-	for i := range t.Funcs {
-		f := &t.Funcs[i]
-		if f.Sym.Name == name {
-			return f
-		}
-	}
-	return nil
-}
-
-// SymByAddr returns the text, data, or bss symbol starting at the given address.
-func (t *Table) SymByAddr(addr uint64) *Sym {
-	for i := range t.Syms {
-		s := &t.Syms[i]
-		switch s.Type {
-		case 'T', 't', 'L', 'l', 'D', 'd', 'B', 'b':
-			if s.Value == addr {
-				return s
-			}
-		}
-	}
-	return nil
-}
-
-/*
- * Object files
- */
-
-// This is legacy code for Go 1.1 and earlier, which used the
-// Plan 9 format for pc-line tables. This code was never quite
-// correct. It's probably very close, and it's usually correct, but
-// we never quite found all the corner cases.
-//
-// Go 1.2 and later use a simpler format, documented at golang.org/s/go12symtab.
-
-func (o *Obj) lineFromAline(aline int) (string, int) {
-	type stackEnt struct {
-		path   string
-		start  int
-		offset int
-		prev   *stackEnt
-	}
-
-	noPath := &stackEnt{"", 0, 0, nil}
-	tos := noPath
-
-pathloop:
-	for _, s := range o.Paths {
-		val := int(s.Value)
-		switch {
-		case val > aline:
-			break pathloop
-
-		case val == 1:
-			// Start a new stack
-			tos = &stackEnt{s.Name, val, 0, noPath}
-
-		case s.Name == "":
-			// Pop
-			if tos == noPath {
-				return "<malformed symbol table>", 0
-			}
-			tos.prev.offset += val - tos.start
-			tos = tos.prev
-
-		default:
-			// Push
-			tos = &stackEnt{s.Name, val, 0, tos}
-		}
-	}
-
-	if tos == noPath {
-		return "", 0
-	}
-	return tos.path, aline - tos.start - tos.offset + 1
-}
-
-func (o *Obj) alineFromLine(path string, line int) (int, error) {
-	if line < 1 {
-		return 0, &UnknownLineError{path, line}
-	}
-
-	for i, s := range o.Paths {
-		// Find this path
-		if s.Name != path {
-			continue
-		}
-
-		// Find this line at this stack level
-		depth := 0
-		var incstart int
-		line += int(s.Value)
-	pathloop:
-		for _, s := range o.Paths[i:] {
-			val := int(s.Value)
-			switch {
-			case depth == 1 && val >= line:
-				return line - 1, nil
-
-			case s.Name == "":
-				depth--
-				if depth == 0 {
-					break pathloop
-				} else if depth == 1 {
-					line += val - incstart
-				}
-
-			default:
-				if depth == 1 {
-					incstart = val
-				}
-				depth++
-			}
-		}
-		return 0, &UnknownLineError{path, line}
-	}
-	return 0, UnknownFileError(path)
-}
-
-/*
- * Errors
- */
-
-// UnknownFileError represents a failure to find the specific file in
-// the symbol table.
-type UnknownFileError string
-
-func (e UnknownFileError) Error() string { return "unknown file: " + string(e) }
-
-// UnknownLineError represents a failure to map a line to a program
-// counter, either because the line is beyond the bounds of the file
-// or because there is no code on the given line.
-type UnknownLineError struct {
-	File string
-	Line int
-}
-
-func (e *UnknownLineError) Error() string {
-	return "no code at " + e.File + ":" + strconv.Itoa(e.Line)
-}
-
-// DecodingError represents an error during the decoding of
-// the symbol table.
-type DecodingError struct {
-	off int
-	msg string
-	val interface{}
-}
-
-func (e *DecodingError) Error() string {
-	msg := e.msg
-	if e.val != nil {
-		msg += fmt.Sprintf(" '%v'", e.val)
-	}
-	msg += fmt.Sprintf(" at byte %#x", e.off)
-	return msg
-}
diff --git a/local/local.go b/local/local.go
deleted file mode 100644
index e054249..0000000
--- a/local/local.go
+++ /dev/null
@@ -1,193 +0,0 @@
-// Copyright 2014 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 local provides access to a local program.
-package local // import "golang.org/x/debug/local"
-
-import (
-	"golang.org/x/debug"
-	"golang.org/x/debug/server"
-	"golang.org/x/debug/server/protocol"
-)
-
-var _ debug.Program = (*Program)(nil)
-var _ debug.File = (*File)(nil)
-
-// Program implements the debug.Program interface.
-// Through that interface it provides access to a program being debugged.
-type Program struct {
-	s *server.Server
-}
-
-// New creates a new program from the specified file.
-// The program can then be started by the Run method.
-func New(textFile string) (*Program, error) {
-	s, err := server.New(textFile)
-	return &Program{s: s}, err
-}
-
-func (p *Program) Open(name string, mode string) (debug.File, error) {
-	req := protocol.OpenRequest{
-		Name: name,
-		Mode: mode,
-	}
-	var resp protocol.OpenResponse
-	err := p.s.Open(&req, &resp)
-	if err != nil {
-		return nil, err
-	}
-	f := &File{
-		prog: p,
-		fd:   resp.FD,
-	}
-	return f, nil
-}
-
-func (p *Program) Run(args ...string) (debug.Status, error) {
-	req := protocol.RunRequest{args}
-	var resp protocol.RunResponse
-	err := p.s.Run(&req, &resp)
-	if err != nil {
-		return debug.Status{}, err
-	}
-	return resp.Status, nil
-}
-
-func (p *Program) Stop() (debug.Status, error) {
-	panic("unimplemented")
-}
-
-func (p *Program) Resume() (debug.Status, error) {
-	req := protocol.ResumeRequest{}
-	var resp protocol.ResumeResponse
-	err := p.s.Resume(&req, &resp)
-	if err != nil {
-		return debug.Status{}, err
-	}
-	return resp.Status, nil
-}
-
-func (p *Program) Kill() (debug.Status, error) {
-	panic("unimplemented")
-}
-
-func (p *Program) Breakpoint(address uint64) ([]uint64, error) {
-	req := protocol.BreakpointRequest{
-		Address: address,
-	}
-	var resp protocol.BreakpointResponse
-	err := p.s.Breakpoint(&req, &resp)
-	return resp.PCs, err
-}
-
-func (p *Program) BreakpointAtFunction(name string) ([]uint64, error) {
-	req := protocol.BreakpointAtFunctionRequest{
-		Function: name,
-	}
-	var resp protocol.BreakpointResponse
-	err := p.s.BreakpointAtFunction(&req, &resp)
-	return resp.PCs, err
-}
-
-func (p *Program) BreakpointAtLine(file string, line uint64) ([]uint64, error) {
-	req := protocol.BreakpointAtLineRequest{
-		File: file,
-		Line: line,
-	}
-	var resp protocol.BreakpointResponse
-	err := p.s.BreakpointAtLine(&req, &resp)
-	return resp.PCs, err
-}
-
-func (p *Program) DeleteBreakpoints(pcs []uint64) error {
-	req := protocol.DeleteBreakpointsRequest{PCs: pcs}
-	var resp protocol.DeleteBreakpointsResponse
-	return p.s.DeleteBreakpoints(&req, &resp)
-}
-
-func (p *Program) Eval(expr string) ([]string, error) {
-	req := protocol.EvalRequest{
-		Expr: expr,
-	}
-	var resp protocol.EvalResponse
-	err := p.s.Eval(&req, &resp)
-	return resp.Result, err
-}
-
-func (p *Program) Evaluate(e string) (debug.Value, error) {
-	req := protocol.EvaluateRequest{
-		Expression: e,
-	}
-	var resp protocol.EvaluateResponse
-	err := p.s.Evaluate(&req, &resp)
-	return resp.Result, err
-}
-
-func (p *Program) Frames(count int) ([]debug.Frame, error) {
-	req := protocol.FramesRequest{
-		Count: count,
-	}
-	var resp protocol.FramesResponse
-	err := p.s.Frames(&req, &resp)
-	return resp.Frames, err
-}
-
-func (p *Program) Goroutines() ([]*debug.Goroutine, error) {
-	req := protocol.GoroutinesRequest{}
-	var resp protocol.GoroutinesResponse
-	err := p.s.Goroutines(&req, &resp)
-	return resp.Goroutines, err
-}
-
-func (p *Program) VarByName(name string) (debug.Var, error) {
-	req := protocol.VarByNameRequest{Name: name}
-	var resp protocol.VarByNameResponse
-	err := p.s.VarByName(&req, &resp)
-	return resp.Var, err
-}
-
-func (p *Program) Value(v debug.Var) (debug.Value, error) {
-	req := protocol.ValueRequest{Var: v}
-	var resp protocol.ValueResponse
-	err := p.s.Value(&req, &resp)
-	return resp.Value, err
-}
-
-func (p *Program) MapElement(m debug.Map, index uint64) (debug.Var, debug.Var, error) {
-	req := protocol.MapElementRequest{Map: m, Index: index}
-	var resp protocol.MapElementResponse
-	err := p.s.MapElement(&req, &resp)
-	return resp.Key, resp.Value, err
-}
-
-// File implements the debug.File interface, providing access
-// to file-like resources associated with the target program.
-type File struct {
-	prog *Program // The Program associated with the file.
-	fd   int      // File descriptor.
-}
-
-func (f *File) ReadAt(p []byte, offset int64) (int, error) {
-	req := protocol.ReadAtRequest{
-		FD:     f.fd,
-		Len:    len(p),
-		Offset: offset,
-	}
-	var resp protocol.ReadAtResponse
-	err := f.prog.s.ReadAt(&req, &resp)
-	return copy(p, resp.Data), err
-}
-
-func (f *File) WriteAt(p []byte, offset int64) (int, error) {
-	panic("unimplemented")
-}
-
-func (f *File) Close() error {
-	req := protocol.CloseRequest{
-		FD: f.fd,
-	}
-	var resp protocol.CloseResponse
-	err := f.prog.s.Close(&req, &resp)
-	return err
-}
diff --git a/macho/fat.go b/macho/fat.go
deleted file mode 100644
index 93b8315..0000000
--- a/macho/fat.go
+++ /dev/null
@@ -1,146 +0,0 @@
-// Copyright 2014 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 macho
-
-import (
-	"encoding/binary"
-	"fmt"
-	"io"
-	"os"
-)
-
-// A FatFile is a Mach-O universal binary that contains at least one architecture.
-type FatFile struct {
-	Magic  uint32
-	Arches []FatArch
-	closer io.Closer
-}
-
-// A FatArchHeader represents a fat header for a specific image architecture.
-type FatArchHeader struct {
-	Cpu    Cpu
-	SubCpu uint32
-	Offset uint32
-	Size   uint32
-	Align  uint32
-}
-
-const fatArchHeaderSize = 5 * 4
-
-// A FatArch is a Mach-O File inside a FatFile.
-type FatArch struct {
-	FatArchHeader
-	*File
-}
-
-// ErrNotFat is returned from NewFatFile or OpenFat when the file is not a
-// universal binary but may be a thin binary, based on its magic number.
-var ErrNotFat = &FormatError{0, "not a fat Mach-O file", nil}
-
-// NewFatFile creates a new FatFile for accessing all the Mach-O images in a
-// universal binary. The Mach-O binary is expected to start at position 0 in
-// the ReaderAt.
-func NewFatFile(r io.ReaderAt) (*FatFile, error) {
-	var ff FatFile
-	sr := io.NewSectionReader(r, 0, 1<<63-1)
-
-	// Read the fat_header struct, which is always in big endian.
-	// Start with the magic number.
-	err := binary.Read(sr, binary.BigEndian, &ff.Magic)
-	if err != nil {
-		return nil, &FormatError{0, "error reading magic number", nil}
-	} else if ff.Magic != MagicFat {
-		// See if this is a Mach-O file via its magic number. The magic
-		// must be converted to little endian first though.
-		var buf [4]byte
-		binary.BigEndian.PutUint32(buf[:], ff.Magic)
-		leMagic := binary.LittleEndian.Uint32(buf[:])
-		if leMagic == Magic32 || leMagic == Magic64 {
-			return nil, ErrNotFat
-		} else {
-			return nil, &FormatError{0, "invalid magic number", nil}
-		}
-	}
-	offset := int64(4)
-
-	// Read the number of FatArchHeaders that come after the fat_header.
-	var narch uint32
-	err = binary.Read(sr, binary.BigEndian, &narch)
-	if err != nil {
-		return nil, &FormatError{offset, "invalid fat_header", nil}
-	}
-	offset += 4
-
-	if narch < 1 {
-		return nil, &FormatError{offset, "file contains no images", nil}
-	}
-
-	// Combine the Cpu and SubCpu (both uint32) into a uint64 to make sure
-	// there are not duplicate architectures.
-	seenArches := make(map[uint64]bool, narch)
-	// Make sure that all images are for the same MH_ type.
-	var machoType Type
-
-	// Following the fat_header comes narch fat_arch structs that index
-	// Mach-O images further in the file.
-	ff.Arches = make([]FatArch, narch)
-	for i := uint32(0); i < narch; i++ {
-		fa := &ff.Arches[i]
-		err = binary.Read(sr, binary.BigEndian, &fa.FatArchHeader)
-		if err != nil {
-			return nil, &FormatError{offset, "invalid fat_arch header", nil}
-		}
-		offset += fatArchHeaderSize
-
-		fr := io.NewSectionReader(r, int64(fa.Offset), int64(fa.Size))
-		fa.File, err = NewFile(fr)
-		if err != nil {
-			return nil, err
-		}
-
-		// Make sure the architecture for this image is not duplicate.
-		seenArch := (uint64(fa.Cpu) << 32) | uint64(fa.SubCpu)
-		if o, k := seenArches[seenArch]; o || k {
-			return nil, &FormatError{offset, fmt.Sprintf("duplicate architecture cpu=%v, subcpu=%#x", fa.Cpu, fa.SubCpu), nil}
-		}
-		seenArches[seenArch] = true
-
-		// Make sure the Mach-O type matches that of the first image.
-		if i == 0 {
-			machoType = fa.Type
-		} else {
-			if fa.Type != machoType {
-				return nil, &FormatError{offset, fmt.Sprintf("Mach-O type for architecture #%d (type=%#x) does not match first (type=%#x)", i, fa.Type, machoType), nil}
-			}
-		}
-	}
-
-	return &ff, nil
-}
-
-// OpenFat opens the named file using os.Open and prepares it for use as a Mach-O
-// universal binary.
-func OpenFat(name string) (ff *FatFile, err error) {
-	f, err := os.Open(name)
-	if err != nil {
-		return nil, err
-	}
-	ff, err = NewFatFile(f)
-	if err != nil {
-		f.Close()
-		return nil, err
-	}
-	ff.closer = f
-	return
-}
-
-func (ff *FatFile) Close() error {
-	var err error
-	if ff.closer != nil {
-		err = ff.closer.Close()
-		ff.closer = nil
-	}
-	return err
-}
diff --git a/macho/file.go b/macho/file.go
deleted file mode 100644
index 7f59901..0000000
--- a/macho/file.go
+++ /dev/null
@@ -1,525 +0,0 @@
-// Copyright 2009 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 macho implements access to Mach-O object files.
-package macho
-
-// High level access to low level data structures.
-
-import (
-	"bytes"
-	"encoding/binary"
-	"fmt"
-	"io"
-	"os"
-
-	"golang.org/x/debug/dwarf"
-)
-
-// A File represents an open Mach-O file.
-type File struct {
-	FileHeader
-	ByteOrder binary.ByteOrder
-	Loads     []Load
-	Sections  []*Section
-
-	Symtab   *Symtab
-	Dysymtab *Dysymtab
-
-	closer io.Closer
-}
-
-// A Load represents any Mach-O load command.
-type Load interface {
-	Raw() []byte
-}
-
-// A LoadBytes is the uninterpreted bytes of a Mach-O load command.
-type LoadBytes []byte
-
-func (b LoadBytes) Raw() []byte { return b }
-
-// A SegmentHeader is the header for a Mach-O 32-bit or 64-bit load segment command.
-type SegmentHeader struct {
-	Cmd     LoadCmd
-	Len     uint32
-	Name    string
-	Addr    uint64
-	Memsz   uint64
-	Offset  uint64
-	Filesz  uint64
-	Maxprot uint32
-	Prot    uint32
-	Nsect   uint32
-	Flag    uint32
-}
-
-// A Segment represents a Mach-O 32-bit or 64-bit load segment command.
-type Segment struct {
-	LoadBytes
-	SegmentHeader
-
-	// Embed ReaderAt for ReadAt method.
-	// Do not embed SectionReader directly
-	// to avoid having Read and Seek.
-	// If a client wants Read and Seek it must use
-	// Open() to avoid fighting over the seek offset
-	// with other clients.
-	io.ReaderAt
-	sr *io.SectionReader
-}
-
-// Data reads and returns the contents of the segment.
-func (s *Segment) Data() ([]byte, error) {
-	dat := make([]byte, s.sr.Size())
-	n, err := s.sr.ReadAt(dat, 0)
-	if n == len(dat) {
-		err = nil
-	}
-	return dat[0:n], err
-}
-
-// Open returns a new ReadSeeker reading the segment.
-func (s *Segment) Open() io.ReadSeeker { return io.NewSectionReader(s.sr, 0, 1<<63-1) }
-
-type SectionHeader struct {
-	Name   string
-	Seg    string
-	Addr   uint64
-	Size   uint64
-	Offset uint32
-	Align  uint32
-	Reloff uint32
-	Nreloc uint32
-	Flags  uint32
-}
-
-type Section struct {
-	SectionHeader
-
-	// Embed ReaderAt for ReadAt method.
-	// Do not embed SectionReader directly
-	// to avoid having Read and Seek.
-	// If a client wants Read and Seek it must use
-	// Open() to avoid fighting over the seek offset
-	// with other clients.
-	io.ReaderAt
-	sr *io.SectionReader
-}
-
-// Data reads and returns the contents of the Mach-O section.
-func (s *Section) Data() ([]byte, error) {
-	dat := make([]byte, s.sr.Size())
-	n, err := s.sr.ReadAt(dat, 0)
-	if n == len(dat) {
-		err = nil
-	}
-	return dat[0:n], err
-}
-
-// Open returns a new ReadSeeker reading the Mach-O section.
-func (s *Section) Open() io.ReadSeeker { return io.NewSectionReader(s.sr, 0, 1<<63-1) }
-
-// A Dylib represents a Mach-O load dynamic library command.
-type Dylib struct {
-	LoadBytes
-	Name           string
-	Time           uint32
-	CurrentVersion uint32
-	CompatVersion  uint32
-}
-
-// A Symtab represents a Mach-O symbol table command.
-type Symtab struct {
-	LoadBytes
-	SymtabCmd
-	Syms []Symbol
-}
-
-// A Dysymtab represents a Mach-O dynamic symbol table command.
-type Dysymtab struct {
-	LoadBytes
-	DysymtabCmd
-	IndirectSyms []uint32 // indices into Symtab.Syms
-}
-
-/*
- * Mach-O reader
- */
-
-// FormatError is returned by some operations if the data does
-// not have the correct format for an object file.
-type FormatError struct {
-	off int64
-	msg string
-	val interface{}
-}
-
-func (e *FormatError) Error() string {
-	msg := e.msg
-	if e.val != nil {
-		msg += fmt.Sprintf(" '%v'", e.val)
-	}
-	msg += fmt.Sprintf(" in record at byte %#x", e.off)
-	return msg
-}
-
-// Open opens the named file using os.Open and prepares it for use as a Mach-O binary.
-func Open(name string) (*File, error) {
-	f, err := os.Open(name)
-	if err != nil {
-		return nil, err
-	}
-	ff, err := NewFile(f)
-	if err != nil {
-		f.Close()
-		return nil, err
-	}
-	ff.closer = f
-	return ff, nil
-}
-
-// Close closes the File.
-// If the File was created using NewFile directly instead of Open,
-// Close has no effect.
-func (f *File) Close() error {
-	var err error
-	if f.closer != nil {
-		err = f.closer.Close()
-		f.closer = nil
-	}
-	return err
-}
-
-// NewFile creates a new File for accessing a Mach-O binary in an underlying reader.
-// The Mach-O binary is expected to start at position 0 in the ReaderAt.
-func NewFile(r io.ReaderAt) (*File, error) {
-	f := new(File)
-	sr := io.NewSectionReader(r, 0, 1<<63-1)
-
-	// Read and decode Mach magic to determine byte order, size.
-	// Magic32 and Magic64 differ only in the bottom bit.
-	var ident [4]byte
-	if _, err := r.ReadAt(ident[0:], 0); err != nil {
-		return nil, err
-	}
-	be := binary.BigEndian.Uint32(ident[0:])
-	le := binary.LittleEndian.Uint32(ident[0:])
-	switch Magic32 &^ 1 {
-	case be &^ 1:
-		f.ByteOrder = binary.BigEndian
-		f.Magic = be
-	case le &^ 1:
-		f.ByteOrder = binary.LittleEndian
-		f.Magic = le
-	default:
-		return nil, &FormatError{0, "invalid magic number", nil}
-	}
-
-	// Read entire file header.
-	if err := binary.Read(sr, f.ByteOrder, &f.FileHeader); err != nil {
-		return nil, err
-	}
-
-	// Then load commands.
-	offset := int64(fileHeaderSize32)
-	if f.Magic == Magic64 {
-		offset = fileHeaderSize64
-	}
-	dat := make([]byte, f.Cmdsz)
-	if _, err := r.ReadAt(dat, offset); err != nil {
-		return nil, err
-	}
-	f.Loads = make([]Load, f.Ncmd)
-	bo := f.ByteOrder
-	for i := range f.Loads {
-		// Each load command begins with uint32 command and length.
-		if len(dat) < 8 {
-			return nil, &FormatError{offset, "command block too small", nil}
-		}
-		cmd, siz := LoadCmd(bo.Uint32(dat[0:4])), bo.Uint32(dat[4:8])
-		if siz < 8 || siz > uint32(len(dat)) {
-			return nil, &FormatError{offset, "invalid command block size", nil}
-		}
-		var cmddat []byte
-		cmddat, dat = dat[0:siz], dat[siz:]
-		offset += int64(siz)
-		var s *Segment
-		switch cmd {
-		default:
-			f.Loads[i] = LoadBytes(cmddat)
-
-		case LoadCmdDylib:
-			var hdr DylibCmd
-			b := bytes.NewReader(cmddat)
-			if err := binary.Read(b, bo, &hdr); err != nil {
-				return nil, err
-			}
-			l := new(Dylib)
-			if hdr.Name >= uint32(len(cmddat)) {
-				return nil, &FormatError{offset, "invalid name in dynamic library command", hdr.Name}
-			}
-			l.Name = cstring(cmddat[hdr.Name:])
-			l.Time = hdr.Time
-			l.CurrentVersion = hdr.CurrentVersion
-			l.CompatVersion = hdr.CompatVersion
-			l.LoadBytes = LoadBytes(cmddat)
-			f.Loads[i] = l
-
-		case LoadCmdSymtab:
-			var hdr SymtabCmd
-			b := bytes.NewReader(cmddat)
-			if err := binary.Read(b, bo, &hdr); err != nil {
-				return nil, err
-			}
-			strtab := make([]byte, hdr.Strsize)
-			if _, err := r.ReadAt(strtab, int64(hdr.Stroff)); err != nil {
-				return nil, err
-			}
-			var symsz int
-			if f.Magic == Magic64 {
-				symsz = 16
-			} else {
-				symsz = 12
-			}
-			symdat := make([]byte, int(hdr.Nsyms)*symsz)
-			if _, err := r.ReadAt(symdat, int64(hdr.Symoff)); err != nil {
-				return nil, err
-			}
-			st, err := f.parseSymtab(symdat, strtab, cmddat, &hdr, offset)
-			if err != nil {
-				return nil, err
-			}
-			f.Loads[i] = st
-			f.Symtab = st
-
-		case LoadCmdDysymtab:
-			var hdr DysymtabCmd
-			b := bytes.NewReader(cmddat)
-			if err := binary.Read(b, bo, &hdr); err != nil {
-				return nil, err
-			}
-			dat := make([]byte, hdr.Nindirectsyms*4)
-			if _, err := r.ReadAt(dat, int64(hdr.Indirectsymoff)); err != nil {
-				return nil, err
-			}
-			x := make([]uint32, hdr.Nindirectsyms)
-			if err := binary.Read(bytes.NewReader(dat), bo, x); err != nil {
-				return nil, err
-			}
-			st := new(Dysymtab)
-			st.LoadBytes = LoadBytes(cmddat)
-			st.DysymtabCmd = hdr
-			st.IndirectSyms = x
-			f.Loads[i] = st
-			f.Dysymtab = st
-
-		case LoadCmdSegment:
-			var seg32 Segment32
-			b := bytes.NewReader(cmddat)
-			if err := binary.Read(b, bo, &seg32); err != nil {
-				return nil, err
-			}
-			s = new(Segment)
-			s.LoadBytes = cmddat
-			s.Cmd = cmd
-			s.Len = siz
-			s.Name = cstring(seg32.Name[0:])
-			s.Addr = uint64(seg32.Addr)
-			s.Memsz = uint64(seg32.Memsz)
-			s.Offset = uint64(seg32.Offset)
-			s.Filesz = uint64(seg32.Filesz)
-			s.Maxprot = seg32.Maxprot
-			s.Prot = seg32.Prot
-			s.Nsect = seg32.Nsect
-			s.Flag = seg32.Flag
-			f.Loads[i] = s
-			for i := 0; i < int(s.Nsect); i++ {
-				var sh32 Section32
-				if err := binary.Read(b, bo, &sh32); err != nil {
-					return nil, err
-				}
-				sh := new(Section)
-				sh.Name = cstring(sh32.Name[0:])
-				sh.Seg = cstring(sh32.Seg[0:])
-				sh.Addr = uint64(sh32.Addr)
-				sh.Size = uint64(sh32.Size)
-				sh.Offset = sh32.Offset
-				sh.Align = sh32.Align
-				sh.Reloff = sh32.Reloff
-				sh.Nreloc = sh32.Nreloc
-				sh.Flags = sh32.Flags
-				f.pushSection(sh, r)
-			}
-
-		case LoadCmdSegment64:
-			var seg64 Segment64
-			b := bytes.NewReader(cmddat)
-			if err := binary.Read(b, bo, &seg64); err != nil {
-				return nil, err
-			}
-			s = new(Segment)
-			s.LoadBytes = cmddat
-			s.Cmd = cmd
-			s.Len = siz
-			s.Name = cstring(seg64.Name[0:])
-			s.Addr = seg64.Addr
-			s.Memsz = seg64.Memsz
-			s.Offset = seg64.Offset
-			s.Filesz = seg64.Filesz
-			s.Maxprot = seg64.Maxprot
-			s.Prot = seg64.Prot
-			s.Nsect = seg64.Nsect
-			s.Flag = seg64.Flag
-			f.Loads[i] = s
-			for i := 0; i < int(s.Nsect); i++ {
-				var sh64 Section64
-				if err := binary.Read(b, bo, &sh64); err != nil {
-					return nil, err
-				}
-				sh := new(Section)
-				sh.Name = cstring(sh64.Name[0:])
-				sh.Seg = cstring(sh64.Seg[0:])
-				sh.Addr = sh64.Addr
-				sh.Size = sh64.Size
-				sh.Offset = sh64.Offset
-				sh.Align = sh64.Align
-				sh.Reloff = sh64.Reloff
-				sh.Nreloc = sh64.Nreloc
-				sh.Flags = sh64.Flags
-				f.pushSection(sh, r)
-			}
-		}
-		if s != nil {
-			s.sr = io.NewSectionReader(r, int64(s.Offset), int64(s.Filesz))
-			s.ReaderAt = s.sr
-		}
-	}
-	return f, nil
-}
-
-func (f *File) parseSymtab(symdat, strtab, cmddat []byte, hdr *SymtabCmd, offset int64) (*Symtab, error) {
-	bo := f.ByteOrder
-	symtab := make([]Symbol, hdr.Nsyms)
-	b := bytes.NewReader(symdat)
-	for i := range symtab {
-		var n Nlist64
-		if f.Magic == Magic64 {
-			if err := binary.Read(b, bo, &n); err != nil {
-				return nil, err
-			}
-		} else {
-			var n32 Nlist32
-			if err := binary.Read(b, bo, &n32); err != nil {
-				return nil, err
-			}
-			n.Name = n32.Name
-			n.Type = n32.Type
-			n.Sect = n32.Sect
-			n.Desc = n32.Desc
-			n.Value = uint64(n32.Value)
-		}
-		sym := &symtab[i]
-		if n.Name >= uint32(len(strtab)) {
-			return nil, &FormatError{offset, "invalid name in symbol table", n.Name}
-		}
-		sym.Name = cstring(strtab[n.Name:])
-		sym.Type = n.Type
-		sym.Sect = n.Sect
-		sym.Desc = n.Desc
-		sym.Value = n.Value
-	}
-	st := new(Symtab)
-	st.LoadBytes = LoadBytes(cmddat)
-	st.Syms = symtab
-	return st, nil
-}
-
-func (f *File) pushSection(sh *Section, r io.ReaderAt) {
-	f.Sections = append(f.Sections, sh)
-	sh.sr = io.NewSectionReader(r, int64(sh.Offset), int64(sh.Size))
-	sh.ReaderAt = sh.sr
-}
-
-func cstring(b []byte) string {
-	var i int
-	for i = 0; i < len(b) && b[i] != 0; i++ {
-	}
-	return string(b[0:i])
-}
-
-// Segment returns the first Segment with the given name, or nil if no such segment exists.
-func (f *File) Segment(name string) *Segment {
-	for _, l := range f.Loads {
-		if s, ok := l.(*Segment); ok && s.Name == name {
-			return s
-		}
-	}
-	return nil
-}
-
-// Section returns the first section with the given name, or nil if no such
-// section exists.
-func (f *File) Section(name string) *Section {
-	for _, s := range f.Sections {
-		if s.Name == name {
-			return s
-		}
-	}
-	return nil
-}
-
-// DWARF returns the DWARF debug information for the Mach-O file.
-func (f *File) DWARF() (*dwarf.Data, error) {
-	// There are many other DWARF sections, but these
-	// are the required ones, and the debug/dwarf package
-	// does not use the others, so don't bother loading them.
-	var names = [...]string{"abbrev", "frame", "info", "line", "str"}
-	var dat [len(names)][]byte
-	for i, name := range names {
-		name = "__debug_" + name
-		s := f.Section(name)
-		if s == nil {
-			continue
-		}
-		b, err := s.Data()
-		if err != nil && uint64(len(b)) < s.Size {
-			return nil, err
-		}
-		dat[i] = b
-	}
-
-	abbrev, frame, info, line, str := dat[0], dat[1], dat[2], dat[3], dat[4]
-	return dwarf.New(abbrev, nil, frame, info, line, nil, nil, str)
-}
-
-// ImportedSymbols returns the names of all symbols
-// referred to by the binary f that are expected to be
-// satisfied by other libraries at dynamic load time.
-func (f *File) ImportedSymbols() ([]string, error) {
-	if f.Dysymtab == nil || f.Symtab == nil {
-		return nil, &FormatError{0, "missing symbol table", nil}
-	}
-
-	st := f.Symtab
-	dt := f.Dysymtab
-	var all []string
-	for _, s := range st.Syms[dt.Iundefsym : dt.Iundefsym+dt.Nundefsym] {
-		all = append(all, s.Name)
-	}
-	return all, nil
-}
-
-// ImportedLibraries returns the paths of all libraries
-// referred to by the binary f that are expected to be
-// linked with the binary at dynamic link time.
-func (f *File) ImportedLibraries() ([]string, error) {
-	var all []string
-	for _, l := range f.Loads {
-		if lib, ok := l.(*Dylib); ok {
-			all = append(all, lib.Name)
-		}
-	}
-	return all, nil
-}
diff --git a/macho/file_test.go b/macho/file_test.go
deleted file mode 100644
index 4797780..0000000
--- a/macho/file_test.go
+++ /dev/null
@@ -1,210 +0,0 @@
-// Copyright 2009 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 macho
-
-import (
-	"reflect"
-	"testing"
-)
-
-type fileTest struct {
-	file     string
-	hdr      FileHeader
-	segments []*SegmentHeader
-	sections []*SectionHeader
-}
-
-var fileTests = []fileTest{
-	{
-		"testdata/gcc-386-darwin-exec",
-		FileHeader{0xfeedface, Cpu386, 0x3, 0x2, 0xc, 0x3c0, 0x85},
-		[]*SegmentHeader{
-			{LoadCmdSegment, 0x38, "__PAGEZERO", 0x0, 0x1000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
-			{LoadCmdSegment, 0xc0, "__TEXT", 0x1000, 0x1000, 0x0, 0x1000, 0x7, 0x5, 0x2, 0x0},
-			{LoadCmdSegment, 0xc0, "__DATA", 0x2000, 0x1000, 0x1000, 0x1000, 0x7, 0x3, 0x2, 0x0},
-			{LoadCmdSegment, 0x7c, "__IMPORT", 0x3000, 0x1000, 0x2000, 0x1000, 0x7, 0x7, 0x1, 0x0},
-			{LoadCmdSegment, 0x38, "__LINKEDIT", 0x4000, 0x1000, 0x3000, 0x12c, 0x7, 0x1, 0x0, 0x0},
-			nil,
-			nil,
-			nil,
-			nil,
-			nil,
-			nil,
-			nil,
-		},
-		[]*SectionHeader{
-			{"__text", "__TEXT", 0x1f68, 0x88, 0xf68, 0x2, 0x0, 0x0, 0x80000400},
-			{"__cstring", "__TEXT", 0x1ff0, 0xd, 0xff0, 0x0, 0x0, 0x0, 0x2},
-			{"__data", "__DATA", 0x2000, 0x14, 0x1000, 0x2, 0x0, 0x0, 0x0},
-			{"__dyld", "__DATA", 0x2014, 0x1c, 0x1014, 0x2, 0x0, 0x0, 0x0},
-			{"__jump_table", "__IMPORT", 0x3000, 0xa, 0x2000, 0x6, 0x0, 0x0, 0x4000008},
-		},
-	},
-	{
-		"testdata/gcc-amd64-darwin-exec",
-		FileHeader{0xfeedfacf, CpuAmd64, 0x80000003, 0x2, 0xb, 0x568, 0x85},
-		[]*SegmentHeader{
-			{LoadCmdSegment64, 0x48, "__PAGEZERO", 0x0, 0x100000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
-			{LoadCmdSegment64, 0x1d8, "__TEXT", 0x100000000, 0x1000, 0x0, 0x1000, 0x7, 0x5, 0x5, 0x0},
-			{LoadCmdSegment64, 0x138, "__DATA", 0x100001000, 0x1000, 0x1000, 0x1000, 0x7, 0x3, 0x3, 0x0},
-			{LoadCmdSegment64, 0x48, "__LINKEDIT", 0x100002000, 0x1000, 0x2000, 0x140, 0x7, 0x1, 0x0, 0x0},
-			nil,
-			nil,
-			nil,
-			nil,
-			nil,
-			nil,
-			nil,
-		},
-		[]*SectionHeader{
-			{"__text", "__TEXT", 0x100000f14, 0x6d, 0xf14, 0x2, 0x0, 0x0, 0x80000400},
-			{"__symbol_stub1", "__TEXT", 0x100000f81, 0xc, 0xf81, 0x0, 0x0, 0x0, 0x80000408},
-			{"__stub_helper", "__TEXT", 0x100000f90, 0x18, 0xf90, 0x2, 0x0, 0x0, 0x0},
-			{"__cstring", "__TEXT", 0x100000fa8, 0xd, 0xfa8, 0x0, 0x0, 0x0, 0x2},
-			{"__eh_frame", "__TEXT", 0x100000fb8, 0x48, 0xfb8, 0x3, 0x0, 0x0, 0x6000000b},
-			{"__data", "__DATA", 0x100001000, 0x1c, 0x1000, 0x3, 0x0, 0x0, 0x0},
-			{"__dyld", "__DATA", 0x100001020, 0x38, 0x1020, 0x3, 0x0, 0x0, 0x0},
-			{"__la_symbol_ptr", "__DATA", 0x100001058, 0x10, 0x1058, 0x2, 0x0, 0x0, 0x7},
-		},
-	},
-	{
-		"testdata/gcc-amd64-darwin-exec-debug",
-		FileHeader{0xfeedfacf, CpuAmd64, 0x80000003, 0xa, 0x4, 0x5a0, 0},
-		[]*SegmentHeader{
-			nil,
-			{LoadCmdSegment64, 0x1d8, "__TEXT", 0x100000000, 0x1000, 0x0, 0x0, 0x7, 0x5, 0x5, 0x0},
-			{LoadCmdSegment64, 0x138, "__DATA", 0x100001000, 0x1000, 0x0, 0x0, 0x7, 0x3, 0x3, 0x0},
-			{LoadCmdSegment64, 0x278, "__DWARF", 0x100002000, 0x1000, 0x1000, 0x1bc, 0x7, 0x3, 0x7, 0x0},
-		},
-		[]*SectionHeader{
-			{"__text", "__TEXT", 0x100000f14, 0x0, 0x0, 0x2, 0x0, 0x0, 0x80000400},
-			{"__symbol_stub1", "__TEXT", 0x100000f81, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80000408},
-			{"__stub_helper", "__TEXT", 0x100000f90, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0},
-			{"__cstring", "__TEXT", 0x100000fa8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2},
-			{"__eh_frame", "__TEXT", 0x100000fb8, 0x0, 0x0, 0x3, 0x0, 0x0, 0x6000000b},
-			{"__data", "__DATA", 0x100001000, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0},
-			{"__dyld", "__DATA", 0x100001020, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0},
-			{"__la_symbol_ptr", "__DATA", 0x100001058, 0x0, 0x0, 0x2, 0x0, 0x0, 0x7},
-			{"__debug_abbrev", "__DWARF", 0x100002000, 0x36, 0x1000, 0x0, 0x0, 0x0, 0x0},
-			{"__debug_aranges", "__DWARF", 0x100002036, 0x30, 0x1036, 0x0, 0x0, 0x0, 0x0},
-			{"__debug_frame", "__DWARF", 0x100002066, 0x40, 0x1066, 0x0, 0x0, 0x0, 0x0},
-			{"__debug_info", "__DWARF", 0x1000020a6, 0x54, 0x10a6, 0x0, 0x0, 0x0, 0x0},
-			{"__debug_line", "__DWARF", 0x1000020fa, 0x47, 0x10fa, 0x0, 0x0, 0x0, 0x0},
-			{"__debug_pubnames", "__DWARF", 0x100002141, 0x1b, 0x1141, 0x0, 0x0, 0x0, 0x0},
-			{"__debug_str", "__DWARF", 0x10000215c, 0x60, 0x115c, 0x0, 0x0, 0x0, 0x0},
-		},
-	},
-}
-
-func TestOpen(t *testing.T) {
-	for i := range fileTests {
-		tt := &fileTests[i]
-
-		f, err := Open(tt.file)
-		if err != nil {
-			t.Error(err)
-			continue
-		}
-		if !reflect.DeepEqual(f.FileHeader, tt.hdr) {
-			t.Errorf("open %s:\n\thave %#v\n\twant %#v\n", tt.file, f.FileHeader, tt.hdr)
-			continue
-		}
-		for i, l := range f.Loads {
-			if i >= len(tt.segments) {
-				break
-			}
-			sh := tt.segments[i]
-			s, ok := l.(*Segment)
-			if sh == nil {
-				if ok {
-					t.Errorf("open %s, section %d: skipping %#v\n", tt.file, i, &s.SegmentHeader)
-				}
-				continue
-			}
-			if !ok {
-				t.Errorf("open %s, section %d: not *Segment\n", tt.file, i)
-				continue
-			}
-			have := &s.SegmentHeader
-			want := sh
-			if !reflect.DeepEqual(have, want) {
-				t.Errorf("open %s, segment %d:\n\thave %#v\n\twant %#v\n", tt.file, i, have, want)
-			}
-		}
-		tn := len(tt.segments)
-		fn := len(f.Loads)
-		if tn != fn {
-			t.Errorf("open %s: len(Loads) = %d, want %d", tt.file, fn, tn)
-		}
-
-		for i, sh := range f.Sections {
-			if i >= len(tt.sections) {
-				break
-			}
-			have := &sh.SectionHeader
-			want := tt.sections[i]
-			if !reflect.DeepEqual(have, want) {
-				t.Errorf("open %s, section %d:\n\thave %#v\n\twant %#v\n", tt.file, i, have, want)
-			}
-		}
-		tn = len(tt.sections)
-		fn = len(f.Sections)
-		if tn != fn {
-			t.Errorf("open %s: len(Sections) = %d, want %d", tt.file, fn, tn)
-		}
-
-	}
-}
-
-func TestOpenFailure(t *testing.T) {
-	filename := "file.go"    // not a Mach-O file
-	_, err := Open(filename) // don't crash
-	if err == nil {
-		t.Errorf("open %s: succeeded unexpectedly", filename)
-	}
-}
-
-func TestOpenFat(t *testing.T) {
-	ff, err := OpenFat("testdata/fat-gcc-386-amd64-darwin-exec")
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	if ff.Magic != MagicFat {
-		t.Errorf("OpenFat: got magic number %#x, want %#x", ff.Magic, MagicFat)
-	}
-	if len(ff.Arches) != 2 {
-		t.Errorf("OpenFat: got %d architectures, want 2", len(ff.Arches))
-	}
-
-	for i := range ff.Arches {
-		arch := &ff.Arches[i]
-		ftArch := &fileTests[i]
-
-		if arch.Cpu != ftArch.hdr.Cpu || arch.SubCpu != ftArch.hdr.SubCpu {
-			t.Errorf("OpenFat: architecture #%d got cpu=%#x subtype=%#x, expected cpu=%#x, subtype=%#x", i, arch.Cpu, arch.SubCpu, ftArch.hdr.Cpu, ftArch.hdr.SubCpu)
-		}
-
-		if !reflect.DeepEqual(arch.FileHeader, ftArch.hdr) {
-			t.Errorf("OpenFat header:\n\tgot %#v\n\twant %#v\n", arch.FileHeader, ftArch.hdr)
-		}
-	}
-}
-
-func TestOpenFatFailure(t *testing.T) {
-	filename := "file.go" // not a Mach-O file
-	if _, err := OpenFat(filename); err == nil {
-		t.Errorf("OpenFat %s: succeeded unexpectedly", filename)
-	}
-
-	filename = "testdata/gcc-386-darwin-exec" // not a fat Mach-O
-	ff, err := OpenFat(filename)
-	if err != ErrNotFat {
-		t.Errorf("OpenFat %s: got %v, want ErrNotFat", filename, err)
-	}
-	if ff != nil {
-		t.Errorf("OpenFat %s: got %v, want nil", filename, ff)
-	}
-}
diff --git a/macho/macho.go b/macho/macho.go
deleted file mode 100644
index b35e436..0000000
--- a/macho/macho.go
+++ /dev/null
@@ -1,316 +0,0 @@
-// Copyright 2009 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.
-
-// Mach-O header data structures
-// http://developer.apple.com/mac/library/documentation/DeveloperTools/Conceptual/MachORuntime/Reference/reference.html
-
-package macho // import "golang.org/x/debug/macho"
-
-import "strconv"
-
-// A FileHeader represents a Mach-O file header.
-type FileHeader struct {
-	Magic  uint32
-	Cpu    Cpu
-	SubCpu uint32
-	Type   Type
-	Ncmd   uint32
-	Cmdsz  uint32
-	Flags  uint32
-}
-
-const (
-	fileHeaderSize32 = 7 * 4
-	fileHeaderSize64 = 8 * 4
-)
-
-const (
-	Magic32  uint32 = 0xfeedface
-	Magic64  uint32 = 0xfeedfacf
-	MagicFat uint32 = 0xcafebabe
-)
-
-// A Type is the Mach-O file type, e.g. an object file, executable, or dynamic library.
-type Type uint32
-
-const (
-	TypeObj    Type = 1
-	TypeExec   Type = 2
-	TypeDylib  Type = 6
-	TypeBundle Type = 8
-)
-
-// A Cpu is a Mach-O cpu type.
-type Cpu uint32
-
-const cpuArch64 = 0x01000000
-
-const (
-	Cpu386   Cpu = 7
-	CpuAmd64 Cpu = Cpu386 | cpuArch64
-	CpuArm   Cpu = 12
-	CpuPpc   Cpu = 18
-	CpuPpc64 Cpu = CpuPpc | cpuArch64
-)
-
-var cpuStrings = []intName{
-	{uint32(Cpu386), "Cpu386"},
-	{uint32(CpuAmd64), "CpuAmd64"},
-	{uint32(CpuArm), "CpuArm"},
-	{uint32(CpuPpc), "CpuPpc"},
-	{uint32(CpuPpc64), "CpuPpc64"},
-}
-
-func (i Cpu) String() string   { return stringName(uint32(i), cpuStrings, false) }
-func (i Cpu) GoString() string { return stringName(uint32(i), cpuStrings, true) }
-
-// A LoadCmd is a Mach-O load command.
-type LoadCmd uint32
-
-const (
-	LoadCmdSegment    LoadCmd = 1
-	LoadCmdSymtab     LoadCmd = 2
-	LoadCmdThread     LoadCmd = 4
-	LoadCmdUnixThread LoadCmd = 5 // thread+stack
-	LoadCmdDysymtab   LoadCmd = 11
-	LoadCmdDylib      LoadCmd = 12
-	LoadCmdDylinker   LoadCmd = 15
-	LoadCmdSegment64  LoadCmd = 25
-)
-
-var cmdStrings = []intName{
-	{uint32(LoadCmdSegment), "LoadCmdSegment"},
-	{uint32(LoadCmdThread), "LoadCmdThread"},
-	{uint32(LoadCmdUnixThread), "LoadCmdUnixThread"},
-	{uint32(LoadCmdDylib), "LoadCmdDylib"},
-	{uint32(LoadCmdSegment64), "LoadCmdSegment64"},
-}
-
-func (i LoadCmd) String() string   { return stringName(uint32(i), cmdStrings, false) }
-func (i LoadCmd) GoString() string { return stringName(uint32(i), cmdStrings, true) }
-
-// A Segment64 is a 64-bit Mach-O segment load command.
-type Segment64 struct {
-	Cmd     LoadCmd
-	Len     uint32
-	Name    [16]byte
-	Addr    uint64
-	Memsz   uint64
-	Offset  uint64
-	Filesz  uint64
-	Maxprot uint32
-	Prot    uint32
-	Nsect   uint32
-	Flag    uint32
-}
-
-// A Segment32 is a 32-bit Mach-O segment load command.
-type Segment32 struct {
-	Cmd     LoadCmd
-	Len     uint32
-	Name    [16]byte
-	Addr    uint32
-	Memsz   uint32
-	Offset  uint32
-	Filesz  uint32
-	Maxprot uint32
-	Prot    uint32
-	Nsect   uint32
-	Flag    uint32
-}
-
-// A DylibCmd is a Mach-O load dynamic library command.
-type DylibCmd struct {
-	Cmd            LoadCmd
-	Len            uint32
-	Name           uint32
-	Time           uint32
-	CurrentVersion uint32
-	CompatVersion  uint32
-}
-
-// A Section32 is a 32-bit Mach-O section header.
-type Section32 struct {
-	Name     [16]byte
-	Seg      [16]byte
-	Addr     uint32
-	Size     uint32
-	Offset   uint32
-	Align    uint32
-	Reloff   uint32
-	Nreloc   uint32
-	Flags    uint32
-	Reserve1 uint32
-	Reserve2 uint32
-}
-
-// A Section32 is a 64-bit Mach-O section header.
-type Section64 struct {
-	Name     [16]byte
-	Seg      [16]byte
-	Addr     uint64
-	Size     uint64
-	Offset   uint32
-	Align    uint32
-	Reloff   uint32
-	Nreloc   uint32
-	Flags    uint32
-	Reserve1 uint32
-	Reserve2 uint32
-	Reserve3 uint32
-}
-
-// A SymtabCmd is a Mach-O symbol table command.
-type SymtabCmd struct {
-	Cmd     LoadCmd
-	Len     uint32
-	Symoff  uint32
-	Nsyms   uint32
-	Stroff  uint32
-	Strsize uint32
-}
-
-// A DysymtabCmd is a Mach-O dynamic symbol table command.
-type DysymtabCmd struct {
-	Cmd            LoadCmd
-	Len            uint32
-	Ilocalsym      uint32
-	Nlocalsym      uint32
-	Iextdefsym     uint32
-	Nextdefsym     uint32
-	Iundefsym      uint32
-	Nundefsym      uint32
-	Tocoffset      uint32
-	Ntoc           uint32
-	Modtaboff      uint32
-	Nmodtab        uint32
-	Extrefsymoff   uint32
-	Nextrefsyms    uint32
-	Indirectsymoff uint32
-	Nindirectsyms  uint32
-	Extreloff      uint32
-	Nextrel        uint32
-	Locreloff      uint32
-	Nlocrel        uint32
-}
-
-// An Nlist32 is a Mach-O 32-bit symbol table entry.
-type Nlist32 struct {
-	Name  uint32
-	Type  uint8
-	Sect  uint8
-	Desc  uint16
-	Value uint32
-}
-
-// An Nlist64 is a Mach-O 64-bit symbol table entry.
-type Nlist64 struct {
-	Name  uint32
-	Type  uint8
-	Sect  uint8
-	Desc  uint16
-	Value uint64
-}
-
-// A Symbol is a Mach-O 32-bit or 64-bit symbol table entry.
-type Symbol struct {
-	Name  string
-	Type  uint8
-	Sect  uint8
-	Desc  uint16
-	Value uint64
-}
-
-// A Thread is a Mach-O thread state command.
-type Thread struct {
-	Cmd  LoadCmd
-	Len  uint32
-	Type uint32
-	Data []uint32
-}
-
-// Regs386 is the Mach-O 386 register structure.
-type Regs386 struct {
-	AX    uint32
-	BX    uint32
-	CX    uint32
-	DX    uint32
-	DI    uint32
-	SI    uint32
-	BP    uint32
-	SP    uint32
-	SS    uint32
-	FLAGS uint32
-	IP    uint32
-	CS    uint32
-	DS    uint32
-	ES    uint32
-	FS    uint32
-	GS    uint32
-}
-
-// RegsAMD64 is the Mach-O AMD64 register structure.
-type RegsAMD64 struct {
-	AX    uint64
-	BX    uint64
-	CX    uint64
-	DX    uint64
-	DI    uint64
-	SI    uint64
-	BP    uint64
-	SP    uint64
-	R8    uint64
-	R9    uint64
-	R10   uint64
-	R11   uint64
-	R12   uint64
-	R13   uint64
-	R14   uint64
-	R15   uint64
-	IP    uint64
-	FLAGS uint64
-	CS    uint64
-	FS    uint64
-	GS    uint64
-}
-
-type intName struct {
-	i uint32
-	s string
-}
-
-func stringName(i uint32, names []intName, goSyntax bool) string {
-	for _, n := range names {
-		if n.i == i {
-			if goSyntax {
-				return "macho." + n.s
-			}
-			return n.s
-		}
-	}
-	return strconv.FormatUint(uint64(i), 10)
-}
-
-func flagName(i uint32, names []intName, goSyntax bool) string {
-	s := ""
-	for _, n := range names {
-		if n.i&i == n.i {
-			if len(s) > 0 {
-				s += "+"
-			}
-			if goSyntax {
-				s += "macho."
-			}
-			s += n.s
-			i -= n.i
-		}
-	}
-	if len(s) == 0 {
-		return "0x" + strconv.FormatUint(uint64(i), 16)
-	}
-	if i != 0 {
-		s += "+0x" + strconv.FormatUint(uint64(i), 16)
-	}
-	return s
-}
diff --git a/macho/testdata/fat-gcc-386-amd64-darwin-exec b/macho/testdata/fat-gcc-386-amd64-darwin-exec
deleted file mode 100644
index 7efd193..0000000
--- a/macho/testdata/fat-gcc-386-amd64-darwin-exec
+++ /dev/null
Binary files differ
diff --git a/macho/testdata/gcc-386-darwin-exec b/macho/testdata/gcc-386-darwin-exec
deleted file mode 100755
index 03ba1ba..0000000
--- a/macho/testdata/gcc-386-darwin-exec
+++ /dev/null
Binary files differ
diff --git a/macho/testdata/gcc-amd64-darwin-exec b/macho/testdata/gcc-amd64-darwin-exec
deleted file mode 100755
index 5155a5a..0000000
--- a/macho/testdata/gcc-amd64-darwin-exec
+++ /dev/null
Binary files differ
diff --git a/macho/testdata/gcc-amd64-darwin-exec-debug b/macho/testdata/gcc-amd64-darwin-exec-debug
deleted file mode 100644
index a47d3ae..0000000
--- a/macho/testdata/gcc-amd64-darwin-exec-debug
+++ /dev/null
Binary files differ
diff --git a/macho/testdata/hello.c b/macho/testdata/hello.c
deleted file mode 100644
index a689d36..0000000
--- a/macho/testdata/hello.c
+++ /dev/null
@@ -1,8 +0,0 @@
-#include <stdio.h>
-
-int
-main(void)
-{
-	printf("hello, world\n");
-	return 0;
-}
diff --git a/program.go b/program.go
deleted file mode 100644
index b988d83..0000000
--- a/program.go
+++ /dev/null
@@ -1,317 +0,0 @@
-// Copyright 2014 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 debug provides the portable interface to a program being debugged.
-package debug // import "golang.org/x/debug"
-
-import (
-	"fmt"
-	"io"
-	"strings"
-)
-
-// Program is the interface to a (possibly remote) program being debugged.
-// The process (if any) and text file associated with it may change during
-// the session, but many resources are associated with the Program rather
-// than process or text file so they persist across debuggging runs.
-type Program interface {
-	// Open opens a virtual file associated with the process.
-	// Names are things like "text", "mem", "fd/2".
-	// Mode is one of "r", "w", "rw".
-	// Return values are open File and error.
-	// When the target binary is re-run, open files are
-	// automatically updated to refer to the corresponding
-	// file in the new process.
-	Open(name string, mode string) (File, error)
-
-	// Run abandons the current running process, if any,
-	// and execs a new instance of the target binary file
-	// (which may have changed underfoot).
-	// Breakpoints and open files are re-established.
-	// The call hangs until the program stops executing,
-	// at which point it returns the program status.
-	// args contains the command-line arguments for the process.
-	Run(args ...string) (Status, error)
-
-	// Stop stops execution of the current process but
-	// does not kill it.
-	Stop() (Status, error)
-
-	// Resume resumes execution of a stopped process.
-	// The call hangs until the program stops executing,
-	// at which point it returns the program status.
-	Resume() (Status, error)
-
-	// TODO: Step(). Where does the granularity happen,
-	// on the proxy end or the debugging control end?
-
-	// Kill kills the current process.
-	Kill() (Status, error)
-
-	// Breakpoint sets a breakpoint at the specified address.
-	Breakpoint(address uint64) (PCs []uint64, err error)
-
-	// BreakpointAtFunction sets a breakpoint at the start of the specified function.
-	BreakpointAtFunction(name string) (PCs []uint64, err error)
-
-	// BreakpointAtLine sets a breakpoint at the specified source line.
-	BreakpointAtLine(file string, line uint64) (PCs []uint64, err error)
-
-	// DeleteBreakpoints removes the breakpoints at the specified addresses.
-	// Addresses where no breakpoint is set are ignored.
-	DeleteBreakpoints(pcs []uint64) error
-
-	// Eval evaluates the expression (typically an address) and returns
-	// its string representation(s). Multivalued expressions such as
-	// matches for regular expressions return multiple values.
-	// TODO: change this to multiple functions with more specific names.
-	// Syntax:
-	//	re:regexp
-	//		Returns a list of symbol names that match the expression
-	//	addr:symbol
-	//		Returns a one-element list holding the hexadecimal
-	//		("0x1234") value of the address of the symbol
-	//	val:symbol
-	//		Returns a one-element list holding the formatted
-	//		value of the symbol
-	//	0x1234, 01234, 467
-	//		Returns a one-element list holding the name of the
-	//		symbol ("main.foo") at that address (hex, octal, decimal).
-	Eval(expr string) ([]string, error)
-
-	// Evaluate evaluates an expression.  Accepts a subset of Go expression syntax:
-	// basic literals, identifiers, parenthesized expressions, and most operators.
-	// Only the len function call is available.
-	//
-	// The expression can refer to local variables and function parameters of the
-	// function where the program is stopped.
-	//
-	// On success, the type of the value returned will be one of:
-	// int8, int16, int32, int64, uint8, uint16, uint32, uint64, float32, float64,
-	// complex64, complex128, bool, Pointer, Array, Slice, String, Map, Struct,
-	// Channel, Func, or Interface.
-	Evaluate(e string) (Value, error)
-
-	// Frames returns up to count stack frames from where the program
-	// is currently stopped.
-	Frames(count int) ([]Frame, error)
-
-	// VarByName returns a Var referring to a global variable with the given name.
-	// TODO: local variables
-	VarByName(name string) (Var, error)
-
-	// Value gets the value of a variable by reading the program's memory.
-	Value(v Var) (Value, error)
-
-	// MapElement returns Vars for the key and value of a map element specified by
-	// a 0-based index.
-	MapElement(m Map, index uint64) (Var, Var, error)
-
-	// Goroutines gets the current goroutines.
-	Goroutines() ([]*Goroutine, error)
-}
-
-type Goroutine struct {
-	ID           int64
-	Status       GoroutineStatus
-	StatusString string // A human-readable string explaining the status in more detail.
-	Function     string // Name of the goroutine function.
-	Caller       string // Name of the function that created this goroutine.
-	StackFrames  []Frame
-}
-
-type GoroutineStatus byte
-
-const (
-	Running GoroutineStatus = iota
-	Queued
-	Blocked
-)
-
-func (g GoroutineStatus) String() string {
-	switch g {
-	case Running:
-		return "running"
-	case Queued:
-		return "queued"
-	case Blocked:
-		return "blocked"
-	}
-	return "invalid status"
-}
-
-func (g *Goroutine) String() string {
-	return fmt.Sprintf("goroutine %d [%s] %s -> %s", g.ID, g.StatusString, g.Caller, g.Function)
-}
-
-// A reference to a variable in a program.
-// TODO: handle variables stored in registers
-type Var struct {
-	TypeID  uint64 // A type identifier, opaque to the user.
-	Address uint64 // The address of the variable.
-}
-
-// A value read from a remote program.
-type Value interface{}
-
-// Pointer is a Value representing a pointer.
-// Note that the TypeID field will be the type of the variable being pointed to,
-// not the type of this pointer.
-type Pointer struct {
-	TypeID  uint64 // A type identifier, opaque to the user.
-	Address uint64 // The address of the variable.
-}
-
-// Array is a Value representing an array.
-type Array struct {
-	ElementTypeID uint64
-	Address       uint64
-	Length        uint64 // Number of elements in the array
-	StrideBits    uint64 // Number of bits between array entries
-}
-
-// Len returns the number of elements in the array.
-func (a Array) Len() uint64 {
-	return a.Length
-}
-
-// Element returns a Var referring to the given element of the array.
-func (a Array) Element(index uint64) Var {
-	return Var{
-		TypeID:  a.ElementTypeID,
-		Address: a.Address + index*(a.StrideBits/8),
-	}
-}
-
-// Slice is a Value representing a slice.
-type Slice struct {
-	Array
-	Capacity uint64
-}
-
-// String is a Value representing a string.
-// TODO: a method to access more of a truncated string.
-type String struct {
-	// Length contains the length of the remote string, in bytes.
-	Length uint64
-	// String contains the string itself; it may be truncated to fewer bytes than the value of the Length field.
-	String string
-}
-
-// Map is a Value representing a map.
-type Map struct {
-	TypeID  uint64
-	Address uint64
-	Length  uint64 // Number of elements in the map.
-}
-
-// Struct is a Value representing a struct.
-type Struct struct {
-	Fields []StructField
-}
-
-// StructField represents a field in a struct object.
-type StructField struct {
-	Name string
-	Var  Var
-}
-
-// Channel is a Value representing a channel.
-type Channel struct {
-	ElementTypeID uint64
-	Address       uint64 // Location of the channel struct in memory.
-	Buffer        uint64 // Location of the buffer; zero for nil channels.
-	Length        uint64 // Number of elements stored in the channel buffer.
-	Capacity      uint64 // Capacity of the buffer; zero for unbuffered channels.
-	Stride        uint64 // Number of bytes between buffer entries.
-	BufferStart   uint64 // Index in the buffer of the element at the head of the queue.
-}
-
-// Element returns a Var referring to the given element of the channel's queue.
-// If the channel is unbuffered, nil, or if the index is too large, returns a Var with Address == 0.
-func (m Channel) Element(index uint64) Var {
-	if index >= m.Length {
-		return Var{
-			TypeID:  m.ElementTypeID,
-			Address: 0,
-		}
-	}
-	if index < m.Capacity-m.BufferStart {
-		// The element is in the part of the queue that occurs later in the buffer
-		// than the head of the queue.
-		return Var{
-			TypeID:  m.ElementTypeID,
-			Address: m.Buffer + (m.BufferStart+index)*m.Stride,
-		}
-	}
-	// The element is in the part of the queue that has wrapped around to the
-	// start of the buffer.
-	return Var{
-		TypeID:  m.ElementTypeID,
-		Address: m.Buffer + (m.BufferStart+index-m.Capacity)*m.Stride,
-	}
-}
-
-// Func is a Value representing a func.
-type Func struct {
-	Address uint64
-}
-
-// Interface is a Value representing an interface.
-type Interface struct{}
-
-// The File interface provides access to file-like resources in the program.
-// It implements only ReaderAt and WriterAt, not Reader and Writer, because
-// random access is a far more common pattern for things like symbol tables,
-// and because enormous address space of virtual memory makes routines
-// like io.Copy dangerous.
-type File interface {
-	io.ReaderAt
-	io.WriterAt
-	io.Closer
-}
-
-type Status struct {
-	PC, SP uint64
-}
-
-type Frame struct {
-	// PC is the hardware program counter.
-	PC uint64
-	// SP is the hardware stack pointer.
-	SP uint64
-	// File and Line are the source code location of the PC.
-	File string
-	Line uint64
-	// Function is the name of this frame's function.
-	Function string
-	// FunctionStart is the starting PC of the function.
-	FunctionStart uint64
-	// Params contains the function's parameters.
-	Params []Param
-	// Vars contains the function's local variables.
-	Vars []LocalVar
-}
-
-func (f Frame) String() string {
-	params := make([]string, len(f.Params))
-	for i, p := range f.Params {
-		params[i] = p.Name // TODO: more information
-	}
-	p := strings.Join(params, ", ")
-	off := f.PC - f.FunctionStart
-	return fmt.Sprintf("%s(%s)\n\t%s:%d +0x%x", f.Function, p, f.File, f.Line, off)
-}
-
-// Param is a parameter of a function.
-type Param struct {
-	Name string
-	Var  Var
-}
-
-// LocalVar is a local variable of a function.
-type LocalVar struct {
-	Name string
-	Var  Var
-}
diff --git a/remote/remote.go b/remote/remote.go
deleted file mode 100644
index 66080c0..0000000
--- a/remote/remote.go
+++ /dev/null
@@ -1,295 +0,0 @@
-// Copyright 2014 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 remote provides remote access to a debugproxy server.
-package remote // import "golang.org/x/debug/remote"
-
-import (
-	"fmt"
-	"io"
-	"net/rpc"
-	"os"
-	"os/exec"
-
-	"golang.org/x/debug"
-	"golang.org/x/debug/server/protocol"
-)
-
-var _ debug.Program = (*Program)(nil)
-var _ debug.File = (*File)(nil)
-
-// Program implements the debug.Program interface.
-// Through that interface it provides access to a program being
-// debugged on a possibly remote machine by communicating
-// with a debugproxy adjacent to the target program.
-type Program struct {
-	client *rpc.Client
-}
-
-// DebugproxyCmd is the path to the debugproxy command. It is a variable in case
-// the default value, "debugproxy", is not in the $PATH.
-var DebugproxyCmd = "debugproxy"
-
-// New connects to the specified host using SSH, starts DebugproxyCmd
-// there, and creates a new program from the specified file.
-// The program can then be started by the Run method.
-func New(host string, textFile string) (*Program, error) {
-	// TODO: add args.
-	cmdStrs := []string{"/usr/bin/ssh", host, DebugproxyCmd, "-text", textFile}
-	if host == "localhost" {
-		cmdStrs = cmdStrs[2:]
-	}
-	cmd := exec.Command(cmdStrs[0], cmdStrs[1:]...)
-	stdin, toStdin, err := os.Pipe()
-	if err != nil {
-		return nil, err
-	}
-	fromStdout, stdout, err := os.Pipe()
-	if err != nil {
-		return nil, err
-	}
-	cmd.Stdin = stdin
-	cmd.Stdout = stdout
-	cmd.Stderr = os.Stderr // Stderr from proxy appears on our stderr.
-	err = cmd.Start()
-	if err != nil {
-		return nil, err
-	}
-	stdout.Close()
-	if msg, err := readLine(fromStdout); err != nil {
-		return nil, err
-	} else if msg != "OK" {
-		// Communication error.
-		return nil, fmt.Errorf("unrecognized message %q", msg)
-	}
-	program := &Program{
-		client: rpc.NewClient(&rwc{
-			ssh: cmd,
-			r:   fromStdout,
-			w:   toStdin,
-		}),
-	}
-	return program, nil
-}
-
-// readLine reads one line of text from the reader. It does no buffering.
-// The trailing newline is read but not returned.
-func readLine(r io.Reader) (string, error) {
-	b := make([]byte, 0, 10)
-	var c [1]byte
-	for {
-		_, err := io.ReadFull(r, c[:])
-		if err != nil {
-			return "", err
-		}
-		if c[0] == '\n' {
-			break
-		}
-		b = append(b, c[0])
-	}
-	return string(b), nil
-}
-
-// rwc creates a single io.ReadWriteCloser from a read side and a write side.
-// It also holds the command object so we can wait for SSH to complete.
-// It allows us to do RPC over an SSH connection.
-type rwc struct {
-	ssh *exec.Cmd
-	r   *os.File
-	w   *os.File
-}
-
-func (rwc *rwc) Read(p []byte) (int, error) {
-	return rwc.r.Read(p)
-}
-
-func (rwc *rwc) Write(p []byte) (int, error) {
-	return rwc.w.Write(p)
-}
-
-func (rwc *rwc) Close() error {
-	rerr := rwc.r.Close()
-	werr := rwc.w.Close()
-	cerr := rwc.ssh.Wait()
-	if cerr != nil {
-		// Wait exit status is most important.
-		return cerr
-	}
-	if rerr != nil {
-		return rerr
-	}
-	return werr
-}
-
-func (p *Program) Open(name string, mode string) (debug.File, error) {
-	req := protocol.OpenRequest{
-		Name: name,
-		Mode: mode,
-	}
-	var resp protocol.OpenResponse
-	err := p.client.Call("Server.Open", &req, &resp)
-	if err != nil {
-		return nil, err
-	}
-	f := &File{
-		prog: p,
-		fd:   resp.FD,
-	}
-	return f, nil
-}
-
-func (p *Program) Run(args ...string) (debug.Status, error) {
-	req := protocol.RunRequest{args}
-	var resp protocol.RunResponse
-	err := p.client.Call("Server.Run", &req, &resp)
-	if err != nil {
-		return debug.Status{}, err
-	}
-	return resp.Status, nil
-}
-
-func (p *Program) Stop() (debug.Status, error) {
-	panic("unimplemented")
-}
-
-func (p *Program) Resume() (debug.Status, error) {
-	req := protocol.ResumeRequest{}
-	var resp protocol.ResumeResponse
-	err := p.client.Call("Server.Resume", &req, &resp)
-	if err != nil {
-		return debug.Status{}, err
-	}
-	return resp.Status, nil
-}
-
-func (p *Program) Kill() (debug.Status, error) {
-	panic("unimplemented")
-}
-
-func (p *Program) Breakpoint(address uint64) ([]uint64, error) {
-	req := protocol.BreakpointRequest{
-		Address: address,
-	}
-	var resp protocol.BreakpointResponse
-	err := p.client.Call("Server.Breakpoint", &req, &resp)
-	return resp.PCs, err
-}
-
-func (p *Program) BreakpointAtFunction(name string) ([]uint64, error) {
-	req := protocol.BreakpointAtFunctionRequest{
-		Function: name,
-	}
-	var resp protocol.BreakpointResponse
-	err := p.client.Call("Server.BreakpointAtFunction", &req, &resp)
-	return resp.PCs, err
-}
-
-func (p *Program) BreakpointAtLine(file string, line uint64) ([]uint64, error) {
-	req := protocol.BreakpointAtLineRequest{
-		File: file,
-		Line: line,
-	}
-	var resp protocol.BreakpointResponse
-	err := p.client.Call("Server.BreakpointAtLine", &req, &resp)
-	return resp.PCs, err
-}
-
-func (p *Program) DeleteBreakpoints(pcs []uint64) error {
-	req := protocol.DeleteBreakpointsRequest{PCs: pcs}
-	var resp protocol.DeleteBreakpointsResponse
-	return p.client.Call("Server.DeleteBreakpoints", &req, &resp)
-}
-
-func (p *Program) Eval(expr string) ([]string, error) {
-	req := protocol.EvalRequest{
-		Expr: expr,
-	}
-	var resp protocol.EvalResponse
-	err := p.client.Call("Server.Eval", &req, &resp)
-	return resp.Result, err
-}
-
-func (p *Program) Evaluate(e string) (debug.Value, error) {
-	req := protocol.EvaluateRequest{
-		Expression: e,
-	}
-	var resp protocol.EvaluateResponse
-	err := p.client.Call("Server.Evaluate", &req, &resp)
-	return resp.Result, err
-}
-
-func (p *Program) Frames(count int) ([]debug.Frame, error) {
-	req := protocol.FramesRequest{
-		Count: count,
-	}
-	var resp protocol.FramesResponse
-	err := p.client.Call("Server.Frames", &req, &resp)
-	return resp.Frames, err
-}
-
-func (p *Program) Goroutines() ([]*debug.Goroutine, error) {
-	req := protocol.GoroutinesRequest{}
-	var resp protocol.GoroutinesResponse
-	err := p.client.Call("Server.Goroutines", &req, &resp)
-	return resp.Goroutines, err
-}
-
-func (p *Program) VarByName(name string) (debug.Var, error) {
-	req := protocol.VarByNameRequest{Name: name}
-	var resp protocol.VarByNameResponse
-	err := p.client.Call("Server.VarByName", &req, &resp)
-	return resp.Var, err
-}
-
-func (p *Program) Value(v debug.Var) (debug.Value, error) {
-	req := protocol.ValueRequest{Var: v}
-	var resp protocol.ValueResponse
-	err := p.client.Call("Server.Value", &req, &resp)
-	return resp.Value, err
-}
-
-func (p *Program) MapElement(m debug.Map, index uint64) (debug.Var, debug.Var, error) {
-	req := protocol.MapElementRequest{Map: m, Index: index}
-	var resp protocol.MapElementResponse
-	err := p.client.Call("Server.MapElement", &req, &resp)
-	return resp.Key, resp.Value, err
-}
-
-// File implements the debug.File interface, providing access
-// to file-like resources associated with the target program.
-type File struct {
-	prog *Program // The Program associated with the file.
-	fd   int      // File descriptor.
-}
-
-func (f *File) ReadAt(p []byte, offset int64) (int, error) {
-	req := protocol.ReadAtRequest{
-		FD:     f.fd,
-		Len:    len(p),
-		Offset: offset,
-	}
-	var resp protocol.ReadAtResponse
-	err := f.prog.client.Call("Server.ReadAt", &req, &resp)
-	return copy(p, resp.Data), err
-}
-
-func (f *File) WriteAt(p []byte, offset int64) (int, error) {
-	req := protocol.WriteAtRequest{
-		FD:     f.fd,
-		Data:   p,
-		Offset: offset,
-	}
-	var resp protocol.WriteAtResponse
-	err := f.prog.client.Call("Server.WriteAt", &req, &resp)
-	return resp.Len, err
-}
-
-func (f *File) Close() error {
-	req := protocol.CloseRequest{
-		FD: f.fd,
-	}
-	var resp protocol.CloseResponse
-	err := f.prog.client.Call("Server.Close", &req, &resp)
-	return err
-}
diff --git a/server/dwarf.go b/server/dwarf.go
deleted file mode 100644
index 3c4e2a2..0000000
--- a/server/dwarf.go
+++ /dev/null
@@ -1,100 +0,0 @@
-// Copyright 2014 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 server
-
-import (
-	"errors"
-	"fmt"
-
-	"golang.org/x/debug/dwarf"
-)
-
-func (s *Server) functionStartAddress(name string) (uint64, error) {
-	entry, err := s.dwarfData.LookupFunction(name)
-	if err != nil {
-		return 0, err
-	}
-	addrAttr := entry.Val(dwarf.AttrLowpc)
-	if addrAttr == nil {
-		return 0, fmt.Errorf("symbol %q has no LowPC attribute", name)
-	}
-	addr, ok := addrAttr.(uint64)
-	if !ok {
-		return 0, fmt.Errorf("symbol %q has non-uint64 LowPC attribute", name)
-	}
-	return addr, nil
-}
-
-// evalLocation parses a DWARF location description encoded in v.  It works for
-// cases where the variable is stored at an offset from the Canonical Frame
-// Address.  The return value is this offset.
-// TODO: a more general location-description-parsing function.
-func evalLocation(v []uint8) (int64, error) {
-	// Some DWARF constants.
-	const (
-		opConsts       = 0x11
-		opPlus         = 0x22
-		opCallFrameCFA = 0x9C
-	)
-	if len(v) == 0 {
-		return 0, errors.New("empty location specifier")
-	}
-	if v[0] != opCallFrameCFA {
-		return 0, errors.New("unsupported location specifier")
-	}
-	if len(v) == 1 {
-		// The location description was just DW_OP_call_frame_cfa, so the location is exactly the CFA.
-		return 0, nil
-	}
-	if v[1] != opConsts {
-		return 0, errors.New("unsupported location specifier")
-	}
-	offset, v, err := sleb128(v[2:])
-	if err != nil {
-		return 0, err
-	}
-	if len(v) == 1 && v[0] == opPlus {
-		// The location description was DW_OP_call_frame_cfa, DW_OP_consts <offset>, DW_OP_plus.
-		// So return the offset.
-		return offset, nil
-	}
-	return 0, errors.New("unsupported location specifier")
-}
-
-func uleb128(v []uint8) (u uint64) {
-	var shift uint
-	for _, x := range v {
-		u |= (uint64(x) & 0x7F) << shift
-		shift += 7
-		if x&0x80 == 0 {
-			break
-		}
-	}
-	return u
-}
-
-// sleb128 parses a signed integer encoded with sleb128 at the start of v, and
-// returns the integer and the remainder of v.
-func sleb128(v []uint8) (s int64, rest []uint8, err error) {
-	var shift uint
-	var sign int64 = -1
-	var i int
-	var x uint8
-	for i, x = range v {
-		s |= (int64(x) & 0x7F) << shift
-		shift += 7
-		sign <<= 7
-		if x&0x80 == 0 {
-			if x&0x40 != 0 {
-				s |= sign
-			}
-			break
-		}
-	}
-	if i == len(v) {
-		return 0, nil, errors.New("truncated sleb128")
-	}
-	return s, v[i+1:], nil
-}
diff --git a/server/eval.go b/server/eval.go
deleted file mode 100644
index d964a32..0000000
--- a/server/eval.go
+++ /dev/null
@@ -1,2103 +0,0 @@
-// Copyright 2015 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.
-//
-// Evaluates Go expressions, using the current values of variables in a program
-// being debugged.
-//
-// TODOs:
-// More overflow checking.
-// Stricter type checking.
-// More expression types.
-
-package server
-
-import (
-	"errors"
-	"fmt"
-	"go/ast"
-	"go/parser"
-	"go/token"
-	"math"
-	"math/big"
-
-	"golang.org/x/debug"
-	"golang.org/x/debug/dwarf"
-)
-
-const prec = 256 // precision for untyped float and complex constants.
-
-var (
-	// Some big.Ints to use in overflow checks.
-	bigIntMaxInt32  = big.NewInt(math.MaxInt32)
-	bigIntMinInt32  = big.NewInt(math.MinInt32)
-	bigIntMaxInt64  = big.NewInt(math.MaxInt64)
-	bigIntMinInt64  = big.NewInt(math.MinInt64)
-	bigIntMaxUint64 = new(big.Int).SetUint64(math.MaxUint64)
-)
-
-// result stores an intermediate value produced during evaluation of an expression.
-//
-// d contains the DWARF type of the value.  For untyped values, d will be nil.
-//
-// v contains the value itself.  For numeric and bool types, v will have the
-// corresponding predeclared Go type.
-// For untyped integer, rune, float, complex, string, and bool constants, v will
-// have type untInt, untRune, untFloat, untComplex, untString, or bool,
-// respectively.
-// For values of type int, uint and uintptr, v will be an int32, int64, uint32
-// or uint64 as appropriate.
-// For address operations, v will have type pointerToValue.
-// For the operands of address operations, v will have type addressableValue.
-// Other types are represented using the corresponding implementation of
-// debug.Value in program.go.
-//
-// If an evaluation results in an error, the zero value of result is used.
-type result struct {
-	d dwarf.Type
-	v interface{}
-}
-
-// untInt is an untyped integer constant
-type untInt struct {
-	*big.Int
-}
-
-// untRune is an untyped rune constant
-type untRune struct {
-	*big.Int
-}
-
-// untFloat is an untyped floating-point constant
-type untFloat struct {
-	*big.Float
-}
-
-// untComplex is an untyped complex constant
-type untComplex struct {
-	r *big.Float
-	i *big.Float
-}
-
-// untString is an untyped string constant
-type untString string
-
-// pointerToValue is a pointer to a value in memory.
-// The evaluator constructs these as the result of address operations like "&x".
-// Unlike debug.Pointer, the DWARF type stored alongside values of this type
-// is the type of the variable, not the type of the pointer.
-type pointerToValue struct {
-	a uint64
-}
-
-// addressableValue is the memory location of a value.
-// The evaluator constructs these while evaluating the operands of address
-// operations like "&x", instead of computing the value of x itself.
-type addressableValue struct {
-	a uint64
-}
-
-// A sliceOf is a slice created by slicing an array.
-// Unlike debug.Slice, the DWARF type stored alongside a value of this type is
-// the type of the slice's elements, not the type of the slice.
-type sliceOf debug.Slice
-
-// ident is a value for representing a special identifier.
-type ident string
-
-// identLookup is a built-in function of the expression evaluator which gets the
-// value of a global symbol.
-var identLookup ident = "lookup"
-
-// evalExpression evaluates a Go expression.
-// If the program counter and stack pointer are nonzero, they are used to determine
-// what local variables are available and where in memory they are.
-func (s *Server) evalExpression(expression string, pc, sp uint64) (debug.Value, error) {
-	e := evaluator{server: s, expression: expression, pc: pc, sp: sp}
-	node, err := parser.ParseExpr(expression)
-	if err != nil {
-		return nil, err
-	}
-	val := e.evalNode(node, false)
-	if e.evalError != nil {
-		return nil, e.evalError
-	}
-
-	// Convert untyped constants to their default types.
-	switch v := val.v.(type) {
-	case untInt:
-		return e.intFromInteger(v)
-	case untRune:
-		if v.Cmp(bigIntMaxInt32) == +1 {
-			return nil, errors.New("constant overflows rune")
-		}
-		if v.Cmp(bigIntMinInt32) == -1 {
-			return nil, errors.New("constant overflows rune")
-		}
-		return int32(v.Int64()), nil
-	case untFloat:
-		f, _ := v.Float64()
-		if math.IsInf(f, 0) {
-			return nil, errors.New("constant overflows float64")
-		}
-		if math.IsNaN(f) {
-			return nil, errors.New("constant is NaN")
-		}
-		return f, nil
-	case untComplex:
-		r, _ := v.r.Float64()
-		i, _ := v.i.Float64()
-		if math.IsInf(r, 0) || math.IsInf(i, 0) {
-			return nil, errors.New("constant overflows complex128")
-		}
-		if math.IsNaN(r) || math.IsNaN(i) {
-			return nil, errors.New("constant is NaN")
-		}
-		return complex(r, i), nil
-	case untString:
-		return debug.String{Length: uint64(len(v)), String: string(v)}, nil
-	case pointerToValue:
-		return debug.Pointer{TypeID: uint64(val.d.Common().Offset), Address: v.a}, nil
-	case sliceOf:
-		return debug.Slice(v), nil
-	case nil, addressableValue:
-		// This case should not be reachable.
-		return nil, errors.New("unknown error")
-	}
-	return val.v, nil
-}
-
-type evaluator struct {
-	// expression is the expression being evaluated.
-	expression string
-	// server interacts with the program being debugged.
-	server *Server
-	// curNode is the current parse tree node.  This is set so that error messages
-	// can quote the part of the expression that caused an error.
-	curNode ast.Node
-	// evalError is the first error that occurred while evaluating the expression,
-	// or nil if no error has occurred.
-	evalError error
-	// pc and sp are the current program counter and stack pointer, used for
-	// finding local variables.  If either are zero, the expression is evaluated
-	// without using local variables.
-	pc uint64
-	sp uint64
-}
-
-// setNode sets curNode, and returns curNode's previous value.
-func (e *evaluator) setNode(node ast.Node) (old ast.Node) {
-	old, e.curNode = e.curNode, node
-	return old
-}
-
-// err saves an error that occurred during evaluation.
-// It returns a zero result, so that functions can exit and set an error with
-//	return e.err(...)
-func (e *evaluator) err(s string) result {
-	if e.evalError != nil {
-		return result{}
-	}
-	// Append the substring of the expression that corresponds to the current AST node.
-	start := int(e.curNode.Pos() - 1)
-	end := int(e.curNode.End() - 1)
-	if start < 0 {
-		start = 0
-	}
-	if end > len(e.expression) {
-		end = len(e.expression)
-	}
-	if start > end {
-		start, end = 0, 0
-	}
-	e.evalError = errors.New(s + `: "` + e.expression[start:end] + `"`)
-	return result{}
-}
-
-// evalNode computes the value of a node in the expression tree.
-// If getAddress is true, the node is the argument of an & operator, so evalNode
-// will return a result with a value of type addressableValue if possible.
-func (e *evaluator) evalNode(node ast.Node, getAddress bool) result {
-	// Set the current node in the evaluator, so that error messages can refer to
-	// it.  Defer a function call that changes it back.
-	defer e.setNode(e.setNode(node))
-
-	switch n := node.(type) {
-	case *ast.Ident:
-		if e.pc != 0 && e.sp != 0 {
-			a, t := e.server.findLocalVar(n.Name, e.pc, e.sp)
-			if t != nil {
-				return e.resultFrom(a, t, getAddress)
-			}
-		}
-		a, t := e.server.findGlobalVar(n.Name)
-		if t != nil {
-			return e.resultFrom(a, t, getAddress)
-		}
-		switch n.Name {
-		// Note: these could have been redefined as constants in the code, but we
-		// don't have a way to detect that.
-		case "true":
-			return result{nil, true}
-		case "false":
-			return result{nil, false}
-		case "lookup":
-			return result{nil, identLookup}
-		}
-		return e.err("unknown identifier")
-
-	case *ast.BasicLit:
-		switch n.Kind {
-		case token.INT:
-			i := new(big.Int)
-			if _, ok := i.SetString(n.Value, 0); !ok {
-				return e.err("invalid integer constant")
-			}
-			return result{nil, untInt{i}}
-		case token.FLOAT:
-			r, _, err := big.ParseFloat(n.Value, 10, prec, big.ToNearestEven)
-			if err != nil {
-				return e.err(err.Error())
-			}
-			return result{nil, untFloat{r}}
-		case token.IMAG:
-			if len(n.Value) <= 1 || n.Value[len(n.Value)-1] != 'i' {
-				return e.err("invalid imaginary constant")
-			}
-			r, _, err := big.ParseFloat(n.Value[:len(n.Value)-1], 10, prec, big.ToNearestEven)
-			if err != nil {
-				return e.err(err.Error())
-			}
-			return result{nil, untComplex{new(big.Float), r}}
-		case token.CHAR:
-			// TODO: unescaping
-			return result{nil, untRune{new(big.Int).SetInt64(int64(n.Value[1]))}}
-		case token.STRING:
-			// TODO: unescaping
-			if len(n.Value) <= 1 {
-				return e.err("invalid string constant")
-			}
-			return result{nil, untString(n.Value[1 : len(n.Value)-1])}
-		}
-
-	case *ast.ParenExpr:
-		return e.evalNode(n.X, getAddress)
-
-	case *ast.StarExpr:
-		x := e.evalNode(n.X, false)
-		switch v := x.v.(type) {
-		case debug.Pointer:
-			// x.d may be a typedef pointing to a pointer type (or a typedef pointing
-			// to a typedef pointing to a pointer type, etc.), so remove typedefs
-			// until we get the underlying pointer type.
-			t := followTypedefs(x.d)
-			if pt, ok := t.(*dwarf.PtrType); ok {
-				return e.resultFrom(v.Address, pt.Type, getAddress)
-			} else {
-				return e.err("invalid DWARF type for pointer")
-			}
-		case pointerToValue:
-			return e.resultFrom(v.a, x.d, getAddress)
-		case nil:
-			return x
-		}
-		return e.err("invalid indirect")
-
-	case *ast.SelectorExpr:
-		x := e.evalNode(n.X, false)
-		sel := n.Sel.Name
-		switch v := x.v.(type) {
-		case debug.Struct:
-			for _, f := range v.Fields {
-				if f.Name == sel {
-					t, err := e.server.dwarfData.Type(dwarf.Offset(f.Var.TypeID))
-					if err != nil {
-						return e.err(err.Error())
-					}
-					return e.resultFrom(f.Var.Address, t, getAddress)
-				}
-			}
-			return e.err("struct field not found")
-		case debug.Pointer:
-			pt, ok := followTypedefs(x.d).(*dwarf.PtrType) // x.d should be a pointer to struct.
-			if !ok {
-				return e.err("invalid DWARF information for pointer")
-			}
-			st, ok := followTypedefs(pt.Type).(*dwarf.StructType)
-			if !ok {
-				break
-			}
-			for _, f := range st.Field {
-				if f.Name == sel {
-					return e.resultFrom(v.Address+uint64(f.ByteOffset), f.Type, getAddress)
-				}
-			}
-			return e.err("struct field not found")
-		case pointerToValue:
-			st, ok := followTypedefs(x.d).(*dwarf.StructType) // x.d should be a struct.
-			if !ok {
-				break
-			}
-			for _, f := range st.Field {
-				if f.Name == sel {
-					return e.resultFrom(v.a+uint64(f.ByteOffset), f.Type, getAddress)
-				}
-			}
-			return e.err("struct field not found")
-		}
-		return e.err("invalid selector expression")
-
-	case *ast.IndexExpr:
-		x, index := e.evalNode(n.X, false), e.evalNode(n.Index, false)
-		if x.v == nil || index.v == nil {
-			return result{}
-		}
-		// The expression is x[index]
-		if m, ok := x.v.(debug.Map); ok {
-			if getAddress {
-				return e.err("can't take address of map value")
-			}
-			mt, ok := followTypedefs(x.d).(*dwarf.MapType)
-			if !ok {
-				return e.err("invalid DWARF type for map")
-			}
-			var (
-				found bool   // true if the key was found
-				value result // the map value for the key
-				abort bool   // true if an error occurred while searching
-				// fn is a function that checks if one (key, value) pair corresponds
-				// to the index in the expression.
-				fn = func(keyAddr, valAddr uint64, keyType, valType dwarf.Type) bool {
-					key := e.resultFrom(keyAddr, keyType, false)
-					if key.v == nil {
-						abort = true
-						return false // stop searching map
-					}
-					equal, ok := e.evalBinaryOp(token.EQL, index, key).v.(bool)
-					if !ok {
-						abort = true
-						return false // stop searching map
-					}
-					if equal {
-						found = true
-						value = e.resultFrom(valAddr, valType, false)
-						return false // stop searching map
-					}
-					return true // continue searching map
-				}
-			)
-			if err := e.server.peekMapValues(mt, m.Address, fn); err != nil {
-				return e.err(err.Error())
-			}
-			if abort {
-				// Some operation on individual map keys failed.
-				return result{}
-			}
-			if found {
-				return value
-			}
-			// The key wasn't in the map; return the zero value.
-			return e.zero(mt.ElemType)
-		}
-
-		// The index should be a non-negative integer for the remaining cases.
-		u, err := uint64FromResult(index)
-		if err != nil {
-			return e.err("invalid index: " + err.Error())
-		}
-		switch v := x.v.(type) {
-		case debug.Array:
-			if u >= v.Length {
-				return e.err("array index out of bounds")
-			}
-			elemType, err := e.server.dwarfData.Type(dwarf.Offset(v.ElementTypeID))
-			if err != nil {
-				return e.err(err.Error())
-			}
-			return e.resultFrom(v.Element(u).Address, elemType, getAddress)
-		case debug.Slice:
-			if u >= v.Length {
-				return e.err("slice index out of bounds")
-			}
-			elemType, err := e.server.dwarfData.Type(dwarf.Offset(v.ElementTypeID))
-			if err != nil {
-				return e.err(err.Error())
-			}
-			return e.resultFrom(v.Element(u).Address, elemType, getAddress)
-		case sliceOf:
-			if u >= v.Length {
-				return e.err("slice index out of bounds")
-			}
-			return e.resultFrom(v.Element(u).Address, x.d, getAddress)
-		case debug.String:
-			if getAddress {
-				return e.err("can't take address of string element")
-			}
-			if u >= v.Length {
-				return e.err("string index out of bounds")
-			}
-			if u >= uint64(len(v.String)) {
-				return e.err("string element unavailable")
-			}
-			return e.uint8Result(v.String[u])
-		case untString:
-			if getAddress {
-				return e.err("can't take address of string element")
-			}
-			if u >= uint64(len(v)) {
-				return e.err("string index out of bounds")
-			}
-			return e.uint8Result(v[u])
-		}
-		return e.err("invalid index expression")
-
-	case *ast.SliceExpr:
-		if n.Slice3 && n.High == nil {
-			return e.err("middle index required in full slice")
-		}
-		if n.Slice3 && n.Max == nil {
-			return e.err("final index required in full slice")
-		}
-		var (
-			low, high, max uint64
-			err            error
-		)
-		if n.Low != nil {
-			low, err = uint64FromResult(e.evalNode(n.Low, false))
-			if err != nil {
-				return e.err("invalid slice lower bound: " + err.Error())
-			}
-		}
-		if n.High != nil {
-			high, err = uint64FromResult(e.evalNode(n.High, false))
-			if err != nil {
-				return e.err("invalid slice upper bound: " + err.Error())
-			}
-		}
-		if n.Max != nil {
-			max, err = uint64FromResult(e.evalNode(n.Max, false))
-			if err != nil {
-				return e.err("invalid slice capacity: " + err.Error())
-			}
-		}
-		x := e.evalNode(n.X, false)
-		switch v := x.v.(type) {
-		case debug.Array, debug.Pointer, pointerToValue:
-			// This case handles the slicing of arrays and pointers to arrays.
-			var arr debug.Array
-			switch v := x.v.(type) {
-			case debug.Array:
-				arr = v
-			case debug.Pointer:
-				pt, ok := followTypedefs(x.d).(*dwarf.PtrType)
-				if !ok {
-					return e.err("invalid DWARF type for pointer")
-				}
-				a := e.resultFrom(v.Address, pt.Type, false)
-				arr, ok = a.v.(debug.Array)
-				if !ok {
-					// v is a pointer to something other than an array.
-					return e.err("cannot slice pointer")
-				}
-			case pointerToValue:
-				a := e.resultFrom(v.a, x.d, false)
-				var ok bool
-				arr, ok = a.v.(debug.Array)
-				if !ok {
-					// v is a pointer to something other than an array.
-					return e.err("cannot slice pointer")
-				}
-			}
-			elemType, err := e.server.dwarfData.Type(dwarf.Offset(arr.ElementTypeID))
-			if err != nil {
-				return e.err(err.Error())
-			}
-			if n.High == nil {
-				high = arr.Length
-			} else if high > arr.Length {
-				return e.err("slice upper bound is too large")
-			}
-			if n.Max == nil {
-				max = arr.Length
-			} else if max > arr.Length {
-				return e.err("slice capacity is too large")
-			}
-			if low > high || high > max {
-				return e.err("invalid slice index")
-			}
-			return result{
-				d: elemType,
-				v: sliceOf{
-					Array: debug.Array{
-						ElementTypeID: arr.ElementTypeID,
-						Address:       arr.Element(low).Address,
-						Length:        high - low,
-						StrideBits:    uint64(elemType.Common().ByteSize) * 8,
-					},
-					Capacity: max - low,
-				},
-			}
-		case debug.Slice:
-			if n.High == nil {
-				high = v.Length
-			} else if high > v.Capacity {
-				return e.err("slice upper bound is too large")
-			}
-			if n.Max == nil {
-				max = v.Capacity
-			} else if max > v.Capacity {
-				return e.err("slice capacity is too large")
-			}
-			if low > high || high > max {
-				return e.err("invalid slice index")
-			}
-			v.Address += low * (v.StrideBits / 8)
-			v.Length = high - low
-			v.Capacity = max - low
-			return result{x.d, v}
-		case sliceOf:
-			if n.High == nil {
-				high = v.Length
-			} else if high > v.Capacity {
-				return e.err("slice upper bound is too large")
-			}
-			if n.Max == nil {
-				max = v.Capacity
-			} else if max > v.Capacity {
-				return e.err("slice capacity is too large")
-			}
-			if low > high || high > max {
-				return e.err("invalid slice index")
-			}
-			v.Address += low * (v.StrideBits / 8)
-			v.Length = high - low
-			v.Capacity = max - low
-			return result{x.d, v}
-		case debug.String:
-			if n.Max != nil {
-				return e.err("full slice of string")
-			}
-			if n.High == nil {
-				high = v.Length
-			}
-			if low > high || high > v.Length {
-				return e.err("invalid slice index")
-			}
-			v.Length = high - low
-			if low > uint64(len(v.String)) {
-				// v.String was truncated before the point where this slice starts.
-				v.String = ""
-			} else {
-				if high > uint64(len(v.String)) {
-					// v.String was truncated before the point where this slice ends.
-					high = uint64(len(v.String))
-				}
-				v.String = v.String[low:high]
-			}
-			return result{x.d, v}
-		case untString:
-			if n.Max != nil {
-				return e.err("full slice of string")
-			}
-			if n.High == nil {
-				high = uint64(len(v))
-			}
-			if low > high {
-				return e.err("invalid slice expression")
-			}
-			if high > uint64(len(v)) {
-				return e.err("slice upper bound is too large")
-			}
-			return e.stringResult(string(v[low:high]))
-		default:
-			return e.err("invalid slice expression")
-		}
-
-	case *ast.CallExpr:
-		// Only supports lookup("x"), which gets the value of a global symbol x.
-		fun := e.evalNode(n.Fun, false)
-		var args []result
-		for _, a := range n.Args {
-			args = append(args, e.evalNode(a, false))
-		}
-		if fun.v == identLookup {
-			if len(args) != 1 {
-				return e.err("lookup should have one argument")
-			}
-			ident, ok := args[0].v.(untString)
-			if !ok {
-				return e.err("argument for lookup should be a string constant")
-			}
-			if a, t := e.server.findGlobalVar(string(ident)); t == nil {
-				return e.err("symbol not found")
-			} else {
-				return e.resultFrom(a, t, getAddress)
-			}
-		}
-		return e.err("function calls not implemented")
-
-	case *ast.UnaryExpr:
-		if n.Op == token.AND {
-			x := e.evalNode(n.X, true)
-			switch v := x.v.(type) {
-			case addressableValue:
-				return result{x.d, pointerToValue{v.a}}
-			case nil:
-				return x
-			}
-			return e.err("can't take address")
-		}
-
-		x := e.evalNode(n.X, false)
-		if x.v == nil {
-			return x
-		}
-		switch v := x.v.(type) {
-
-		case int8:
-			switch n.Op {
-			case token.ADD:
-			case token.SUB:
-				v = -v
-			case token.XOR:
-				v = ^v
-			default:
-				return e.err("invalid operation")
-			}
-			return result{x.d, v}
-
-		case int16:
-			switch n.Op {
-			case token.ADD:
-			case token.SUB:
-				v = -v
-			case token.XOR:
-				v = ^v
-			default:
-				return e.err("invalid operation")
-			}
-			return result{x.d, v}
-
-		case int32:
-			switch n.Op {
-			case token.ADD:
-			case token.SUB:
-				v = -v
-			case token.XOR:
-				v = ^v
-			default:
-				return e.err("invalid operation")
-			}
-			return result{x.d, v}
-
-		case int64:
-			switch n.Op {
-			case token.ADD:
-			case token.SUB:
-				v = -v
-			case token.XOR:
-				v = ^v
-			default:
-				return e.err("invalid operation")
-			}
-			return result{x.d, v}
-
-		case uint8:
-			switch n.Op {
-			case token.ADD:
-			case token.SUB:
-				v = -v
-			case token.XOR:
-				v = ^v
-			default:
-				return e.err("invalid operation")
-			}
-			return result{x.d, v}
-
-		case uint16:
-			switch n.Op {
-			case token.ADD:
-			case token.SUB:
-				v = -v
-			case token.XOR:
-				v = ^v
-			default:
-				return e.err("invalid operation")
-			}
-			return result{x.d, v}
-
-		case uint32:
-			switch n.Op {
-			case token.ADD:
-			case token.SUB:
-				v = -v
-			case token.XOR:
-				v = ^v
-			default:
-				return e.err("invalid operation")
-			}
-			return result{x.d, v}
-
-		case uint64:
-			switch n.Op {
-			case token.ADD:
-			case token.SUB:
-				v = -v
-			case token.XOR:
-				v = ^v
-			default:
-				return e.err("invalid operation")
-			}
-			return result{x.d, v}
-
-		case float32:
-			switch n.Op {
-			case token.ADD:
-			case token.SUB:
-				v = -v
-			default:
-				return e.err("invalid operation")
-			}
-			return result{x.d, v}
-
-		case float64:
-			switch n.Op {
-			case token.ADD:
-			case token.SUB:
-				v = -v
-			default:
-				return e.err("invalid operation")
-			}
-			return result{x.d, v}
-
-		case complex64:
-			switch n.Op {
-			case token.ADD:
-			case token.SUB:
-				v = -v
-			default:
-				return e.err("invalid operation")
-			}
-			return result{x.d, v}
-
-		case complex128:
-			switch n.Op {
-			case token.ADD:
-			case token.SUB:
-				v = -v
-			default:
-				return e.err("invalid operation")
-			}
-			return result{x.d, v}
-
-		case untInt:
-			switch n.Op {
-			case token.ADD:
-			case token.SUB:
-				v.Int.Neg(v.Int)
-			case token.XOR:
-				v.Int.Not(v.Int)
-			default:
-				return e.err("invalid operation")
-			}
-			return result{x.d, v}
-
-		case untRune:
-			switch n.Op {
-			case token.ADD:
-			case token.SUB:
-				v.Int.Neg(v.Int)
-			case token.XOR:
-				v.Int.Not(v.Int)
-			default:
-				return e.err("invalid operation")
-			}
-			return result{x.d, v}
-
-		case untFloat:
-			switch n.Op {
-			case token.ADD:
-			case token.SUB:
-				v.Float.Neg(v.Float)
-			default:
-				return e.err("invalid operation")
-			}
-			return result{x.d, v}
-
-		case untComplex:
-			switch n.Op {
-			case token.ADD:
-			case token.SUB:
-				v.r.Neg(v.r)
-				v.i.Neg(v.i)
-			default:
-				return e.err("invalid operation")
-			}
-			return result{x.d, v}
-
-		case bool:
-			switch n.Op {
-			case token.NOT:
-				v = !v
-			default:
-				return e.err("invalid operation")
-			}
-			return result{x.d, v}
-		}
-
-	case *ast.BinaryExpr:
-		x := e.evalNode(n.X, false)
-		if x.v == nil {
-			return x
-		}
-		y := e.evalNode(n.Y, false)
-		if y.v == nil {
-			return y
-		}
-		return e.evalBinaryOp(n.Op, x, y)
-	}
-	return e.err("invalid expression")
-}
-
-// evalBinaryOp evaluates a binary operator op applied to x and y.
-func (e *evaluator) evalBinaryOp(op token.Token, x, y result) result {
-	if op == token.NEQ {
-		tmp := e.evalBinaryOp(token.EQL, x, y)
-		b, ok := tmp.v.(bool)
-		if !ok {
-			return tmp
-		}
-		return result{nil, !b}
-	}
-	if op == token.GTR {
-		return e.evalBinaryOp(token.LSS, y, x)
-	}
-	if op == token.GEQ {
-		return e.evalBinaryOp(token.LEQ, x, y)
-	}
-
-	x = convertUntyped(x, y)
-	y = convertUntyped(y, x)
-
-	switch a := x.v.(type) {
-
-	case int8:
-		b, ok := y.v.(int8)
-		if !ok {
-			return e.err("type mismatch")
-		}
-		var c int8
-		switch op {
-		case token.EQL:
-			return result{nil, a == b}
-		case token.LSS:
-			return result{nil, a < b}
-		case token.LEQ:
-			return result{nil, a <= b}
-		case token.ADD:
-			c = a + b
-		case token.SUB:
-			c = a - b
-		case token.OR:
-			c = a | b
-		case token.XOR:
-			c = a ^ b
-		case token.MUL:
-			c = a * b
-		case token.QUO:
-			if b == 0 {
-				return e.err("integer divide by zero")
-			}
-			c = a / b
-		case token.REM:
-			if b == 0 {
-				return e.err("integer divide by zero")
-			}
-			c = a % b
-		case token.AND:
-			c = a & b
-		case token.AND_NOT:
-			c = a &^ b
-		default:
-			return e.err("invalid operation")
-		}
-		return result{x.d, c}
-
-	case int16:
-		b, ok := y.v.(int16)
-		if !ok {
-			return e.err("type mismatch")
-		}
-		var c int16
-		switch op {
-		case token.EQL:
-			return result{nil, a == b}
-		case token.LSS:
-			return result{nil, a < b}
-		case token.LEQ:
-			return result{nil, a <= b}
-		case token.ADD:
-			c = a + b
-		case token.SUB:
-			c = a - b
-		case token.OR:
-			c = a | b
-		case token.XOR:
-			c = a ^ b
-		case token.MUL:
-			c = a * b
-		case token.QUO:
-			if b == 0 {
-				return e.err("integer divide by zero")
-			}
-			c = a / b
-		case token.REM:
-			if b == 0 {
-				return e.err("integer divide by zero")
-			}
-			c = a % b
-		case token.AND:
-			c = a & b
-		case token.AND_NOT:
-			c = a &^ b
-		default:
-			return e.err("invalid operation")
-		}
-		return result{x.d, c}
-
-	case int32:
-		b, ok := y.v.(int32)
-		if !ok {
-			return e.err("type mismatch")
-		}
-		var c int32
-		switch op {
-		case token.EQL:
-			return result{nil, a == b}
-		case token.LSS:
-			return result{nil, a < b}
-		case token.LEQ:
-			return result{nil, a <= b}
-		case token.ADD:
-			c = a + b
-		case token.SUB:
-			c = a - b
-		case token.OR:
-			c = a | b
-		case token.XOR:
-			c = a ^ b
-		case token.MUL:
-			c = a * b
-		case token.QUO:
-			if b == 0 {
-				return e.err("integer divide by zero")
-			}
-			c = a / b
-		case token.REM:
-			if b == 0 {
-				return e.err("integer divide by zero")
-			}
-			c = a % b
-		case token.AND:
-			c = a & b
-		case token.AND_NOT:
-			c = a &^ b
-		default:
-			return e.err("invalid operation")
-		}
-		return result{x.d, c}
-
-	case int64:
-		b, ok := y.v.(int64)
-		if !ok {
-			return e.err("type mismatch")
-		}
-		var c int64
-		switch op {
-		case token.EQL:
-			return result{nil, a == b}
-		case token.LSS:
-			return result{nil, a < b}
-		case token.LEQ:
-			return result{nil, a <= b}
-		case token.ADD:
-			c = a + b
-		case token.SUB:
-			c = a - b
-		case token.OR:
-			c = a | b
-		case token.XOR:
-			c = a ^ b
-		case token.MUL:
-			c = a * b
-		case token.QUO:
-			if b == 0 {
-				return e.err("integer divide by zero")
-			}
-			c = a / b
-		case token.REM:
-			if b == 0 {
-				return e.err("integer divide by zero")
-			}
-			c = a % b
-		case token.AND:
-			c = a & b
-		case token.AND_NOT:
-			c = a &^ b
-		default:
-			return e.err("invalid operation")
-		}
-		return result{x.d, c}
-
-	case uint8:
-		b, ok := y.v.(uint8)
-		if !ok {
-			return e.err("type mismatch")
-		}
-		var c uint8
-		switch op {
-		case token.EQL:
-			return result{nil, a == b}
-		case token.LSS:
-			return result{nil, a < b}
-		case token.LEQ:
-			return result{nil, a <= b}
-		case token.ADD:
-			c = a + b
-		case token.SUB:
-			c = a - b
-		case token.OR:
-			c = a | b
-		case token.XOR:
-			c = a ^ b
-		case token.MUL:
-			c = a * b
-		case token.QUO:
-			if b == 0 {
-				return e.err("integer divide by zero")
-			}
-			c = a / b
-		case token.REM:
-			if b == 0 {
-				return e.err("integer divide by zero")
-			}
-			c = a % b
-		case token.AND:
-			c = a & b
-		case token.AND_NOT:
-			c = a &^ b
-		default:
-			return e.err("invalid operation")
-		}
-		return result{x.d, c}
-
-	case uint16:
-		b, ok := y.v.(uint16)
-		if !ok {
-			return e.err("type mismatch")
-		}
-		var c uint16
-		switch op {
-		case token.EQL:
-			return result{nil, a == b}
-		case token.LSS:
-			return result{nil, a < b}
-		case token.LEQ:
-			return result{nil, a <= b}
-		case token.ADD:
-			c = a + b
-		case token.SUB:
-			c = a - b
-		case token.OR:
-			c = a | b
-		case token.XOR:
-			c = a ^ b
-		case token.MUL:
-			c = a * b
-		case token.QUO:
-			if b == 0 {
-				return e.err("integer divide by zero")
-			}
-			c = a / b
-		case token.REM:
-			if b == 0 {
-				return e.err("integer divide by zero")
-			}
-			c = a % b
-		case token.AND:
-			c = a & b
-		case token.AND_NOT:
-			c = a &^ b
-		default:
-			return e.err("invalid operation")
-		}
-		return result{x.d, c}
-
-	case uint32:
-		b, ok := y.v.(uint32)
-		if !ok {
-			return e.err("type mismatch")
-		}
-		var c uint32
-		switch op {
-		case token.EQL:
-			return result{nil, a == b}
-		case token.LSS:
-			return result{nil, a < b}
-		case token.LEQ:
-			return result{nil, a <= b}
-		case token.ADD:
-			c = a + b
-		case token.SUB:
-			c = a - b
-		case token.OR:
-			c = a | b
-		case token.XOR:
-			c = a ^ b
-		case token.MUL:
-			c = a * b
-		case token.QUO:
-			if b == 0 {
-				return e.err("integer divide by zero")
-			}
-			c = a / b
-		case token.REM:
-			if b == 0 {
-				return e.err("integer divide by zero")
-			}
-			c = a % b
-		case token.AND:
-			c = a & b
-		case token.AND_NOT:
-			c = a &^ b
-		default:
-			return e.err("invalid operation")
-		}
-		return result{x.d, c}
-
-	case uint64:
-		b, ok := y.v.(uint64)
-		if !ok {
-			return e.err("type mismatch")
-		}
-		var c uint64
-		switch op {
-		case token.EQL:
-			return result{nil, a == b}
-		case token.LSS:
-			return result{nil, a < b}
-		case token.LEQ:
-			return result{nil, a <= b}
-		case token.ADD:
-			c = a + b
-		case token.SUB:
-			c = a - b
-		case token.OR:
-			c = a | b
-		case token.XOR:
-			c = a ^ b
-		case token.MUL:
-			c = a * b
-		case token.QUO:
-			if b == 0 {
-				return e.err("integer divide by zero")
-			}
-			c = a / b
-		case token.REM:
-			if b == 0 {
-				return e.err("integer divide by zero")
-			}
-			c = a % b
-		case token.AND:
-			c = a & b
-		case token.AND_NOT:
-			c = a &^ b
-		default:
-			return e.err("invalid operation")
-		}
-		return result{x.d, c}
-
-	case float32:
-		b, ok := y.v.(float32)
-		if !ok {
-			return e.err("type mismatch")
-		}
-		var c float32
-		switch op {
-		case token.EQL:
-			return result{nil, a == b}
-		case token.LSS:
-			return result{nil, a < b}
-		case token.LEQ:
-			return result{nil, a <= b}
-		case token.ADD:
-			c = a + b
-		case token.SUB:
-			c = a - b
-		case token.MUL:
-			c = a * b
-		case token.QUO:
-			c = a / b
-		default:
-			return e.err("invalid operation")
-		}
-		return result{x.d, c}
-
-	case float64:
-		b, ok := y.v.(float64)
-		if !ok {
-			return e.err("type mismatch")
-		}
-		var c float64
-		switch op {
-		case token.EQL:
-			return result{nil, a == b}
-		case token.LSS:
-			return result{nil, a < b}
-		case token.LEQ:
-			return result{nil, a <= b}
-		case token.ADD:
-			c = a + b
-		case token.SUB:
-			c = a - b
-		case token.MUL:
-			c = a * b
-		case token.QUO:
-			c = a / b
-		default:
-			return e.err("invalid operation")
-		}
-		return result{x.d, c}
-
-	case complex64:
-		b, ok := y.v.(complex64)
-		if !ok {
-			return e.err("type mismatch")
-		}
-		var c complex64
-		switch op {
-		case token.EQL:
-			return result{nil, a == b}
-		case token.ADD:
-			c = a + b
-		case token.SUB:
-			c = a - b
-		case token.MUL:
-			c = a * b
-		case token.QUO:
-			c = a / b
-		default:
-			return e.err("invalid operation")
-		}
-		return result{x.d, c}
-
-	case complex128:
-		b, ok := y.v.(complex128)
-		if !ok {
-			return e.err("type mismatch")
-		}
-		var c complex128
-		switch op {
-		case token.EQL:
-			return result{nil, a == b}
-		case token.ADD:
-			c = a + b
-		case token.SUB:
-			c = a - b
-		case token.MUL:
-			c = a * b
-		case token.QUO:
-			c = a / b
-		default:
-			return e.err("invalid operation")
-		}
-		return result{x.d, c}
-
-	case bool:
-		b, ok := y.v.(bool)
-		if !ok {
-			return e.err("type mismatch")
-		}
-		var c bool
-		switch op {
-		case token.LOR:
-			c = a || b
-		case token.LAND:
-			c = a && b
-		case token.EQL:
-			c = a == b
-		default:
-			return e.err("invalid operation")
-		}
-		return result{x.d, c}
-
-	case debug.String:
-		b, ok := y.v.(debug.String)
-		if !ok {
-			return e.err("type mismatch")
-		}
-		var c debug.String
-		switch op {
-		// TODO: these comparison operators only use the part of the string that
-		// was read.  Very large strings do not have their entire contents read by
-		// server.value.
-		case token.EQL:
-			return result{nil, a.Length == b.Length && a.String == b.String}
-		case token.LSS:
-			return result{nil, a.String < b.String}
-		case token.LEQ:
-			return result{nil, a.String <= b.String}
-		case token.ADD:
-			c.Length = a.Length + b.Length
-			if a.Length == uint64(len(a.String)) {
-				c.String = a.String + b.String
-			} else {
-				// The first string was truncated at a.Length characters, so the sum
-				// must be truncated there too.
-				c.String = a.String
-			}
-		default:
-			return e.err("invalid operation")
-		}
-		return result{x.d, c}
-
-	case untString:
-		b, ok := y.v.(untString)
-		if !ok {
-			return e.err("type mismatch")
-		}
-		var c untString
-		switch op {
-		case token.EQL:
-			return result{nil, a == b}
-		case token.LSS:
-			return result{nil, a < b}
-		case token.LEQ:
-			return result{nil, a <= b}
-		case token.ADD:
-			c = a + b
-		default:
-			return e.err("invalid operation")
-		}
-		return result{x.d, c}
-
-	case untInt:
-		i := a.Int
-		b, ok := y.v.(untInt)
-		if !ok {
-			return e.err("type mismatch")
-		}
-		switch op {
-		case token.EQL:
-			return result{nil, i.Cmp(b.Int) == 0}
-		case token.LSS:
-			return result{nil, i.Cmp(b.Int) < 0}
-		case token.LEQ:
-			return result{nil, i.Cmp(b.Int) <= 0}
-		}
-		c := new(big.Int)
-		switch op {
-		case token.ADD:
-			c.Add(i, b.Int)
-		case token.SUB:
-			c.Sub(i, b.Int)
-		case token.OR:
-			c.Or(i, b.Int)
-		case token.XOR:
-			c.Xor(i, b.Int)
-		case token.MUL:
-			c.Mul(i, b.Int)
-		case token.QUO:
-			if b.Sign() == 0 {
-				return e.err("integer divide by zero")
-			}
-			c.Quo(i, b.Int)
-		case token.REM:
-			if b.Sign() == 0 {
-				return e.err("integer divide by zero")
-			}
-			c.Mod(i, b.Int)
-		case token.AND:
-			c.And(i, b.Int)
-		case token.AND_NOT:
-			c.AndNot(i, b.Int)
-		default:
-			return e.err("invalid operation")
-		}
-		return result{nil, untInt{c}}
-
-	case untRune:
-		i := a.Int
-		b, ok := y.v.(untRune)
-		if !ok {
-			return e.err("type mismatch")
-		}
-		switch op {
-		case token.EQL:
-			return result{nil, i.Cmp(b.Int) == 0}
-		case token.LSS:
-			return result{nil, i.Cmp(b.Int) < 0}
-		case token.LEQ:
-			return result{nil, i.Cmp(b.Int) <= 0}
-		}
-		c := new(big.Int)
-		switch op {
-		case token.ADD:
-			c.Add(i, b.Int)
-		case token.SUB:
-			c.Sub(i, b.Int)
-		case token.OR:
-			c.Or(i, b.Int)
-		case token.XOR:
-			c.Xor(i, b.Int)
-		case token.MUL:
-			c.Mul(i, b.Int)
-		case token.QUO:
-			if b.Sign() == 0 {
-				return e.err("integer divide by zero")
-			}
-			c.Quo(i, b.Int)
-		case token.REM:
-			if b.Sign() == 0 {
-				return e.err("integer divide by zero")
-			}
-			c.Mod(i, b.Int)
-		case token.AND:
-			c.And(i, b.Int)
-		case token.AND_NOT:
-			c.AndNot(i, b.Int)
-		default:
-			return e.err("invalid operation")
-		}
-		return result{nil, untRune{c}}
-
-	case untFloat:
-		r := a.Float
-		b, ok := y.v.(untFloat)
-		if !ok {
-			return e.err("type mismatch")
-		}
-		switch op {
-		case token.EQL:
-			return result{nil, r.Cmp(b.Float) == 0}
-		case token.LSS:
-			return result{nil, r.Cmp(b.Float) < 0}
-		case token.LEQ:
-			return result{nil, r.Cmp(b.Float) <= 0}
-		}
-		c := new(big.Float)
-		switch op {
-		case token.ADD:
-			c.Add(r, b.Float)
-		case token.SUB:
-			c.Sub(r, b.Float)
-		case token.MUL:
-			c.Mul(r, b.Float)
-		case token.QUO:
-			if b.Sign() == 0 {
-				return e.err("divide by zero")
-			}
-			c.Quo(r, b.Float)
-		default:
-			return e.err("invalid operation")
-		}
-		return result{nil, untFloat{c}}
-
-	case untComplex:
-		b, ok := y.v.(untComplex)
-		if !ok {
-			return e.err("type mismatch")
-		}
-		var (
-			ar = a.r
-			br = b.r
-			ai = a.i
-			bi = b.i
-		)
-		if op == token.EQL {
-			return result{nil, ar.Cmp(br) == 0 && ai.Cmp(bi) == 0}
-		}
-		var (
-			cr = new(big.Float)
-			ci = new(big.Float)
-		)
-		switch op {
-		case token.ADD:
-			cr.Add(ar, br)
-			ci.Add(ai, bi)
-		case token.SUB:
-			cr.Sub(ar, br)
-			ci.Sub(ai, bi)
-		case token.MUL:
-			var t0, t1 big.Float
-			t0.Mul(ar, br)
-			t1.Mul(ai, bi)
-			cr.Sub(&t0, &t1)
-			t0.Mul(ar, bi)
-			t1.Mul(ai, br)
-			ci.Add(&t0, &t1)
-		case token.QUO:
-			// a/b = a*conj(b)/|b|^2
-			var t0, t1 big.Float
-			cr.Mul(ar, br)
-			t0.Mul(ai, bi)
-			cr.Add(cr, &t0) // cr = Re(a*conj(b))
-			ci.Mul(ai, br)
-			t0.Mul(ar, bi)
-			ci.Sub(ci, &t0) // ci = Im(a*conj(b))
-			t0.Mul(br, br)
-			t1.Mul(bi, bi)
-			t0.Add(&t0, &t1) // t0 = |b|^2
-			if t0.Sign() == 0 {
-				return e.err("divide by zero")
-			}
-			cr.Quo(cr, &t0) // cr = Re(a*conj(b))/|b|^2 = Re(a/b)
-			ci.Quo(ci, &t0) // ci = Im(a*conj(b))/|b|^2 = Im(a/b)
-		}
-		return result{nil, untComplex{cr, ci}}
-	}
-
-	return e.err("invalid operation")
-}
-
-// findLocalVar finds a local variable (or function parameter) by name, and
-// returns its address and DWARF type.  It returns a nil type on failure.
-// The PC and SP are used to determine the current function and stack frame.
-func (s *Server) findLocalVar(name string, pc, sp uint64) (uint64, dwarf.Type) {
-	// Find the DWARF entry for the function at pc.
-	funcEntry, _, err := s.dwarfData.PCToFunction(uint64(pc))
-	if err != nil {
-		return 0, nil
-	}
-
-	// Compute the stack frame pointer.
-	fpOffset, err := s.dwarfData.PCToSPOffset(uint64(pc))
-	if err != nil {
-		return 0, nil
-	}
-	framePointer := sp + uint64(fpOffset)
-
-	// Check each child of the function's DWARF entry to see if it is a parameter
-	// or local variable with the right name.  If so, return its address and type.
-	r := s.dwarfData.Reader()
-	r.Seek(funcEntry.Offset)
-	for {
-		varEntry, err := r.Next()
-		if err != nil {
-			break
-		}
-		if varEntry.Tag == 0 {
-			// This tag marks the end of the function's DWARF entry's children.
-			break
-		}
-
-		// Check this entry corresponds to a local variable or function parameter,
-		// that it has the correct name, and that we can get its type and location.
-		// If so, return them.
-		if varEntry.Tag != dwarf.TagFormalParameter && varEntry.Tag != dwarf.TagVariable {
-			continue
-		}
-		varName, ok := varEntry.Val(dwarf.AttrName).(string)
-		if !ok {
-			continue
-		}
-		if varName != name {
-			continue
-		}
-		varTypeOffset, ok := varEntry.Val(dwarf.AttrType).(dwarf.Offset)
-		if !ok {
-			continue
-		}
-		varType, err := s.dwarfData.Type(varTypeOffset)
-		if err != nil {
-			continue
-		}
-		locationAttribute := varEntry.Val(dwarf.AttrLocation)
-		if locationAttribute == nil {
-			continue
-		}
-		locationDescription, ok := locationAttribute.([]uint8)
-		if !ok {
-			continue
-		}
-		frameOffset, err := evalLocation(locationDescription)
-		if err != nil {
-			continue
-		}
-		return framePointer + uint64(frameOffset), varType
-	}
-
-	return 0, nil
-}
-
-// findGlobalVar finds a global variable by name, and returns its address and
-// DWARF type.  It returns a nil type on failure.
-func (s *Server) findGlobalVar(name string) (uint64, dwarf.Type) {
-	entry, err := s.dwarfData.LookupVariable(name)
-	if err != nil {
-		return 0, nil
-	}
-	loc, err := s.dwarfData.EntryLocation(entry)
-	if err != nil {
-		return 0, nil
-	}
-	ofs, err := s.dwarfData.EntryTypeOffset(entry)
-	if err != nil {
-		return 0, nil
-	}
-	typ, err := s.dwarfData.Type(ofs)
-	if err != nil {
-		return 0, nil
-	}
-	return loc, typ
-}
-
-// intFromInteger converts an untyped integer constant to an int32 or int64,
-// depending on the int size of the debugged program.
-// It returns an error on overflow, or if it can't determine the int size.
-func (e *evaluator) intFromInteger(v untInt) (interface{}, error) {
-	t, ok := e.getBaseType("int")
-	if !ok {
-		return nil, errors.New("couldn't get int size from DWARF info")
-	}
-	switch t.Common().ByteSize {
-	case 4:
-		if v.Cmp(bigIntMaxInt32) == +1 || v.Cmp(bigIntMinInt32) == -1 {
-			return nil, errors.New("constant overflows int")
-		}
-		return int32(v.Int64()), nil
-	case 8:
-		if v.Cmp(bigIntMaxInt64) == +1 || v.Cmp(bigIntMinInt64) == -1 {
-			return nil, errors.New("constant overflows int")
-		}
-		return v.Int64(), nil
-	}
-	return nil, errors.New("invalid int size in DWARF info")
-}
-
-// uint8Result constructs a result for a uint8 value.
-func (e *evaluator) uint8Result(v uint8) result {
-	t, ok := e.getBaseType("uint8")
-	if !ok {
-		e.err("couldn't construct uint8")
-	}
-	return result{t, uint8(v)}
-}
-
-// stringResult constructs a result for a string value.
-func (e *evaluator) stringResult(s string) result {
-	t, ok := e.getBaseType("string")
-	if !ok {
-		e.err("couldn't construct string")
-	}
-	return result{t, debug.String{Length: uint64(len(s)), String: s}}
-}
-
-// getBaseType returns the *dwarf.Type with a given name.
-// TODO: cache this.
-func (e *evaluator) getBaseType(name string) (dwarf.Type, bool) {
-	entry, err := e.server.dwarfData.LookupEntry(name)
-	if err != nil {
-		return nil, false
-	}
-	t, err := e.server.dwarfData.Type(entry.Offset)
-	if err != nil {
-		return nil, false
-	}
-	return t, true
-}
-
-// resultFrom constructs a result corresponding to a value in the program with
-// the given address and DWARF type.
-// If getAddress is true, the result will be the operand of an address expression,
-// so resultFrom returns a result containing a value of type addressableValue.
-func (e *evaluator) resultFrom(a uint64, t dwarf.Type, getAddress bool) result {
-	if a == 0 {
-		return e.err("nil pointer dereference")
-	}
-	if getAddress {
-		return result{t, addressableValue{a}}
-	}
-	v, err := e.server.value(t, a)
-	if err != nil {
-		return e.err(err.Error())
-	}
-	return result{t, v}
-}
-
-// zero returns the zero value of type t.
-// TODO: implement for array and struct.
-func (e *evaluator) zero(t dwarf.Type) result {
-	var v interface{}
-	switch typ := followTypedefs(t).(type) {
-	case *dwarf.CharType, *dwarf.IntType, *dwarf.EnumType:
-		switch typ.Common().ByteSize {
-		case 1:
-			v = int8(0)
-		case 2:
-			v = int16(0)
-		case 4:
-			v = int32(0)
-		case 8:
-			v = int64(0)
-		default:
-			return e.err("invalid integer size " + fmt.Sprint(typ.Common().ByteSize))
-		}
-	case *dwarf.UcharType, *dwarf.UintType:
-		switch typ.Common().ByteSize {
-		case 1:
-			v = uint8(0)
-		case 2:
-			v = uint16(0)
-		case 4:
-			v = uint32(0)
-		case 8:
-			v = uint64(0)
-		default:
-			return e.err("invalid unsigned integer size " + fmt.Sprint(typ.Common().ByteSize))
-		}
-	case *dwarf.FloatType:
-		switch typ.Common().ByteSize {
-		case 4:
-			v = float32(0)
-		case 8:
-			v = float64(0)
-		default:
-			return e.err("invalid float size " + fmt.Sprint(typ.Common().ByteSize))
-		}
-	case *dwarf.ComplexType:
-		switch typ.Common().ByteSize {
-		case 8:
-			v = complex64(0)
-		case 16:
-			v = complex128(0)
-		default:
-			return e.err("invalid complex size " + fmt.Sprint(typ.Common().ByteSize))
-		}
-	case *dwarf.BoolType:
-		v = false
-	case *dwarf.PtrType:
-		v = debug.Pointer{TypeID: uint64(t.Common().Offset)}
-	case *dwarf.SliceType:
-		v = debug.Slice{
-			Array: debug.Array{
-				ElementTypeID: uint64(typ.ElemType.Common().Offset),
-				StrideBits:    uint64(typ.ElemType.Common().ByteSize) * 8,
-			},
-		}
-	case *dwarf.StringType:
-		v = debug.String{}
-	case *dwarf.InterfaceType:
-		v = debug.Interface{}
-	case *dwarf.FuncType:
-		v = debug.Func{}
-	case *dwarf.MapType:
-		v = debug.Map{TypeID: uint64(t.Common().Offset)}
-	case *dwarf.ChanType:
-		v = debug.Channel{
-			ElementTypeID: uint64(typ.ElemType.Common().Offset),
-			Stride:        uint64(typ.ElemType.Common().ByteSize),
-		}
-	default:
-		return e.err("can't get zero value of this type")
-	}
-	return result{t, v}
-}
-
-// convertUntyped converts x to be the same type as y, if x is untyped and the
-// conversion is possible.
-//
-// An untyped bool can be converted to a boolean type.
-// An untyped string can be converted to a string type.
-// An untyped integer, rune, float or complex value can be converted to a
-// numeric type, or to an untyped value later in that list.
-//
-// x is returned unchanged if none of these cases apply.
-func convertUntyped(x, y result) result {
-	switch a := x.v.(type) {
-	case untInt:
-		i := a.Int
-		switch y.v.(type) {
-		case int8:
-			return result{y.d, int8(i.Int64())}
-		case int16:
-			return result{y.d, int16(i.Int64())}
-		case int32:
-			return result{y.d, int32(i.Int64())}
-		case int64:
-			return result{y.d, int64(i.Int64())}
-		case uint8:
-			return result{y.d, uint8(i.Uint64())}
-		case uint16:
-			return result{y.d, uint16(i.Uint64())}
-		case uint32:
-			return result{y.d, uint32(i.Uint64())}
-		case uint64:
-			return result{y.d, uint64(i.Uint64())}
-		case float32:
-			f, _ := new(big.Float).SetInt(i).Float32()
-			return result{y.d, f}
-		case float64:
-			f, _ := new(big.Float).SetInt(i).Float64()
-			return result{y.d, f}
-		case complex64:
-			f, _ := new(big.Float).SetInt(i).Float32()
-			return result{y.d, complex(f, 0)}
-		case complex128:
-			f, _ := new(big.Float).SetInt(i).Float64()
-			return result{y.d, complex(f, 0)}
-		case untRune:
-			return result{nil, untRune{i}}
-		case untFloat:
-			return result{nil, untFloat{new(big.Float).SetPrec(prec).SetInt(i)}}
-		case untComplex:
-			return result{nil, untComplex{new(big.Float).SetPrec(prec).SetInt(i), new(big.Float)}}
-		}
-	case untRune:
-		i := a.Int
-		switch y.v.(type) {
-		case int8:
-			return result{y.d, int8(i.Int64())}
-		case int16:
-			return result{y.d, int16(i.Int64())}
-		case int32:
-			return result{y.d, int32(i.Int64())}
-		case int64:
-			return result{y.d, int64(i.Int64())}
-		case uint8:
-			return result{y.d, uint8(i.Uint64())}
-		case uint16:
-			return result{y.d, uint16(i.Uint64())}
-		case uint32:
-			return result{y.d, uint32(i.Uint64())}
-		case uint64:
-			return result{y.d, uint64(i.Uint64())}
-		case float32:
-			f, _ := new(big.Float).SetInt(i).Float32()
-			return result{y.d, f}
-		case float64:
-			f, _ := new(big.Float).SetInt(i).Float64()
-			return result{y.d, f}
-		case complex64:
-			f, _ := new(big.Float).SetInt(i).Float32()
-			return result{y.d, complex(f, 0)}
-		case complex128:
-			f, _ := new(big.Float).SetInt(i).Float64()
-			return result{y.d, complex(f, 0)}
-		case untRune:
-			return result{nil, untRune{i}}
-		case untFloat:
-			return result{nil, untFloat{new(big.Float).SetPrec(prec).SetInt(i)}}
-		case untComplex:
-			return result{nil, untComplex{new(big.Float).SetPrec(prec).SetInt(i), new(big.Float)}}
-		}
-	case untFloat:
-		if a.IsInt() {
-			i, _ := a.Int(nil)
-			switch y.v.(type) {
-			case int8:
-				return result{y.d, int8(i.Int64())}
-			case int16:
-				return result{y.d, int16(i.Int64())}
-			case int32:
-				return result{y.d, int32(i.Int64())}
-			case int64:
-				return result{y.d, int64(i.Int64())}
-			case uint8:
-				return result{y.d, uint8(i.Uint64())}
-			case uint16:
-				return result{y.d, uint16(i.Uint64())}
-			case uint32:
-				return result{y.d, uint32(i.Uint64())}
-			case uint64:
-				return result{y.d, uint64(i.Uint64())}
-			}
-		}
-		switch y.v.(type) {
-		case float32:
-			f, _ := a.Float32()
-			return result{y.d, float32(f)}
-		case float64:
-			f, _ := a.Float64()
-			return result{y.d, float64(f)}
-		case complex64:
-			f, _ := a.Float32()
-			return result{y.d, complex(f, 0)}
-		case complex128:
-			f, _ := a.Float64()
-			return result{y.d, complex(f, 0)}
-		case untComplex:
-			return result{nil, untComplex{a.Float, new(big.Float)}}
-		}
-	case untComplex:
-		if a.i.Sign() == 0 {
-			// a is a real number.
-			if a.r.IsInt() {
-				// a is an integer.
-				i, _ := a.r.Int(nil)
-				switch y.v.(type) {
-				case int8:
-					return result{y.d, int8(i.Int64())}
-				case int16:
-					return result{y.d, int16(i.Int64())}
-				case int32:
-					return result{y.d, int32(i.Int64())}
-				case int64:
-					return result{y.d, int64(i.Int64())}
-				case uint8:
-					return result{y.d, uint8(i.Uint64())}
-				case uint16:
-					return result{y.d, uint16(i.Uint64())}
-				case uint32:
-					return result{y.d, uint32(i.Uint64())}
-				case uint64:
-					return result{y.d, uint64(i.Uint64())}
-				}
-			}
-			switch y.v.(type) {
-			case float32:
-				f, _ := a.r.Float32()
-				return result{y.d, float32(f)}
-			case float64:
-				f, _ := a.r.Float64()
-				return result{y.d, float64(f)}
-			}
-		}
-		switch y.v.(type) {
-		case complex64:
-			r, _ := a.r.Float32()
-			i, _ := a.i.Float32()
-			return result{y.d, complex(r, i)}
-		case complex128:
-			r, _ := a.r.Float64()
-			i, _ := a.i.Float64()
-			return result{y.d, complex(r, i)}
-		}
-	case bool:
-		if x.d != nil {
-			// x is a typed bool, not an untyped bool.
-			break
-		}
-		switch y.v.(type) {
-		case bool:
-			return result{y.d, bool(a)}
-		}
-	case untString:
-		switch y.v.(type) {
-		case debug.String:
-			return result{y.d, debug.String{Length: uint64(len(a)), String: string(a)}}
-		}
-	}
-	return x
-}
-
-// uint64FromResult converts a result into a uint64 for slice or index expressions.
-// It returns an error if the conversion cannot be done.
-func uint64FromResult(x result) (uint64, error) {
-	switch v := x.v.(type) {
-	case int8:
-		if v < 0 {
-			return 0, errors.New("value is negative")
-		}
-		return uint64(v), nil
-	case int16:
-		if v < 0 {
-			return 0, errors.New("value is negative")
-		}
-		return uint64(v), nil
-	case int32:
-		if v < 0 {
-			return 0, errors.New("value is negative")
-		}
-		return uint64(v), nil
-	case int64:
-		if v < 0 {
-			return 0, errors.New("value is negative")
-		}
-		return uint64(v), nil
-	case uint8:
-		return uint64(v), nil
-	case uint16:
-		return uint64(v), nil
-	case uint32:
-		return uint64(v), nil
-	case uint64:
-		return v, nil
-	case untInt:
-		if v.Int.Sign() == -1 {
-			return 0, errors.New("value is negative")
-		}
-		if v.Int.Cmp(bigIntMaxUint64) == +1 {
-			return 0, errors.New("value is too large")
-		}
-		return v.Int.Uint64(), nil
-	case untRune:
-		if v.Sign() == -1 {
-			return 0, errors.New("value is negative")
-		}
-		if v.Cmp(bigIntMaxUint64) == +1 {
-			return 0, errors.New("value is too large")
-		}
-		return v.Uint64(), nil
-	case untFloat:
-		if !v.IsInt() {
-			return 0, errors.New("value is not an integer")
-		}
-		if v.Sign() == -1 {
-			return 0, errors.New("value is negative")
-		}
-		i, _ := v.Int(nil)
-		if i.Cmp(bigIntMaxUint64) == +1 {
-			return 0, errors.New("value is too large")
-		}
-		return i.Uint64(), nil
-	case untComplex:
-		if v.i.Sign() != 0 {
-			return 0, errors.New("value is complex")
-		}
-		if !v.r.IsInt() {
-			return 0, errors.New("value is not an integer")
-		}
-		if v.r.Sign() == -1 {
-			return 0, errors.New("value is negative")
-		}
-		i, _ := v.r.Int(nil)
-		if i.Cmp(bigIntMaxUint64) == +1 {
-			return 0, errors.New("value is too large")
-		}
-		return i.Uint64(), nil
-	}
-	return 0, fmt.Errorf("cannot convert to unsigned integer")
-}
-
-// followTypedefs returns the underlying type of t, removing any typedefs.
-// If t leads to a cycle of typedefs, followTypedefs returns nil.
-func followTypedefs(t dwarf.Type) dwarf.Type {
-	// If t is a *dwarf.TypedefType, next returns t.Type, otherwise it returns t.
-	// The bool returned is true when the argument was a typedef.
-	next := func(t dwarf.Type) (dwarf.Type, bool) {
-		tt, ok := t.(*dwarf.TypedefType)
-		if !ok {
-			return t, false
-		}
-		return tt.Type, true
-	}
-	// Advance two pointers, one at twice the speed, so we can detect if we get
-	// stuck in a cycle.
-	slow, fast := t, t
-	for {
-		var wasTypedef bool
-		fast, wasTypedef = next(fast)
-		if !wasTypedef {
-			return fast
-		}
-		fast, wasTypedef = next(fast)
-		if !wasTypedef {
-			return fast
-		}
-		slow, _ = next(slow)
-		if slow == fast {
-			return nil
-		}
-	}
-}
diff --git a/server/eval.m4 b/server/eval.m4
deleted file mode 100644
index 7b7594a..0000000
--- a/server/eval.m4
+++ /dev/null
@@ -1,1711 +0,0 @@
-// Copyright 2015 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.
-//m4_changequote(`@',`@')
-// Evaluates Go expressions, using the current values of variables in a program
-// being debugged.
-//
-// TODOs:
-// More overflow checking.
-// Stricter type checking.
-// More expression types.
-
-package server
-
-import (
-	"errors"
-	"fmt"
-	"go/ast"
-	"go/parser"
-	"go/token"
-	"math"
-	"math/big"
-
-	"golang.org/x/debug"
-	"golang.org/x/debug/dwarf"
-)
-
-const prec = 256 // precision for untyped float and complex constants.
-
-var (
-	// Some big.Ints to use in overflow checks.
-	bigIntMaxInt32  = big.NewInt(math.MaxInt32)
-	bigIntMinInt32  = big.NewInt(math.MinInt32)
-	bigIntMaxInt64  = big.NewInt(math.MaxInt64)
-	bigIntMinInt64  = big.NewInt(math.MinInt64)
-	bigIntMaxUint64 = new(big.Int).SetUint64(math.MaxUint64)
-)
-
-// result stores an intermediate value produced during evaluation of an expression.
-//
-// d contains the DWARF type of the value.  For untyped values, d will be nil.
-//
-// v contains the value itself.  For numeric and bool types, v will have the
-// corresponding predeclared Go type.
-// For untyped integer, rune, float, complex, string, and bool constants, v will
-// have type untInt, untRune, untFloat, untComplex, untString, or bool,
-// respectively.
-// For values of type int, uint and uintptr, v will be an int32, int64, uint32
-// or uint64 as appropriate.
-// For address operations, v will have type pointerToValue.
-// For the operands of address operations, v will have type addressableValue.
-// Other types are represented using the corresponding implementation of
-// debug.Value in program.go.
-//
-// If an evaluation results in an error, the zero value of result is used.
-type result struct {
-	d dwarf.Type
-	v interface{}
-}
-
-// untInt is an untyped integer constant
-type untInt struct {
-	*big.Int
-}
-
-// untRune is an untyped rune constant
-type untRune struct {
-	*big.Int
-}
-
-// untFloat is an untyped floating-point constant
-type untFloat struct {
-	*big.Float
-}
-
-// untComplex is an untyped complex constant
-type untComplex struct {
-	r *big.Float
-	i *big.Float
-}
-
-// untString is an untyped string constant
-type untString string
-
-// pointerToValue is a pointer to a value in memory.
-// The evaluator constructs these as the result of address operations like "&x".
-// Unlike debug.Pointer, the DWARF type stored alongside values of this type
-// is the type of the variable, not the type of the pointer.
-type pointerToValue struct {
-	a uint64
-}
-
-// addressableValue is the memory location of a value.
-// The evaluator constructs these while evaluating the operands of address
-// operations like "&x", instead of computing the value of x itself.
-type addressableValue struct {
-	a uint64
-}
-
-// A sliceOf is a slice created by slicing an array.
-// Unlike debug.Slice, the DWARF type stored alongside a value of this type is
-// the type of the slice's elements, not the type of the slice.
-type sliceOf debug.Slice
-
-// ident is a value for representing a special identifier.
-type ident string
-
-// identLookup is a built-in function of the expression evaluator which gets the
-// value of a global symbol.
-var identLookup ident = "lookup"
-
-// evalExpression evaluates a Go expression.
-// If the program counter and stack pointer are nonzero, they are used to determine
-// what local variables are available and where in memory they are.
-func (s *Server) evalExpression(expression string, pc, sp uint64) (debug.Value, error) {
-	e := evaluator{server: s, expression: expression, pc: pc, sp: sp}
-	node, err := parser.ParseExpr(expression)
-	if err != nil {
-		return nil, err
-	}
-	val := e.evalNode(node, false)
-	if e.evalError != nil {
-		return nil, e.evalError
-	}
-
-	// Convert untyped constants to their default types.
-	switch v := val.v.(type) {
-	case untInt:
-		return e.intFromInteger(v)
-	case untRune:
-		if v.Cmp(bigIntMaxInt32) == +1 {
-			return nil, errors.New("constant overflows rune")
-		}
-		if v.Cmp(bigIntMinInt32) == -1 {
-			return nil, errors.New("constant overflows rune")
-		}
-		return int32(v.Int64()), nil
-	case untFloat:
-		f, _ := v.Float64()
-		if math.IsInf(f, 0) {
-			return nil, errors.New("constant overflows float64")
-		}
-		if math.IsNaN(f) {
-			return nil, errors.New("constant is NaN")
-		}
-		return f, nil
-	case untComplex:
-		r, _ := v.r.Float64()
-		i, _ := v.i.Float64()
-		if math.IsInf(r, 0) || math.IsInf(i, 0) {
-			return nil, errors.New("constant overflows complex128")
-		}
-		if math.IsNaN(r) || math.IsNaN(i) {
-			return nil, errors.New("constant is NaN")
-		}
-		return complex(r, i), nil
-	case untString:
-		return debug.String{Length: uint64(len(v)), String: string(v)}, nil
-	case pointerToValue:
-		return debug.Pointer{TypeID: uint64(val.d.Common().Offset), Address: v.a}, nil
-	case sliceOf:
-		return debug.Slice(v), nil
-	case nil, addressableValue:
-		// This case should not be reachable.
-		return nil, errors.New("unknown error")
-	}
-	return val.v, nil
-}
-
-type evaluator struct {
-	// expression is the expression being evaluated.
-	expression string
-	// server interacts with the program being debugged.
-	server *Server
-	// curNode is the current parse tree node.  This is set so that error messages
-	// can quote the part of the expression that caused an error.
-	curNode ast.Node
-	// evalError is the first error that occurred while evaluating the expression,
-	// or nil if no error has occurred.
-	evalError error
-	// pc and sp are the current program counter and stack pointer, used for
-	// finding local variables.  If either are zero, the expression is evaluated
-	// without using local variables.
-	pc uint64
-	sp uint64
-}
-
-// setNode sets curNode, and returns curNode's previous value.
-func (e *evaluator) setNode(node ast.Node) (old ast.Node) {
-	old, e.curNode = e.curNode, node
-	return old
-}
-
-// err saves an error that occurred during evaluation.
-// It returns a zero result, so that functions can exit and set an error with
-//	return e.err(...)
-func (e *evaluator) err(s string) result {
-	if e.evalError != nil {
-		return result{}
-	}
-	// Append the substring of the expression that corresponds to the current AST node.
-	start := int(e.curNode.Pos() - 1)
-	end := int(e.curNode.End() - 1)
-	if start < 0 {
-		start = 0
-	}
-	if end > len(e.expression) {
-		end = len(e.expression)
-	}
-	if start > end {
-		start, end = 0, 0
-	}
-	e.evalError = errors.New(s + `: "` + e.expression[start:end] + `"`)
-	return result{}
-}
-
-// evalNode computes the value of a node in the expression tree.
-// If getAddress is true, the node is the argument of an & operator, so evalNode
-// will return a result with a value of type addressableValue if possible.
-func (e *evaluator) evalNode(node ast.Node, getAddress bool) result {
-	// Set the current node in the evaluator, so that error messages can refer to
-	// it.  Defer a function call that changes it back.
-	defer e.setNode(e.setNode(node))
-
-	switch n := node.(type) {
-	case *ast.Ident:
-		if e.pc != 0 && e.sp != 0 {
-			a, t := e.server.findLocalVar(n.Name, e.pc, e.sp)
-			if t != nil {
-				return e.resultFrom(a, t, getAddress)
-			}
-		}
-		a, t := e.server.findGlobalVar(n.Name)
-		if t != nil {
-			return e.resultFrom(a, t, getAddress)
-		}
-		switch n.Name {
-		// Note: these could have been redefined as constants in the code, but we
-		// don't have a way to detect that.
-		case "true":
-			return result{nil, true}
-		case "false":
-			return result{nil, false}
-		case "lookup":
-			return result{nil, identLookup}
-		}
-		return e.err("unknown identifier")
-
-	case *ast.BasicLit:
-		switch n.Kind {
-		case token.INT:
-			i := new(big.Int)
-			if _, ok := i.SetString(n.Value, 0); !ok {
-				return e.err("invalid integer constant")
-			}
-			return result{nil, untInt{i}}
-		case token.FLOAT:
-			r, _, err := big.ParseFloat(n.Value, 10, prec, big.ToNearestEven)
-			if err != nil {
-				return e.err(err.Error())
-			}
-			return result{nil, untFloat{r}}
-		case token.IMAG:
-			if len(n.Value) <= 1 || n.Value[len(n.Value)-1] != 'i' {
-				return e.err("invalid imaginary constant")
-			}
-			r, _, err := big.ParseFloat(n.Value[:len(n.Value)-1], 10, prec, big.ToNearestEven)
-			if err != nil {
-				return e.err(err.Error())
-			}
-			return result{nil, untComplex{new(big.Float), r}}
-		case token.CHAR:
-			// TODO: unescaping
-			return result{nil, untRune{new(big.Int).SetInt64(int64(n.Value[1]))}}
-		case token.STRING:
-			// TODO: unescaping
-			if len(n.Value) <= 1 {
-				return e.err("invalid string constant")
-			}
-			return result{nil, untString(n.Value[1 : len(n.Value)-1])}
-		}
-
-	case *ast.ParenExpr:
-		return e.evalNode(n.X, getAddress)
-
-	case *ast.StarExpr:
-		x := e.evalNode(n.X, false)
-		switch v := x.v.(type) {
-		case debug.Pointer:
-			// x.d may be a typedef pointing to a pointer type (or a typedef pointing
-			// to a typedef pointing to a pointer type, etc.), so remove typedefs
-			// until we get the underlying pointer type.
-			t := followTypedefs(x.d)
-			if pt, ok := t.(*dwarf.PtrType); ok {
-				return e.resultFrom(v.Address, pt.Type, getAddress)
-			} else {
-				return e.err("invalid DWARF type for pointer")
-			}
-		case pointerToValue:
-			return e.resultFrom(v.a, x.d, getAddress)
-		case nil:
-			return x
-		}
-		return e.err("invalid indirect")
-
-	case *ast.SelectorExpr:
-		x := e.evalNode(n.X, false)
-		sel := n.Sel.Name
-		switch v := x.v.(type) {
-		case debug.Struct:
-			for _, f := range v.Fields {
-				if f.Name == sel {
-					t, err := e.server.dwarfData.Type(dwarf.Offset(f.Var.TypeID))
-					if err != nil {
-						return e.err(err.Error())
-					}
-					return e.resultFrom(f.Var.Address, t, getAddress)
-				}
-			}
-			return e.err("struct field not found")
-		case debug.Pointer:
-			pt, ok := followTypedefs(x.d).(*dwarf.PtrType) // x.d should be a pointer to struct.
-			if !ok {
-				return e.err("invalid DWARF information for pointer")
-			}
-			st, ok := followTypedefs(pt.Type).(*dwarf.StructType)
-			if !ok {
-				break
-			}
-			for _, f := range st.Field {
-				if f.Name == sel {
-					return e.resultFrom(v.Address+uint64(f.ByteOffset), f.Type, getAddress)
-				}
-			}
-			return e.err("struct field not found")
-		case pointerToValue:
-			st, ok := followTypedefs(x.d).(*dwarf.StructType) // x.d should be a struct.
-			if !ok {
-				break
-			}
-			for _, f := range st.Field {
-				if f.Name == sel {
-					return e.resultFrom(v.a+uint64(f.ByteOffset), f.Type, getAddress)
-				}
-			}
-			return e.err("struct field not found")
-		}
-		return e.err("invalid selector expression")
-
-	case *ast.IndexExpr:
-		x, index := e.evalNode(n.X, false), e.evalNode(n.Index, false)
-		if x.v == nil || index.v == nil {
-			return result{}
-		}
-		// The expression is x[index]
-		if m, ok := x.v.(debug.Map); ok {
-			if getAddress {
-				return e.err("can't take address of map value")
-			}
-			mt, ok := followTypedefs(x.d).(*dwarf.MapType)
-			if !ok {
-				return e.err("invalid DWARF type for map")
-			}
-			var (
-				found bool   // true if the key was found
-				value result // the map value for the key
-				abort bool   // true if an error occurred while searching
-				// fn is a function that checks if one (key, value) pair corresponds
-				// to the index in the expression.
-				fn = func(keyAddr, valAddr uint64, keyType, valType dwarf.Type) bool {
-					key := e.resultFrom(keyAddr, keyType, false)
-					if key.v == nil {
-						abort = true
-						return false // stop searching map
-					}
-					equal, ok := e.evalBinaryOp(token.EQL, index, key).v.(bool)
-					if !ok {
-						abort = true
-						return false // stop searching map
-					}
-					if equal {
-						found = true
-						value = e.resultFrom(valAddr, valType, false)
-						return false // stop searching map
-					}
-					return true // continue searching map
-				}
-			)
-			if err := e.server.peekMapValues(mt, m.Address, fn); err != nil {
-				return e.err(err.Error())
-			}
-			if abort {
-				// Some operation on individual map keys failed.
-				return result{}
-			}
-			if found {
-				return value
-			}
-			// The key wasn't in the map; return the zero value.
-			return e.zero(mt.ElemType)
-		}
-
-		// The index should be a non-negative integer for the remaining cases.
-		u, err := uint64FromResult(index)
-		if err != nil {
-			return e.err("invalid index: " + err.Error())
-		}
-		switch v := x.v.(type) {
-		case debug.Array:
-			if u >= v.Length {
-				return e.err("array index out of bounds")
-			}
-			elemType, err := e.server.dwarfData.Type(dwarf.Offset(v.ElementTypeID))
-			if err != nil {
-				return e.err(err.Error())
-			}
-			return e.resultFrom(v.Element(u).Address, elemType, getAddress)
-		case debug.Slice:
-			if u >= v.Length {
-				return e.err("slice index out of bounds")
-			}
-			elemType, err := e.server.dwarfData.Type(dwarf.Offset(v.ElementTypeID))
-			if err != nil {
-				return e.err(err.Error())
-			}
-			return e.resultFrom(v.Element(u).Address, elemType, getAddress)
-		case sliceOf:
-			if u >= v.Length {
-				return e.err("slice index out of bounds")
-			}
-			return e.resultFrom(v.Element(u).Address, x.d, getAddress)
-		case debug.String:
-			if getAddress {
-				return e.err("can't take address of string element")
-			}
-			if u >= v.Length {
-				return e.err("string index out of bounds")
-			}
-			if u >= uint64(len(v.String)) {
-				return e.err("string element unavailable")
-			}
-			return e.uint8Result(v.String[u])
-		case untString:
-			if getAddress {
-				return e.err("can't take address of string element")
-			}
-			if u >= uint64(len(v)) {
-				return e.err("string index out of bounds")
-			}
-			return e.uint8Result(v[u])
-		}
-		return e.err("invalid index expression")
-
-	case *ast.SliceExpr:
-		if n.Slice3 && n.High == nil {
-			return e.err("middle index required in full slice")
-		}
-		if n.Slice3 && n.Max == nil {
-			return e.err("final index required in full slice")
-		}
-		var (
-			low, high, max uint64
-			err            error
-		)
-		if n.Low != nil {
-			low, err = uint64FromResult(e.evalNode(n.Low, false))
-			if err != nil {
-				return e.err("invalid slice lower bound: " + err.Error())
-			}
-		}
-		if n.High != nil {
-			high, err = uint64FromResult(e.evalNode(n.High, false))
-			if err != nil {
-				return e.err("invalid slice upper bound: " + err.Error())
-			}
-		}
-		if n.Max != nil {
-			max, err = uint64FromResult(e.evalNode(n.Max, false))
-			if err != nil {
-				return e.err("invalid slice capacity: " + err.Error())
-			}
-		}
-		x := e.evalNode(n.X, false)
-		switch v := x.v.(type) {
-		case debug.Array, debug.Pointer, pointerToValue:
-			// This case handles the slicing of arrays and pointers to arrays.
-			var arr debug.Array
-			switch v := x.v.(type) {
-			case debug.Array:
-				arr = v
-			case debug.Pointer:
-				pt, ok := followTypedefs(x.d).(*dwarf.PtrType)
-				if !ok {
-					return e.err("invalid DWARF type for pointer")
-				}
-				a := e.resultFrom(v.Address, pt.Type, false)
-				arr, ok = a.v.(debug.Array)
-				if !ok {
-					// v is a pointer to something other than an array.
-					return e.err("cannot slice pointer")
-				}
-			case pointerToValue:
-				a := e.resultFrom(v.a, x.d, false)
-				var ok bool
-				arr, ok = a.v.(debug.Array)
-				if !ok {
-					// v is a pointer to something other than an array.
-					return e.err("cannot slice pointer")
-				}
-			}
-			elemType, err := e.server.dwarfData.Type(dwarf.Offset(arr.ElementTypeID))
-			if err != nil {
-				return e.err(err.Error())
-			}
-			if n.High == nil {
-				high = arr.Length
-			} else if high > arr.Length {
-				return e.err("slice upper bound is too large")
-			}
-			if n.Max == nil {
-				max = arr.Length
-			} else if max > arr.Length {
-				return e.err("slice capacity is too large")
-			}
-			if low > high || high > max {
-				return e.err("invalid slice index")
-			}
-			return result{
-				d: elemType,
-				v: sliceOf{
-					Array: debug.Array{
-						ElementTypeID: arr.ElementTypeID,
-						Address:       arr.Element(low).Address,
-						Length:        high - low,
-						StrideBits:    uint64(elemType.Common().ByteSize) * 8,
-					},
-					Capacity: max - low,
-				},
-			}
-		case debug.Slice:
-			if n.High == nil {
-				high = v.Length
-			} else if high > v.Capacity {
-				return e.err("slice upper bound is too large")
-			}
-			if n.Max == nil {
-				max = v.Capacity
-			} else if max > v.Capacity {
-				return e.err("slice capacity is too large")
-			}
-			if low > high || high > max {
-				return e.err("invalid slice index")
-			}
-			v.Address += low * (v.StrideBits / 8)
-			v.Length = high - low
-			v.Capacity = max - low
-			return result{x.d, v}
-		case sliceOf:
-			if n.High == nil {
-				high = v.Length
-			} else if high > v.Capacity {
-				return e.err("slice upper bound is too large")
-			}
-			if n.Max == nil {
-				max = v.Capacity
-			} else if max > v.Capacity {
-				return e.err("slice capacity is too large")
-			}
-			if low > high || high > max {
-				return e.err("invalid slice index")
-			}
-			v.Address += low * (v.StrideBits / 8)
-			v.Length = high - low
-			v.Capacity = max - low
-			return result{x.d, v}
-		case debug.String:
-			if n.Max != nil {
-				return e.err("full slice of string")
-			}
-			if n.High == nil {
-				high = v.Length
-			}
-			if low > high || high > v.Length {
-				return e.err("invalid slice index")
-			}
-			v.Length = high - low
-			if low > uint64(len(v.String)) {
-				// v.String was truncated before the point where this slice starts.
-				v.String = ""
-			} else {
-				if high > uint64(len(v.String)) {
-					// v.String was truncated before the point where this slice ends.
-					high = uint64(len(v.String))
-				}
-				v.String = v.String[low:high]
-			}
-			return result{x.d, v}
-		case untString:
-			if n.Max != nil {
-				return e.err("full slice of string")
-			}
-			if n.High == nil {
-				high = uint64(len(v))
-			}
-			if low > high {
-				return e.err("invalid slice expression")
-			}
-			if high > uint64(len(v)) {
-				return e.err("slice upper bound is too large")
-			}
-			return e.stringResult(string(v[low:high]))
-		default:
-			return e.err("invalid slice expression")
-		}
-
-	case *ast.CallExpr:
-		// Only supports lookup("x"), which gets the value of a global symbol x.
-		fun := e.evalNode(n.Fun, false)
-		var args []result
-		for _, a := range n.Args {
-			args = append(args, e.evalNode(a, false))
-		}
-		if fun.v == identLookup {
-			if len(args) != 1 {
-				return e.err("lookup should have one argument")
-			}
-			ident, ok := args[0].v.(untString)
-			if !ok {
-				return e.err("argument for lookup should be a string constant")
-			}
-			if a, t := e.server.findGlobalVar(string(ident)); t == nil {
-				return e.err("symbol not found")
-			} else {
-				return e.resultFrom(a, t, getAddress)
-			}
-		}
-		return e.err("function calls not implemented")
-
-	case *ast.UnaryExpr:
-		if n.Op == token.AND {
-			x := e.evalNode(n.X, true)
-			switch v := x.v.(type) {
-			case addressableValue:
-				return result{x.d, pointerToValue{v.a}}
-			case nil:
-				return x
-			}
-			return e.err("can't take address")
-		}
-
-		x := e.evalNode(n.X, false)
-		if x.v == nil {
-			return x
-		}
-		switch v := x.v.(type) {
-m4_define(UNARY_INT_OPS, @case $1:
-			switch n.Op {
-			case token.ADD:
-			case token.SUB:
-				v = -v
-			case token.XOR:
-				v = ^v
-			default:
-				return e.err("invalid operation")
-			}
-			return result{x.d, v}
-@)
-m4_define(UNARY_FLOAT_OPS, @case $1:
-			switch n.Op {
-			case token.ADD:
-			case token.SUB:
-				v = -v
-			default:
-				return e.err("invalid operation")
-			}
-			return result{x.d, v}
-@)
-		UNARY_INT_OPS(int8)
-		UNARY_INT_OPS(int16)
-		UNARY_INT_OPS(int32)
-		UNARY_INT_OPS(int64)
-		UNARY_INT_OPS(uint8)
-		UNARY_INT_OPS(uint16)
-		UNARY_INT_OPS(uint32)
-		UNARY_INT_OPS(uint64)
-		UNARY_FLOAT_OPS(float32)
-		UNARY_FLOAT_OPS(float64)
-		UNARY_FLOAT_OPS(complex64)
-		UNARY_FLOAT_OPS(complex128)
-		case untInt:
-			switch n.Op {
-			case token.ADD:
-			case token.SUB:
-				v.Int.Neg(v.Int)
-			case token.XOR:
-				v.Int.Not(v.Int)
-			default:
-				return e.err("invalid operation")
-			}
-			return result{x.d, v}
-
-		case untRune:
-			switch n.Op {
-			case token.ADD:
-			case token.SUB:
-				v.Int.Neg(v.Int)
-			case token.XOR:
-				v.Int.Not(v.Int)
-			default:
-				return e.err("invalid operation")
-			}
-			return result{x.d, v}
-
-		case untFloat:
-			switch n.Op {
-			case token.ADD:
-			case token.SUB:
-				v.Float.Neg(v.Float)
-			default:
-				return e.err("invalid operation")
-			}
-			return result{x.d, v}
-
-		case untComplex:
-			switch n.Op {
-			case token.ADD:
-			case token.SUB:
-				v.r.Neg(v.r)
-				v.i.Neg(v.i)
-			default:
-				return e.err("invalid operation")
-			}
-			return result{x.d, v}
-
-		case bool:
-			switch n.Op {
-			case token.NOT:
-				v = !v
-			default:
-				return e.err("invalid operation")
-			}
-			return result{x.d, v}
-		}
-
-	case *ast.BinaryExpr:
-		x := e.evalNode(n.X, false)
-		if x.v == nil {
-			return x
-		}
-		y := e.evalNode(n.Y, false)
-		if y.v == nil {
-			return y
-		}
-		return e.evalBinaryOp(n.Op, x, y)
-	}
-	return e.err("invalid expression")
-}
-
-// evalBinaryOp evaluates a binary operator op applied to x and y.
-func (e *evaluator) evalBinaryOp(op token.Token, x, y result) result {
-	if op == token.NEQ {
-		tmp := e.evalBinaryOp(token.EQL, x, y)
-		b, ok := tmp.v.(bool)
-		if !ok {
-			return tmp
-		}
-		return result{nil, !b}
-	}
-	if op == token.GTR {
-		return e.evalBinaryOp(token.LSS, y, x)
-	}
-	if op == token.GEQ {
-		return e.evalBinaryOp(token.LEQ, x, y)
-	}
-
-	x = convertUntyped(x, y)
-	y = convertUntyped(y, x)
-
-	switch a := x.v.(type) {
-m4_define(INT_OPS, @case $1:
-		b, ok := y.v.($1)
-		if !ok {
-			return e.err("type mismatch")
-		}
-		var c $1
-		switch op {
-		case token.EQL:
-			return result{nil, a == b}
-		case token.LSS:
-			return result{nil, a < b}
-		case token.LEQ:
-			return result{nil, a <= b}
-		case token.ADD:
-			c = a + b
-		case token.SUB:
-			c = a - b
-		case token.OR:
-			c = a | b
-		case token.XOR:
-			c = a ^ b
-		case token.MUL:
-			c = a * b
-		case token.QUO:
-			if b == 0 {
-				return e.err("integer divide by zero")
-			}
-			c = a / b
-		case token.REM:
-			if b == 0 {
-				return e.err("integer divide by zero")
-			}
-			c = a % b
-		case token.AND:
-			c = a & b
-		case token.AND_NOT:
-			c = a &^ b
-		default:
-			return e.err("invalid operation")
-		}
-		return result{x.d, c}
-@)
-m4_define(UINT_OPS, @case $1:
-		b, ok := y.v.($1)
-		if !ok {
-			return e.err("type mismatch")
-		}
-		var c $1
-		switch op {
-		case token.EQL:
-			return result{nil, a == b}
-		case token.LSS:
-			return result{nil, a < b}
-		case token.LEQ:
-			return result{nil, a <= b}
-		case token.ADD:
-			c = a + b
-		case token.SUB:
-			c = a - b
-		case token.OR:
-			c = a | b
-		case token.XOR:
-			c = a ^ b
-		case token.MUL:
-			c = a * b
-		case token.QUO:
-			if b == 0 {
-				return e.err("integer divide by zero")
-			}
-			c = a / b
-		case token.REM:
-			if b == 0 {
-				return e.err("integer divide by zero")
-			}
-			c = a % b
-		case token.AND:
-			c = a & b
-		case token.AND_NOT:
-			c = a &^ b
-		default:
-			return e.err("invalid operation")
-		}
-		return result{x.d, c}
-@)
-m4_define(FLOAT_OPS, @case $1:
-		b, ok := y.v.($1)
-		if !ok {
-			return e.err("type mismatch")
-		}
-		var c $1
-		switch op {
-		case token.EQL:
-			return result{nil, a == b}
-		case token.LSS:
-			return result{nil, a < b}
-		case token.LEQ:
-			return result{nil, a <= b}
-		case token.ADD:
-			c = a + b
-		case token.SUB:
-			c = a - b
-		case token.MUL:
-			c = a * b
-		case token.QUO:
-			c = a / b
-		default:
-			return e.err("invalid operation")
-		}
-		return result{x.d, c}
-@)
-m4_define(COMPLEX_OPS, @case $1:
-		b, ok := y.v.($1)
-		if !ok {
-			return e.err("type mismatch")
-		}
-		var c $1
-		switch op {
-		case token.EQL:
-			return result{nil, a == b}
-		case token.ADD:
-			c = a + b
-		case token.SUB:
-			c = a - b
-		case token.MUL:
-			c = a * b
-		case token.QUO:
-			c = a / b
-		default:
-			return e.err("invalid operation")
-		}
-		return result{x.d, c}
-@)
-	INT_OPS(int8)
-	INT_OPS(int16)
-	INT_OPS(int32)
-	INT_OPS(int64)
-	UINT_OPS(uint8)
-	UINT_OPS(uint16)
-	UINT_OPS(uint32)
-	UINT_OPS(uint64)
-	FLOAT_OPS(float32)
-	FLOAT_OPS(float64)
-	COMPLEX_OPS(complex64)
-	COMPLEX_OPS(complex128)
-	case bool:
-		b, ok := y.v.(bool)
-		if !ok {
-			return e.err("type mismatch")
-		}
-		var c bool
-		switch op {
-		case token.LOR:
-			c = a || b
-		case token.LAND:
-			c = a && b
-		case token.EQL:
-			c = a == b
-		default:
-			return e.err("invalid operation")
-		}
-		return result{x.d, c}
-
-	case debug.String:
-		b, ok := y.v.(debug.String)
-		if !ok {
-			return e.err("type mismatch")
-		}
-		var c debug.String
-		switch op {
-		// TODO: these comparison operators only use the part of the string that
-		// was read.  Very large strings do not have their entire contents read by
-		// server.value.
-		case token.EQL:
-			return result{nil, a.Length == b.Length && a.String == b.String}
-		case token.LSS:
-			return result{nil, a.String < b.String}
-		case token.LEQ:
-			return result{nil, a.String <= b.String}
-		case token.ADD:
-			c.Length = a.Length + b.Length
-			if a.Length == uint64(len(a.String)) {
-				c.String = a.String + b.String
-			} else {
-				// The first string was truncated at a.Length characters, so the sum
-				// must be truncated there too.
-				c.String = a.String
-			}
-		default:
-			return e.err("invalid operation")
-		}
-		return result{x.d, c}
-
-	case untString:
-		b, ok := y.v.(untString)
-		if !ok {
-			return e.err("type mismatch")
-		}
-		var c untString
-		switch op {
-		case token.EQL:
-			return result{nil, a == b}
-		case token.LSS:
-			return result{nil, a < b}
-		case token.LEQ:
-			return result{nil, a <= b}
-		case token.ADD:
-			c = a + b
-		default:
-			return e.err("invalid operation")
-		}
-		return result{x.d, c}
-
-	case untInt:
-		i := a.Int
-		b, ok := y.v.(untInt)
-		if !ok {
-			return e.err("type mismatch")
-		}
-		switch op {
-		case token.EQL:
-			return result{nil, i.Cmp(b.Int) == 0}
-		case token.LSS:
-			return result{nil, i.Cmp(b.Int) < 0}
-		case token.LEQ:
-			return result{nil, i.Cmp(b.Int) <= 0}
-		}
-		c := new(big.Int)
-		switch op {
-		case token.ADD:
-			c.Add(i, b.Int)
-		case token.SUB:
-			c.Sub(i, b.Int)
-		case token.OR:
-			c.Or(i, b.Int)
-		case token.XOR:
-			c.Xor(i, b.Int)
-		case token.MUL:
-			c.Mul(i, b.Int)
-		case token.QUO:
-			if b.Sign() == 0 {
-				return e.err("integer divide by zero")
-			}
-			c.Quo(i, b.Int)
-		case token.REM:
-			if b.Sign() == 0 {
-				return e.err("integer divide by zero")
-			}
-			c.Mod(i, b.Int)
-		case token.AND:
-			c.And(i, b.Int)
-		case token.AND_NOT:
-			c.AndNot(i, b.Int)
-		default:
-			return e.err("invalid operation")
-		}
-		return result{nil, untInt{c}}
-
-	case untRune:
-		i := a.Int
-		b, ok := y.v.(untRune)
-		if !ok {
-			return e.err("type mismatch")
-		}
-		switch op {
-		case token.EQL:
-			return result{nil, i.Cmp(b.Int) == 0}
-		case token.LSS:
-			return result{nil, i.Cmp(b.Int) < 0}
-		case token.LEQ:
-			return result{nil, i.Cmp(b.Int) <= 0}
-		}
-		c := new(big.Int)
-		switch op {
-		case token.ADD:
-			c.Add(i, b.Int)
-		case token.SUB:
-			c.Sub(i, b.Int)
-		case token.OR:
-			c.Or(i, b.Int)
-		case token.XOR:
-			c.Xor(i, b.Int)
-		case token.MUL:
-			c.Mul(i, b.Int)
-		case token.QUO:
-			if b.Sign() == 0 {
-				return e.err("integer divide by zero")
-			}
-			c.Quo(i, b.Int)
-		case token.REM:
-			if b.Sign() == 0 {
-				return e.err("integer divide by zero")
-			}
-			c.Mod(i, b.Int)
-		case token.AND:
-			c.And(i, b.Int)
-		case token.AND_NOT:
-			c.AndNot(i, b.Int)
-		default:
-			return e.err("invalid operation")
-		}
-		return result{nil, untRune{c}}
-
-	case untFloat:
-		r := a.Float
-		b, ok := y.v.(untFloat)
-		if !ok {
-			return e.err("type mismatch")
-		}
-		switch op {
-		case token.EQL:
-			return result{nil, r.Cmp(b.Float) == 0}
-		case token.LSS:
-			return result{nil, r.Cmp(b.Float) < 0}
-		case token.LEQ:
-			return result{nil, r.Cmp(b.Float) <= 0}
-		}
-		c := new(big.Float)
-		switch op {
-		case token.ADD:
-			c.Add(r, b.Float)
-		case token.SUB:
-			c.Sub(r, b.Float)
-		case token.MUL:
-			c.Mul(r, b.Float)
-		case token.QUO:
-			if b.Sign() == 0 {
-				return e.err("divide by zero")
-			}
-			c.Quo(r, b.Float)
-		default:
-			return e.err("invalid operation")
-		}
-		return result{nil, untFloat{c}}
-
-	case untComplex:
-		b, ok := y.v.(untComplex)
-		if !ok {
-			return e.err("type mismatch")
-		}
-		var (
-			ar = a.r
-			br = b.r
-			ai = a.i
-			bi = b.i
-		)
-		if op == token.EQL {
-			return result{nil, ar.Cmp(br) == 0 && ai.Cmp(bi) == 0}
-		}
-		var (
-			cr = new(big.Float)
-			ci = new(big.Float)
-		)
-		switch op {
-		case token.ADD:
-			cr.Add(ar, br)
-			ci.Add(ai, bi)
-		case token.SUB:
-			cr.Sub(ar, br)
-			ci.Sub(ai, bi)
-		case token.MUL:
-			var t0, t1 big.Float
-			t0.Mul(ar, br)
-			t1.Mul(ai, bi)
-			cr.Sub(&t0, &t1)
-			t0.Mul(ar, bi)
-			t1.Mul(ai, br)
-			ci.Add(&t0, &t1)
-		case token.QUO:
-			// a/b = a*conj(b)/|b|^2
-			var t0, t1 big.Float
-			cr.Mul(ar, br)
-			t0.Mul(ai, bi)
-			cr.Add(cr, &t0) // cr = Re(a*conj(b))
-			ci.Mul(ai, br)
-			t0.Mul(ar, bi)
-			ci.Sub(ci, &t0) // ci = Im(a*conj(b))
-			t0.Mul(br, br)
-			t1.Mul(bi, bi)
-			t0.Add(&t0, &t1) // t0 = |b|^2
-			if t0.Sign() == 0 {
-				return e.err("divide by zero")
-			}
-			cr.Quo(cr, &t0) // cr = Re(a*conj(b))/|b|^2 = Re(a/b)
-			ci.Quo(ci, &t0) // ci = Im(a*conj(b))/|b|^2 = Im(a/b)
-		}
-		return result{nil, untComplex{cr, ci}}
-	}
-
-	return e.err("invalid operation")
-}
-
-// findLocalVar finds a local variable (or function parameter) by name, and
-// returns its address and DWARF type.  It returns a nil type on failure.
-// The PC and SP are used to determine the current function and stack frame.
-func (s *Server) findLocalVar(name string, pc, sp uint64) (uint64, dwarf.Type) {
-	// Find the DWARF entry for the function at pc.
-	funcEntry, _, err := s.dwarfData.PCToFunction(uint64(pc))
-	if err != nil {
-		return 0, nil
-	}
-
-	// Compute the stack frame pointer.
-	fpOffset, err := s.dwarfData.PCToSPOffset(uint64(pc))
-	if err != nil {
-		return 0, nil
-	}
-	framePointer := sp + uint64(fpOffset)
-
-	// Check each child of the function's DWARF entry to see if it is a parameter
-	// or local variable with the right name.  If so, return its address and type.
-	r := s.dwarfData.Reader()
-	r.Seek(funcEntry.Offset)
-	for {
-		varEntry, err := r.Next()
-		if err != nil {
-			break
-		}
-		if varEntry.Tag == 0 {
-			// This tag marks the end of the function's DWARF entry's children.
-			break
-		}
-
-		// Check this entry corresponds to a local variable or function parameter,
-		// that it has the correct name, and that we can get its type and location.
-		// If so, return them.
-		if varEntry.Tag != dwarf.TagFormalParameter && varEntry.Tag != dwarf.TagVariable {
-			continue
-		}
-		varName, ok := varEntry.Val(dwarf.AttrName).(string)
-		if !ok {
-			continue
-		}
-		if varName != name {
-			continue
-		}
-		varTypeOffset, ok := varEntry.Val(dwarf.AttrType).(dwarf.Offset)
-		if !ok {
-			continue
-		}
-		varType, err := s.dwarfData.Type(varTypeOffset)
-		if err != nil {
-			continue
-		}
-		locationAttribute := varEntry.Val(dwarf.AttrLocation)
-		if locationAttribute == nil {
-			continue
-		}
-		locationDescription, ok := locationAttribute.([]uint8)
-		if !ok {
-			continue
-		}
-		frameOffset, err := evalLocation(locationDescription)
-		if err != nil {
-			continue
-		}
-		return framePointer + uint64(frameOffset), varType
-	}
-
-	return 0, nil
-}
-
-// findGlobalVar finds a global variable by name, and returns its address and
-// DWARF type.  It returns a nil type on failure.
-func (s *Server) findGlobalVar(name string) (uint64, dwarf.Type) {
-	entry, err := s.dwarfData.LookupVariable(name)
-	if err != nil {
-		return 0, nil
-	}
-	loc, err := s.dwarfData.EntryLocation(entry)
-	if err != nil {
-		return 0, nil
-	}
-	ofs, err := s.dwarfData.EntryTypeOffset(entry)
-	if err != nil {
-		return 0, nil
-	}
-	typ, err := s.dwarfData.Type(ofs)
-	if err != nil {
-		return 0, nil
-	}
-	return loc, typ
-}
-
-// intFromInteger converts an untyped integer constant to an int32 or int64,
-// depending on the int size of the debugged program.
-// It returns an error on overflow, or if it can't determine the int size.
-func (e *evaluator) intFromInteger(v untInt) (interface{}, error) {
-	t, ok := e.getBaseType("int")
-	if !ok {
-		return nil, errors.New("couldn't get int size from DWARF info")
-	}
-	switch t.Common().ByteSize {
-	case 4:
-		if v.Cmp(bigIntMaxInt32) == +1 || v.Cmp(bigIntMinInt32) == -1 {
-			return nil, errors.New("constant overflows int")
-		}
-		return int32(v.Int64()), nil
-	case 8:
-		if v.Cmp(bigIntMaxInt64) == +1 || v.Cmp(bigIntMinInt64) == -1 {
-			return nil, errors.New("constant overflows int")
-		}
-		return v.Int64(), nil
-	}
-	return nil, errors.New("invalid int size in DWARF info")
-}
-
-// uint8Result constructs a result for a uint8 value.
-func (e *evaluator) uint8Result(v uint8) result {
-	t, ok := e.getBaseType("uint8")
-	if !ok {
-		e.err("couldn't construct uint8")
-	}
-	return result{t, uint8(v)}
-}
-
-// stringResult constructs a result for a string value.
-func (e *evaluator) stringResult(s string) result {
-	t, ok := e.getBaseType("string")
-	if !ok {
-		e.err("couldn't construct string")
-	}
-	return result{t, debug.String{Length: uint64(len(s)), String: s}}
-}
-
-// getBaseType returns the *dwarf.Type with a given name.
-// TODO: cache this.
-func (e *evaluator) getBaseType(name string) (dwarf.Type, bool) {
-	entry, err := e.server.dwarfData.LookupEntry(name)
-	if err != nil {
-		return nil, false
-	}
-	t, err := e.server.dwarfData.Type(entry.Offset)
-	if err != nil {
-		return nil, false
-	}
-	return t, true
-}
-
-// resultFrom constructs a result corresponding to a value in the program with
-// the given address and DWARF type.
-// If getAddress is true, the result will be the operand of an address expression,
-// so resultFrom returns a result containing a value of type addressableValue.
-func (e *evaluator) resultFrom(a uint64, t dwarf.Type, getAddress bool) result {
-	if a == 0 {
-		return e.err("nil pointer dereference")
-	}
-	if getAddress {
-		return result{t, addressableValue{a}}
-	}
-	v, err := e.server.value(t, a)
-	if err != nil {
-		return e.err(err.Error())
-	}
-	return result{t, v}
-}
-
-// zero returns the zero value of type t.
-// TODO: implement for array and struct.
-func (e *evaluator) zero(t dwarf.Type) result {
-	var v interface{}
-	switch typ := followTypedefs(t).(type) {
-	case *dwarf.CharType, *dwarf.IntType, *dwarf.EnumType:
-		switch typ.Common().ByteSize {
-		case 1:
-			v = int8(0)
-		case 2:
-			v = int16(0)
-		case 4:
-			v = int32(0)
-		case 8:
-			v = int64(0)
-		default:
-			return e.err("invalid integer size " + fmt.Sprint(typ.Common().ByteSize))
-		}
-	case *dwarf.UcharType, *dwarf.UintType:
-		switch typ.Common().ByteSize {
-		case 1:
-			v = uint8(0)
-		case 2:
-			v = uint16(0)
-		case 4:
-			v = uint32(0)
-		case 8:
-			v = uint64(0)
-		default:
-			return e.err("invalid unsigned integer size " + fmt.Sprint(typ.Common().ByteSize))
-		}
-	case *dwarf.FloatType:
-		switch typ.Common().ByteSize {
-		case 4:
-			v = float32(0)
-		case 8:
-			v = float64(0)
-		default:
-			return e.err("invalid float size " + fmt.Sprint(typ.Common().ByteSize))
-		}
-	case *dwarf.ComplexType:
-		switch typ.Common().ByteSize {
-		case 8:
-			v = complex64(0)
-		case 16:
-			v = complex128(0)
-		default:
-			return e.err("invalid complex size " + fmt.Sprint(typ.Common().ByteSize))
-		}
-	case *dwarf.BoolType:
-		v = false
-	case *dwarf.PtrType:
-		v = debug.Pointer{TypeID: uint64(t.Common().Offset)}
-	case *dwarf.SliceType:
-		v = debug.Slice{
-			Array: debug.Array{
-				ElementTypeID: uint64(typ.ElemType.Common().Offset),
-				StrideBits:    uint64(typ.ElemType.Common().ByteSize) * 8,
-			},
-		}
-	case *dwarf.StringType:
-		v = debug.String{}
-	case *dwarf.InterfaceType:
-		v = debug.Interface{}
-	case *dwarf.FuncType:
-		v = debug.Func{}
-	case *dwarf.MapType:
-		v = debug.Map{TypeID: uint64(t.Common().Offset)}
-	case *dwarf.ChanType:
-		v = debug.Channel{
-			ElementTypeID: uint64(typ.ElemType.Common().Offset),
-			Stride:        uint64(typ.ElemType.Common().ByteSize),
-		}
-	default:
-		return e.err("can't get zero value of this type")
-	}
-	return result{t, v}
-}
-
-// convertUntyped converts x to be the same type as y, if x is untyped and the
-// conversion is possible.
-//
-// An untyped bool can be converted to a boolean type.
-// An untyped string can be converted to a string type.
-// An untyped integer, rune, float or complex value can be converted to a
-// numeric type, or to an untyped value later in that list.
-//
-// x is returned unchanged if none of these cases apply.
-func convertUntyped(x, y result) result {
-	switch a := x.v.(type) {
-	case untInt:
-		i := a.Int
-		switch y.v.(type) {
-		case int8:
-			return result{y.d, int8(i.Int64())}
-		case int16:
-			return result{y.d, int16(i.Int64())}
-		case int32:
-			return result{y.d, int32(i.Int64())}
-		case int64:
-			return result{y.d, int64(i.Int64())}
-		case uint8:
-			return result{y.d, uint8(i.Uint64())}
-		case uint16:
-			return result{y.d, uint16(i.Uint64())}
-		case uint32:
-			return result{y.d, uint32(i.Uint64())}
-		case uint64:
-			return result{y.d, uint64(i.Uint64())}
-		case float32:
-			f, _ := new(big.Float).SetInt(i).Float32()
-			return result{y.d, f}
-		case float64:
-			f, _ := new(big.Float).SetInt(i).Float64()
-			return result{y.d, f}
-		case complex64:
-			f, _ := new(big.Float).SetInt(i).Float32()
-			return result{y.d, complex(f, 0)}
-		case complex128:
-			f, _ := new(big.Float).SetInt(i).Float64()
-			return result{y.d, complex(f, 0)}
-		case untRune:
-			return result{nil, untRune{i}}
-		case untFloat:
-			return result{nil, untFloat{new(big.Float).SetPrec(prec).SetInt(i)}}
-		case untComplex:
-			return result{nil, untComplex{new(big.Float).SetPrec(prec).SetInt(i), new(big.Float)}}
-		}
-	case untRune:
-		i := a.Int
-		switch y.v.(type) {
-		case int8:
-			return result{y.d, int8(i.Int64())}
-		case int16:
-			return result{y.d, int16(i.Int64())}
-		case int32:
-			return result{y.d, int32(i.Int64())}
-		case int64:
-			return result{y.d, int64(i.Int64())}
-		case uint8:
-			return result{y.d, uint8(i.Uint64())}
-		case uint16:
-			return result{y.d, uint16(i.Uint64())}
-		case uint32:
-			return result{y.d, uint32(i.Uint64())}
-		case uint64:
-			return result{y.d, uint64(i.Uint64())}
-		case float32:
-			f, _ := new(big.Float).SetInt(i).Float32()
-			return result{y.d, f}
-		case float64:
-			f, _ := new(big.Float).SetInt(i).Float64()
-			return result{y.d, f}
-		case complex64:
-			f, _ := new(big.Float).SetInt(i).Float32()
-			return result{y.d, complex(f, 0)}
-		case complex128:
-			f, _ := new(big.Float).SetInt(i).Float64()
-			return result{y.d, complex(f, 0)}
-		case untRune:
-			return result{nil, untRune{i}}
-		case untFloat:
-			return result{nil, untFloat{new(big.Float).SetPrec(prec).SetInt(i)}}
-		case untComplex:
-			return result{nil, untComplex{new(big.Float).SetPrec(prec).SetInt(i), new(big.Float)}}
-		}
-	case untFloat:
-		if a.IsInt() {
-			i, _ := a.Int(nil)
-			switch y.v.(type) {
-			case int8:
-				return result{y.d, int8(i.Int64())}
-			case int16:
-				return result{y.d, int16(i.Int64())}
-			case int32:
-				return result{y.d, int32(i.Int64())}
-			case int64:
-				return result{y.d, int64(i.Int64())}
-			case uint8:
-				return result{y.d, uint8(i.Uint64())}
-			case uint16:
-				return result{y.d, uint16(i.Uint64())}
-			case uint32:
-				return result{y.d, uint32(i.Uint64())}
-			case uint64:
-				return result{y.d, uint64(i.Uint64())}
-			}
-		}
-		switch y.v.(type) {
-		case float32:
-			f, _ := a.Float32()
-			return result{y.d, float32(f)}
-		case float64:
-			f, _ := a.Float64()
-			return result{y.d, float64(f)}
-		case complex64:
-			f, _ := a.Float32()
-			return result{y.d, complex(f, 0)}
-		case complex128:
-			f, _ := a.Float64()
-			return result{y.d, complex(f, 0)}
-		case untComplex:
-			return result{nil, untComplex{a.Float, new(big.Float)}}
-		}
-	case untComplex:
-		if a.i.Sign() == 0 {
-			// a is a real number.
-			if a.r.IsInt() {
-				// a is an integer.
-				i, _ := a.r.Int(nil)
-				switch y.v.(type) {
-				case int8:
-					return result{y.d, int8(i.Int64())}
-				case int16:
-					return result{y.d, int16(i.Int64())}
-				case int32:
-					return result{y.d, int32(i.Int64())}
-				case int64:
-					return result{y.d, int64(i.Int64())}
-				case uint8:
-					return result{y.d, uint8(i.Uint64())}
-				case uint16:
-					return result{y.d, uint16(i.Uint64())}
-				case uint32:
-					return result{y.d, uint32(i.Uint64())}
-				case uint64:
-					return result{y.d, uint64(i.Uint64())}
-				}
-			}
-			switch y.v.(type) {
-			case float32:
-				f, _ := a.r.Float32()
-				return result{y.d, float32(f)}
-			case float64:
-				f, _ := a.r.Float64()
-				return result{y.d, float64(f)}
-			}
-		}
-		switch y.v.(type) {
-		case complex64:
-			r, _ := a.r.Float32()
-			i, _ := a.i.Float32()
-			return result{y.d, complex(r, i)}
-		case complex128:
-			r, _ := a.r.Float64()
-			i, _ := a.i.Float64()
-			return result{y.d, complex(r, i)}
-		}
-	case bool:
-		if x.d != nil {
-			// x is a typed bool, not an untyped bool.
-			break
-		}
-		switch y.v.(type) {
-		case bool:
-			return result{y.d, bool(a)}
-		}
-	case untString:
-		switch y.v.(type) {
-		case debug.String:
-			return result{y.d, debug.String{Length: uint64(len(a)), String: string(a)}}
-		}
-	}
-	return x
-}
-
-// uint64FromResult converts a result into a uint64 for slice or index expressions.
-// It returns an error if the conversion cannot be done.
-func uint64FromResult(x result) (uint64, error) {
-	switch v := x.v.(type) {
-	case int8:
-		if v < 0 {
-			return 0, errors.New("value is negative")
-		}
-		return uint64(v), nil
-	case int16:
-		if v < 0 {
-			return 0, errors.New("value is negative")
-		}
-		return uint64(v), nil
-	case int32:
-		if v < 0 {
-			return 0, errors.New("value is negative")
-		}
-		return uint64(v), nil
-	case int64:
-		if v < 0 {
-			return 0, errors.New("value is negative")
-		}
-		return uint64(v), nil
-	case uint8:
-		return uint64(v), nil
-	case uint16:
-		return uint64(v), nil
-	case uint32:
-		return uint64(v), nil
-	case uint64:
-		return v, nil
-	case untInt:
-		if v.Int.Sign() == -1 {
-			return 0, errors.New("value is negative")
-		}
-		if v.Int.Cmp(bigIntMaxUint64) == +1 {
-			return 0, errors.New("value is too large")
-		}
-		return v.Int.Uint64(), nil
-	case untRune:
-		if v.Sign() == -1 {
-			return 0, errors.New("value is negative")
-		}
-		if v.Cmp(bigIntMaxUint64) == +1 {
-			return 0, errors.New("value is too large")
-		}
-		return v.Uint64(), nil
-	case untFloat:
-		if !v.IsInt() {
-			return 0, errors.New("value is not an integer")
-		}
-		if v.Sign() == -1 {
-			return 0, errors.New("value is negative")
-		}
-		i, _ := v.Int(nil)
-		if i.Cmp(bigIntMaxUint64) == +1 {
-			return 0, errors.New("value is too large")
-		}
-		return i.Uint64(), nil
-	case untComplex:
-		if v.i.Sign() != 0 {
-			return 0, errors.New("value is complex")
-		}
-		if !v.r.IsInt() {
-			return 0, errors.New("value is not an integer")
-		}
-		if v.r.Sign() == -1 {
-			return 0, errors.New("value is negative")
-		}
-		i, _ := v.r.Int(nil)
-		if i.Cmp(bigIntMaxUint64) == +1 {
-			return 0, errors.New("value is too large")
-		}
-		return i.Uint64(), nil
-	}
-	return 0, fmt.Errorf("cannot convert to unsigned integer")
-}
-
-// followTypedefs returns the underlying type of t, removing any typedefs.
-// If t leads to a cycle of typedefs, followTypedefs returns nil.
-func followTypedefs(t dwarf.Type) dwarf.Type {
-	// If t is a *dwarf.TypedefType, next returns t.Type, otherwise it returns t.
-	// The bool returned is true when the argument was a typedef.
-	next := func(t dwarf.Type) (dwarf.Type, bool) {
-		tt, ok := t.(*dwarf.TypedefType)
-		if !ok {
-			return t, false
-		}
-		return tt.Type, true
-	}
-	// Advance two pointers, one at twice the speed, so we can detect if we get
-	// stuck in a cycle.
-	slow, fast := t, t
-	for {
-		var wasTypedef bool
-		fast, wasTypedef = next(fast)
-		if !wasTypedef {
-			return fast
-		}
-		fast, wasTypedef = next(fast)
-		if !wasTypedef {
-			return fast
-		}
-		slow, _ = next(slow)
-		if slow == fast {
-			return nil
-		}
-	}
-}
diff --git a/server/peek.go b/server/peek.go
deleted file mode 100644
index a26677d..0000000
--- a/server/peek.go
+++ /dev/null
@@ -1,366 +0,0 @@
-// Copyright 2015 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.
-
-// Functions for reading values of various types from a program's memory.
-
-package server
-
-import (
-	"errors"
-	"fmt"
-
-	"golang.org/x/debug"
-	"golang.org/x/debug/dwarf"
-)
-
-// peekBytes reads len(buf) bytes at addr.
-func (s *Server) peekBytes(addr uint64, buf []byte) error {
-	return s.ptracePeek(s.stoppedPid, uintptr(addr), buf)
-}
-
-// peekPtr reads a pointer at addr.
-func (s *Server) peekPtr(addr uint64) (uint64, error) {
-	buf := make([]byte, s.arch.PointerSize)
-	if err := s.peekBytes(addr, buf); err != nil {
-		return 0, err
-	}
-	return s.arch.Uintptr(buf), nil
-}
-
-// peekUint8 reads a single byte at addr.
-func (s *Server) peekUint8(addr uint64) (byte, error) {
-	buf := make([]byte, 1)
-	if err := s.peekBytes(addr, buf); err != nil {
-		return 0, err
-	}
-	return uint8(s.arch.UintN(buf)), nil
-}
-
-// peekInt reads an int of size n bytes at addr.
-func (s *Server) peekInt(addr uint64, n int64) (int64, error) {
-	buf := make([]byte, n)
-	if err := s.peekBytes(addr, buf); err != nil {
-		return 0, err
-	}
-	return s.arch.IntN(buf), nil
-}
-
-// peekUint reads a uint of size n bytes at addr.
-func (s *Server) peekUint(addr uint64, n int64) (uint64, error) {
-	buf := make([]byte, n)
-	if err := s.peekBytes(addr, buf); err != nil {
-		return 0, err
-	}
-	return s.arch.UintN(buf), nil
-}
-
-// peekSlice reads the header of a slice with the given type and address.
-func (s *Server) peekSlice(t *dwarf.SliceType, addr uint64) (debug.Slice, error) {
-	ptr, err := s.peekPtrStructField(&t.StructType, addr, "array")
-	if err != nil {
-		return debug.Slice{}, fmt.Errorf("reading slice location: %s", err)
-	}
-	length, err := s.peekUintOrIntStructField(&t.StructType, addr, "len")
-	if err != nil {
-		return debug.Slice{}, fmt.Errorf("reading slice length: %s", err)
-	}
-	capacity, err := s.peekUintOrIntStructField(&t.StructType, addr, "cap")
-	if err != nil {
-		return debug.Slice{}, fmt.Errorf("reading slice capacity: %s", err)
-	}
-	if capacity < length {
-		return debug.Slice{}, fmt.Errorf("slice's capacity %d is less than its length %d", capacity, length)
-	}
-
-	return debug.Slice{
-		debug.Array{
-			ElementTypeID: uint64(t.ElemType.Common().Offset),
-			Address:       uint64(ptr),
-			Length:        length,
-			StrideBits:    uint64(t.ElemType.Common().ByteSize) * 8,
-		},
-		capacity,
-	}, nil
-}
-
-// peekString reads a string of the given type at the given address.
-// At most byteLimit bytes will be read.  If the string is longer, "..." is appended.
-func (s *Server) peekString(typ *dwarf.StringType, a uint64, byteLimit uint64) (string, error) {
-	ptr, err := s.peekPtrStructField(&typ.StructType, a, "str")
-	if err != nil {
-		return "", err
-	}
-	length, err := s.peekUintOrIntStructField(&typ.StructType, a, "len")
-	if err != nil {
-		return "", err
-	}
-	if length > byteLimit {
-		buf := make([]byte, byteLimit, byteLimit+3)
-		if err := s.peekBytes(ptr, buf); err != nil {
-			return "", err
-		} else {
-			buf = append(buf, '.', '.', '.')
-			return string(buf), nil
-		}
-	} else {
-		buf := make([]byte, length)
-		if err := s.peekBytes(ptr, buf); err != nil {
-			return "", err
-		} else {
-			return string(buf), nil
-		}
-	}
-}
-
-// peekCString reads a NUL-terminated string at the given address.
-// At most byteLimit bytes will be read.  If the string is longer, "..." is appended.
-// peekCString never returns errors; if an error occurs, the string will be truncated in some way.
-func (s *Server) peekCString(a uint64, byteLimit uint64) string {
-	buf := make([]byte, byteLimit, byteLimit+3)
-	s.peekBytes(a, buf)
-	for i, c := range buf {
-		if c == 0 {
-			return string(buf[0:i])
-		}
-	}
-	buf = append(buf, '.', '.', '.')
-	return string(buf)
-}
-
-// peekPtrStructField reads a pointer in the field fieldName of the struct
-// of type t at addr.
-func (s *Server) peekPtrStructField(t *dwarf.StructType, addr uint64, fieldName string) (uint64, error) {
-	f, err := getField(t, fieldName)
-	if err != nil {
-		return 0, fmt.Errorf("reading field %s: %s", fieldName, err)
-	}
-	if _, ok := f.Type.(*dwarf.PtrType); !ok {
-		return 0, fmt.Errorf("field %s is not a pointer", fieldName)
-	}
-	return s.peekPtr(addr + uint64(f.ByteOffset))
-}
-
-// peekUintOrIntStructField reads a signed or unsigned integer in the field fieldName
-// of the struct of type t at addr. If the value is negative, it returns an error.
-// This function is used when the value should be non-negative, but the DWARF
-// type of the field may be signed or unsigned.
-func (s *Server) peekUintOrIntStructField(t *dwarf.StructType, addr uint64, fieldName string) (uint64, error) {
-	f, err := getField(t, fieldName)
-	if err != nil {
-		return 0, fmt.Errorf("reading field %s: %s", fieldName, err)
-	}
-	ut, ok := f.Type.(*dwarf.UintType)
-	if ok {
-		return s.peekUint(addr+uint64(f.ByteOffset), ut.ByteSize)
-	}
-	it, ok := f.Type.(*dwarf.IntType)
-	if !ok {
-		return 0, fmt.Errorf("field %s is not an integer", fieldName)
-	}
-	i, err := s.peekInt(addr+uint64(f.ByteOffset), it.ByteSize)
-	if err != nil {
-		return 0, err
-	}
-	if i < 0 {
-		return 0, fmt.Errorf("field %s is negative", fieldName)
-	}
-	return uint64(i), nil
-}
-
-// peekUintStructField reads a uint in the field fieldName of the struct
-// of type t at addr.  The size of the uint is determined by the field.
-func (s *Server) peekUintStructField(t *dwarf.StructType, addr uint64, fieldName string) (uint64, error) {
-	f, err := getField(t, fieldName)
-	if err != nil {
-		return 0, fmt.Errorf("reading field %s: %s", fieldName, err)
-	}
-	ut, ok := f.Type.(*dwarf.UintType)
-	if !ok {
-		return 0, fmt.Errorf("field %s is not an unsigned integer", fieldName)
-	}
-	return s.peekUint(addr+uint64(f.ByteOffset), ut.ByteSize)
-}
-
-// peekIntStructField reads an int in the field fieldName of the struct
-// of type t at addr.  The size of the int is determined by the field.
-func (s *Server) peekIntStructField(t *dwarf.StructType, addr uint64, fieldName string) (int64, error) {
-	f, err := getField(t, fieldName)
-	if err != nil {
-		return 0, fmt.Errorf("reading field %s: %s", fieldName, err)
-	}
-	it, ok := f.Type.(*dwarf.IntType)
-	if !ok {
-		return 0, fmt.Errorf("field %s is not a signed integer", fieldName)
-	}
-	return s.peekInt(addr+uint64(f.ByteOffset), it.ByteSize)
-}
-
-// peekStringStructField reads a string field from the struct of the given type
-// at the given address.
-// At most byteLimit bytes will be read.  If the string is longer, "..." is appended.
-func (s *Server) peekStringStructField(t *dwarf.StructType, addr uint64, fieldName string, byteLimit uint64) (string, error) {
-	f, err := getField(t, fieldName)
-	if err != nil {
-		return "", fmt.Errorf("reading field %s: %s", fieldName, err)
-	}
-	st, ok := followTypedefs(f.Type).(*dwarf.StringType)
-	if !ok {
-		return "", fmt.Errorf("field %s is not a string", fieldName)
-	}
-	return s.peekString(st, addr+uint64(f.ByteOffset), byteLimit)
-}
-
-// peekMapLocationAndType returns the address and DWARF type of the underlying
-// struct of a map variable.
-func (s *Server) peekMapLocationAndType(t *dwarf.MapType, a uint64) (uint64, *dwarf.StructType, error) {
-	// Maps are pointers to structs.
-	pt, ok := t.Type.(*dwarf.PtrType)
-	if !ok {
-		return 0, nil, errors.New("bad map type: not a pointer")
-	}
-	st, ok := pt.Type.(*dwarf.StructType)
-	if !ok {
-		return 0, nil, errors.New("bad map type: not a pointer to a struct")
-	}
-	// a is the address of a pointer to a struct.  Get the pointer's value.
-	a, err := s.peekPtr(a)
-	if err != nil {
-		return 0, nil, fmt.Errorf("reading map pointer: %s", err)
-	}
-	return a, st, nil
-}
-
-// peekMapValues reads a map at the given address and calls fn with the addresses for each (key, value) pair.
-// If fn returns false, peekMapValues stops.
-func (s *Server) peekMapValues(t *dwarf.MapType, a uint64, fn func(keyAddr, valAddr uint64, keyType, valType dwarf.Type) bool) error {
-	a, st, err := s.peekMapLocationAndType(t, a)
-	if err != nil {
-		return err
-	}
-	if a == 0 {
-		// The pointer was nil, so the map is empty.
-		return nil
-	}
-	// Gather information about the struct type and the map bucket type.
-	b, err := s.peekUintStructField(st, a, "B")
-	if err != nil {
-		return fmt.Errorf("reading map: %s", err)
-	}
-	buckets, err := s.peekPtrStructField(st, a, "buckets")
-	if err != nil {
-		return fmt.Errorf("reading map: %s", err)
-	}
-	oldbuckets, err := s.peekPtrStructField(st, a, "oldbuckets")
-	if err != nil {
-		return fmt.Errorf("reading map: %s", err)
-	}
-	bf, err := getField(st, "buckets")
-	if err != nil {
-		return fmt.Errorf("reading map: %s", err)
-	}
-	bucketPtrType, ok := bf.Type.(*dwarf.PtrType)
-	if !ok {
-		return errors.New("bad map bucket type: not a pointer")
-	}
-	bt, ok := bucketPtrType.Type.(*dwarf.StructType)
-	if !ok {
-		return errors.New("bad map bucket type: not a pointer to a struct")
-	}
-	bucketSize := uint64(bucketPtrType.Type.Size())
-	tophashField, err := getField(bt, "tophash")
-	if err != nil {
-		return fmt.Errorf("reading map: %s", err)
-	}
-	bucketCnt := uint64(tophashField.Type.Size())
-	tophashFieldOffset := uint64(tophashField.ByteOffset)
-	keysField, err := getField(bt, "keys")
-	if err != nil {
-		return fmt.Errorf("reading map: %s", err)
-	}
-	keysType, ok := keysField.Type.(*dwarf.ArrayType)
-	if !ok {
-		return errors.New(`bad map bucket type: "keys" is not an array`)
-	}
-	keyType := keysType.Type
-	keysStride := uint64(keysType.StrideBitSize / 8)
-	keysFieldOffset := uint64(keysField.ByteOffset)
-	valuesField, err := getField(bt, "values")
-	if err != nil {
-		return fmt.Errorf("reading map: %s", err)
-	}
-	valuesType, ok := valuesField.Type.(*dwarf.ArrayType)
-	if !ok {
-		return errors.New(`bad map bucket type: "values" is not an array`)
-	}
-	valueType := valuesType.Type
-	valuesStride := uint64(valuesType.StrideBitSize / 8)
-	valuesFieldOffset := uint64(valuesField.ByteOffset)
-	overflowField, err := getField(bt, "overflow")
-	if err != nil {
-		return fmt.Errorf("reading map: %s", err)
-	}
-	overflowFieldOffset := uint64(overflowField.ByteOffset)
-
-	// Iterate through the two arrays of buckets.
-	bucketArrays := [2]struct {
-		addr uint64
-		size uint64
-	}{
-		{buckets, 1 << b},
-		{oldbuckets, 1 << (b - 1)},
-	}
-	for _, bucketArray := range bucketArrays {
-		if bucketArray.addr == 0 {
-			continue
-		}
-		for i := uint64(0); i < bucketArray.size; i++ {
-			bucketAddr := bucketArray.addr + i*bucketSize
-			// Iterate through the linked list of buckets.
-			// TODO: check for repeated bucket pointers.
-			for bucketAddr != 0 {
-				// Iterate through each entry in the bucket.
-				for j := uint64(0); j < bucketCnt; j++ {
-					tophash, err := s.peekUint8(bucketAddr + tophashFieldOffset + j)
-					if err != nil {
-						return errors.New("reading map: " + err.Error())
-					}
-					// From runtime/hashmap.go
-					const minTopHash = 4
-					if tophash < minTopHash {
-						continue
-					}
-					keyAddr := bucketAddr + keysFieldOffset + j*keysStride
-					valAddr := bucketAddr + valuesFieldOffset + j*valuesStride
-					if !fn(keyAddr, valAddr, keyType, valueType) {
-						return nil
-					}
-				}
-				var err error
-				bucketAddr, err = s.peekPtr(bucketAddr + overflowFieldOffset)
-				if err != nil {
-					return errors.New("reading map: " + err.Error())
-				}
-			}
-		}
-	}
-
-	return nil
-}
-
-// peekMapLength returns the number of elements in a map at the given address.
-func (s *Server) peekMapLength(t *dwarf.MapType, a uint64) (uint64, error) {
-	a, st, err := s.peekMapLocationAndType(t, a)
-	if err != nil {
-		return 0, err
-	}
-	if a == 0 {
-		// The pointer was nil, so the map is empty.
-		return 0, nil
-	}
-	length, err := s.peekUintOrIntStructField(st, a, "count")
-	if err != nil {
-		return 0, fmt.Errorf("reading map: %s", err)
-	}
-	return uint64(length), nil
-}
diff --git a/server/print.go b/server/print.go
deleted file mode 100644
index e370498..0000000
--- a/server/print.go
+++ /dev/null
@@ -1,536 +0,0 @@
-// Copyright 2014 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 server
-
-import (
-	"bytes"
-	"fmt"
-
-	"golang.org/x/debug/arch"
-	"golang.org/x/debug/dwarf"
-)
-
-// typeAndAddress associates an address in the target with a DWARF type.
-type typeAndAddress struct {
-	Type    dwarf.Type
-	Address uint64
-}
-
-// Routines to print a value using DWARF type descriptions.
-// TODO: Does this deserve its own package? It has no dependencies on Server.
-
-// A Printer pretty-prints values in the target address space.
-// It can be reused after each printing operation to avoid unnecessary
-// allocations. However, it is not safe for concurrent access.
-type Printer struct {
-	err      error // Sticky error value.
-	server   *Server
-	dwarf    *dwarf.Data
-	arch     *arch.Architecture
-	printBuf bytes.Buffer            // Accumulates the output.
-	visited  map[typeAndAddress]bool // Prevents looping on cyclic data.
-}
-
-// printf prints to printBuf.
-func (p *Printer) printf(format string, args ...interface{}) {
-	fmt.Fprintf(&p.printBuf, format, args...)
-}
-
-// errorf prints the error to printBuf, then sets the sticky error for the
-// printer, if not already set.
-func (p *Printer) errorf(format string, args ...interface{}) {
-	fmt.Fprintf(&p.printBuf, "<"+format+">", args...)
-	if p.err != nil {
-		return
-	}
-	p.err = fmt.Errorf(format, args...)
-}
-
-// NewPrinter returns a printer that can use the Server to access and print
-// values of the specified architecture described by the provided DWARF data.
-func NewPrinter(arch *arch.Architecture, dwarf *dwarf.Data, server *Server) *Printer {
-	return &Printer{
-		server:  server,
-		arch:    arch,
-		dwarf:   dwarf,
-		visited: make(map[typeAndAddress]bool),
-	}
-}
-
-// reset resets the Printer. It must be called before starting a new
-// printing operation.
-func (p *Printer) reset() {
-	p.err = nil
-	p.printBuf.Reset()
-	// Just wipe the map rather than reallocating. It's almost always tiny.
-	for k := range p.visited {
-		delete(p.visited, k)
-	}
-}
-
-// Sprint returns the pretty-printed value of the item with the given name, such as "main.global".
-func (p *Printer) Sprint(name string) (string, error) {
-	entry, err := p.dwarf.LookupEntry(name)
-	if err != nil {
-		return "", err
-	}
-	p.reset()
-	switch entry.Tag {
-	case dwarf.TagVariable: // TODO: What other entries have global location attributes?
-		var a uint64
-		iface := entry.Val(dwarf.AttrLocation)
-		if iface != nil {
-			a = p.decodeLocation(iface.([]byte))
-		}
-		p.printEntryValueAt(entry, a)
-	default:
-		p.errorf("unrecognized entry type %s", entry.Tag)
-	}
-	return p.printBuf.String(), p.err
-}
-
-// Figure 24 of DWARF v4.
-const (
-	locationAddr = 0x03
-)
-
-// decodeLocation decodes the dwarf data describing an address.
-func (p *Printer) decodeLocation(data []byte) uint64 {
-	switch data[0] {
-	case locationAddr:
-		return p.arch.Uintptr(data[1:])
-	default:
-		p.errorf("unimplemented location type %#x", data[0])
-	}
-	return 0
-}
-
-// SprintEntry returns the pretty-printed value of the item with the specified DWARF Entry and address.
-func (p *Printer) SprintEntry(entry *dwarf.Entry, a uint64) (string, error) {
-	p.reset()
-	p.printEntryValueAt(entry, a)
-	return p.printBuf.String(), p.err
-}
-
-// printEntryValueAt pretty-prints the data at the specified address.
-// using the type information in the Entry.
-func (p *Printer) printEntryValueAt(entry *dwarf.Entry, a uint64) {
-	if a == 0 {
-		p.printf("<nil>")
-		return
-	}
-	switch entry.Tag {
-	case dwarf.TagVariable, dwarf.TagFormalParameter:
-		// OK
-	default:
-		p.errorf("unrecognized entry type %s", entry.Tag)
-		return
-	}
-	iface := entry.Val(dwarf.AttrType)
-	if iface == nil {
-		p.errorf("no type")
-		return
-	}
-	typ, err := p.dwarf.Type(iface.(dwarf.Offset))
-	if err != nil {
-		p.errorf("type lookup: %v", err)
-		return
-	}
-	p.printValueAt(typ, a)
-}
-
-// printValueAt pretty-prints the data at the specified address.
-// using the provided type information.
-func (p *Printer) printValueAt(typ dwarf.Type, a uint64) {
-	if a != 0 {
-		// Check if we are repeating the same type and address.
-		ta := typeAndAddress{typ, a}
-		if p.visited[ta] {
-			p.printf("(%v %#x)", typ, a)
-			return
-		}
-		p.visited[ta] = true
-	}
-	switch typ := typ.(type) {
-	case *dwarf.BoolType:
-		if typ.ByteSize != 1 {
-			p.errorf("unrecognized bool size %d", typ.ByteSize)
-			return
-		}
-		if b, err := p.server.peekUint8(a); err != nil {
-			p.errorf("reading bool: %s", err)
-		} else {
-			p.printf("%t", b != 0)
-		}
-	case *dwarf.PtrType:
-		if ptr, err := p.server.peekPtr(a); err != nil {
-			p.errorf("reading pointer: %s", err)
-		} else {
-			p.printf("%#x", ptr)
-		}
-	case *dwarf.IntType:
-		// Sad we can't tell a rune from an int32.
-		if i, err := p.server.peekInt(a, typ.ByteSize); err != nil {
-			p.errorf("reading integer: %s", err)
-		} else {
-			p.printf("%d", i)
-		}
-	case *dwarf.UintType:
-		if u, err := p.server.peekUint(a, typ.ByteSize); err != nil {
-			p.errorf("reading unsigned integer: %s", err)
-		} else {
-			p.printf("%d", u)
-		}
-	case *dwarf.FloatType:
-		buf := make([]byte, typ.ByteSize)
-		if err := p.server.peekBytes(a, buf); err != nil {
-			p.errorf("reading float: %s", err)
-			return
-		}
-		switch typ.ByteSize {
-		case 4:
-			p.printf("%g", p.arch.Float32(buf))
-		case 8:
-			p.printf("%g", p.arch.Float64(buf))
-		default:
-			p.errorf("unrecognized float size %d", typ.ByteSize)
-		}
-	case *dwarf.ComplexType:
-		buf := make([]byte, typ.ByteSize)
-		if err := p.server.peekBytes(a, buf); err != nil {
-			p.errorf("reading complex: %s", err)
-			return
-		}
-		switch typ.ByteSize {
-		case 8:
-			p.printf("%g", p.arch.Complex64(buf))
-		case 16:
-			p.printf("%g", p.arch.Complex128(buf))
-		default:
-			p.errorf("unrecognized complex size %d", typ.ByteSize)
-		}
-	case *dwarf.StructType:
-		if typ.Kind != "struct" {
-			// Could be "class" or "union".
-			p.errorf("can't handle struct type %s", typ.Kind)
-			return
-		}
-		p.printf("%s {", typ.String())
-		for i, field := range typ.Field {
-			if i != 0 {
-				p.printf(", ")
-			}
-			p.printValueAt(field.Type, a+uint64(field.ByteOffset))
-		}
-		p.printf("}")
-	case *dwarf.ArrayType:
-		p.printArrayAt(typ, a)
-	case *dwarf.InterfaceType:
-		p.printInterfaceAt(typ, a)
-	case *dwarf.MapType:
-		p.printMapAt(typ, a)
-	case *dwarf.ChanType:
-		p.printChannelAt(typ, a)
-	case *dwarf.SliceType:
-		p.printSliceAt(typ, a)
-	case *dwarf.StringType:
-		p.printStringAt(typ, a)
-	case *dwarf.TypedefType:
-		p.printValueAt(typ.Type, a)
-	case *dwarf.FuncType:
-		p.printf("%v @%#x ", typ, a)
-	case *dwarf.VoidType:
-		p.printf("void")
-	default:
-		p.errorf("unimplemented type %v", typ)
-	}
-}
-
-func (p *Printer) printArrayAt(typ *dwarf.ArrayType, a uint64) {
-	elemType := typ.Type
-	length := typ.Count
-	stride, ok := p.arrayStride(typ)
-	if !ok {
-		p.errorf("can't determine element size")
-	}
-	p.printf("%s{", typ)
-	n := length
-	if n > 100 {
-		n = 100 // TODO: Have a way to control this?
-	}
-	for i := int64(0); i < n; i++ {
-		if i != 0 {
-			p.printf(", ")
-		}
-		p.printValueAt(elemType, a)
-		a += stride // TODO: Alignment and padding - not given by Type
-	}
-	if n < length {
-		p.printf(", ...")
-	}
-	p.printf("}")
-}
-
-func (p *Printer) printInterfaceAt(t *dwarf.InterfaceType, a uint64) {
-	// t embeds a TypedefType, which may point to another typedef.
-	// The underlying type should be a struct.
-	st, ok := followTypedefs(&t.TypedefType).(*dwarf.StructType)
-	if !ok {
-		p.errorf("bad interface type: not a struct")
-		return
-	}
-	p.printf("(")
-	tab, err := p.server.peekPtrStructField(st, a, "tab")
-	if err != nil {
-		p.errorf("reading interface type: %s", err)
-	} else {
-		f, err := getField(st, "tab")
-		if err != nil {
-			p.errorf("%s", err)
-		} else {
-			p.printTypeOfInterface(f.Type, tab)
-		}
-	}
-	p.printf(", ")
-	data, err := p.server.peekPtrStructField(st, a, "data")
-	if err != nil {
-		p.errorf("reading interface value: %s", err)
-	} else if data == 0 {
-		p.printf("<nil>")
-	} else {
-		p.printf("%#x", data)
-	}
-	p.printf(")")
-}
-
-// printTypeOfInterface prints the type of the given tab pointer.
-func (p *Printer) printTypeOfInterface(t dwarf.Type, a uint64) {
-	if a == 0 {
-		p.printf("<nil>")
-		return
-	}
-	// t should be a pointer to a struct containing _type, which is a pointer to a
-	// struct containing _string, which is the name of the type.
-	// Depending on the compiler version, some of these types can be typedefs, and
-	// _string may be a string or a *string.
-	t1, ok := followTypedefs(t).(*dwarf.PtrType)
-	if !ok {
-		p.errorf("interface's tab is not a pointer")
-		return
-	}
-	t2, ok := followTypedefs(t1.Type).(*dwarf.StructType)
-	if !ok {
-		p.errorf("interface's tab is not a pointer to struct")
-		return
-	}
-	typeField, err := getField(t2, "_type")
-	if err != nil {
-		p.errorf("%s", err)
-		return
-	}
-	t3, ok := followTypedefs(typeField.Type).(*dwarf.PtrType)
-	if !ok {
-		p.errorf("interface's _type is not a pointer")
-		return
-	}
-	t4, ok := followTypedefs(t3.Type).(*dwarf.StructType)
-	if !ok {
-		p.errorf("interface's _type is not a pointer to struct")
-		return
-	}
-	stringField, err := getField(t4, "_string")
-	if err != nil {
-		p.errorf("%s", err)
-		return
-	}
-	if t5, ok := stringField.Type.(*dwarf.PtrType); ok {
-		stringType, ok := t5.Type.(*dwarf.StringType)
-		if !ok {
-			p.errorf("interface _string is a pointer to %T, want string or *string", t5.Type)
-			return
-		}
-		typeAddr, err := p.server.peekPtrStructField(t2, a, "_type")
-		if err != nil {
-			p.errorf("reading interface type: %s", err)
-			return
-		}
-		stringAddr, err := p.server.peekPtrStructField(t4, typeAddr, "_string")
-		if err != nil {
-			p.errorf("reading interface type: %s", err)
-			return
-		}
-		p.printStringAt(stringType, stringAddr)
-	} else {
-		stringType, ok := stringField.Type.(*dwarf.StringType)
-		if !ok {
-			p.errorf("interface _string is a %T, want string or *string", stringField.Type)
-			return
-		}
-		typeAddr, err := p.server.peekPtrStructField(t2, a, "_type")
-		if err != nil {
-			p.errorf("reading interface type: %s", err)
-			return
-		}
-		stringAddr := typeAddr + uint64(stringField.ByteOffset)
-		p.printStringAt(stringType, stringAddr)
-	}
-}
-
-// maxMapValuesToPrint values are printed for each map; any remaining values are
-// truncated to "...".
-const maxMapValuesToPrint = 8
-
-func (p *Printer) printMapAt(typ *dwarf.MapType, a uint64) {
-	count := 0
-	fn := func(keyAddr, valAddr uint64, keyType, valType dwarf.Type) (stop bool) {
-		count++
-		if count > maxMapValuesToPrint {
-			return false
-		}
-		if count > 1 {
-			p.printf(" ")
-		}
-		p.printValueAt(keyType, keyAddr)
-		p.printf(":")
-		p.printValueAt(valType, valAddr)
-		return true
-	}
-	p.printf("map[")
-	if err := p.server.peekMapValues(typ, a, fn); err != nil {
-		p.errorf("reading map values: %s", err)
-	}
-	if count > maxMapValuesToPrint {
-		p.printf(" ...")
-	}
-	p.printf("]")
-}
-
-func (p *Printer) printChannelAt(ct *dwarf.ChanType, a uint64) {
-	p.printf("(chan %s ", ct.ElemType)
-	defer p.printf(")")
-
-	a, err := p.server.peekPtr(a)
-	if err != nil {
-		p.errorf("reading channel: %s", err)
-		return
-	}
-	if a == 0 {
-		p.printf("<nil>")
-		return
-	}
-	p.printf("%#x", a)
-
-	// ct is a typedef for a pointer to a struct.
-	pt, ok := ct.TypedefType.Type.(*dwarf.PtrType)
-	if !ok {
-		p.errorf("bad channel type: not a pointer")
-		return
-	}
-	st, ok := pt.Type.(*dwarf.StructType)
-	if !ok {
-		p.errorf("bad channel type: not a pointer to a struct")
-		return
-	}
-
-	// Print the channel buffer's length (qcount) and capacity (dataqsiz),
-	// if not 0/0.
-	qcount, err := p.server.peekUintOrIntStructField(st, a, "qcount")
-	if err != nil {
-		p.errorf("reading channel: %s", err)
-		return
-	}
-	dataqsiz, err := p.server.peekUintOrIntStructField(st, a, "dataqsiz")
-	if err != nil {
-		p.errorf("reading channel: %s", err)
-		return
-	}
-	if qcount != 0 || dataqsiz != 0 {
-		p.printf(" [%d/%d]", qcount, dataqsiz)
-	}
-}
-
-func (p *Printer) printSliceAt(typ *dwarf.SliceType, a uint64) {
-	// Slices look like a struct with fields array *elemtype, len uint32/64, cap uint32/64.
-	// BUG: Slice header appears to have fields with ByteSize == 0
-	ptr, err := p.server.peekPtrStructField(&typ.StructType, a, "array")
-	if err != nil {
-		p.errorf("reading slice: %s", err)
-		return
-	}
-	length, err := p.server.peekUintOrIntStructField(&typ.StructType, a, "len")
-	if err != nil {
-		p.errorf("reading slice: %s", err)
-		return
-	}
-	// Capacity is not used yet.
-	_, err = p.server.peekUintOrIntStructField(&typ.StructType, a, "cap")
-	if err != nil {
-		p.errorf("reading slice: %s", err)
-		return
-	}
-	elemType := typ.ElemType
-	size, ok := p.sizeof(typ.ElemType)
-	if !ok {
-		p.errorf("can't determine element size")
-	}
-	p.printf("%s{", typ)
-	for i := uint64(0); i < length; i++ {
-		if i != 0 {
-			p.printf(", ")
-		}
-		p.printValueAt(elemType, ptr)
-		ptr += size // TODO: Alignment and padding - not given by Type
-	}
-	p.printf("}")
-}
-
-func (p *Printer) printStringAt(typ *dwarf.StringType, a uint64) {
-	const maxStringSize = 100
-	if s, err := p.server.peekString(typ, a, maxStringSize); err != nil {
-		p.errorf("reading string: %s", err)
-	} else {
-		p.printf("%q", s)
-	}
-}
-
-// sizeof returns the byte size of the type.
-func (p *Printer) sizeof(typ dwarf.Type) (uint64, bool) {
-	size := typ.Size() // Will be -1 if ByteSize is not set.
-	if size >= 0 {
-		return uint64(size), true
-	}
-	switch typ.(type) {
-	case *dwarf.PtrType:
-		// This is the only one we know of, but more may arise.
-		return uint64(p.arch.PointerSize), true
-	}
-	return 0, false
-}
-
-// arrayStride returns the stride of a dwarf.ArrayType in bytes.
-func (p *Printer) arrayStride(t *dwarf.ArrayType) (uint64, bool) {
-	stride := t.StrideBitSize
-	if stride > 0 {
-		return uint64(stride / 8), true
-	}
-	return p.sizeof(t.Type)
-}
-
-// getField finds the *dwarf.StructField in a dwarf.StructType with name fieldName.
-func getField(t *dwarf.StructType, fieldName string) (*dwarf.StructField, error) {
-	var r *dwarf.StructField
-	for _, f := range t.Field {
-		if f.Name == fieldName {
-			if r != nil {
-				return nil, fmt.Errorf("struct definition repeats field %s", fieldName)
-			}
-			r = f
-		}
-	}
-	if r == nil {
-		return nil, fmt.Errorf("struct field %s missing", fieldName)
-	}
-	return r, nil
-}
diff --git a/server/protocol/protocol.go b/server/protocol/protocol.go
deleted file mode 100644
index c08b895..0000000
--- a/server/protocol/protocol.go
+++ /dev/null
@@ -1,164 +0,0 @@
-// Copyright 2014 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 protocol defines the types used to represent calls to the debug server.
-package protocol // import "golang.org/x/debug/server/protocol"
-
-import (
-	"encoding/gob"
-
-	"golang.org/x/debug"
-)
-
-func init() {
-	// Register implementations of debug.Value with gob.
-	gob.Register(debug.Pointer{})
-	gob.Register(debug.Array{})
-	gob.Register(debug.Struct{})
-	gob.Register(debug.Slice{})
-	gob.Register(debug.Map{})
-	gob.Register(debug.String{})
-	gob.Register(debug.Channel{})
-	gob.Register(debug.Func{})
-	gob.Register(debug.Interface{})
-}
-
-// For regularity, each method has a unique Request and a Response type even
-// when not strictly necessary.
-
-// File I/O, at the top because they're simple.
-
-type ReadAtRequest struct {
-	FD     int
-	Len    int
-	Offset int64
-}
-
-type ReadAtResponse struct {
-	Data []byte
-}
-
-type WriteAtRequest struct {
-	FD     int
-	Data   []byte
-	Offset int64
-}
-
-type WriteAtResponse struct {
-	Len int
-}
-
-type CloseRequest struct {
-	FD int
-}
-
-type CloseResponse struct {
-}
-
-// Program methods.
-
-type OpenRequest struct {
-	Name string
-	Mode string
-}
-
-type OpenResponse struct {
-	FD int
-}
-
-type RunRequest struct {
-	Args []string
-}
-
-type RunResponse struct {
-	Status debug.Status
-}
-
-type ResumeRequest struct {
-}
-
-type ResumeResponse struct {
-	Status debug.Status
-}
-
-type BreakpointRequest struct {
-	Address uint64
-}
-
-type BreakpointAtFunctionRequest struct {
-	Function string
-}
-
-type BreakpointAtLineRequest struct {
-	File string
-	Line uint64
-}
-
-type BreakpointResponse struct {
-	PCs []uint64
-}
-
-type DeleteBreakpointsRequest struct {
-	PCs []uint64
-}
-
-type DeleteBreakpointsResponse struct {
-}
-
-type EvalRequest struct {
-	Expr string
-}
-
-type EvalResponse struct {
-	Result []string
-}
-
-type EvaluateRequest struct {
-	Expression string
-}
-
-type EvaluateResponse struct {
-	Result debug.Value
-}
-
-type FramesRequest struct {
-	Count int
-}
-
-type FramesResponse struct {
-	Frames []debug.Frame
-}
-
-type VarByNameRequest struct {
-	Name string
-}
-
-type VarByNameResponse struct {
-	Var debug.Var
-}
-
-type ValueRequest struct {
-	Var debug.Var
-}
-
-type ValueResponse struct {
-	Value debug.Value
-}
-
-type MapElementRequest struct {
-	Map   debug.Map
-	Index uint64
-}
-
-type MapElementResponse struct {
-	Key   debug.Var
-	Value debug.Var
-}
-
-type GoroutinesRequest struct {
-}
-
-type GoroutinesResponse struct {
-	Goroutines []*debug.Goroutine
-}
diff --git a/server/ptrace.go b/server/ptrace.go
deleted file mode 100644
index 068e234..0000000
--- a/server/ptrace.go
+++ /dev/null
@@ -1,145 +0,0 @@
-// Copyright 2014 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 server
-
-import (
-	"fmt"
-	"os"
-	"runtime"
-	"syscall"
-	"time"
-)
-
-// ptraceRun runs all the closures from fc on a dedicated OS thread. Errors
-// are returned on ec. Both channels must be unbuffered, to ensure that the
-// resultant error is sent back to the same goroutine that sent the closure.
-func ptraceRun(fc chan func() error, ec chan error) {
-	if cap(fc) != 0 || cap(ec) != 0 {
-		panic("ptraceRun was given buffered channels")
-	}
-	runtime.LockOSThread()
-	for f := range fc {
-		ec <- f()
-	}
-}
-
-func (s *Server) startProcess(name string, argv []string, attr *os.ProcAttr) (proc *os.Process, err error) {
-	s.fc <- func() error {
-		var err1 error
-		proc, err1 = os.StartProcess(name, argv, attr)
-		return err1
-	}
-	err = <-s.ec
-	return
-}
-
-func (s *Server) ptraceCont(pid int, signal int) (err error) {
-	s.fc <- func() error {
-		return syscall.PtraceCont(pid, signal)
-	}
-	return <-s.ec
-}
-
-func (s *Server) ptraceGetRegs(pid int, regsout *syscall.PtraceRegs) (err error) {
-	s.fc <- func() error {
-		return syscall.PtraceGetRegs(pid, regsout)
-	}
-	return <-s.ec
-}
-
-func (s *Server) ptracePeek(pid int, addr uintptr, out []byte) (err error) {
-	s.fc <- func() error {
-		n, err := syscall.PtracePeekText(pid, addr, out)
-		if err != nil {
-			return err
-		}
-		if n != len(out) {
-			return fmt.Errorf("ptracePeek: peeked %d bytes, want %d", n, len(out))
-		}
-		return nil
-	}
-	return <-s.ec
-}
-
-func (s *Server) ptracePoke(pid int, addr uintptr, data []byte) (err error) {
-	s.fc <- func() error {
-		n, err := syscall.PtracePokeText(pid, addr, data)
-		if err != nil {
-			return err
-		}
-		if n != len(data) {
-			return fmt.Errorf("ptracePoke: poked %d bytes, want %d", n, len(data))
-		}
-		return nil
-	}
-	return <-s.ec
-}
-
-func (s *Server) ptraceSetOptions(pid int, options int) (err error) {
-	s.fc <- func() error {
-		return syscall.PtraceSetOptions(pid, options)
-	}
-	return <-s.ec
-}
-
-func (s *Server) ptraceSetRegs(pid int, regs *syscall.PtraceRegs) (err error) {
-	s.fc <- func() error {
-		return syscall.PtraceSetRegs(pid, regs)
-	}
-	return <-s.ec
-}
-
-func (s *Server) ptraceSingleStep(pid int) (err error) {
-	s.fc <- func() error {
-		return syscall.PtraceSingleStep(pid)
-	}
-	return <-s.ec
-}
-
-type breakpointsChangedError struct {
-	call call
-}
-
-func (*breakpointsChangedError) Error() string {
-	return "breakpoints changed"
-}
-
-func (s *Server) wait(pid int, allowBreakpointsChange bool) (wpid int, status syscall.WaitStatus, err error) {
-	// We poll syscall.Wait4 with WNOHANG, sleeping in between, as a poor man's
-	// waitpid-with-timeout. This allows adding and removing breakpoints
-	// concurrently with waiting to hit an existing breakpoint.
-	f := func() error {
-		var err1 error
-		wpid, err1 = syscall.Wait4(pid, &status, syscall.WALL|syscall.WNOHANG, nil)
-		return err1
-	}
-
-	const (
-		minSleep = 1 * time.Microsecond
-		maxSleep = 100 * time.Millisecond
-	)
-	for sleep := minSleep; ; {
-		s.fc <- f
-		err = <-s.ec
-
-		// wpid == 0 means that wait found nothing (and returned due to WNOHANG).
-		if wpid != 0 {
-			return
-		}
-
-		if allowBreakpointsChange {
-			select {
-			case c := <-s.breakpointc:
-				return 0, 0, &breakpointsChangedError{c}
-			default:
-			}
-		}
-
-		time.Sleep(sleep)
-		if sleep < maxSleep {
-			sleep *= 10
-		}
-	}
-}
diff --git a/server/server.go b/server/server.go
deleted file mode 100644
index e4caa40..0000000
--- a/server/server.go
+++ /dev/null
@@ -1,1145 +0,0 @@
-// Copyright 2014 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 server provides RPC access to a local program being debugged.
-// It is the remote end of the client implementation of the Program interface.
-package server // import "golang.org/x/debug/server"
-
-//go:generate sh -c "m4 -P eval.m4 > eval.go"
-
-import (
-	"bytes"
-	"errors"
-	"fmt"
-	"os"
-	"regexp"
-	"strconv"
-	"strings"
-	"sync"
-	"syscall"
-
-	"golang.org/x/debug"
-	"golang.org/x/debug/arch"
-	"golang.org/x/debug/dwarf"
-	"golang.org/x/debug/elf"
-	"golang.org/x/debug/macho"
-	"golang.org/x/debug/server/protocol"
-)
-
-type breakpoint struct {
-	pc        uint64
-	origInstr [arch.MaxBreakpointSize]byte
-}
-
-type call struct {
-	req, resp interface{}
-	errc      chan error
-}
-
-type Server struct {
-	arch       arch.Architecture
-	executable string // Name of executable.
-	dwarfData  *dwarf.Data
-
-	breakpointc chan call
-	otherc      chan call
-
-	fc chan func() error
-	ec chan error
-
-	proc            *os.Process
-	procIsUp        bool
-	stoppedPid      int
-	stoppedRegs     syscall.PtraceRegs
-	topOfStackAddrs []uint64
-	breakpoints     map[uint64]breakpoint
-	files           []*file // Index == file descriptor.
-	printer         *Printer
-
-	// goroutineStack reads the stack of a (non-running) goroutine.
-	goroutineStack     func(uint64) ([]debug.Frame, error)
-	goroutineStackOnce sync.Once
-}
-
-// peek implements the Peeker interface required by the printer.
-func (s *Server) peek(offset uintptr, buf []byte) error {
-	return s.ptracePeek(s.stoppedPid, offset, buf)
-}
-
-// New parses the executable and builds local data structures for answering requests.
-// It returns a Server ready to serve requests about the executable.
-func New(executable string) (*Server, error) {
-	fd, err := os.Open(executable)
-	if err != nil {
-		return nil, err
-	}
-	defer fd.Close()
-	architecture, dwarfData, err := loadExecutable(fd)
-	if err != nil {
-		return nil, err
-	}
-	srv := &Server{
-		arch:        *architecture,
-		executable:  executable,
-		dwarfData:   dwarfData,
-		breakpointc: make(chan call),
-		otherc:      make(chan call),
-		fc:          make(chan func() error),
-		ec:          make(chan error),
-		breakpoints: make(map[uint64]breakpoint),
-	}
-	srv.printer = NewPrinter(architecture, dwarfData, srv)
-	go ptraceRun(srv.fc, srv.ec)
-	go srv.loop()
-	return srv, nil
-}
-
-func loadExecutable(f *os.File) (*arch.Architecture, *dwarf.Data, error) {
-	// TODO: How do we detect NaCl?
-	if obj, err := elf.NewFile(f); err == nil {
-		dwarfData, err := obj.DWARF()
-		if err != nil {
-			return nil, nil, err
-		}
-
-		switch obj.Machine {
-		case elf.EM_ARM:
-			return &arch.ARM, dwarfData, nil
-		case elf.EM_386:
-			switch obj.Class {
-			case elf.ELFCLASS32:
-				return &arch.X86, dwarfData, nil
-			case elf.ELFCLASS64:
-				return &arch.AMD64, dwarfData, nil
-			}
-		case elf.EM_X86_64:
-			return &arch.AMD64, dwarfData, nil
-		}
-		return nil, nil, fmt.Errorf("unrecognized ELF architecture")
-	}
-	if obj, err := macho.NewFile(f); err == nil {
-		dwarfData, err := obj.DWARF()
-		if err != nil {
-			return nil, nil, err
-		}
-
-		/* TODO
-		table, err := parseMachO(obj)
-		if err != nil {
-			return nil, nil, err
-		}
-		*/
-		switch obj.Cpu {
-		case macho.Cpu386:
-			return &arch.X86, dwarfData, nil
-		case macho.CpuAmd64:
-			return &arch.AMD64, dwarfData, nil
-		}
-		return nil, nil, fmt.Errorf("unrecognized Mach-O architecture")
-	}
-	return nil, nil, fmt.Errorf("unrecognized binary format")
-}
-
-func (s *Server) loop() {
-	for {
-		var c call
-		select {
-		case c = <-s.breakpointc:
-		case c = <-s.otherc:
-		}
-		s.dispatch(c)
-	}
-}
-
-func (s *Server) dispatch(c call) {
-	switch req := c.req.(type) {
-	case *protocol.BreakpointRequest:
-		c.errc <- s.handleBreakpoint(req, c.resp.(*protocol.BreakpointResponse))
-	case *protocol.BreakpointAtFunctionRequest:
-		c.errc <- s.handleBreakpointAtFunction(req, c.resp.(*protocol.BreakpointResponse))
-	case *protocol.BreakpointAtLineRequest:
-		c.errc <- s.handleBreakpointAtLine(req, c.resp.(*protocol.BreakpointResponse))
-	case *protocol.DeleteBreakpointsRequest:
-		c.errc <- s.handleDeleteBreakpoints(req, c.resp.(*protocol.DeleteBreakpointsResponse))
-	case *protocol.CloseRequest:
-		c.errc <- s.handleClose(req, c.resp.(*protocol.CloseResponse))
-	case *protocol.EvalRequest:
-		c.errc <- s.handleEval(req, c.resp.(*protocol.EvalResponse))
-	case *protocol.EvaluateRequest:
-		c.errc <- s.handleEvaluate(req, c.resp.(*protocol.EvaluateResponse))
-	case *protocol.FramesRequest:
-		c.errc <- s.handleFrames(req, c.resp.(*protocol.FramesResponse))
-	case *protocol.OpenRequest:
-		c.errc <- s.handleOpen(req, c.resp.(*protocol.OpenResponse))
-	case *protocol.ReadAtRequest:
-		c.errc <- s.handleReadAt(req, c.resp.(*protocol.ReadAtResponse))
-	case *protocol.ResumeRequest:
-		c.errc <- s.handleResume(req, c.resp.(*protocol.ResumeResponse))
-	case *protocol.RunRequest:
-		c.errc <- s.handleRun(req, c.resp.(*protocol.RunResponse))
-	case *protocol.VarByNameRequest:
-		c.errc <- s.handleVarByName(req, c.resp.(*protocol.VarByNameResponse))
-	case *protocol.ValueRequest:
-		c.errc <- s.handleValue(req, c.resp.(*protocol.ValueResponse))
-	case *protocol.MapElementRequest:
-		c.errc <- s.handleMapElement(req, c.resp.(*protocol.MapElementResponse))
-	case *protocol.GoroutinesRequest:
-		c.errc <- s.handleGoroutines(req, c.resp.(*protocol.GoroutinesResponse))
-	default:
-		panic(fmt.Sprintf("unexpected call request type %T", c.req))
-	}
-}
-
-func (s *Server) call(c chan call, req, resp interface{}) error {
-	errc := make(chan error)
-	c <- call{req, resp, errc}
-	return <-errc
-}
-
-type file struct {
-	mode  string
-	index int
-	f     debug.File
-}
-
-func (s *Server) Open(req *protocol.OpenRequest, resp *protocol.OpenResponse) error {
-	return s.call(s.otherc, req, resp)
-}
-
-func (s *Server) handleOpen(req *protocol.OpenRequest, resp *protocol.OpenResponse) error {
-	// TODO: Better simulation. For now we just open the named OS file.
-	var flag int
-	switch req.Mode {
-	case "r":
-		flag = os.O_RDONLY
-	case "w":
-		flag = os.O_WRONLY
-	case "rw":
-		flag = os.O_RDWR
-	default:
-		return fmt.Errorf("Open: bad open mode %q", req.Mode)
-	}
-	osFile, err := os.OpenFile(req.Name, flag, 0)
-	if err != nil {
-		return err
-	}
-	// Find a file descriptor (index) slot.
-	index := 0
-	for ; index < len(s.files) && s.files[index] != nil; index++ {
-	}
-	f := &file{
-		mode:  req.Mode,
-		index: index,
-		f:     osFile,
-	}
-	if index == len(s.files) {
-		s.files = append(s.files, f)
-	} else {
-		s.files[index] = f
-	}
-	return nil
-}
-
-func (s *Server) ReadAt(req *protocol.ReadAtRequest, resp *protocol.ReadAtResponse) error {
-	return s.call(s.otherc, req, resp)
-}
-
-func (s *Server) handleReadAt(req *protocol.ReadAtRequest, resp *protocol.ReadAtResponse) error {
-	fd := req.FD
-	if fd < 0 || len(s.files) <= fd || s.files[fd] == nil {
-		return fmt.Errorf("ReadAt: bad file descriptor %d", fd)
-	}
-	f := s.files[fd]
-	buf := make([]byte, req.Len) // TODO: Don't allocate every time
-	n, err := f.f.ReadAt(buf, req.Offset)
-	resp.Data = buf[:n]
-	return err
-}
-
-func (s *Server) Close(req *protocol.CloseRequest, resp *protocol.CloseResponse) error {
-	return s.call(s.otherc, req, resp)
-}
-
-func (s *Server) handleClose(req *protocol.CloseRequest, resp *protocol.CloseResponse) error {
-	fd := req.FD
-	if fd < 0 || fd >= len(s.files) || s.files[fd] == nil {
-		return fmt.Errorf("Close: bad file descriptor %d", fd)
-	}
-	err := s.files[fd].f.Close()
-	// Remove it regardless
-	s.files[fd] = nil
-	return err
-}
-
-func (s *Server) Run(req *protocol.RunRequest, resp *protocol.RunResponse) error {
-	return s.call(s.otherc, req, resp)
-}
-
-func (s *Server) handleRun(req *protocol.RunRequest, resp *protocol.RunResponse) error {
-	if s.proc != nil {
-		s.proc.Kill()
-		s.proc = nil
-		s.procIsUp = false
-		s.stoppedPid = 0
-		s.stoppedRegs = syscall.PtraceRegs{}
-		s.topOfStackAddrs = nil
-	}
-	argv := append([]string{s.executable}, req.Args...)
-	p, err := s.startProcess(s.executable, argv, &os.ProcAttr{
-		Files: []*os.File{
-			nil,       // TODO: be able to feed the target's stdin.
-			os.Stderr, // TODO: be able to capture the target's stdout.
-			os.Stderr,
-		},
-		Sys: &syscall.SysProcAttr{
-			Pdeathsig: syscall.SIGKILL,
-			Ptrace:    true,
-		},
-	})
-	if err != nil {
-		return err
-	}
-	s.proc = p
-	s.stoppedPid = p.Pid
-	return nil
-}
-
-func (s *Server) Resume(req *protocol.ResumeRequest, resp *protocol.ResumeResponse) error {
-	return s.call(s.otherc, req, resp)
-}
-
-func (s *Server) handleResume(req *protocol.ResumeRequest, resp *protocol.ResumeResponse) error {
-	if s.proc == nil {
-		return fmt.Errorf("Resume: Run did not successfully start a process")
-	}
-
-	if !s.procIsUp {
-		s.procIsUp = true
-		if _, err := s.waitForTrap(s.stoppedPid, false); err != nil {
-			return err
-		}
-		if err := s.ptraceSetOptions(s.stoppedPid, syscall.PTRACE_O_TRACECLONE); err != nil {
-			return fmt.Errorf("ptraceSetOptions: %v", err)
-		}
-	} else if _, ok := s.breakpoints[s.stoppedRegs.Rip]; ok {
-		if err := s.ptraceSingleStep(s.stoppedPid); err != nil {
-			return fmt.Errorf("ptraceSingleStep: %v", err)
-		}
-		if _, err := s.waitForTrap(s.stoppedPid, false); err != nil {
-			return err
-		}
-	}
-
-	for {
-		if err := s.setBreakpoints(); err != nil {
-			return err
-		}
-		if err := s.ptraceCont(s.stoppedPid, 0); err != nil {
-			return fmt.Errorf("ptraceCont: %v", err)
-		}
-
-		wpid, err := s.waitForTrap(-1, true)
-		if err == nil {
-			s.stoppedPid = wpid
-			break
-		}
-		bce, ok := err.(*breakpointsChangedError)
-		if !ok {
-			return err
-		}
-
-		if err := syscall.Kill(s.stoppedPid, syscall.SIGSTOP); err != nil {
-			return fmt.Errorf("kill(SIGSTOP): %v", err)
-		}
-		_, status, err := s.wait(s.stoppedPid, false)
-		if err != nil {
-			return fmt.Errorf("wait (after SIGSTOP): %v", err)
-		}
-		if !status.Stopped() || status.StopSignal() != syscall.SIGSTOP {
-			return fmt.Errorf("wait (after SIGSTOP): unexpected wait status 0x%x", status)
-		}
-
-		if err := s.liftBreakpoints(); err != nil {
-			return err
-		}
-
-	loop:
-		for c := bce.call; ; {
-			s.dispatch(c)
-			select {
-			case c = <-s.breakpointc:
-			default:
-				break loop
-			}
-		}
-	}
-	if err := s.liftBreakpoints(); err != nil {
-		return err
-	}
-
-	if err := s.ptraceGetRegs(s.stoppedPid, &s.stoppedRegs); err != nil {
-		return fmt.Errorf("ptraceGetRegs: %v", err)
-	}
-
-	s.stoppedRegs.Rip -= uint64(s.arch.BreakpointSize)
-
-	if err := s.ptraceSetRegs(s.stoppedPid, &s.stoppedRegs); err != nil {
-		return fmt.Errorf("ptraceSetRegs: %v", err)
-	}
-
-	resp.Status.PC = s.stoppedRegs.Rip
-	resp.Status.SP = s.stoppedRegs.Rsp
-	return nil
-}
-
-func (s *Server) waitForTrap(pid int, allowBreakpointsChange bool) (wpid int, err error) {
-	for {
-		wpid, status, err := s.wait(pid, allowBreakpointsChange)
-		if err != nil {
-			if _, ok := err.(*breakpointsChangedError); !ok {
-				err = fmt.Errorf("wait: %v", err)
-			}
-			return 0, err
-		}
-		if status.StopSignal() == syscall.SIGTRAP && status.TrapCause() != syscall.PTRACE_EVENT_CLONE {
-			return wpid, nil
-		}
-		if status.StopSignal() == syscall.SIGPROF {
-			err = s.ptraceCont(wpid, int(syscall.SIGPROF))
-		} else {
-			err = s.ptraceCont(wpid, 0) // TODO: non-zero when wait catches other signals?
-		}
-		if err != nil {
-			return 0, fmt.Errorf("ptraceCont: %v", err)
-		}
-	}
-}
-
-func (s *Server) Breakpoint(req *protocol.BreakpointRequest, resp *protocol.BreakpointResponse) error {
-	return s.call(s.breakpointc, req, resp)
-}
-
-func (s *Server) handleBreakpoint(req *protocol.BreakpointRequest, resp *protocol.BreakpointResponse) error {
-	return s.addBreakpoints([]uint64{req.Address}, resp)
-}
-
-func (s *Server) BreakpointAtFunction(req *protocol.BreakpointAtFunctionRequest, resp *protocol.BreakpointResponse) error {
-	return s.call(s.breakpointc, req, resp)
-}
-
-func (s *Server) handleBreakpointAtFunction(req *protocol.BreakpointAtFunctionRequest, resp *protocol.BreakpointResponse) error {
-	pc, err := s.functionStartAddress(req.Function)
-	if err != nil {
-		return err
-	}
-	return s.addBreakpoints([]uint64{pc}, resp)
-}
-
-func (s *Server) BreakpointAtLine(req *protocol.BreakpointAtLineRequest, resp *protocol.BreakpointResponse) error {
-	return s.call(s.breakpointc, req, resp)
-}
-
-func (s *Server) handleBreakpointAtLine(req *protocol.BreakpointAtLineRequest, resp *protocol.BreakpointResponse) error {
-	if s.dwarfData == nil {
-		return fmt.Errorf("no DWARF data")
-	}
-	if pcs, err := s.dwarfData.LineToBreakpointPCs(req.File, req.Line); err != nil {
-		return err
-	} else {
-		return s.addBreakpoints(pcs, resp)
-	}
-}
-
-// addBreakpoints adds breakpoints at the addresses in pcs, then stores pcs in the response.
-func (s *Server) addBreakpoints(pcs []uint64, resp *protocol.BreakpointResponse) error {
-	// Get the original code at each address with ptracePeek.
-	bps := make([]breakpoint, 0, len(pcs))
-	for _, pc := range pcs {
-		if _, alreadySet := s.breakpoints[pc]; alreadySet {
-			continue
-		}
-		var bp breakpoint
-		if err := s.ptracePeek(s.stoppedPid, uintptr(pc), bp.origInstr[:s.arch.BreakpointSize]); err != nil {
-			return fmt.Errorf("ptracePeek: %v", err)
-		}
-		bp.pc = pc
-		bps = append(bps, bp)
-	}
-	// If all the peeks succeeded, update the list of breakpoints.
-	for _, bp := range bps {
-		s.breakpoints[bp.pc] = bp
-	}
-	resp.PCs = pcs
-	return nil
-}
-
-func (s *Server) DeleteBreakpoints(req *protocol.DeleteBreakpointsRequest, resp *protocol.DeleteBreakpointsResponse) error {
-	return s.call(s.breakpointc, req, resp)
-}
-
-func (s *Server) handleDeleteBreakpoints(req *protocol.DeleteBreakpointsRequest, resp *protocol.DeleteBreakpointsResponse) error {
-	for _, pc := range req.PCs {
-		delete(s.breakpoints, pc)
-	}
-	return nil
-}
-
-func (s *Server) setBreakpoints() error {
-	for pc := range s.breakpoints {
-		err := s.ptracePoke(s.stoppedPid, uintptr(pc), s.arch.BreakpointInstr[:s.arch.BreakpointSize])
-		if err != nil {
-			return fmt.Errorf("setBreakpoints: %v", err)
-		}
-	}
-	return nil
-}
-
-func (s *Server) liftBreakpoints() error {
-	for pc, breakpoint := range s.breakpoints {
-		err := s.ptracePoke(s.stoppedPid, uintptr(pc), breakpoint.origInstr[:s.arch.BreakpointSize])
-		if err != nil {
-			return fmt.Errorf("liftBreakpoints: %v", err)
-		}
-	}
-	return nil
-}
-
-func (s *Server) Eval(req *protocol.EvalRequest, resp *protocol.EvalResponse) error {
-	return s.call(s.otherc, req, resp)
-}
-
-func (s *Server) handleEval(req *protocol.EvalRequest, resp *protocol.EvalResponse) (err error) {
-	resp.Result, err = s.eval(req.Expr)
-	return err
-}
-
-// eval evaluates an expression.
-// TODO: very weak.
-func (s *Server) eval(expr string) ([]string, error) {
-	switch {
-	case strings.HasPrefix(expr, "re:"):
-		// Regular expression. Return list of symbols.
-		re, err := regexp.Compile(expr[3:])
-		if err != nil {
-			return nil, err
-		}
-		return s.dwarfData.LookupMatchingSymbols(re)
-
-	case strings.HasPrefix(expr, "addr:"):
-		// Symbol lookup. Return address.
-		addr, err := s.functionStartAddress(expr[5:])
-		if err != nil {
-			return nil, err
-		}
-		return []string{fmt.Sprintf("%#x", addr)}, nil
-
-	case strings.HasPrefix(expr, "val:"):
-		// Symbol lookup. Return formatted value.
-		value, err := s.printer.Sprint(expr[4:])
-		if err != nil {
-			return nil, err
-		}
-		return []string{value}, nil
-
-	case strings.HasPrefix(expr, "src:"):
-		// Numerical address. Return file.go:123.
-		addr, err := strconv.ParseUint(expr[4:], 0, 0)
-		if err != nil {
-			return nil, err
-		}
-		file, line, err := s.lookupSource(addr)
-		if err != nil {
-			return nil, err
-		}
-		return []string{fmt.Sprintf("%s:%d", file, line)}, nil
-
-	case len(expr) > 0 && '0' <= expr[0] && expr[0] <= '9':
-		// Numerical address. Return symbol.
-		addr, err := strconv.ParseUint(expr, 0, 0)
-		if err != nil {
-			return nil, err
-		}
-		entry, _, err := s.dwarfData.PCToFunction(addr)
-		if err != nil {
-			return nil, err
-		}
-		name, ok := entry.Val(dwarf.AttrName).(string)
-		if !ok {
-			return nil, fmt.Errorf("function at 0x%x has no name", addr)
-		}
-		return []string{name}, nil
-	}
-
-	return nil, fmt.Errorf("bad expression syntax: %q", expr)
-}
-
-func (s *Server) Evaluate(req *protocol.EvaluateRequest, resp *protocol.EvaluateResponse) error {
-	return s.call(s.otherc, req, resp)
-}
-
-func (s *Server) handleEvaluate(req *protocol.EvaluateRequest, resp *protocol.EvaluateResponse) (err error) {
-	resp.Result, err = s.evalExpression(req.Expression, s.stoppedRegs.Rip, s.stoppedRegs.Rsp)
-	return err
-}
-
-func (s *Server) lookupSource(pc uint64) (file string, line uint64, err error) {
-	if s.dwarfData == nil {
-		return
-	}
-	// TODO: The gosym equivalent also returns the relevant Func. Do that when
-	// DWARF has the same facility.
-	return s.dwarfData.PCToLine(pc)
-}
-
-func (s *Server) Frames(req *protocol.FramesRequest, resp *protocol.FramesResponse) error {
-	return s.call(s.otherc, req, resp)
-}
-
-func (s *Server) handleFrames(req *protocol.FramesRequest, resp *protocol.FramesResponse) error {
-	// TODO: verify that we're stopped.
-	if s.topOfStackAddrs == nil {
-		if err := s.evaluateTopOfStackAddrs(); err != nil {
-			return err
-		}
-	}
-
-	regs := syscall.PtraceRegs{}
-	err := s.ptraceGetRegs(s.stoppedPid, &regs)
-	if err != nil {
-		return err
-	}
-	resp.Frames, err = s.walkStack(regs.Rip, regs.Rsp, req.Count)
-	return err
-}
-
-// walkStack returns up to the requested number of stack frames.
-func (s *Server) walkStack(pc, sp uint64, count int) ([]debug.Frame, error) {
-	var frames []debug.Frame
-
-	var buf [8]byte
-	b := new(bytes.Buffer)
-	r := s.dwarfData.Reader()
-
-	// TODO: handle walking over a split stack.
-	for i := 0; i < count; i++ {
-		b.Reset()
-		file, line, err := s.dwarfData.PCToLine(pc)
-		if err != nil {
-			return frames, err
-		}
-		fpOffset, err := s.dwarfData.PCToSPOffset(pc)
-		if err != nil {
-			return frames, err
-		}
-		fp := sp + uint64(fpOffset)
-		entry, funcEntry, err := s.dwarfData.PCToFunction(pc)
-		if err != nil {
-			return frames, err
-		}
-		frame := debug.Frame{
-			PC:            pc,
-			SP:            sp,
-			File:          file,
-			Line:          line,
-			FunctionStart: funcEntry,
-		}
-		frame.Function, _ = entry.Val(dwarf.AttrName).(string)
-		r.Seek(entry.Offset)
-		for {
-			entry, err := r.Next()
-			if err != nil {
-				return frames, err
-			}
-			if entry.Tag == 0 {
-				break
-			}
-			// TODO: report variables we couldn't parse?
-			if entry.Tag == dwarf.TagFormalParameter {
-				if v, err := s.parseParameterOrLocal(entry, fp); err == nil {
-					frame.Params = append(frame.Params, debug.Param(v))
-				}
-			}
-			if entry.Tag == dwarf.TagVariable {
-				if v, err := s.parseParameterOrLocal(entry, fp); err == nil {
-					frame.Vars = append(frame.Vars, v)
-				}
-			}
-		}
-		frames = append(frames, frame)
-
-		// Walk to the caller's PC and SP.
-		if s.topOfStack(funcEntry) {
-			break
-		}
-		err = s.ptracePeek(s.stoppedPid, uintptr(fp-uint64(s.arch.PointerSize)), buf[:s.arch.PointerSize])
-		if err != nil {
-			return frames, fmt.Errorf("ptracePeek: %v", err)
-		}
-		pc, sp = s.arch.Uintptr(buf[:s.arch.PointerSize]), fp
-	}
-	return frames, nil
-}
-
-// parseParameterOrLocal parses the entry for a function parameter or local
-// variable, which are both specified the same way. fp contains the frame
-// pointer, which is used to calculate the variable location.
-func (s *Server) parseParameterOrLocal(entry *dwarf.Entry, fp uint64) (debug.LocalVar, error) {
-	var v debug.LocalVar
-	v.Name, _ = entry.Val(dwarf.AttrName).(string)
-	if off, err := s.dwarfData.EntryTypeOffset(entry); err != nil {
-		return v, err
-	} else {
-		v.Var.TypeID = uint64(off)
-	}
-	if i := entry.Val(dwarf.AttrLocation); i == nil {
-		return v, fmt.Errorf("missing location description")
-	} else if locationDescription, ok := i.([]uint8); !ok {
-		return v, fmt.Errorf("unsupported location description")
-	} else if offset, err := evalLocation(locationDescription); err != nil {
-		return v, err
-	} else {
-		v.Var.Address = fp + uint64(offset)
-	}
-	return v, nil
-}
-
-func (s *Server) evaluateTopOfStackAddrs() error {
-	var (
-		lookup   func(name string) (uint64, error)
-		indirect bool
-		names    []string
-	)
-	if _, err := s.dwarfData.LookupVariable("runtime.rt0_goPC"); err != nil {
-		// Look for a Go 1.3 binary (or earlier version).
-		lookup, indirect, names = s.functionStartAddress, false, []string{
-			"runtime.goexit",
-			"runtime.mstart",
-			"runtime.mcall",
-			"runtime.morestack",
-			"runtime.lessstack",
-			"_rt0_go",
-		}
-	} else {
-		// Look for a Go 1.4 binary (or later version).
-		lookup = func(name string) (uint64, error) {
-			entry, err := s.dwarfData.LookupVariable(name)
-			if err != nil {
-				return 0, err
-			}
-			return s.dwarfData.EntryLocation(entry)
-		}
-		indirect, names = true, []string{
-			"runtime.goexitPC",
-			"runtime.mstartPC",
-			"runtime.mcallPC",
-			"runtime.morestackPC",
-			"runtime.rt0_goPC",
-		}
-	}
-	// TODO: also look for runtime.externalthreadhandlerp, on Windows.
-
-	addrs := make([]uint64, 0, len(names))
-	for _, name := range names {
-		addr, err := lookup(name)
-		if err != nil {
-			return err
-		}
-		addrs = append(addrs, addr)
-	}
-
-	if indirect {
-		buf := make([]byte, s.arch.PointerSize)
-		for i, addr := range addrs {
-			if err := s.ptracePeek(s.stoppedPid, uintptr(addr), buf); err != nil {
-				return fmt.Errorf("ptracePeek: %v", err)
-			}
-			addrs[i] = s.arch.Uintptr(buf)
-		}
-	}
-
-	s.topOfStackAddrs = addrs
-	return nil
-}
-
-// topOfStack is the out-of-process equivalent of runtime·topofstack.
-func (s *Server) topOfStack(funcEntry uint64) bool {
-	for _, addr := range s.topOfStackAddrs {
-		if addr == funcEntry {
-			return true
-		}
-	}
-	return false
-}
-
-func (s *Server) VarByName(req *protocol.VarByNameRequest, resp *protocol.VarByNameResponse) error {
-	return s.call(s.otherc, req, resp)
-}
-
-func (s *Server) handleVarByName(req *protocol.VarByNameRequest, resp *protocol.VarByNameResponse) error {
-	entry, err := s.dwarfData.LookupVariable(req.Name)
-	if err != nil {
-		return fmt.Errorf("variable %s: %s", req.Name, err)
-	}
-
-	loc, err := s.dwarfData.EntryLocation(entry)
-	if err != nil {
-		return fmt.Errorf("variable %s: %s", req.Name, err)
-	}
-
-	off, err := s.dwarfData.EntryTypeOffset(entry)
-	if err != nil {
-		return fmt.Errorf("variable %s: %s", req.Name, err)
-	}
-
-	resp.Var.TypeID = uint64(off)
-	resp.Var.Address = loc
-	return nil
-}
-
-func (s *Server) Value(req *protocol.ValueRequest, resp *protocol.ValueResponse) error {
-	return s.call(s.otherc, req, resp)
-}
-
-func (s *Server) handleValue(req *protocol.ValueRequest, resp *protocol.ValueResponse) error {
-	t, err := s.dwarfData.Type(dwarf.Offset(req.Var.TypeID))
-	if err != nil {
-		return err
-	}
-	resp.Value, err = s.value(t, req.Var.Address)
-	return err
-}
-
-func (s *Server) MapElement(req *protocol.MapElementRequest, resp *protocol.MapElementResponse) error {
-	return s.call(s.otherc, req, resp)
-}
-
-func (s *Server) handleMapElement(req *protocol.MapElementRequest, resp *protocol.MapElementResponse) error {
-	t, err := s.dwarfData.Type(dwarf.Offset(req.Map.TypeID))
-	if err != nil {
-		return err
-	}
-	m, ok := t.(*dwarf.MapType)
-	if !ok {
-		return fmt.Errorf("variable is not a map")
-	}
-	var count uint64
-	// fn will be called for each element of the map.
-	// When we reach the requested element, we fill in *resp and stop.
-	// TODO: cache locations of elements.
-	fn := func(keyAddr, valAddr uint64, keyType, valType dwarf.Type) bool {
-		count++
-		if count == req.Index+1 {
-			resp.Key = debug.Var{TypeID: uint64(keyType.Common().Offset), Address: keyAddr}
-			resp.Value = debug.Var{TypeID: uint64(valType.Common().Offset), Address: valAddr}
-			return false
-		}
-		return true
-	}
-	if err := s.peekMapValues(m, req.Map.Address, fn); err != nil {
-		return err
-	}
-	if count <= req.Index {
-		// There weren't enough elements.
-		return fmt.Errorf("map has no element %d", req.Index)
-	}
-	return nil
-}
-
-func (s *Server) Goroutines(req *protocol.GoroutinesRequest, resp *protocol.GoroutinesResponse) error {
-	return s.call(s.otherc, req, resp)
-}
-
-const invalidStatus debug.GoroutineStatus = 99
-
-var (
-	gStatus = [...]debug.GoroutineStatus{
-		0: debug.Queued,  // _Gidle
-		1: debug.Queued,  // _Grunnable
-		2: debug.Running, // _Grunning
-		3: debug.Blocked, // _Gsyscall
-		4: debug.Blocked, // _Gwaiting
-		5: invalidStatus, // _Gmoribund_unused
-		6: invalidStatus, // _Gdead
-		7: invalidStatus, // _Genqueue
-		8: debug.Running, // _Gcopystack
-	}
-	gScanStatus = [...]debug.GoroutineStatus{
-		0: invalidStatus, // _Gscan + _Gidle
-		1: debug.Queued,  // _Gscanrunnable
-		2: debug.Running, // _Gscanrunning
-		3: debug.Blocked, // _Gscansyscall
-		4: debug.Blocked, // _Gscanwaiting
-		5: invalidStatus, // _Gscan + _Gmoribund_unused
-		6: invalidStatus, // _Gscan + _Gdead
-		7: debug.Queued,  // _Gscanenqueue
-	}
-	gStatusString = [...]string{
-		0: "idle",
-		1: "runnable",
-		2: "running",
-		3: "syscall",
-		4: "waiting",
-		8: "copystack",
-	}
-	gScanStatusString = [...]string{
-		1: "scanrunnable",
-		2: "scanrunning",
-		3: "scansyscall",
-		4: "scanwaiting",
-		7: "scanenqueue",
-	}
-)
-
-func (s *Server) handleGoroutines(req *protocol.GoroutinesRequest, resp *protocol.GoroutinesResponse) error {
-	// Get DWARF type information for runtime.g.
-	ge, err := s.dwarfData.LookupEntry("runtime.g")
-	if err != nil {
-		return err
-	}
-	t, err := s.dwarfData.Type(ge.Offset)
-	if err != nil {
-		return err
-	}
-	gType, ok := followTypedefs(t).(*dwarf.StructType)
-	if !ok {
-		return errors.New("runtime.g is not a struct")
-	}
-
-	var (
-		allgPtr, allgLen uint64
-		allgPtrOk        bool
-	)
-	for {
-		// Try to read the slice runtime.allgs.
-		allgsEntry, err := s.dwarfData.LookupVariable("runtime.allgs")
-		if err != nil {
-			break
-		}
-		allgsAddr, err := s.dwarfData.EntryLocation(allgsEntry)
-		if err != nil {
-			break
-		}
-		off, err := s.dwarfData.EntryTypeOffset(allgsEntry)
-		if err != nil {
-			break
-		}
-		t, err := s.dwarfData.Type(off)
-		if err != nil {
-			break
-		}
-		allgsType, ok := followTypedefs(t).(*dwarf.SliceType)
-		if !ok {
-			break
-		}
-		allgs, err := s.peekSlice(allgsType, allgsAddr)
-		if err != nil {
-			break
-		}
-
-		allgPtr, allgLen, allgPtrOk = allgs.Address, allgs.Length, true
-		break
-	}
-	if !allgPtrOk {
-		// Read runtime.allg.
-		allgEntry, err := s.dwarfData.LookupVariable("runtime.allg")
-		if err != nil {
-			return err
-		}
-		allgAddr, err := s.dwarfData.EntryLocation(allgEntry)
-		if err != nil {
-			return err
-		}
-		allgPtr, err = s.peekPtr(allgAddr)
-		if err != nil {
-			return fmt.Errorf("reading allg: %v", err)
-		}
-
-		// Read runtime.allglen.
-		allglenEntry, err := s.dwarfData.LookupVariable("runtime.allglen")
-		if err != nil {
-			return err
-		}
-		off, err := s.dwarfData.EntryTypeOffset(allglenEntry)
-		if err != nil {
-			return err
-		}
-		allglenType, err := s.dwarfData.Type(off)
-		if err != nil {
-			return err
-		}
-		allglenAddr, err := s.dwarfData.EntryLocation(allglenEntry)
-		if err != nil {
-			return err
-		}
-		switch followTypedefs(allglenType).(type) {
-		case *dwarf.UintType, *dwarf.IntType:
-			allgLen, err = s.peekUint(allglenAddr, allglenType.Common().ByteSize)
-			if err != nil {
-				return fmt.Errorf("reading allglen: %v", err)
-			}
-		default:
-			// Some runtimes don't specify the type for allglen.  Assume it's uint32.
-			allgLen, err = s.peekUint(allglenAddr, 4)
-			if err != nil {
-				return fmt.Errorf("reading allglen: %v", err)
-			}
-			if allgLen != 0 {
-				break
-			}
-			// Zero?  Let's try uint64.
-			allgLen, err = s.peekUint(allglenAddr, 8)
-			if err != nil {
-				return fmt.Errorf("reading allglen: %v", err)
-			}
-		}
-	}
-
-	// Initialize s.goroutineStack.
-	s.goroutineStackOnce.Do(func() { s.goroutineStackInit(gType) })
-
-	for i := uint64(0); i < allgLen; i++ {
-		// allg is an array of pointers to g structs.  Read allg[i].
-		g, err := s.peekPtr(allgPtr + i*uint64(s.arch.PointerSize))
-		if err != nil {
-			return err
-		}
-		gr := debug.Goroutine{}
-
-		// Read status from the field named "atomicstatus" or "status".
-		status, err := s.peekUintStructField(gType, g, "atomicstatus")
-		if err != nil {
-			status, err = s.peekUintOrIntStructField(gType, g, "status")
-		}
-		if err != nil {
-			return err
-		}
-		if status == 6 {
-			// _Gdead.
-			continue
-		}
-		gr.Status = invalidStatus
-		if status < uint64(len(gStatus)) {
-			gr.Status = gStatus[status]
-			gr.StatusString = gStatusString[status]
-		} else if status^0x1000 < uint64(len(gScanStatus)) {
-			gr.Status = gScanStatus[status^0x1000]
-			gr.StatusString = gScanStatusString[status^0x1000]
-		}
-		if gr.Status == invalidStatus {
-			return fmt.Errorf("unexpected goroutine status 0x%x", status)
-		}
-		if status == 4 || status == 0x1004 {
-			// _Gwaiting or _Gscanwaiting.
-			// Try reading waitreason to get a better value for StatusString.
-			// Depending on the runtime, waitreason may be a Go string or a C string.
-			if waitreason, err := s.peekStringStructField(gType, g, "waitreason", 80); err == nil {
-				if waitreason != "" {
-					gr.StatusString = waitreason
-				}
-			} else if ptr, err := s.peekPtrStructField(gType, g, "waitreason"); err == nil {
-				waitreason := s.peekCString(ptr, 80)
-				if waitreason != "" {
-					gr.StatusString = waitreason
-				}
-			}
-		}
-
-		gr.ID, err = s.peekIntStructField(gType, g, "goid")
-		if err != nil {
-			return err
-		}
-
-		// Best-effort attempt to get the names of the goroutine function and the
-		// function that created the goroutine.  They aren't always available.
-		functionName := func(pc uint64) string {
-			entry, _, err := s.dwarfData.PCToFunction(pc)
-			if err != nil {
-				return ""
-			}
-			name, _ := entry.Val(dwarf.AttrName).(string)
-			return name
-		}
-		if startpc, err := s.peekUintStructField(gType, g, "startpc"); err == nil {
-			gr.Function = functionName(startpc)
-		}
-		if gopc, err := s.peekUintStructField(gType, g, "gopc"); err == nil {
-			gr.Caller = functionName(gopc)
-		}
-		if gr.Status != debug.Running {
-			// TODO: running goroutines too.
-			gr.StackFrames, _ = s.goroutineStack(g)
-		}
-
-		resp.Goroutines = append(resp.Goroutines, &gr)
-	}
-
-	return nil
-}
-
-// TODO: let users specify how many frames they want.  10 will be enough to
-// determine the reason a goroutine is blocked.
-const goroutineStackFrameCount = 10
-
-// goroutineStackInit initializes s.goroutineStack.
-func (s *Server) goroutineStackInit(gType *dwarf.StructType) {
-	// If we fail to read the DWARF data needed for s.goroutineStack, calling it
-	// will always return the error that occurred during initialization.
-	var err error // err is captured by the func below.
-	s.goroutineStack = func(gAddr uint64) ([]debug.Frame, error) {
-		return nil, err
-	}
-
-	// Get g field "sched", which contains fields pc and sp.
-	schedField, err := getField(gType, "sched")
-	if err != nil {
-		return
-	}
-	schedOffset := uint64(schedField.ByteOffset)
-	schedType, ok := followTypedefs(schedField.Type).(*dwarf.StructType)
-	if !ok {
-		err = errors.New(`g field "sched" has the wrong type`)
-		return
-	}
-
-	// Get the size of the pc and sp fields and their offsets inside the g struct,
-	// so we can quickly peek those values for each goroutine later.
-	var (
-		schedPCOffset, schedSPOffset     uint64
-		schedPCByteSize, schedSPByteSize int64
-	)
-	for _, x := range []struct {
-		field    string
-		offset   *uint64
-		bytesize *int64
-	}{
-		{"pc", &schedPCOffset, &schedPCByteSize},
-		{"sp", &schedSPOffset, &schedSPByteSize},
-	} {
-		var f *dwarf.StructField
-		f, err = getField(schedType, x.field)
-		if err != nil {
-			return
-		}
-		*x.offset = schedOffset + uint64(f.ByteOffset)
-		switch t := followTypedefs(f.Type).(type) {
-		case *dwarf.UintType, *dwarf.IntType:
-			*x.bytesize = t.Common().ByteSize
-		default:
-			err = fmt.Errorf("gobuf field %q has the wrong type", x.field)
-			return
-		}
-	}
-
-	s.goroutineStack = func(gAddr uint64) ([]debug.Frame, error) {
-		schedPC, err := s.peekUint(gAddr+schedPCOffset, schedPCByteSize)
-		if err != nil {
-			return nil, err
-		}
-		schedSP, err := s.peekUint(gAddr+schedSPOffset, schedSPByteSize)
-		if err != nil {
-			return nil, err
-		}
-		return s.walkStack(schedPC, schedSP, goroutineStackFrameCount)
-	}
-}
diff --git a/server/value.go b/server/value.go
deleted file mode 100644
index e5bb0d2..0000000
--- a/server/value.go
+++ /dev/null
@@ -1,248 +0,0 @@
-// Copyright 2015 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 server
-
-import (
-	"fmt"
-
-	"golang.org/x/debug"
-	"golang.org/x/debug/dwarf"
-)
-
-// value peeks the program's memory at the given address, parsing it as a value of type t.
-func (s *Server) value(t dwarf.Type, addr uint64) (debug.Value, error) {
-	// readBasic reads the memory for a basic type of size n bytes.
-	readBasic := func(n int64) ([]byte, error) {
-		switch n {
-		case 1, 2, 4, 8, 16:
-		default:
-			return nil, fmt.Errorf("invalid size: %d", n)
-		}
-		buf := make([]byte, n)
-		if err := s.peek(uintptr(addr), buf); err != nil {
-			return nil, err
-		}
-		return buf, nil
-	}
-
-	switch t := t.(type) {
-	case *dwarf.CharType, *dwarf.IntType:
-		bs := t.Common().ByteSize
-		buf, err := readBasic(bs)
-		if err != nil {
-			return nil, fmt.Errorf("reading integer: %s", err)
-		}
-		x := s.arch.IntN(buf)
-		switch bs {
-		case 1:
-			return int8(x), nil
-		case 2:
-			return int16(x), nil
-		case 4:
-			return int32(x), nil
-		case 8:
-			return int64(x), nil
-		default:
-			return nil, fmt.Errorf("invalid integer size: %d", bs)
-		}
-	case *dwarf.UcharType, *dwarf.UintType, *dwarf.AddrType:
-		bs := t.Common().ByteSize
-		buf, err := readBasic(bs)
-		if err != nil {
-			return nil, fmt.Errorf("reading unsigned integer: %s", err)
-		}
-		x := s.arch.UintN(buf)
-		switch bs {
-		case 1:
-			return uint8(x), nil
-		case 2:
-			return uint16(x), nil
-		case 4:
-			return uint32(x), nil
-		case 8:
-			return uint64(x), nil
-		default:
-			return nil, fmt.Errorf("invalid unsigned integer size: %d", bs)
-		}
-	case *dwarf.BoolType:
-		bs := t.Common().ByteSize
-		buf, err := readBasic(bs)
-		if err != nil {
-			return nil, fmt.Errorf("reading boolean: %s", err)
-		}
-		for _, b := range buf {
-			if b != 0 {
-				return true, nil
-			}
-		}
-		return false, nil
-	case *dwarf.FloatType:
-		bs := t.Common().ByteSize
-		buf, err := readBasic(bs)
-		if err != nil {
-			return nil, fmt.Errorf("reading float: %s", err)
-		}
-		switch bs {
-		case 4:
-			return s.arch.Float32(buf), nil
-		case 8:
-			return s.arch.Float64(buf), nil
-		default:
-			return nil, fmt.Errorf("invalid float size: %d", bs)
-		}
-	case *dwarf.ComplexType:
-		bs := t.Common().ByteSize
-		buf, err := readBasic(bs)
-		if err != nil {
-			return nil, fmt.Errorf("reading complex: %s", err)
-		}
-		switch bs {
-		case 8:
-			return s.arch.Complex64(buf), nil
-		case 16:
-			return s.arch.Complex128(buf), nil
-		default:
-			return nil, fmt.Errorf("invalid complex size: %d", bs)
-		}
-	case *dwarf.PtrType:
-		bs := t.Common().ByteSize
-		if bs != int64(s.arch.PointerSize) {
-			return nil, fmt.Errorf("invalid pointer size: %d", bs)
-		}
-		buf, err := readBasic(bs)
-		if err != nil {
-			return nil, fmt.Errorf("reading pointer: %s", err)
-		}
-		return debug.Pointer{
-			TypeID:  uint64(t.Type.Common().Offset),
-			Address: uint64(s.arch.Uintptr(buf)),
-		}, nil
-	case *dwarf.SliceType:
-		if s, err := s.peekSlice(t, addr); err != nil {
-			return nil, err
-		} else {
-			return s, nil
-		}
-	case *dwarf.ArrayType:
-		length := t.Count
-		stride := t.StrideBitSize
-		if stride%8 != 0 {
-			return nil, fmt.Errorf("array is not byte-aligned")
-		}
-		return debug.Array{
-			ElementTypeID: uint64(t.Type.Common().Offset),
-			Address:       uint64(addr),
-			Length:        uint64(length),
-			StrideBits:    uint64(stride),
-		}, nil
-	case *dwarf.StructType:
-		fields := make([]debug.StructField, len(t.Field))
-		for i, field := range t.Field {
-			fields[i] = debug.StructField{
-				Name: field.Name,
-				Var: debug.Var{
-					TypeID:  uint64(field.Type.Common().Offset),
-					Address: uint64(addr) + uint64(field.ByteOffset),
-				},
-			}
-		}
-		return debug.Struct{fields}, nil
-	case *dwarf.TypedefType:
-		return s.value(t.Type, addr)
-	case *dwarf.MapType:
-		length, err := s.peekMapLength(t, addr)
-		if err != nil {
-			return nil, err
-		}
-		return debug.Map{
-			TypeID:  uint64(t.Common().Offset),
-			Address: addr,
-			Length:  length,
-		}, nil
-	case *dwarf.StringType:
-		ptr, err := s.peekPtrStructField(&t.StructType, addr, "str")
-		if err != nil {
-			return nil, fmt.Errorf("reading string location: %s", err)
-		}
-		length, err := s.peekUintOrIntStructField(&t.StructType, addr, "len")
-		if err != nil {
-			return nil, fmt.Errorf("reading string length: %s", err)
-		}
-
-		const maxStringSize = 256
-
-		n := length
-		if n > maxStringSize {
-			n = maxStringSize
-		}
-		tmp := make([]byte, n)
-		if err := s.peekBytes(ptr, tmp); err != nil {
-			return nil, fmt.Errorf("reading string contents: %s", err)
-		}
-		return debug.String{Length: length, String: string(tmp)}, nil
-	case *dwarf.ChanType:
-		pt, ok := t.TypedefType.Type.(*dwarf.PtrType)
-		if !ok {
-			return nil, fmt.Errorf("reading channel: type is not a pointer")
-		}
-		st, ok := pt.Type.(*dwarf.StructType)
-		if !ok {
-			return nil, fmt.Errorf("reading channel: type is not a pointer to struct")
-		}
-
-		a, err := s.peekPtr(addr)
-		if err != nil {
-			return nil, fmt.Errorf("reading channel pointer: %s", err)
-		}
-		if a == 0 {
-			// This channel is nil.
-			return debug.Channel{
-				ElementTypeID: uint64(t.ElemType.Common().Offset),
-				Address:       0,
-				Buffer:        0,
-				Length:        0,
-				Capacity:      0,
-				Stride:        uint64(t.ElemType.Common().ByteSize),
-				BufferStart:   0,
-			}, nil
-		}
-
-		buf, err := s.peekPtrStructField(st, a, "buf")
-		if err != nil {
-			return nil, fmt.Errorf("reading channel buffer location: %s", err)
-		}
-		qcount, err := s.peekUintOrIntStructField(st, a, "qcount")
-		if err != nil {
-			return nil, fmt.Errorf("reading channel length: %s", err)
-		}
-		capacity, err := s.peekUintOrIntStructField(st, a, "dataqsiz")
-		if err != nil {
-			return nil, fmt.Errorf("reading channel capacity: %s", err)
-		}
-		recvx, err := s.peekUintOrIntStructField(st, a, "recvx")
-		if err != nil {
-			return nil, fmt.Errorf("reading channel buffer index: %s", err)
-		}
-		return debug.Channel{
-			ElementTypeID: uint64(t.ElemType.Common().Offset),
-			Address:       a,
-			Buffer:        buf,
-			Length:        qcount,
-			Capacity:      capacity,
-			Stride:        uint64(t.ElemType.Common().ByteSize),
-			BufferStart:   recvx,
-		}, nil
-	case *dwarf.FuncType:
-		a, err := s.peekPtr(addr)
-		if err != nil {
-			return nil, fmt.Errorf("reading func: %s", err)
-		}
-		return debug.Func{Address: a}, nil
-	case *dwarf.InterfaceType:
-		return debug.Interface{}, nil
-		// TODO: more types
-	}
-	return nil, fmt.Errorf("Unsupported type %T", t)
-}
diff --git a/tests/peek/peek_test.go b/tests/peek/peek_test.go
deleted file mode 100644
index 12c748f..0000000
--- a/tests/peek/peek_test.go
+++ /dev/null
@@ -1,1060 +0,0 @@
-// Copyright 2014 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 peek_test
-
-import (
-	"flag"
-	"fmt"
-	"log"
-	"os"
-	"os/exec"
-	"reflect"
-	"regexp"
-	"sync"
-	"testing"
-
-	"golang.org/x/debug"
-	"golang.org/x/debug/local"
-	"golang.org/x/debug/remote"
-)
-
-var expectedVarValues = map[string]interface{}{
-	`main.Z_bool_false`: false,
-	`main.Z_bool_true`:  true,
-	`main.Z_complex128`: complex128(1.987654321 - 2.987654321i),
-	`main.Z_complex64`:  complex64(1.54321 + 2.54321i),
-	`main.Z_float32`:    float32(1.54321),
-	`main.Z_float64`:    float64(1.987654321),
-	`main.Z_int16`:      int16(-32321),
-	`main.Z_int32`:      int32(-1987654321),
-	`main.Z_int64`:      int64(-9012345678987654321),
-	`main.Z_int8`:       int8(-121),
-	`main.Z_uint16`:     uint16(54321),
-	`main.Z_uint32`:     uint32(3217654321),
-	`main.Z_uint64`:     uint64(12345678900987654321),
-	`main.Z_uint8`:      uint8(231),
-}
-
-// TODO: the string forms of some types we're testing aren't stable
-var expectedVars = map[string]string{
-	`main.Z_array`:               `[5]int8{-121, 121, 3, 2, 1}`,
-	`main.Z_array_empty`:         `[0]int8{}`,
-	`main.Z_bool_false`:          `false`,
-	`main.Z_bool_true`:           `true`,
-	`main.Z_channel`:             `(chan int16 0xX)`,
-	`main.Z_channel_2`:           `(chan int16 0xX)`,
-	`main.Z_channel_buffered`:    `(chan int16 0xX [6/10])`,
-	`main.Z_channel_nil`:         `(chan int16 <nil>)`,
-	`main.Z_array_of_empties`:    `[2]{}{{} {}, ({} 0xX)}`,
-	`main.Z_complex128`:          `(1.987654321-2.987654321i)`,
-	`main.Z_complex64`:           `(1.54321+2.54321i)`,
-	`main.Z_float32`:             `1.54321`,
-	`main.Z_float64`:             `1.987654321`,
-	`main.Z_func_int8_r_int8`:    `func(int8, *int8) void @0xX `,
-	`main.Z_func_int8_r_pint8`:   `func(int8, **int8) void @0xX `,
-	`main.Z_func_bar`:            `func(*main.FooStruct) void @0xX `,
-	`main.Z_func_nil`:            `func(int8, *int8) void @0xX `,
-	`main.Z_int`:                 `-21`,
-	`main.Z_int16`:               `-32321`,
-	`main.Z_int32`:               `-1987654321`,
-	`main.Z_int64`:               `-9012345678987654321`,
-	`main.Z_int8`:                `-121`,
-	`main.Z_int_typedef`:         `88`,
-	`main.Z_interface`:           `("*main.FooStruct", 0xX)`,
-	`main.Z_interface_nil`:       `(<nil>, <nil>)`,
-	`main.Z_interface_typed_nil`: `("*main.FooStruct", <nil>)`,
-	`main.Z_map`:                 `map[-21:3.54321]`,
-	`main.Z_map_2`:               `map[1024:1]`,
-	`main.Z_map_3`:               `map[1024:1 512:-1]`,
-	`main.Z_map_empty`:           `map[]`,
-	`main.Z_map_nil`:             `map[]`,
-	`main.Z_pointer`:             `0xX`,
-	`main.Z_pointer_nil`:         `0x0`,
-	`main.Z_slice`:               `[]uint8{115, 108, 105, 99, 101}`,
-	`main.Z_slice_2`:             `[]int8{-121, 121}`,
-	`main.Z_slice_nil`:           `[]uint8{}`,
-	`main.Z_string`:              `"I'm a string"`,
-	`main.Z_struct`:              `main.FooStruct {21, "hi"}`,
-	`main.Z_uint`:                `21`,
-	`main.Z_uint16`:              `54321`,
-	`main.Z_uint32`:              `3217654321`,
-	`main.Z_uint64`:              `12345678900987654321`,
-	`main.Z_uint8`:               `231`,
-	`main.Z_uintptr`:             `21`,
-	`main.Z_unsafe_pointer`:      `0xX`,
-	`main.Z_unsafe_pointer_nil`:  `0x0`,
-}
-
-// expectedEvaluate contains expected results of the debug.Evaluate function.
-// A nil value indicates that an error is expected.
-var expectedEvaluate = map[string]debug.Value{
-	`x`:                                                          int16(42),
-	`local_array`:                                                debug.Array{42, 42, 5, 8},
-	`local_channel`:                                              debug.Channel{42, 42, 42, 0, 0, 2, 0},
-	`local_channel_buffered`:                                     debug.Channel{42, 42, 42, 6, 10, 2, 8},
-	`local_map`:                                                  debug.Map{42, 42, 1},
-	`local_map_2`:                                                debug.Map{42, 42, 1},
-	`local_map_3`:                                                debug.Map{42, 42, 2},
-	`local_map_empty`:                                            debug.Map{42, 42, 0},
-	`x + 5`:                                                      int16(47),
-	`x - 5`:                                                      int16(37),
-	`x / 5`:                                                      int16(8),
-	`x % 5`:                                                      int16(2),
-	`x & 2`:                                                      int16(2),
-	`x | 1`:                                                      int16(43),
-	`x ^ 3`:                                                      int16(41),
-	`5 + x`:                                                      int16(47),
-	`5 - x`:                                                      int16(-37),
-	`100 / x`:                                                    int16(2),
-	`100 % x`:                                                    int16(16),
-	`2 & x`:                                                      int16(2),
-	`1 | x`:                                                      int16(43),
-	`3 ^ x`:                                                      int16(41),
-	`12`:                                                         12,
-	`+42`:                                                        42,
-	`23i`:                                                        23i,
-	`34.0`:                                                       34.0,
-	`34.5`:                                                       34.5,
-	`1e5`:                                                        100000.0,
-	`0x42`:                                                       66,
-	`'c'`:                                                        'c',
-	`"de"`:                                                       debug.String{2, `de`},
-	"`ef`":                                                       debug.String{2, `ef`},
-	`"de" + "fg"`:                                                debug.String{4, `defg`},
-	`/* comment */ -5`:                                           -5,
-	`false`:                                                      false,
-	`true`:                                                       true,
-	`!false`:                                                     true,
-	`!true`:                                                      false,
-	`5 + 5`:                                                      10,
-	`true || false`:                                              true,
-	`false || false`:                                             false,
-	`true && false`:                                              false,
-	`true && true`:                                               true,
-	`!(5 > 8)`:                                                   true,
-	`10 + 'a'`:                                                   'k',
-	`10 + 10.5`:                                                  20.5,
-	`10 + 10.5i`:                                                 10 + 10.5i,
-	`'a' + 10.5`:                                                 107.5,
-	`'a' + 10.5i`:                                                97 + 10.5i,
-	`10.5 + 20.5i`:                                               10.5 + 20.5i,
-	`10 * 20`:                                                    200,
-	`10.0 - 20.5`:                                                -10.5,
-	`(6 + 8i) * 4`:                                               24 + 32i,
-	`(6 + 8i) * (1 + 1i)`:                                        -2 + 14i,
-	`(6 + 8i) * (6 - 8i)`:                                        complex128(100),
-	`(6 + 8i) / (3 + 4i)`:                                        complex128(2),
-	`local_array[2]`:                                             int8(3),
-	`&local_array[1]`:                                            debug.Pointer{42, 42},
-	`local_map[-21]`:                                             float32(3.54321),
-	`local_map[+21]`:                                             float32(0),
-	`local_map_3[1024]`:                                          int8(1),
-	`local_map_3[512]`:                                           int8(-1),
-	`local_map_empty[21]`:                                        float32(0),
-	`"hello"[2]`:                                                 uint8('l'),
-	`local_array[1:3][1]`:                                        int8(3),
-	`local_array[0:4][2:3][0]`:                                   int8(3),
-	`local_array[:]`:                                             debug.Slice{debug.Array{42, 42, 5, 8}, 5},
-	`local_array[:2]`:                                            debug.Slice{debug.Array{42, 42, 2, 8}, 5},
-	`local_array[2:]`:                                            debug.Slice{debug.Array{42, 42, 3, 8}, 3},
-	`local_array[1:3]`:                                           debug.Slice{debug.Array{42, 42, 2, 8}, 4},
-	`local_array[:3:4]`:                                          debug.Slice{debug.Array{42, 42, 3, 8}, 4},
-	`local_array[1:3:4]`:                                         debug.Slice{debug.Array{42, 42, 2, 8}, 3},
-	`local_array[1:][1:][1:]`:                                    debug.Slice{debug.Array{42, 42, 2, 8}, 2},
-	`(&local_array)[:]`:                                          debug.Slice{debug.Array{42, 42, 5, 8}, 5},
-	`(&local_array)[:2]`:                                         debug.Slice{debug.Array{42, 42, 2, 8}, 5},
-	`(&local_array)[2:]`:                                         debug.Slice{debug.Array{42, 42, 3, 8}, 3},
-	`(&local_array)[1:3]`:                                        debug.Slice{debug.Array{42, 42, 2, 8}, 4},
-	`(&local_array)[:3:4]`:                                       debug.Slice{debug.Array{42, 42, 3, 8}, 4},
-	`(&local_array)[1:3:4]`:                                      debug.Slice{debug.Array{42, 42, 2, 8}, 3},
-	`lookup("main.Z_array")`:                                     debug.Array{42, 42, 5, 8},
-	`lookup("main.Z_array_empty")`:                               debug.Array{42, 42, 0, 8},
-	`lookup("main.Z_bool_false")`:                                false,
-	`lookup("main.Z_bool_true")`:                                 true,
-	`lookup("main.Z_channel")`:                                   debug.Channel{42, 42, 42, 0, 0, 2, 0},
-	`lookup("main.Z_channel_buffered")`:                          debug.Channel{42, 42, 42, 6, 10, 2, 8},
-	`lookup("main.Z_channel_nil")`:                               debug.Channel{42, 0, 0, 0, 0, 2, 0},
-	`lookup("main.Z_array_of_empties")`:                          debug.Array{42, 42, 2, 0},
-	`lookup("main.Z_complex128")`:                                complex128(1.987654321 - 2.987654321i),
-	`lookup("main.Z_complex64")`:                                 complex64(1.54321 + 2.54321i),
-	`lookup("main.Z_float32")`:                                   float32(1.54321),
-	`lookup("main.Z_float64")`:                                   float64(1.987654321),
-	`lookup("main.Z_func_int8_r_int8")`:                          debug.Func{42},
-	`lookup("main.Z_func_int8_r_pint8")`:                         debug.Func{42},
-	`lookup("main.Z_func_bar")`:                                  debug.Func{42},
-	`lookup("main.Z_func_nil")`:                                  debug.Func{0},
-	`lookup("main.Z_int")`:                                       -21,
-	`lookup("main.Z_int16")`:                                     int16(-32321),
-	`lookup("main.Z_int32")`:                                     int32(-1987654321),
-	`lookup("main.Z_int64")`:                                     int64(-9012345678987654321),
-	`lookup("main.Z_int8")`:                                      int8(-121),
-	`lookup("main.Z_int_typedef")`:                               int16(88),
-	`lookup("main.Z_interface")`:                                 debug.Interface{},
-	`lookup("main.Z_interface_nil")`:                             debug.Interface{},
-	`lookup("main.Z_interface_typed_nil")`:                       debug.Interface{},
-	`lookup("main.Z_map")`:                                       debug.Map{42, 42, 1},
-	`lookup("main.Z_map_2")`:                                     debug.Map{42, 42, 1},
-	`lookup("main.Z_map_3")`:                                     debug.Map{42, 42, 2},
-	`lookup("main.Z_map_empty")`:                                 debug.Map{42, 42, 0},
-	`lookup("main.Z_map_nil")`:                                   debug.Map{42, 42, 0},
-	`lookup("main.Z_pointer")`:                                   debug.Pointer{42, 42},
-	`lookup("main.Z_pointer_nil")`:                               debug.Pointer{42, 0},
-	`lookup("main.Z_slice")`:                                     debug.Slice{debug.Array{42, 42, 5, 8}, 5},
-	`lookup("main.Z_slice_2")`:                                   debug.Slice{debug.Array{42, 42, 2, 8}, 5},
-	`lookup("main.Z_slice_nil")`:                                 debug.Slice{debug.Array{42, 0, 0, 8}, 0},
-	`lookup("main.Z_string")`:                                    debug.String{12, `I'm a string`},
-	`lookup("main.Z_struct")`:                                    debug.Struct{[]debug.StructField{{"a", debug.Var{}}, {"b", debug.Var{}}}},
-	`lookup("main.Z_uint")`:                                      uint(21),
-	`lookup("main.Z_uint16")`:                                    uint16(54321),
-	`lookup("main.Z_uint32")`:                                    uint32(3217654321),
-	`lookup("main.Z_uint64")`:                                    uint64(12345678900987654321),
-	`lookup("main.Z_uint8")`:                                     uint8(231),
-	`lookup("main.Z_uintptr")`:                                   uint(21),
-	`lookup("main.Z_unsafe_pointer")`:                            debug.Pointer{0, 42},
-	`lookup("main.Z_unsafe_pointer_nil")`:                        debug.Pointer{0, 0},
-	`lookup("main.Z_int") + lookup("main.Z_int")`:                -42,
-	`lookup("main.Z_int16") < 0`:                                 true,
-	`lookup("main.Z_uint32") + lookup("main.Z_uint32")`:          uint32(2140341346),
-	`lookup("main.Z_bool_true") || lookup("main.Z_bool_false")`:  true,
-	`lookup("main.Z_bool_true") && lookup("main.Z_bool_false")`:  false,
-	`lookup("main.Z_bool_false") || lookup("main.Z_bool_false")`: false,
-	`!lookup("main.Z_bool_true")`:                                false,
-	`!lookup("main.Z_bool_false")`:                               true,
-	`lookup("main.Z_array")[2]`:                                  int8(3),
-	`lookup("main.Z_array")[1:3][1]`:                             int8(3),
-	`lookup("main.Z_array")[0:4][2:3][0]`:                        int8(3),
-	`lookup("main.Z_array_of_empties")[0]`:                       debug.Struct{},
-	`lookup("main.Z_complex128") * 10.0`:                         complex128(19.87654321 - 29.87654321i),
-	`lookup("main.Z_complex64") * 0.1`:                           complex64(0.154321 + 0.254321i),
-	`lookup("main.Z_float32") * 10.0`:                            float32(15.4321),
-	`lookup("main.Z_float64") * 0.1`:                             float64(0.1987654321),
-	`lookup("main.Z_int") + 1`:                                   int(-20),
-	`lookup("main.Z_int16") - 10`:                                int16(-32331),
-	`lookup("main.Z_int32") / 10`:                                int32(-198765432),
-	`lookup("main.Z_int64") / 10`:                                int64(-901234567898765432),
-	`lookup("main.Z_int8") + 10`:                                 int8(-111),
-	`lookup("main.Z_map")[-21]`:                                  float32(3.54321),
-	`lookup("main.Z_map")[+21]`:                                  float32(0),
-	`lookup("main.Z_map_empty")[21]`:                             float32(0),
-	`lookup("main.Z_slice")[1]`:                                  uint8(108),
-	`lookup("main.Z_slice_2")[1]`:                                int8(121),
-	`lookup("main.Z_slice")[1:5][0:3][1]`:                        uint8('i'),
-	`lookup("main.Z_array")[1:3:4]`:                              debug.Slice{debug.Array{42, 42, 2, 8}, 3},
-	`(&lookup("main.Z_array"))[1:3:4]`:                           debug.Slice{debug.Array{42, 42, 2, 8}, 3},
-	`lookup("main.Z_string") + "!"`:                              debug.String{13, `I'm a string!`},
-	`lookup("main.Z_struct").a`:                                  21,
-	`(&lookup("main.Z_struct")).a`:                               21,
-	`lookup("main.Z_uint")/10`:                                   uint(2),
-	`lookup("main.Z_uint16")/10`:                                 uint16(5432),
-	`lookup("main.Z_uint32")/10`:                                 uint32(321765432),
-	`lookup("main.Z_uint64")/10`:                                 uint64(1234567890098765432),
-	`lookup("main.Z_uint8")/10`:                                  uint8(23),
-	`lookup("main.Z_pointer").a`:                                 21,
-	`(*lookup("main.Z_pointer")).a`:                              21,
-	`(&*lookup("main.Z_pointer")).a`:                             21,
-	`lookup("main.Z_pointer").b`:                                 debug.String{2, `hi`},
-	`(*lookup("main.Z_pointer")).b`:                              debug.String{2, `hi`},
-	`(&*lookup("main.Z_pointer")).b`:                             debug.String{2, `hi`},
-	`lookup("main.Z_map_nil")[32]`:                               float32(0),
-	`&lookup("main.Z_int16")`:                                    debug.Pointer{42, 42},
-	`&lookup("main.Z_array")[1]`:                                 debug.Pointer{42, 42},
-	`&lookup("main.Z_slice")[1]`:                                 debug.Pointer{42, 42},
-	`*&lookup("main.Z_int16")`:                                   int16(-32321),
-	`*&*&*&*&lookup("main.Z_int16")`:                             int16(-32321),
-	`lookup("time.Local")`:                                       debug.Pointer{42, 42},
-	`5 + false`:                                                  nil,
-	``:                                                           nil,
-	`x + ""`:                                                     nil,
-	`x / 0`:                                                      nil,
-	`0 / 0`:                                                      nil,
-	`'a' / ('a'-'a')`:                                            nil,
-	`0.0 / 0.0`:                                                  nil,
-	`3i / 0.0`:                                                   nil,
-	`x % 0`:                                                      nil,
-	`0 % 0`:                                                      nil,
-	`'a' % ('a'-'a')`:                                            nil,
-	`local_array[-2] + 1`:                                        nil,
-	`local_array[22] + 1`:                                        nil,
-	`local_slice[-2] + 1`:                                        nil,
-	`local_slice[22] + 1`:                                        nil,
-	`local_string[-2]`:                                           nil,
-	`local_string[22]`:                                           nil,
-	`"hello"[-2]`:                                                nil,
-	`"hello"[22]`:                                                nil,
-	`local_pointer_nil.a`:                                        nil,
-	`(local_struct).c`:                                           nil,
-	`(&local_struct).c`:                                          nil,
-	`(*local_pointer).c`:                                         nil,
-	`lookup("not a real symbol")`:                                nil,
-	`lookup("x")`:                                                nil,
-	`lookup(x)`:                                                  nil,
-	`lookup(42)`:                                                 nil,
-}
-
-func isHex(r uint8) bool {
-	switch {
-	case '0' <= r && r <= '9':
-		return true
-	case 'a' <= r && r <= 'f':
-		return true
-	case 'A' <= r && r <= 'F':
-		return true
-	default:
-		return false
-	}
-}
-
-// structRE is used by matches to remove 'struct ' from type names, which is not
-// output by every version of the compiler.
-var structRE = regexp.MustCompile("struct *")
-
-// Check s matches the pattern in p.
-// An 'X' in p greedily matches one or more hex characters in s.
-func matches(p, s string) bool {
-	// Remove 'struct' and following spaces from s.
-	s = structRE.ReplaceAllString(s, "")
-	j := 0
-	for i := 0; i < len(p); i++ {
-		if j == len(s) {
-			return false
-		}
-		c := p[i]
-		if c == 'X' {
-			if !isHex(s[j]) {
-				return false
-			}
-			for j < len(s) && isHex(s[j]) {
-				j++
-			}
-			continue
-		}
-		if c != s[j] {
-			return false
-		}
-		j++
-	}
-	return j == len(s)
-}
-
-const (
-	proxySrc  = "golang.org/x/debug/cmd/debugproxy"
-	traceeSrc = "golang.org/x/debug/tests/peek/testdata"
-)
-
-var (
-	// Locations of the proxy and tracee executables.
-	proxyBinary  = "./debugproxy.out"
-	traceeBinary = "./tracee.out"
-	// Onces that ensure initProxy and initTracee are called at most once.
-	proxyOnce  sync.Once
-	traceeOnce sync.Once
-	// Flags for setting the location of the proxy and tracee, so they don't need to be built.
-	proxyFlag  = flag.String("proxy", "", "Location of debugproxy.  If empty, proxy will be built.")
-	traceeFlag = flag.String("target", "", "Location of target.  If empty, target will be built.")
-	// Executables this test has built, which will be removed on completion of the tests.
-	filesToRemove []string
-)
-
-func TestMain(m *testing.M) {
-	flag.Parse()
-	x := m.Run()
-	for _, f := range filesToRemove {
-		os.Remove(f)
-	}
-	os.Exit(x)
-}
-
-func run(name string, args ...string) error {
-	cmd := exec.Command(name, args...)
-	cmd.Stdout = os.Stdout
-	cmd.Stderr = os.Stderr
-	return cmd.Run()
-}
-
-func initProxy() {
-	if *proxyFlag != "" {
-		proxyBinary = *proxyFlag
-		remote.DebugproxyCmd = proxyBinary
-		return
-	}
-	if err := run("go", "build", "-o", proxyBinary, proxySrc); err != nil {
-		log.Fatalf("couldn't build proxy: %v", err)
-	}
-	filesToRemove = append(filesToRemove, proxyBinary)
-	remote.DebugproxyCmd = proxyBinary
-}
-
-func initTracee() {
-	if *traceeFlag != "" {
-		traceeBinary = *traceeFlag
-		return
-	}
-	if err := run("go", "build", "-o", traceeBinary, traceeSrc); err != nil {
-		log.Fatalf("couldn't build target: %v", err)
-	}
-	filesToRemove = append(filesToRemove, traceeBinary)
-}
-
-func TestLocalProgram(t *testing.T) {
-	traceeOnce.Do(initTracee)
-	prog, err := local.New(traceeBinary)
-	if err != nil {
-		t.Fatal("local.New:", err)
-	}
-	testProgram(t, prog)
-}
-
-func TestRemoteProgram(t *testing.T) {
-	traceeOnce.Do(initTracee)
-	proxyOnce.Do(initProxy)
-	prog, err := remote.New("localhost", traceeBinary)
-	if err != nil {
-		t.Fatal("remote.New:", err)
-	}
-	testProgram(t, prog)
-}
-
-func testProgram(t *testing.T, prog debug.Program) {
-	_, err := prog.Run("some", "arguments")
-	if err != nil {
-		log.Fatalf("Run: %v", err)
-	}
-
-	pcs, err := prog.BreakpointAtFunction("main.foo")
-	if err != nil {
-		log.Fatalf("BreakpointAtFunction: %v", err)
-	}
-	fmt.Printf("breakpoints set at %x\n", pcs)
-
-	_, err = prog.Resume()
-	if err != nil {
-		log.Fatalf("Resume: %v", err)
-	}
-
-	gs, err := prog.Goroutines()
-	if err != nil {
-		t.Fatalf("Goroutines(): got error %s", err)
-	}
-	for _, g := range gs {
-		fmt.Println(g)
-		for _, f := range g.StackFrames {
-			fmt.Println(f)
-		}
-	}
-
-	frames, err := prog.Frames(100)
-	if err != nil {
-		log.Fatalf("prog.Frames error: %v", err)
-	}
-	fmt.Printf("%#v\n", frames)
-	if len(frames) == 0 {
-		t.Fatalf("no stack frames returned")
-	}
-	if frames[0].Function != "main.foo" {
-		t.Errorf("function name: got %s expected main.foo", frames[0].Function)
-	}
-	if len(frames[0].Params) != 2 {
-		t.Errorf("got %d parameters, expected 2", len(frames[0].Params))
-	} else {
-		x := frames[0].Params[0]
-		y := frames[0].Params[1]
-		if x.Name != "x" {
-			x, y = y, x
-		}
-		if x.Name != "x" {
-			t.Errorf("parameter name: got %s expected x", x.Name)
-		}
-		if y.Name != "y" {
-			t.Errorf("parameter name: got %s expected y", y.Name)
-		}
-		if val, err := prog.Value(x.Var); err != nil {
-			t.Errorf("value of x: %s", err)
-		} else if val != int16(42) {
-			t.Errorf("value of x: got %T(%v) expected int16(42)", val, val)
-		}
-		if val, err := prog.Value(y.Var); err != nil {
-			t.Errorf("value of y: %s", err)
-		} else if val != float32(1.5) {
-			t.Errorf("value of y: got %T(%v) expected float32(1.5)", val, val)
-		}
-	}
-
-	varnames, err := prog.Eval(`re:main\.Z_.*`)
-	if err != nil {
-		log.Fatalf("prog.Eval error: %v", err)
-	}
-
-	// Evaluate each of the variables found above, and check they match
-	// expectedVars.
-	seen := make(map[string]bool)
-	for _, v := range varnames {
-		val, err := prog.Eval("val:" + v)
-		if err != nil {
-			log.Fatalf("prog.Eval error for %s: %v", v, err)
-		} else {
-			fmt.Printf("%s = %v\n", v, val)
-			if seen[v] {
-				log.Fatalf("repeated variable %s\n", v)
-			}
-			seen[v] = true
-			if len(val) != 1 {
-				log.Fatalf("should be one value for %s\n", v)
-			}
-			expected, ok := expectedVars[v]
-			if !ok {
-				log.Fatalf("unexpected variable %s\n", v)
-			} else {
-				if !matches(expected, val[0]) {
-					log.Fatalf("expected %s = %s\n", v, expected)
-				}
-			}
-		}
-	}
-	for v, e := range expectedVars {
-		if !seen[v] {
-			log.Fatalf("didn't get %s = %s\n", v, e)
-		}
-	}
-
-	// Remove the breakpoint at main.foo.
-	err = prog.DeleteBreakpoints(pcs)
-	if err != nil {
-		log.Fatalf("DeleteBreakpoints: %v", err)
-	}
-
-	// Set a breakpoint at line 125, resume, and check we stopped there.
-	pcsLine125, err := prog.BreakpointAtLine("testdata/main.go", 125)
-	if err != nil {
-		t.Fatal("BreakpointAtLine:", err)
-	}
-	status, err := prog.Resume()
-	if err != nil {
-		log.Fatalf("Resume: %v", err)
-	}
-	stoppedAt := func(pcs []uint64) bool {
-		for _, pc := range pcs {
-			if status.PC == pc {
-				return true
-			}
-		}
-		return false
-	}
-	if !stoppedAt(pcsLine125) {
-		t.Errorf("stopped at %X; expected one of %X.", status.PC, pcsLine125)
-	}
-
-	for k, v := range expectedEvaluate {
-		val, err := prog.Evaluate(k)
-		if v == nil {
-			if err == nil {
-				t.Errorf("got Evaluate(%s) = %v, expected error", k, val)
-			}
-			continue
-		}
-		if err != nil {
-			t.Errorf("Evaluate(%s): got error %s, expected %v", k, err, v)
-			continue
-		}
-		typ := reflect.TypeOf(v)
-		if typ != reflect.TypeOf(val) && typ != reflect.TypeOf(int(0)) && typ != reflect.TypeOf(uint(0)) {
-			t.Errorf("got Evaluate(%s) = %T(%v), expected %T(%v)", k, val, val, v, v)
-			continue
-		}
-
-		// For types with fields like Address, TypeID, etc., we can't know the exact
-		// value, so we only test whether those fields are zero or not.
-		switch v := v.(type) {
-		default:
-			if v != val {
-				t.Errorf("got Evaluate(%s) = %T(%v), expected %T(%v)", k, val, val, v, v)
-			}
-		case debug.Array:
-			val := val.(debug.Array)
-			if v.ElementTypeID == 0 && val.ElementTypeID != 0 {
-				t.Errorf("got Evaluate(%s) = %+v, expected zero ElementTypeID", k, val)
-			}
-			if v.ElementTypeID != 0 && val.ElementTypeID == 0 {
-				t.Errorf("got Evaluate(%s) = %+v, expected non-zero ElementTypeID", k, val)
-			}
-			if v.Address == 0 && val.Address != 0 {
-				t.Errorf("got Evaluate(%s) = %+v, expected zero Address", k, val)
-			}
-			if v.Address != 0 && val.Address == 0 {
-				t.Errorf("got Evaluate(%s) = %+v, expected non-zero Address", k, val)
-			}
-		case debug.Slice:
-			val := val.(debug.Slice)
-			if v.ElementTypeID == 0 && val.ElementTypeID != 0 {
-				t.Errorf("got Evaluate(%s) = %+v, expected zero ElementTypeID", k, val)
-			}
-			if v.ElementTypeID != 0 && val.ElementTypeID == 0 {
-				t.Errorf("got Evaluate(%s) = %+v, expected non-zero ElementTypeID", k, val)
-			}
-			if v.Address == 0 && val.Address != 0 {
-				t.Errorf("got Evaluate(%s) = %+v, expected zero Address", k, val)
-			}
-			if v.Address != 0 && val.Address == 0 {
-				t.Errorf("got Evaluate(%s) = %+v, expected non-zero Address", k, val)
-			}
-		case debug.Map:
-			val := val.(debug.Map)
-			if v.TypeID == 0 && val.TypeID != 0 {
-				t.Errorf("got Evaluate(%s) = %+v, expected zero TypeID", k, val)
-			}
-			if v.TypeID != 0 && val.TypeID == 0 {
-				t.Errorf("got Evaluate(%s) = %+v, expected non-zero TypeID", k, val)
-			}
-			if v.Address == 0 && val.Address != 0 {
-				t.Errorf("got Evaluate(%s) = %+v, expected zero Address", k, val)
-			}
-			if v.Address != 0 && val.Address == 0 {
-				t.Errorf("got Evaluate(%s) = %+v, expected non-zero Address", k, val)
-			}
-		case debug.Pointer:
-			val := val.(debug.Pointer)
-			if v.TypeID == 0 && val.TypeID != 0 {
-				t.Errorf("got Evaluate(%s) = %+v, expected zero TypeID", k, val)
-			}
-			if v.TypeID != 0 && val.TypeID == 0 {
-				t.Errorf("got Evaluate(%s) = %+v, expected non-zero TypeID", k, val)
-			}
-			if v.Address == 0 && val.Address != 0 {
-				t.Errorf("got Evaluate(%s) = %+v, expected zero Address", k, val)
-			}
-			if v.Address != 0 && val.Address == 0 {
-				t.Errorf("got Evaluate(%s) = %+v, expected non-zero Address", k, val)
-			}
-		case debug.Channel:
-			val := val.(debug.Channel)
-			if v.ElementTypeID == 0 && val.ElementTypeID != 0 {
-				t.Errorf("got Evaluate(%s) = %+v, expected zero ElementTypeID", k, val)
-			}
-			if v.ElementTypeID != 0 && val.ElementTypeID == 0 {
-				t.Errorf("got Evaluate(%s) = %+v, expected non-zero ElementTypeID", k, val)
-			}
-			if v.Address == 0 && val.Address != 0 {
-				t.Errorf("got Evaluate(%s) = %+v, expected zero Address", k, val)
-			}
-			if v.Address != 0 && val.Address == 0 {
-				t.Errorf("got Evaluate(%s) = %+v, expected non-zero Address", k, val)
-			}
-			if v.Buffer == 0 && val.Buffer != 0 {
-				t.Errorf("got Evaluate(%s) = %+v, expected zero Buffer", k, val)
-			}
-			if v.Buffer != 0 && val.Buffer == 0 {
-				t.Errorf("got Evaluate(%s) = %+v, expected non-zero Buffer", k, val)
-			}
-		case debug.Struct:
-			val := val.(debug.Struct)
-			if len(v.Fields) != len(val.Fields) {
-				t.Errorf("got Evaluate(%s) = %T(%v), expected %T(%v)", k, val, val, v, v)
-				break
-			}
-			for i := range v.Fields {
-				a := v.Fields[i].Name
-				b := val.Fields[i].Name
-				if a != b {
-					t.Errorf("Evaluate(%s): field name mismatch: %s vs %s", k, a, b)
-					break
-				}
-			}
-		case debug.Func:
-			val := val.(debug.Func)
-			if v.Address == 0 && val.Address != 0 {
-				t.Errorf("got Evaluate(%s) = %+v, expected zero Address", k, val)
-			}
-			if v.Address != 0 && val.Address == 0 {
-				t.Errorf("got Evaluate(%s) = %+v, expected non-zero Address", k, val)
-			}
-		case int:
-			// ints in a remote program can be returned as int32 or int64
-			switch val := val.(type) {
-			case int32:
-				if val != int32(v) {
-					t.Errorf("got Evaluate(%s) = %T(%v), expected %v", k, val, val, v)
-				}
-			case int64:
-				if val != int64(v) {
-					t.Errorf("got Evaluate(%s) = %T(%v), expected %v", k, val, val, v)
-				}
-			default:
-				t.Errorf("got Evaluate(%s) = %T(%v), expected %T(%v)", k, val, val, v, v)
-			}
-		case uint:
-			// uints in a remote program can be returned as uint32 or uint64
-			switch val := val.(type) {
-			case uint32:
-				if val != uint32(v) {
-					t.Errorf("got Evaluate(%s) = %T(%v), expected %v", k, val, val, v)
-				}
-			case uint64:
-				if val != uint64(v) {
-					t.Errorf("got Evaluate(%s) = %T(%v), expected %v", k, val, val, v)
-				}
-			default:
-				t.Errorf("got Evaluate(%s) = %T(%v), expected %T(%v)", k, val, val, v, v)
-			}
-		}
-	}
-
-	// Evaluate a struct.
-	v := `lookup("main.Z_struct")`
-	val, err := prog.Evaluate(v)
-	if err != nil {
-		t.Fatalf("Evaluate: %s", err)
-	}
-	s, ok := val.(debug.Struct)
-	if !ok {
-		t.Fatalf("got Evaluate(%q) = %T(%v), expected debug.Struct", v, val, val)
-	}
-	// Check the values of its fields.
-	if len(s.Fields) != 2 {
-		t.Fatalf("got Evaluate(%q) = %+v, expected 2 fields", v, s)
-	}
-	if v0, err := prog.Value(s.Fields[0].Var); err != nil {
-		t.Errorf("Value: %s", err)
-	} else if v0 != int32(21) && v0 != int64(21) {
-		t.Errorf("Value: got %T(%v), expected 21", v0, v0)
-	}
-	if v1, err := prog.Value(s.Fields[1].Var); err != nil {
-		t.Errorf("Value: %s", err)
-	} else if v1 != (debug.String{2, "hi"}) {
-		t.Errorf("Value: got %T(%v), expected `hi`", v1, v1)
-	}
-
-	// Remove the breakpoint at line 125, set a breakpoint at main.f1 and main.f2,
-	// then delete the breakpoint at main.f1.  Resume, then check we stopped at
-	// main.f2.
-	err = prog.DeleteBreakpoints(pcsLine125)
-	if err != nil {
-		log.Fatalf("DeleteBreakpoints: %v", err)
-	}
-	pcs1, err := prog.BreakpointAtFunction("main.f1")
-	if err != nil {
-		log.Fatalf("BreakpointAtFunction: %v", err)
-	}
-	pcs2, err := prog.BreakpointAtFunction("main.f2")
-	if err != nil {
-		log.Fatalf("BreakpointAtFunction: %v", err)
-	}
-	err = prog.DeleteBreakpoints(pcs1)
-	if err != nil {
-		log.Fatalf("DeleteBreakpoints: %v", err)
-	}
-	status, err = prog.Resume()
-	if err != nil {
-		log.Fatalf("Resume: %v", err)
-	}
-	if !stoppedAt(pcs2) {
-		t.Errorf("stopped at %X; expected one of %X.", status.PC, pcs2)
-	}
-
-	// Check we get the expected results calling VarByName then Value
-	// for the variables in expectedVarValues.
-	for name, exp := range expectedVarValues {
-		if v, err := prog.VarByName(name); err != nil {
-			t.Errorf("VarByName(%s): %s", name, err)
-		} else if val, err := prog.Value(v); err != nil {
-			t.Errorf("value of %s: %s", name, err)
-		} else if val != exp {
-			t.Errorf("value of %s: got %T(%v) want %T(%v)", name, val, val, exp, exp)
-		}
-	}
-
-	// Check some error cases for VarByName and Value.
-	if _, err = prog.VarByName("not a real name"); err == nil {
-		t.Error("VarByName for invalid name: expected error")
-	}
-	if _, err = prog.Value(debug.Var{}); err == nil {
-		t.Error("value of invalid var: expected error")
-	}
-	if v, err := prog.VarByName("main.Z_int16"); err != nil {
-		t.Error("VarByName(main.Z_int16) error:", err)
-	} else {
-		v.Address = 0
-		// v now has a valid type but a bad address.
-		_, err = prog.Value(v)
-		if err == nil {
-			t.Error("value of invalid location: expected error")
-		}
-	}
-
-	// checkValue tests that we can get a Var for a variable with the given name,
-	// that we can then get the value of that Var, and that calling fn for that
-	// value succeeds.
-	checkValue := func(name string, fn func(val debug.Value) error) {
-		if v, err := prog.VarByName(name); err != nil {
-			t.Errorf("VarByName(%s): %s", name, err)
-		} else if val, err := prog.Value(v); err != nil {
-			t.Errorf("value of %s: %s", name, err)
-		} else if err := fn(val); err != nil {
-			t.Errorf("value of %s: %s", name, err)
-		}
-	}
-
-	checkValue("main.Z_uintptr", func(val debug.Value) error {
-		if val != uint32(21) && val != uint64(21) {
-			// Z_uintptr should be an unsigned integer with size equal to the debugged
-			// program's address size.
-			return fmt.Errorf("got %T(%v) want 21", val, val)
-		}
-		return nil
-	})
-
-	checkValue("main.Z_int", func(val debug.Value) error {
-		if val != int32(-21) && val != int64(-21) {
-			return fmt.Errorf("got %T(%v) want -21", val, val)
-		}
-		return nil
-	})
-
-	checkValue("main.Z_uint", func(val debug.Value) error {
-		if val != uint32(21) && val != uint64(21) {
-			return fmt.Errorf("got %T(%v) want 21", val, val)
-		}
-		return nil
-	})
-
-	checkValue("main.Z_pointer", func(val debug.Value) error {
-		if _, ok := val.(debug.Pointer); !ok {
-			return fmt.Errorf("got %T(%v) expected Pointer", val, val)
-		}
-		return nil
-	})
-
-	checkValue("main.Z_pointer_nil", func(val debug.Value) error {
-		if p, ok := val.(debug.Pointer); !ok {
-			return fmt.Errorf("got %T(%v) expected Pointer", val, val)
-		} else if p.Address != 0 {
-			return fmt.Errorf("got %T(%v) expected nil pointer", val, val)
-		}
-		return nil
-	})
-
-	checkValue("main.Z_array", func(val debug.Value) error {
-		a, ok := val.(debug.Array)
-		if !ok {
-			return fmt.Errorf("got %T(%v) expected Array", val, val)
-		}
-		if a.Len() != 5 {
-			return fmt.Errorf("got array length %d expected 5", a.Len())
-		}
-		expected := [5]int8{-121, 121, 3, 2, 1}
-		for i := uint64(0); i < 5; i++ {
-			if v, err := prog.Value(a.Element(i)); err != nil {
-				return fmt.Errorf("reading element %d: %s", i, err)
-			} else if v != expected[i] {
-				return fmt.Errorf("element %d: got %T(%v) want %T(%d)", i, v, v, expected[i], expected[i])
-			}
-		}
-		return nil
-	})
-
-	checkValue("main.Z_slice", func(val debug.Value) error {
-		s, ok := val.(debug.Slice)
-		if !ok {
-			return fmt.Errorf("got %T(%v) expected Slice", val, val)
-		}
-		if s.Len() != 5 {
-			return fmt.Errorf("got slice length %d expected 5", s.Len())
-		}
-		expected := []uint8{115, 108, 105, 99, 101}
-		for i := uint64(0); i < 5; i++ {
-			if v, err := prog.Value(s.Element(i)); err != nil {
-				return fmt.Errorf("reading element %d: %s", i, err)
-			} else if v != expected[i] {
-				return fmt.Errorf("element %d: got %T(%v) want %T(%d)", i, v, v, expected[i], expected[i])
-			}
-		}
-		return nil
-	})
-
-	checkValue("main.Z_map_empty", func(val debug.Value) error {
-		m, ok := val.(debug.Map)
-		if !ok {
-			return fmt.Errorf("got %T(%v) expected Map", val, val)
-		}
-		if m.Length != 0 {
-			return fmt.Errorf("got map length %d expected 0", m.Length)
-		}
-		return nil
-	})
-
-	checkValue("main.Z_map_nil", func(val debug.Value) error {
-		m, ok := val.(debug.Map)
-		if !ok {
-			return fmt.Errorf("got %T(%v) expected Map", val, val)
-		}
-		if m.Length != 0 {
-			return fmt.Errorf("got map length %d expected 0", m.Length)
-		}
-		return nil
-	})
-
-	checkValue("main.Z_map_3", func(val debug.Value) error {
-		m, ok := val.(debug.Map)
-		if !ok {
-			return fmt.Errorf("got %T(%v) expected Map", val, val)
-		}
-		if m.Length != 2 {
-			return fmt.Errorf("got map length %d expected 2", m.Length)
-		}
-		keyVar0, valVar0, err := prog.MapElement(m, 0)
-		if err != nil {
-			return err
-		}
-		keyVar1, valVar1, err := prog.MapElement(m, 1)
-		if err != nil {
-			return err
-		}
-		key0, err := prog.Value(keyVar0)
-		if err != nil {
-			return err
-		}
-		key1, err := prog.Value(keyVar1)
-		if err != nil {
-			return err
-		}
-		val0, err := prog.Value(valVar0)
-		if err != nil {
-			return err
-		}
-		val1, err := prog.Value(valVar1)
-		if err != nil {
-			return err
-		}
-		// The map should contain 1024,1 and 512,-1 in some order.
-		ok1 := key0 == int16(1024) && val0 == int8(1) && key1 == int16(512) && val1 == int8(-1)
-		ok2 := key1 == int16(1024) && val1 == int8(1) && key0 == int16(512) && val0 == int8(-1)
-		if !ok1 && !ok2 {
-			return fmt.Errorf("got values (%d,%d) and (%d,%d), expected (1024,1) and (512,-1) in some order", key0, val0, key1, val1)
-		}
-		_, _, err = prog.MapElement(m, 2)
-		if err == nil {
-			return fmt.Errorf("MapElement: reading at a bad index succeeded, expected error")
-		}
-		return nil
-	})
-
-	checkValue("main.Z_string", func(val debug.Value) error {
-		s, ok := val.(debug.String)
-		if !ok {
-			return fmt.Errorf("got %T(%v) expected String", val, val)
-		}
-		if s.Length != 12 {
-			return fmt.Errorf("got string length %d expected 12", s.Length)
-		}
-		expected := "I'm a string"
-		if s.String != expected {
-			return fmt.Errorf("got %s expected %s", s.String, expected)
-		}
-		return nil
-	})
-
-	checkValue("main.Z_channel", func(val debug.Value) error {
-		c, ok := val.(debug.Channel)
-		if !ok {
-			return fmt.Errorf("got %T(%v) expected Channel", val, val)
-		}
-		if c.Buffer == 0 {
-			return fmt.Errorf("got buffer address %d expected nonzero", c.Buffer)
-		}
-		if c.Length != 0 {
-			return fmt.Errorf("got length %d expected 0", c.Length)
-		}
-		if c.Capacity != 0 {
-			return fmt.Errorf("got capacity %d expected 0", c.Capacity)
-		}
-		return nil
-	})
-
-	checkValue("main.Z_channel_2", func(val debug.Value) error {
-		c, ok := val.(debug.Channel)
-		if !ok {
-			return fmt.Errorf("got %T(%v) expected Channel", val, val)
-		}
-		if c.Buffer == 0 {
-			return fmt.Errorf("got buffer address %d expected nonzero", c.Buffer)
-		}
-		if c.Length != 0 {
-			return fmt.Errorf("got length %d expected 0", c.Length)
-		}
-		if c.Capacity != 0 {
-			return fmt.Errorf("got capacity %d expected 0", c.Capacity)
-		}
-		return nil
-	})
-
-	checkValue("main.Z_channel_nil", func(val debug.Value) error {
-		c, ok := val.(debug.Channel)
-		if !ok {
-			return fmt.Errorf("got %T(%v) expected Channel", val, val)
-		}
-		if c.Buffer != 0 {
-			return fmt.Errorf("got buffer address %d expected 0", c.Buffer)
-		}
-		if c.Length != 0 {
-			return fmt.Errorf("got length %d expected 0", c.Length)
-		}
-		if c.Capacity != 0 {
-			return fmt.Errorf("got capacity %d expected 0", c.Capacity)
-		}
-		return nil
-	})
-
-	checkValue("main.Z_channel_buffered", func(val debug.Value) error {
-		c, ok := val.(debug.Channel)
-		if !ok {
-			return fmt.Errorf("got %T(%v) expected Channel", val, val)
-		}
-		if c.Buffer == 0 {
-			return fmt.Errorf("got buffer address %d expected nonzero", c.Buffer)
-		}
-		if c.Length != 6 {
-			return fmt.Errorf("got length %d expected 6", c.Length)
-		}
-		if c.Capacity != 10 {
-			return fmt.Errorf("got capacity %d expected 10", c.Capacity)
-		}
-		if c.Stride != 2 {
-			return fmt.Errorf("got stride %d expected 2", c.Stride)
-		}
-		expected := []int16{8, 9, 10, 11, 12, 13}
-		for i := uint64(0); i < 6; i++ {
-			if v, err := prog.Value(c.Element(i)); err != nil {
-				return fmt.Errorf("reading element %d: %s", i, err)
-			} else if v != expected[i] {
-				return fmt.Errorf("element %d: got %T(%v) want %T(%d)", i, v, v, expected[i], expected[i])
-			}
-		}
-		v := c.Element(6)
-		if v.Address != 0 {
-			return fmt.Errorf("invalid element returned Var with address %d, expected 0", v.Address)
-		}
-		return nil
-	})
-
-	checkValue("main.Z_func_bar", func(val debug.Value) error {
-		f, ok := val.(debug.Func)
-		if !ok {
-			return fmt.Errorf("got %T(%v) expected Func", val, val)
-		}
-		if f.Address == 0 {
-			return fmt.Errorf("got func address %d expected nonzero", f.Address)
-		}
-		return nil
-	})
-
-	checkValue("main.Z_func_nil", func(val debug.Value) error {
-		f, ok := val.(debug.Func)
-		if !ok {
-			return fmt.Errorf("got %T(%v) expected Func", val, val)
-		}
-		if f.Address != 0 {
-			return fmt.Errorf("got func address %d expected zero", f.Address)
-		}
-		return nil
-	})
-}
diff --git a/tests/peek/testdata/main.go b/tests/peek/testdata/main.go
deleted file mode 100644
index 61a568e..0000000
--- a/tests/peek/testdata/main.go
+++ /dev/null
@@ -1,193 +0,0 @@
-// Copyright 2014 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 main
-
-import (
-	"fmt"
-	"log"
-	"os"
-	"time"
-	"unsafe"
-)
-
-type FooInterface interface {
-	Bar()
-}
-
-type FooStruct struct {
-	a int
-	b string
-}
-
-func (f *FooStruct) Bar() {}
-
-type myInt int16
-
-var (
-	Z_bool_false          bool        = false
-	Z_bool_true           bool        = true
-	Z_int                 int         = -21
-	Z_int8                int8        = -121
-	Z_int16               int16       = -32321
-	Z_int32               int32       = -1987654321
-	Z_int64               int64       = -9012345678987654321
-	Z_int_typedef         myInt       = 88
-	Z_uint                uint        = 21
-	Z_uint8               uint8       = 231
-	Z_uint16              uint16      = 54321
-	Z_uint32              uint32      = 3217654321
-	Z_uint64              uint64      = 12345678900987654321
-	Z_uintptr             uintptr     = 21
-	Z_float32             float32     = 1.54321
-	Z_float64             float64     = 1.987654321
-	Z_complex64           complex64   = 1.54321 + 2.54321i
-	Z_complex128          complex128  = 1.987654321 - 2.987654321i
-	Z_array               [5]int8     = [5]int8{-121, 121, 3, 2, 1}
-	Z_array_empty         [0]int8     = [0]int8{}
-	Z_array_of_empties    [2]struct{} = [2]struct{}{struct{}{}, struct{}{}}
-	Z_channel             chan int16  = make(chan int16)
-	Z_channel_2           chan int16  = make(chan int16)
-	Z_channel_buffered    chan int16  = make(chan int16, 10)
-	Z_channel_nil         chan int16
-	Z_func_bar                              = (*FooStruct).Bar
-	Z_func_int8_r_int8                      = func(x int8) int8 { return x + 1 }
-	Z_func_int8_r_pint8                     = func(x int8) *int8 { y := x + 1; return &y }
-	Z_func_nil            func(x int8) int8 = nil
-	Z_interface           FooInterface      = &Z_struct
-	Z_interface_typed_nil FooInterface      = Z_pointer_nil
-	Z_interface_nil       FooInterface
-	Z_map                 map[int8]float32 = map[int8]float32{-21: 3.54321}
-	Z_map_2               map[int16]int8   = map[int16]int8{1024: 1}
-	Z_map_3               map[int16]int8   = map[int16]int8{1024: 1, 512: -1}
-	Z_map_empty           map[int8]float32 = map[int8]float32{}
-	Z_map_nil             map[int8]float32
-	Z_pointer             *FooStruct = &Z_struct
-	Z_pointer_nil         *FooStruct
-	Z_slice               []byte = []byte{'s', 'l', 'i', 'c', 'e'}
-	Z_slice_2             []int8 = Z_array[0:2]
-	Z_slice_nil           []byte
-	Z_string              string         = "I'm a string"
-	Z_struct              FooStruct      = FooStruct{a: 21, b: "hi"}
-	Z_unsafe_pointer      unsafe.Pointer = unsafe.Pointer(&Z_uint)
-	Z_unsafe_pointer_nil  unsafe.Pointer
-)
-
-func foo(x int16, y float32) {
-	var (
-		local_array               [5]int8    = [5]int8{-121, 121, 3, 2, 1}
-		local_bool_false          bool       = false
-		local_bool_true           bool       = true
-		local_channel             chan int16 = Z_channel
-		local_channel_buffered    chan int16 = Z_channel_buffered
-		local_channel_nil         chan int16
-		local_complex128          complex128        = 1.987654321 - 2.987654321i
-		local_complex64           complex64         = 1.54321 + 2.54321i
-		local_float32             float32           = 1.54321
-		local_float64             float64           = 1.987654321
-		local_func_bar                              = (*FooStruct).Bar
-		local_func_int8_r_int8                      = func(x int8) int8 { return x + 1 }
-		local_func_int8_r_pint8                     = func(x int8) *int8 { y := x + 1; return &y }
-		local_func_nil            func(x int8) int8 = nil
-		local_int                 int               = -21
-		local_int16               int16             = -32321
-		local_int32               int32             = -1987654321
-		local_int64               int64             = -9012345678987654321
-		local_int8                int8              = -121
-		local_int_typedef         myInt             = 88
-		local_interface           FooInterface      = &Z_struct
-		local_interface_nil       FooInterface
-		local_interface_typed_nil FooInterface     = Z_pointer_nil
-		local_map                 map[int8]float32 = map[int8]float32{-21: 3.54321}
-		local_map_2               map[int16]int8   = map[int16]int8{1024: 1}
-		local_map_3               map[int16]int8   = map[int16]int8{1024: 1, 512: -1}
-		local_map_empty           map[int8]float32 = map[int8]float32{}
-		local_map_nil             map[int8]float32
-		local_pointer             *FooStruct = &Z_struct
-		local_pointer_nil         *FooStruct
-		local_slice               []byte = []byte{'s', 'l', 'i', 'c', 'e'}
-		local_slice_2             []int8 = Z_array[0:2]
-		local_slice_nil           []byte
-		local_string              string         = "I'm a string"
-		local_struct              FooStruct      = FooStruct{a: 21, b: "hi"}
-		local_uint                uint           = 21
-		local_uint16              uint16         = 54321
-		local_uint32              uint32         = 3217654321
-		local_uint64              uint64         = 12345678900987654321
-		local_uint8               uint8          = 231
-		local_uintptr             uintptr        = 21
-		local_unsafe_pointer      unsafe.Pointer = unsafe.Pointer(&Z_uint)
-		local_unsafe_pointer_nil  unsafe.Pointer
-	)
-	fmt.Println(Z_bool_false, Z_bool_true)
-	fmt.Println(Z_int, Z_int8, Z_int16, Z_int32, Z_int64, Z_int_typedef)
-	fmt.Println(Z_uint, Z_uint8, Z_uint16, Z_uint32, Z_uint64, Z_uintptr)
-	fmt.Println(Z_float32, Z_float64, Z_complex64, Z_complex128)
-	fmt.Println(Z_array, Z_array_empty, Z_array_of_empties)
-	fmt.Println(Z_channel, Z_channel_buffered, Z_channel_nil)
-	fmt.Println(Z_func_bar, Z_func_int8_r_int8, Z_func_int8_r_pint8, Z_func_nil)
-	fmt.Println(Z_interface, Z_interface_nil, Z_interface_typed_nil)
-	fmt.Println(Z_map, Z_map_2, Z_map_3, Z_map_empty, Z_map_nil)
-	fmt.Println(Z_pointer, Z_pointer_nil)
-	fmt.Println(Z_slice, Z_slice_2, Z_slice_nil)
-	fmt.Println(Z_string, Z_struct)
-	fmt.Println(Z_unsafe_pointer, Z_unsafe_pointer_nil)
-	fmt.Println(local_bool_false, local_bool_true)
-	fmt.Println(local_int, local_int8, local_int16, local_int32, local_int64, local_int_typedef)
-	fmt.Println(local_uint, local_uint8, local_uint16, local_uint32, local_uint64, local_uintptr)
-	fmt.Println(local_float32, local_float64, local_complex64, local_complex128, local_array)
-	fmt.Println(local_channel, local_channel_buffered, local_channel_nil)
-	fmt.Println(local_func_bar, local_func_int8_r_int8, local_func_int8_r_pint8, local_func_nil)
-	fmt.Println(local_interface, local_interface_nil, local_interface_typed_nil)
-	fmt.Println(local_map, local_map_2, local_map_3, local_map_empty, local_map_nil)
-	fmt.Println(local_pointer, local_pointer_nil)
-	fmt.Println(local_slice, local_slice_2, local_slice_nil)
-	fmt.Println(local_string, local_struct)
-	fmt.Println(local_unsafe_pointer, local_unsafe_pointer_nil)
-	f1()
-	f2()
-}
-
-func f1() {
-	fmt.Println()
-}
-
-func f2() {
-	fmt.Println()
-}
-
-func bar() {
-	foo(42, 1.5)
-	fmt.Print()
-}
-
-func populateChannels() {
-	go func() {
-		Z_channel_2 <- 8
-	}()
-	go func() {
-		for i := int16(0); i < 14; i++ {
-			Z_channel_buffered <- i
-		}
-	}()
-	go func() {
-		for i := 0; i < 8; i++ {
-			<-Z_channel_buffered
-		}
-	}()
-	time.Sleep(time.Second / 20)
-}
-
-func main() {
-	args := os.Args[1:]
-	expected := []string{"some", "arguments"}
-	if len(args) != 2 || args[0] != expected[0] || args[1] != expected[1] {
-		log.Fatalf("got command-line args %v, expected %v", args, expected)
-	}
-	populateChannels()
-	for ; ; time.Sleep(2 * time.Second) {
-		bar()
-	}
-	select {}
-}