go1.1rc2
diff --git a/VERSION b/VERSION
new file mode 100644
index 0000000..f02a1e8
--- /dev/null
+++ b/VERSION
@@ -0,0 +1 @@
+go1.1rc2
\ No newline at end of file
diff --git a/src/cmd/cov/Makefile b/src/cmd/cov/Makefile
deleted file mode 100644
index 3f528d7..0000000
--- a/src/cmd/cov/Makefile
+++ /dev/null
@@ -1,5 +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.
-
-include ../../Make.dist
diff --git a/src/cmd/cov/doc.go b/src/cmd/cov/doc.go
deleted file mode 100644
index ab5d122..0000000
--- a/src/cmd/cov/doc.go
+++ /dev/null
@@ -1,36 +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.
-
-// +build ignore
-
-/*
-
-Cov is a rudimentary code coverage tool.
-
-Usage:
-	go tool cov [-lsv] [-g substring] [-m minlines] [6.out args]
-
-Given a command to run, it runs the command while tracking which
-sections of code have been executed.  When the command finishes,
-cov prints the line numbers of sections of code in the binary that
-were not executed.   With no arguments it assumes the command "6.out".
-
-
-The options are:
-
-	-l
-		print full path names instead of paths relative to the current directory
-	-s
-		show the source code that didn't execute, in addition to the line numbers.
-	-v
-		print debugging information during the run.
-	-g substring
-		restrict the coverage analysis to functions or files whose names contain substring
-	-m minlines
-		only report uncovered sections of code larger than minlines lines
-
-The program is the same for all architectures: 386, amd64, and arm.
-
-*/
-package main
diff --git a/src/cmd/cov/main.c b/src/cmd/cov/main.c
deleted file mode 100644
index 33ef49e..0000000
--- a/src/cmd/cov/main.c
+++ /dev/null
@@ -1,484 +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.
-
-/*
- * code coverage
- */
-
-#include <u.h>
-#include <libc.h>
-#include <bio.h>
-#include "tree.h"
-
-#include <ureg_amd64.h>
-#include <mach.h>
-typedef struct Ureg Ureg;
-
-void
-usage(void)
-{
-	fprint(2, "usage: cov [-lsv] [-g substring] [-m minlines] [6.out args...]\n");
-	fprint(2, "-g specifies pattern of interesting functions or files\n");
-	exits("usage");
-}
-
-typedef struct Range Range;
-struct Range
-{
-	uvlong pc;
-	uvlong epc;
-};
-
-int chatty;
-int fd;
-int longnames;
-int pid;
-int doshowsrc;
-Map *mem;
-Map *text;
-Fhdr fhdr;
-char *substring;
-char cwd[1000];
-int ncwd;
-int minlines = -1000;
-
-Tree breakpoints;	// code ranges not run
-
-/*
- * comparison for Range structures
- * they are "equal" if they overlap, so
- * that a search for [pc, pc+1) finds the
- * Range containing pc.
- */
-int
-rangecmp(void *va, void *vb)
-{
-	Range *a = va, *b = vb;
-	if(a->epc <= b->pc)
-		return 1;
-	if(b->epc <= a->pc)
-		return -1;
-	return 0;
-}
-
-/*
- * remember that we ran the section of code [pc, epc).
- */
-void
-ran(uvlong pc, uvlong epc)
-{
-	Range key;
-	Range *r;
-	uvlong oldepc;
-
-	if(chatty)
-		print("run %#llux-%#llux\n", pc, epc);
-
-	key.pc = pc;
-	key.epc = pc+1;
-	r = treeget(&breakpoints, &key);
-	if(r == nil)
-		sysfatal("unchecked breakpoint at %#llux+%d", pc, (int)(epc-pc));
-
-	// Might be that the tail of the sequence
-	// was run already, so r->epc is before the end.
-	// Adjust len.
-	if(epc > r->epc)
-		epc = r->epc;
-
-	if(r->pc == pc) {
-		r->pc = epc;
-	} else {
-		// Chop r to before pc;
-		// add new entry for after if needed.
-		// Changing r->epc does not affect r's position in the tree.
-		oldepc = r->epc;
-		r->epc = pc;
-		if(epc < oldepc) {
-			Range *n;
-			n = malloc(sizeof *n);
-			if(n == nil)
-				sysfatal("out of memory");
-			n->pc = epc;
-			n->epc = oldepc;
-			treeput(&breakpoints, n, n);
-		}
-	}
-}
-
-void
-showsrc(char *file, int line1, int line2)
-{
-	Biobuf *b;
-	char *p;
-	int n, stop;
-
-	if((b = Bopen(file, OREAD)) == nil) {
-		print("\topen %s: %r\n", file);
-		return;
-	}
-
-	for(n=1; n<line1 && (p = Brdstr(b, '\n', 1)) != nil; n++)
-		free(p);
-
-	// print up to five lines (this one and 4 more).
-	// if there are more than five lines, print 4 and "..."
-	stop = n+4;
-	if(stop > line2)
-		stop = line2;
-	if(stop < line2)
-		stop--;
-	for(; n<=stop && (p = Brdstr(b, '\n', 1)) != nil; n++) {
-		print("  %d %s\n", n, p);
-		free(p);
-	}
-	if(n < line2)
-		print("  ...\n");
-	Bterm(b);
-}
-
-/*
- * if s is in the current directory or below,
- * return the relative path.
- */
-char*
-shortname(char *s)
-{
-	if(!longnames && strlen(s) > ncwd && memcmp(s, cwd, ncwd) == 0 && s[ncwd] == '/')
-		return s+ncwd+1;
-	return s;
-}
-
-/*
- * we've decided that [pc, epc) did not run.
- * do something about it.
- */
-void
-missing(uvlong pc, uvlong epc)
-{
-	char file[1000];
-	int line1, line2;
-	char buf[100];
-	Symbol s;
-	char *p;
-	uvlong uv;
-
-	if(!findsym(pc, CTEXT, &s) || !fileline(file, sizeof file, pc)) {
-	notfound:
-		print("%#llux-%#llux\n", pc, epc);
-		return;
-	}
-	p = strrchr(file, ':');
-	*p++ = 0;
-	line1 = atoi(p);
-	for(uv=pc; uv<epc; ) {
-		if(!fileline(file, sizeof file, epc-2))
-			goto notfound;
-		uv += machdata->instsize(text, uv);
-	}
-	p = strrchr(file, ':');
-	*p++ = 0;
-	line2 = atoi(p);
-
-	if(line2+1-line2 < minlines)
-		return;
-
-	if(pc == s.value) {
-		// never entered function
-		print("%s:%d %s never called (%#llux-%#llux)\n", shortname(file), line1, s.name, pc, epc);
-		return;
-	}
-	if(pc <= s.value+13) {
-		// probably stub for stack growth.
-		// check whether last instruction is call to morestack.
-		// the -5 below is the length of
-		//	CALL sys.morestack.
-		buf[0] = 0;
-		machdata->das(text, epc-5, 0, buf, sizeof buf);
-		if(strstr(buf, "morestack"))
-			return;
-	}
-
-	if(epc - pc == 5) {
-		// check for CALL sys.panicindex
-		buf[0] = 0;
-		machdata->das(text, pc, 0, buf, sizeof buf);
-		if(strstr(buf, "panicindex"))
-			return;
-	}
-
-	if(epc - pc == 2 || epc -pc == 3) {
-		// check for XORL inside shift.
-		// (on x86 have to implement large left or unsigned right shift with explicit zeroing).
-		//	f+90 0x00002c9f	CMPL	CX,$20
-		//	f+93 0x00002ca2	JCS	f+97(SB)
-		//	f+95 0x00002ca4	XORL	AX,AX <<<
-		//	f+97 0x00002ca6	SHLL	CL,AX
-		//	f+99 0x00002ca8	MOVL	$1,CX
-		//
-		//	f+c8 0x00002cd7	CMPL	CX,$40
-		//	f+cb 0x00002cda	JCS	f+d0(SB)
-		//	f+cd 0x00002cdc	XORQ	AX,AX <<<
-		//	f+d0 0x00002cdf	SHLQ	CL,AX
-		//	f+d3 0x00002ce2	MOVQ	$1,CX
-		buf[0] = 0;
-		machdata->das(text, pc, 0, buf, sizeof buf);
-		if(strncmp(buf, "XOR", 3) == 0) {
-			machdata->das(text, epc, 0, buf, sizeof buf);
-			if(strncmp(buf, "SHL", 3) == 0 || strncmp(buf, "SHR", 3) == 0)
-				return;
-		}
-	}
-
-	if(epc - pc == 3) {
-		// check for SAR inside shift.
-		// (on x86 have to implement large signed right shift as >>31).
-		//	f+36 0x00016216	CMPL	CX,$20
-		//	f+39 0x00016219	JCS	f+3e(SB)
-		//	f+3b 0x0001621b	SARL	$1f,AX <<<
-		//	f+3e 0x0001621e	SARL	CL,AX
-		//	f+40 0x00016220	XORL	CX,CX
-		//	f+42 0x00016222	CMPL	CX,AX
-		buf[0] = 0;
-		machdata->das(text, pc, 0, buf, sizeof buf);
-		if(strncmp(buf, "SAR", 3) == 0) {
-			machdata->das(text, epc, 0, buf, sizeof buf);
-			if(strncmp(buf, "SAR", 3) == 0)
-				return;
-		}
-	}
-
-	// show first instruction to make clear where we were.
-	machdata->das(text, pc, 0, buf, sizeof buf);
-
-	if(line1 != line2)
-		print("%s:%d,%d %#llux-%#llux %s\n",
-			shortname(file), line1, line2, pc, epc, buf);
-	else
-		print("%s:%d %#llux-%#llux %s\n",
-			shortname(file), line1, pc, epc, buf);
-	if(doshowsrc)
-		showsrc(file, line1, line2);
-}
-
-/*
- * walk the tree, calling missing for each non-empty
- * section of missing code.
- */
-void
-walktree(TreeNode *t)
-{
-	Range *n;
-
-	if(t == nil)
-		return;
-	walktree(t->left);
-	n = t->key;
-	if(n->pc < n->epc)
-		missing(n->pc, n->epc);
-	walktree(t->right);
-}
-
-/*
- * set a breakpoint all over [pc, epc)
- * and remember that we did.
- */
-void
-breakpoint(uvlong pc, uvlong epc)
-{
-	Range *r;
-
-	r = malloc(sizeof *r);
-	if(r == nil)
-		sysfatal("out of memory");
-	r->pc = pc;
-	r->epc = epc;
-	treeput(&breakpoints, r, r);
-
-	for(; pc < epc; pc+=machdata->bpsize)
-		put1(mem, pc, machdata->bpinst, machdata->bpsize);
-}
-
-/*
- * install breakpoints over all text symbols
- * that match the pattern.
- */
-void
-cover(void)
-{
-	Symbol s;
-	char *lastfn;
-	uvlong lastpc;
-	int i;
-	char buf[200];
-
-	lastfn = nil;
-	lastpc = 0;
-	for(i=0; textsym(&s, i); i++) {
-		switch(s.type) {
-		case 'T':
-		case 't':
-			if(lastpc != 0) {
-				breakpoint(lastpc, s.value);
-				lastpc = 0;
-			}
-			// Ignore second entry for a given name;
-			// that's the debugging blob.
-			if(lastfn && strcmp(s.name, lastfn) == 0)
-				break;
-			lastfn = s.name;
-			buf[0] = 0;
-			fileline(buf, sizeof buf, s.value);
-			if(substring == nil || strstr(buf, substring) || strstr(s.name, substring))
-				lastpc = s.value;
-		}
-	}
-}
-
-uvlong
-rgetzero(Map *map, char *reg)
-{
-	USED(map);
-	USED(reg);
-
-	return 0;
-}
-
-/*
- * remove the breakpoints at pc and successive instructions,
- * up to and including the first jump or other control flow transfer.
- */
-void
-uncover(uvlong pc)
-{
-	uchar buf[1000];
-	int n, n1, n2;
-	uvlong foll[2];
-
-	// Double-check that we stopped at a breakpoint.
-	if(get1(mem, pc, buf, machdata->bpsize) < 0)
-		sysfatal("read mem inst at %#llux: %r", pc);
-	if(memcmp(buf, machdata->bpinst, machdata->bpsize) != 0)
-		sysfatal("stopped at %#llux; not at breakpoint %d", pc, machdata->bpsize);
-
-	// Figure out how many bytes of straight-line code
-	// there are in the text starting at pc.
-	n = 0;
-	while(n < sizeof buf) {
-		n1 = machdata->instsize(text, pc+n);
-		if(n+n1 > sizeof buf)
-			break;
-		n2 = machdata->foll(text, pc+n, rgetzero, foll);
-		n += n1;
-		if(n2 != 1 || foll[0] != pc+n)
-			break;
-	}
-
-	// Record that this section of code ran.
-	ran(pc, pc+n);
-
-	// Put original instructions back.
-	if(get1(text, pc, buf, n) < 0)
-		sysfatal("get1: %r");
-	if(put1(mem, pc, buf, n) < 0)
-		sysfatal("put1: %r");
-}
-
-int
-startprocess(char **argv)
-{
-	int pid;
-
-	if((pid = fork()) < 0)
-		sysfatal("fork: %r");
-	if(pid == 0) {
-		pid = getpid();
-		if(ctlproc(pid, "hang") < 0)
-			sysfatal("ctlproc hang: %r");
-		exec(argv[0], argv);
-		sysfatal("exec %s: %r", argv[0]);
-	}
-	if(ctlproc(pid, "attached") < 0 || ctlproc(pid, "waitstop") < 0)
-		sysfatal("attach %d %s: %r", pid, argv[0]);
-	return pid;
-}
-
-int
-go(void)
-{
-	uvlong pc;
-	char buf[100];
-	int n;
-
-	for(n = 0;; n++) {
-		ctlproc(pid, "startstop");
-		if(get8(mem, offsetof(Ureg, ip), &pc) < 0) {
-			rerrstr(buf, sizeof buf);
-			if(strstr(buf, "exited") || strstr(buf, "No such process"))
-				return n;
-			sysfatal("cannot read pc: %r");
-		}
-		pc--;
-		if(put8(mem, offsetof(Ureg, ip), pc) < 0)
-			sysfatal("cannot write pc: %r");
-		uncover(pc);
-	}
-}
-
-void
-main(int argc, char **argv)
-{
-	int n;
-
-	ARGBEGIN{
-	case 'g':
-		substring = EARGF(usage());
-		break;
-	case 'l':
-		longnames++;
-		break;
-	case 'n':
-		minlines = atoi(EARGF(usage()));
-		break;
-	case 's':
-		doshowsrc = 1;
-		break;
-	case 'v':
-		chatty++;
-		break;
-	default:
-		usage();
-	}ARGEND
-
-	getwd(cwd, sizeof cwd);
-	ncwd = strlen(cwd);
-
-	if(argc == 0) {
-		*--argv = "6.out";
-	}
-	fd = open(argv[0], OREAD);
-	if(fd < 0)
-		sysfatal("open %s: %r", argv[0]);
-	if(crackhdr(fd, &fhdr) <= 0)
-		sysfatal("crackhdr: %r");
-	machbytype(fhdr.type);
-	if(syminit(fd, &fhdr) <= 0)
-		sysfatal("syminit: %r");
-	text = loadmap(nil, fd, &fhdr);
-	if(text == nil)
-		sysfatal("loadmap: %r");
-	pid = startprocess(argv);
-	mem = attachproc(pid, &fhdr);
-	if(mem == nil)
-		sysfatal("attachproc: %r");
-	breakpoints.cmp = rangecmp;
-	cover();
-	n = go();
-	walktree(breakpoints.root);
-	if(chatty)
-		print("%d breakpoints\n", n);
-	detachproc(mem);
-	exits(0);
-}
-
diff --git a/src/cmd/cov/tree.c b/src/cmd/cov/tree.c
deleted file mode 100644
index 366a47e..0000000
--- a/src/cmd/cov/tree.c
+++ /dev/null
@@ -1,245 +0,0 @@
-// Renamed from Map to Tree to avoid conflict with libmach.
-
-/*
-Copyright (c) 2003-2007 Russ Cox, Tom Bergan, Austin Clements,
-	Massachusetts Institute of Technology
-Portions Copyright (c) 2009 The Go Authors. All rights reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-*/
-
-// Mutable map structure, but still based on
-// Okasaki, Red Black Trees in a Functional Setting, JFP 1999,
-// which is a lot easier than the traditional red-black
-// and plenty fast enough for me.  (Also I could copy
-// and edit fmap.c.)
-
-#include <u.h>
-#include <libc.h>
-#include "tree.h"
-
-enum
-{
-	Red = 0,
-	Black = 1
-};
-
-
-// Red-black trees are binary trees with this property:
-//	1. No red node has a red parent.
-//	2. Every path from the root to a leaf contains the
-//		same number of black nodes.
-
-static TreeNode*
-rwTreeNode(TreeNode *p, int color, TreeNode *left, void *key, void *value, TreeNode *right)
-{
-	if(p == nil)
-		p = malloc(sizeof *p);
-	if(p == nil)
-		sysfatal("out of memory");
-	p->color = color;
-	p->left = left;
-	p->key = key;
-	p->value = value;
-	p->right = right;
-	return p;
-}
-
-static TreeNode*
-balance(TreeNode *m0)
-{
-	void *xk, *xv, *yk, *yv, *zk, *zv;
-	TreeNode *a, *b, *c, *d;
-	TreeNode *m1, *m2;
-	int color;
-	TreeNode *left, *right;
-	void *key, *value;
-
-	color = m0->color;
-	left = m0->left;
-	key = m0->key;
-	value = m0->value;
-	right = m0->right;
-
-	// Okasaki notation: (T is mkTreeNode, B is Black, R is Red, x, y, z are key-value.
-	//
-	// balance B (T R (T R a x b) y c) z d
-	// balance B (T R a x (T R b y c)) z d
-	// balance B a x (T R (T R b y c) z d)
-	// balance B a x (T R b y (T R c z d))
-	//
-	//     = T R (T B a x b) y (T B c z d)
-
-	if(color == Black){
-		if(left && left->color == Red){
-			if(left->left && left->left->color == Red){
-				a = left->left->left;
-				xk = left->left->key;
-				xv = left->left->value;
-				b = left->left->right;
-				yk = left->key;
-				yv = left->value;
-				c = left->right;
-				zk = key;
-				zv = value;
-				d = right;
-				m1 = left;
-				m2 = left->left;
-				goto hard;
-			}else if(left->right && left->right->color == Red){
-				a = left->left;
-				xk = left->key;
-				xv = left->value;
-				b = left->right->left;
-				yk = left->right->key;
-				yv = left->right->value;
-				c = left->right->right;
-				zk = key;
-				zv = value;
-				d = right;
-				m1 = left;
-				m2 = left->right;
-				goto hard;
-			}
-		}else if(right && right->color == Red){
-			if(right->left && right->left->color == Red){
-				a = left;
-				xk = key;
-				xv = value;
-				b = right->left->left;
-				yk = right->left->key;
-				yv = right->left->value;
-				c = right->left->right;
-				zk = right->key;
-				zv = right->value;
-				d = right->right;
-				m1 = right;
-				m2 = right->left;
-				goto hard;
-			}else if(right->right && right->right->color == Red){
-				a = left;
-				xk = key;
-				xv = value;
-				b = right->left;
-				yk = right->key;
-				yv = right->value;
-				c = right->right->left;
-				zk = right->right->key;
-				zv = right->right->value;
-				d = right->right->right;
-				m1 = right;
-				m2 = right->right;
-				goto hard;
-			}
-		}
-	}
-	return rwTreeNode(m0, color, left, key, value, right);
-
-hard:
-	return rwTreeNode(m0, Red, rwTreeNode(m1, Black, a, xk, xv, b),
-		yk, yv, rwTreeNode(m2, Black, c, zk, zv, d));
-}
-
-static TreeNode*
-ins0(TreeNode *p, void *k, void *v, TreeNode *rw)
-{
-	if(p == nil)
-		return rwTreeNode(rw, Red, nil, k, v, nil);
-	if(p->key == k){
-		if(rw)
-			return rwTreeNode(rw, p->color, p->left, k, v, p->right);
-		p->value = v;
-		return p;
-	}
-	if(p->key < k)
-		p->left = ins0(p->left, k, v, rw);
-	else
-		p->right = ins0(p->right, k, v, rw);
-	return balance(p);
-}
-
-static TreeNode*
-ins1(Tree *m, TreeNode *p, void *k, void *v, TreeNode *rw)
-{
-	int i;
-
-	if(p == nil)
-		return rwTreeNode(rw, Red, nil, k, v, nil);
-	i = m->cmp(p->key, k);
-	if(i == 0){
-		if(rw)
-			return rwTreeNode(rw, p->color, p->left, k, v, p->right);
-		p->value = v;
-		return p;
-	}
-	if(i < 0)
-		p->left = ins1(m, p->left, k, v, rw);
-	else
-		p->right = ins1(m, p->right, k, v, rw);
-	return balance(p);
-}
-
-void
-treeputelem(Tree *m, void *key, void *val, TreeNode *rw)
-{
-	if(m->cmp)
-		m->root = ins1(m, m->root, key, val, rw);
-	else
-		m->root = ins0(m->root, key, val, rw);
-}
-
-void
-treeput(Tree *m, void *key, void *val)
-{
-	treeputelem(m, key, val, nil);
-}
-
-void*
-treeget(Tree *m, void *key)
-{
-	int i;
-	TreeNode *p;
-
-	p = m->root;
-	if(m->cmp){
-		for(;;){
-			if(p == nil)
-				return nil;
-			i = m->cmp(p->key, key);
-			if(i < 0)
-				p = p->left;
-			else if(i > 0)
-				p = p->right;
-			else
-				return p->value;
-		}
-	}else{
-		for(;;){
-			if(p == nil)
-				return nil;
-			if(p->key == key)
-				return p->value;
-			if(p->key < key)
-				p = p->left;
-			else
-				p = p->right;
-		}
-	}
-}
diff --git a/src/cmd/cov/tree.h b/src/cmd/cov/tree.h
deleted file mode 100644
index a716d83..0000000
--- a/src/cmd/cov/tree.h
+++ /dev/null
@@ -1,47 +0,0 @@
-// Renamed from Map to Tree to avoid conflict with libmach.
-
-/*
-Copyright (c) 2003-2007 Russ Cox, Tom Bergan, Austin Clements,
-                        Massachusetts Institute of Technology
-Portions Copyright (c) 2009 The Go Authors. All rights reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-*/
-
-typedef struct Tree Tree;
-typedef struct TreeNode TreeNode;
-struct Tree
-{
-        int (*cmp)(void*, void*);
-        TreeNode *root;
-};
-
-struct TreeNode
-{
-        int color;
-        TreeNode *left;
-        void *key;
-        void *value;
-        TreeNode *right;
-};
-
-void *treeget(Tree*, void*);
-void treeput(Tree*, void*, void*);
-void treeputelem(Tree*, void*, void*, TreeNode*);
diff --git a/src/cmd/prof/Makefile b/src/cmd/prof/Makefile
deleted file mode 100644
index 3f528d7..0000000
--- a/src/cmd/prof/Makefile
+++ /dev/null
@@ -1,5 +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.
-
-include ../../Make.dist
diff --git a/src/cmd/prof/doc.go b/src/cmd/prof/doc.go
deleted file mode 100644
index 2640167..0000000
--- a/src/cmd/prof/doc.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.
-
-// +build ignore
-
-/*
-
-Prof is a rudimentary real-time profiler.
-
-Given a command to run or the process id (pid) of a command already
-running, it samples the program's state at regular intervals and reports
-on its behavior.  With no options, it prints a histogram of the locations
-in the code that were sampled during execution.
-
-Since it is a real-time profiler, unlike a traditional profiler it samples
-the program's state even when it is not running, such as when it is
-asleep or waiting for I/O.  Each thread contributes equally to the
-statistics.
-
-Usage:
-	go tool prof -p pid [-t total_secs] [-d delta_msec] [6.out args ...]
-
-The output modes (default -h) are:
-
-	-P file.prof:
-		Write the profile information to file.prof, in the format used by pprof.
-		At the moment, this only works on Linux amd64 binaries and requires that the
-		binary be written using 6l -e to produce ELF debug info.
-		See http://code.google.com/p/google-perftools for details.
-	-h: histograms
-		How many times a sample occurred at each location.
-	-f: dynamic functions
-		At each sample period, print the name of the executing function.
-	-l: dynamic file and line numbers
-		At each sample period, print the file and line number of the executing instruction.
-	-r: dynamic registers
-		At each sample period, print the register contents.
-	-s: dynamic function stack traces
-		At each sample period, print the symbolic stack trace.
-
-Flag -t sets the maximum real time to sample, in seconds, and -d
-sets the sampling interval in milliseconds.  The default is to sample
-every 100ms until the program completes.
-
-It is installed as go tool prof and is architecture-independent.
-
-*/
-package main
diff --git a/src/cmd/prof/main.c b/src/cmd/prof/main.c
deleted file mode 100644
index 6c591ba..0000000
--- a/src/cmd/prof/main.c
+++ /dev/null
@@ -1,910 +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.
-
-// +build !plan9
-
-#include <u.h>
-#include <time.h>
-#include <libc.h>
-#include <bio.h>
-#include <ctype.h>
-
-#define Ureg Ureg_amd64
-	#include <ureg_amd64.h>
-#undef Ureg
-#define Ureg Ureg_x86
-	#include <ureg_x86.h>
-#undef Ureg
-#include <mach.h>
-
-char* file = "6.out";
-static Fhdr fhdr;
-int have_syms;
-int fd;
-struct Ureg_amd64 ureg_amd64;
-struct Ureg_x86 ureg_x86;
-int total_sec = 0;
-int delta_msec = 100;
-int nsample;
-int nsamplethread;
-
-// pprof data, stored as sequences of N followed by N PC values.
-// See http://code.google.com/p/google-perftools .
-uvlong	*ppdata;	// traces
-Biobuf*	pproffd;	// file descriptor to write trace info
-long	ppstart;	// start position of current trace
-long	nppdata;	// length of data
-long	ppalloc;	// size of allocated data
-char	ppmapdata[10*1024];	// the map information for the output file
-
-// output formats
-int pprof;	// print pprof output to named file
-int functions;	// print functions
-int histograms;	// print histograms
-int linenums;	// print file and line numbers rather than function names
-int registers;	// print registers
-int stacks;		// print stack traces
-
-int pid;		// main process pid
-
-int nthread;	// number of threads
-int thread[32];	// thread pids
-Map *map[32];	// thread maps
-
-void
-Usage(void)
-{
-	fprint(2, "Usage: prof -p pid [-t total_secs] [-d delta_msec]\n");
-	fprint(2, "       prof [-t total_secs] [-d delta_msec] 6.out args ...\n");
-	fprint(2, "\tformats (default -h):\n");
-	fprint(2, "\t\t-P file.prof: write [c]pprof output to file.prof\n");
-	fprint(2, "\t\t-h: histograms\n");
-	fprint(2, "\t\t-f: dynamic functions\n");
-	fprint(2, "\t\t-l: dynamic file and line numbers\n");
-	fprint(2, "\t\t-r: dynamic registers\n");
-	fprint(2, "\t\t-s: dynamic function stack traces\n");
-	fprint(2, "\t\t-hs: include stack info in histograms\n");
-	exit(2);
-}
-
-typedef struct PC PC;
-struct PC {
-	uvlong pc;
-	uvlong callerpc;
-	unsigned int count;
-	PC* next;
-};
-
-enum {
-	Ncounters = 256
-};
-
-PC *counters[Ncounters];
-
-// Set up by setarch() to make most of the code architecture-independent.
-typedef struct Arch Arch;
-struct Arch {
-	char*	name;
-	void	(*regprint)(void);
-	int	(*getregs)(Map*);
-	int	(*getPC)(Map*);
-	int	(*getSP)(Map*);
-	uvlong	(*uregPC)(void);
-	uvlong	(*uregSP)(void);
-	void	(*ppword)(uvlong w);
-};
-
-void
-amd64_regprint(void)
-{
-	fprint(2, "ax\t0x%llux\n", ureg_amd64.ax);
-	fprint(2, "bx\t0x%llux\n", ureg_amd64.bx);
-	fprint(2, "cx\t0x%llux\n", ureg_amd64.cx);
-	fprint(2, "dx\t0x%llux\n", ureg_amd64.dx);
-	fprint(2, "si\t0x%llux\n", ureg_amd64.si);
-	fprint(2, "di\t0x%llux\n", ureg_amd64.di);
-	fprint(2, "bp\t0x%llux\n", ureg_amd64.bp);
-	fprint(2, "r8\t0x%llux\n", ureg_amd64.r8);
-	fprint(2, "r9\t0x%llux\n", ureg_amd64.r9);
-	fprint(2, "r10\t0x%llux\n", ureg_amd64.r10);
-	fprint(2, "r11\t0x%llux\n", ureg_amd64.r11);
-	fprint(2, "r12\t0x%llux\n", ureg_amd64.r12);
-	fprint(2, "r13\t0x%llux\n", ureg_amd64.r13);
-	fprint(2, "r14\t0x%llux\n", ureg_amd64.r14);
-	fprint(2, "r15\t0x%llux\n", ureg_amd64.r15);
-	fprint(2, "ds\t0x%llux\n", ureg_amd64.ds);
-	fprint(2, "es\t0x%llux\n", ureg_amd64.es);
-	fprint(2, "fs\t0x%llux\n", ureg_amd64.fs);
-	fprint(2, "gs\t0x%llux\n", ureg_amd64.gs);
-	fprint(2, "type\t0x%llux\n", ureg_amd64.type);
-	fprint(2, "error\t0x%llux\n", ureg_amd64.error);
-	fprint(2, "pc\t0x%llux\n", ureg_amd64.ip);
-	fprint(2, "cs\t0x%llux\n", ureg_amd64.cs);
-	fprint(2, "flags\t0x%llux\n", ureg_amd64.flags);
-	fprint(2, "sp\t0x%llux\n", ureg_amd64.sp);
-	fprint(2, "ss\t0x%llux\n", ureg_amd64.ss);
-}
-
-int
-amd64_getregs(Map *map)
-{
-	int i;
-	union {
-		uvlong regs[1];
-		struct Ureg_amd64 ureg;
-	} u;
-
-	for(i = 0; i < sizeof ureg_amd64; i+=8) {
-		if(get8(map, (uvlong)i, &u.regs[i/8]) < 0)
-			return -1;
-	}
-	ureg_amd64 = u.ureg;
-	return 0;
-}
-
-int
-amd64_getPC(Map *map)
-{
-	uvlong x;
-	int r;
-
-	r = get8(map, offsetof(struct Ureg_amd64, ip), &x);
-	ureg_amd64.ip = x;
-	return r;
-}
-
-int
-amd64_getSP(Map *map)
-{
-	uvlong x;
-	int r;
-
-	r = get8(map, offsetof(struct Ureg_amd64, sp), &x);
-	ureg_amd64.sp = x;
-	return r;
-}
-
-uvlong
-amd64_uregPC(void)
-{
-	return ureg_amd64.ip;
-}
-
-uvlong
-amd64_uregSP(void)
-{
-	return ureg_amd64.sp;
-}
-
-void
-amd64_ppword(uvlong w)
-{
-	uchar buf[8];
-
-	buf[0] = w;
-	buf[1] = w >> 8;
-	buf[2] = w >> 16;
-	buf[3] = w >> 24;
-	buf[4] = w >> 32;
-	buf[5] = w >> 40;
-	buf[6] = w >> 48;
-	buf[7] = w >> 56;
-	Bwrite(pproffd, buf, 8);
-}
-
-void
-x86_regprint(void)
-{
-	fprint(2, "ax\t0x%ux\n", ureg_x86.ax);
-	fprint(2, "bx\t0x%ux\n", ureg_x86.bx);
-	fprint(2, "cx\t0x%ux\n", ureg_x86.cx);
-	fprint(2, "dx\t0x%ux\n", ureg_x86.dx);
-	fprint(2, "si\t0x%ux\n", ureg_x86.si);
-	fprint(2, "di\t0x%ux\n", ureg_x86.di);
-	fprint(2, "bp\t0x%ux\n", ureg_x86.bp);
-	fprint(2, "ds\t0x%ux\n", ureg_x86.ds);
-	fprint(2, "es\t0x%ux\n", ureg_x86.es);
-	fprint(2, "fs\t0x%ux\n", ureg_x86.fs);
-	fprint(2, "gs\t0x%ux\n", ureg_x86.gs);
-	fprint(2, "cs\t0x%ux\n", ureg_x86.cs);
-	fprint(2, "flags\t0x%ux\n", ureg_x86.flags);
-	fprint(2, "pc\t0x%ux\n", ureg_x86.pc);
-	fprint(2, "sp\t0x%ux\n", ureg_x86.sp);
-	fprint(2, "ss\t0x%ux\n", ureg_x86.ss);
-}
-
-int
-x86_getregs(Map *map)
-{
-	int i;
-
-	for(i = 0; i < sizeof ureg_x86; i+=4) {
-		if(get4(map, (uvlong)i, &((uint32*)&ureg_x86)[i/4]) < 0)
-			return -1;
-	}
-	return 0;
-}
-
-int
-x86_getPC(Map* map)
-{
-	return get4(map, offsetof(struct Ureg_x86, pc), &ureg_x86.pc);
-}
-
-int
-x86_getSP(Map* map)
-{
-	return get4(map, offsetof(struct Ureg_x86, sp), &ureg_x86.sp);
-}
-
-uvlong
-x86_uregPC(void)
-{
-	return (uvlong)ureg_x86.pc;
-}
-
-uvlong
-x86_uregSP(void)
-{
-	return (uvlong)ureg_x86.sp;
-}
-
-void
-x86_ppword(uvlong w)
-{
-	uchar buf[4];
-
-	buf[0] = w;
-	buf[1] = w >> 8;
-	buf[2] = w >> 16;
-	buf[3] = w >> 24;
-	Bwrite(pproffd, buf, 4);
-}
-
-Arch archtab[] = {
-	{
-		"amd64",
-		amd64_regprint,
-		amd64_getregs,
-		amd64_getPC,
-		amd64_getSP,
-		amd64_uregPC,
-		amd64_uregSP,
-		amd64_ppword,
-	},
-	{
-		"386",
-		x86_regprint,
-		x86_getregs,
-		x86_getPC,
-		x86_getSP,
-		x86_uregPC,
-		x86_uregSP,
-		x86_ppword,
-	},
-	{
-		nil
-	}
-};
-
-Arch *arch;
-
-int
-setarch(void)
-{
-	int i;
-
-	if(mach != nil) {
-		for(i = 0; archtab[i].name != nil; i++) {
-			if (strcmp(mach->name, archtab[i].name) == 0) {
-				arch = &archtab[i];
-				return 0;
-			}
-		}
-	}
-	return -1;
-}
-
-int
-getthreads(void)
-{
-	int i, j, curn, found;
-	Map *curmap[nelem(map)];
-	int curthread[nelem(map)];
-	static int complained = 0;
-
-	curn = procthreadpids(pid, curthread, nelem(curthread));
-	if(curn <= 0)
-		return curn;
-
-	if(curn > nelem(map)) {
-		if(complained == 0) {
-			fprint(2, "prof: too many threads; limiting to %d\n", nthread, nelem(map));
-			complained = 1;
-		}
-		curn = nelem(map);
-	}
-	if(curn == nthread && memcmp(thread, curthread, curn*sizeof(*thread)) == 0)
-		return curn;	// no changes
-
-	// Number of threads has changed (might be the init case).
-	// A bit expensive but rare enough not to bother being clever.
-	for(i = 0; i < curn; i++) {
-		found = 0;
-		for(j = 0; j < nthread; j++) {
-			if(curthread[i] == thread[j]) {
-				found = 1;
-				curmap[i] = map[j];
-				map[j] = nil;
-				break;
-			}
-		}
-		if(found)
-			continue;
-
-		// map new thread
-		curmap[i] = attachproc(curthread[i], &fhdr);
-		if(curmap[i] == nil) {
-			fprint(2, "prof: can't attach to %d: %r\n", curthread[i]);
-			return -1;
-		}
-	}
-
-	for(j = 0; j < nthread; j++)
-		if(map[j] != nil)
-			detachproc(map[j]);
-
-	nthread = curn;
-	memmove(thread, curthread, nthread*sizeof thread[0]);
-	memmove(map, curmap, sizeof map);
-	return nthread;
-}
-
-int
-sample(Map *map)
-{
-	static int n;
-
-	n++;
-	if(registers) {
-		if(arch->getregs(map) < 0)
-			goto bad;
-	} else {
-		// we need only two registers
-		if(arch->getPC(map) < 0)
-			goto bad;
-		if(arch->getSP(map) < 0)
-			goto bad;
-	}
-	return 1;
-bad:
-	if(n == 1)
-		fprint(2, "prof: can't read registers: %r\n");
-	return 0;
-}
-
-void
-addtohistogram(uvlong pc, uvlong callerpc, uvlong sp)
-{
-	int h;
-	PC *x;
-	
-	USED(sp);
-
-	h = (pc + callerpc*101) % Ncounters;
-	for(x = counters[h]; x != NULL; x = x->next) {
-		if(x->pc == pc && x->callerpc == callerpc) {
-			x->count++;
-			return;
-		}
-	}
-	x = malloc(sizeof(PC));
-	if(x == nil)
-		sysfatal("out of memory");
-	x->pc = pc;
-	x->callerpc = callerpc;
-	x->count = 1;
-	x->next = counters[h];
-	counters[h] = x;
-}
-
-void
-addppword(uvlong pc)
-{
-	if(pc == 0) {
-		return;
-	}
-	if(nppdata == ppalloc) {
-		ppalloc = (1000+nppdata)*2;
-		ppdata = realloc(ppdata, ppalloc * sizeof ppdata[0]);
-		if(ppdata == nil) {
-			fprint(2, "prof: realloc failed: %r\n");
-			exit(2);
-		}
-	}
-	ppdata[nppdata++] = pc;
-}
-
-void
-startpptrace(void)
-{
-	ppstart = nppdata;
-	addppword(~0);
-}
-
-void
-endpptrace(void)
-{
-	ppdata[ppstart] = nppdata-ppstart-1;
-}
-
-uvlong nextpc;
-
-void
-xptrace(Map *map, uvlong pc, uvlong sp, Symbol *sym)
-{
-	USED(map);
-
-	char buf[1024];
-	if(sym == nil){
-		fprint(2, "syms\n");
-		return;
-	}
-	if(histograms)
-		addtohistogram(nextpc, pc, sp);
-	if(!histograms || stacks > 1 || pprof) {
-		if(nextpc == 0)
-			nextpc = sym->value;
-		if(stacks){
-			fprint(2, "%s(", sym->name);
-			fprint(2, ")");
-			if(nextpc != sym->value)
-				fprint(2, "+%#llux ", nextpc - sym->value);
-			if(have_syms && linenums && fileline(buf, sizeof buf, pc)) {
-				fprint(2, " %s", buf);
-			}
-			fprint(2, "\n");
-		}
-		if (pprof) {
-			addppword(nextpc);
-		}
-	}
-	nextpc = pc;
-}
-
-void
-stacktracepcsp(Map *map, uvlong pc, uvlong sp)
-{
-	nextpc = pc;
-	if(pprof){
-		startpptrace();
-	}
-	if(machdata->ctrace==nil)
-		fprint(2, "no machdata->ctrace\n");
-	else if(machdata->ctrace(map, pc, sp, 0, xptrace) <= 0)
-		fprint(2, "no stack frame: pc=%#p sp=%#p\n", pc, sp);
-	else {
-		addtohistogram(nextpc, 0, sp);
-		if(stacks)
-			fprint(2, "\n");
-	}
-	if(pprof){
-		endpptrace();
-	}
-}
-
-void
-printpc(Map *map, uvlong pc, uvlong sp)
-{
-	char buf[1024];
-	if(registers)
-		arch->regprint();
-	if(have_syms > 0 && linenums &&  fileline(buf, sizeof buf, pc))
-		fprint(2, "%s\n", buf);
-	if(have_syms > 0 && functions) {
-		symoff(buf, sizeof(buf), pc, CANY);
-		fprint(2, "%s\n", buf);
-	}
-	if(stacks || pprof){
-		stacktracepcsp(map, pc, sp);
-	}
-	else if(histograms){
-		addtohistogram(pc, 0, sp);
-	}
-}
-
-void
-ppmaps(void)
-{
-	int fd, n;
-	char tmp[100];
-	Seg *seg;
-
-	// If it's Linux, the info is in /proc/$pid/maps
-	snprint(tmp, sizeof tmp, "/proc/%d/maps", pid);
-	fd = open(tmp, 0);
-	if(fd >= 0) {
-		n = read(fd, ppmapdata, sizeof ppmapdata - 1);
-		close(fd);
-		if(n < 0) {
-			fprint(2, "prof: can't read %s: %r\n", tmp);
-			exit(2);
-		}
-		ppmapdata[n] = 0;
-		return;
-	}
-
-	// It's probably a mac. Synthesize an entry for the text file.
-	// The register segment may come first but it has a zero offset, so grab the first non-zero offset segment.
-	for(n = 0; n < 3; n++){
-		seg = &map[0]->seg[n];
-		if(seg->b == 0) {
-			continue;
-		}
-		snprint(ppmapdata, sizeof ppmapdata,
-			"%.16x-%.16x r-xp %d 00:00 34968549                           %s\n",
-			seg->b, seg->e, seg->f, "/home/r/6.out"
-		);
-		return;
-	}
-	fprint(2, "prof: no text segment in maps for %s\n", file);
-	exit(2);
-}
-
-void
-samples(void)
-{
-	int i, pid, msec;
-	struct timespec req;
-	int getmaps;
-
-	req.tv_sec = delta_msec/1000;
-	req.tv_nsec = 1000000*(delta_msec % 1000);
-	getmaps = 0;
-	if(pprof)
-		getmaps= 1;
-	for(msec = 0; total_sec <= 0 || msec < 1000*total_sec; msec += delta_msec) {
-		nsample++;
-		nsamplethread += nthread;
-		for(i = 0; i < nthread; i++) {
-			pid = thread[i];
-			if(ctlproc(pid, "stop") < 0)
-				return;
-			if(!sample(map[i])) {
-				ctlproc(pid, "start");
-				return;
-			}
-			printpc(map[i], arch->uregPC(), arch->uregSP());
-			ctlproc(pid, "start");
-		}
-		nanosleep(&req, NULL);
-		getthreads();
-		if(nthread == 0)
-			break;
-		if(getmaps) {
-			getmaps = 0;
-			ppmaps();
-		}
-	}
-}
-
-typedef struct Func Func;
-struct Func
-{
-	Func *next;
-	Symbol s;
-	uint onstack;
-	uint leaf;
-};
-
-Func *func[257];
-int nfunc;
-
-Func*
-findfunc(uvlong pc)
-{
-	Func *f;
-	uint h;
-	Symbol s;
-
-	if(pc == 0)
-		return nil;
-
-	if(!findsym(pc, CTEXT, &s))
-		return nil;
-
-	h = s.value % nelem(func);
-	for(f = func[h]; f != NULL; f = f->next)
-		if(f->s.value == s.value)
-			return f;
-
-	f = malloc(sizeof *f);
-	if(f == nil)
-		sysfatal("out of memory");
-	memset(f, 0, sizeof *f);
-	f->s = s;
-	f->next = func[h];
-	func[h] = f;
-	nfunc++;
-	return f;
-}
-
-int
-compareleaf(const void *va, const void *vb)
-{
-	Func *a, *b;
-
-	a = *(Func**)va;
-	b = *(Func**)vb;
-	if(a->leaf != b->leaf)
-		return b->leaf - a->leaf;
-	if(a->onstack != b->onstack)
-		return b->onstack - a->onstack;
-	return strcmp(a->s.name, b->s.name);
-}
-
-void
-dumphistogram(void)
-{
-	int i, h, n;
-	PC *x;
-	Func *f, **ff;
-
-	if(!histograms)
-		return;
-
-	// assign counts to functions.
-	for(h = 0; h < Ncounters; h++) {
-		for(x = counters[h]; x != NULL; x = x->next) {
-			f = findfunc(x->pc);
-			if(f) {
-				f->onstack += x->count;
-				f->leaf += x->count;
-			}
-			f = findfunc(x->callerpc);
-			if(f)
-				f->leaf -= x->count;
-		}
-	}
-
-	// build array
-	ff = malloc(nfunc*sizeof ff[0]);
-	if(ff == nil)
-		sysfatal("out of memory");
-	n = 0;
-	for(h = 0; h < nelem(func); h++)
-		for(f = func[h]; f != NULL; f = f->next)
-			ff[n++] = f;
-
-	// sort by leaf counts
-	qsort(ff, nfunc, sizeof ff[0], compareleaf);
-
-	// print.
-	fprint(2, "%d samples (avg %.1g threads)\n", nsample, (double)nsamplethread/nsample);
-	for(i = 0; i < nfunc; i++) {
-		f = ff[i];
-		fprint(2, "%6.2f%%\t", 100.0*(double)f->leaf/nsample);
-		if(stacks)
-			fprint(2, "%6.2f%%\t", 100.0*(double)f->onstack/nsample);
-		fprint(2, "%s\n", f->s.name);
-	}
-}
-
-typedef struct Trace Trace;
-struct Trace {
-	int	count;
-	int	npc;
-	uvlong	*pc;
-	Trace	*next;
-};
-
-void
-dumppprof(void)
-{
-	uvlong i, n, *p, *e;
-	int ntrace;
-	Trace *trace, *tp, *up, *prev;
-
-	if(!pprof)
-		return;
-	e = ppdata + nppdata;
-	// Create list of traces.  First, count the traces
-	ntrace = 0;
-	for(p = ppdata; p < e;) {
-		n = *p++;
-		p += n;
-		if(n == 0)
-			continue;
-		ntrace++;
-	}
-	if(ntrace <= 0)
-		return;
-	// Allocate and link the traces together.
-	trace = malloc(ntrace * sizeof(Trace));
-	if(trace == nil)
-		sysfatal("out of memory");
-	tp = trace;
-	for(p = ppdata; p < e;) {
-		n = *p++;
-		if(n == 0)
-			continue;
-		tp->count = 1;
-		tp->npc = n;
-		tp->pc = p;
-		tp->next = tp+1;
-		tp++;
-		p += n;
-	}
-	trace[ntrace-1].next = nil;
-	// Eliminate duplicates.  Lousy algorithm, although not as bad as it looks because
-	// the list collapses fast.
-	for(tp = trace; tp != nil; tp = tp->next) {
-		prev = tp;
-		for(up = tp->next; up != nil; up = up->next) {
-			if(up->npc == tp->npc && memcmp(up->pc, tp->pc, up->npc*sizeof up->pc[0]) == 0) {
-				tp->count++;
-				prev->next = up->next;
-			} else {
-				prev = up;
-			}
-		}
-	}
-	// Write file.
-	// See http://code.google.com/p/google-perftools/source/browse/trunk/doc/cpuprofile-fileformat.html
-	// 1) Header
-	arch->ppword(0);	// must be zero
-	arch->ppword(3);	// 3 words follow in header
-	arch->ppword(0);	// must be zero
-	arch->ppword(delta_msec * 1000);	// sampling period in microseconds
-	arch->ppword(0);	// must be zero (padding)
-	// 2) One record for each trace.
-	for(tp = trace; tp != nil; tp = tp->next) {
-		arch->ppword(tp->count);
-		arch->ppword(tp->npc);
-		for(i = 0; i < tp->npc; i++) {
-			arch->ppword(tp->pc[i]);
-		}
-	}
-	// 3) Binary trailer
-	arch->ppword(0);	// must be zero
-	arch->ppword(1);	// must be one
-	arch->ppword(0);	// must be zero
-	// 4) Mapped objects.
-	Bwrite(pproffd, ppmapdata, strlen(ppmapdata));
-	// 5) That's it.
-	Bterm(pproffd);
-}
-
-int
-startprocess(char **argv)
-{
-	int pid;
-
-	if((pid = fork()) == 0) {
-		pid = getpid();
-		if(ctlproc(pid, "hang") < 0){
-			fprint(2, "prof: child process could not hang\n");
-			exits(0);
-		}
-		execv(argv[0], argv);
-		fprint(2, "prof: could not exec %s: %r\n", argv[0]);
-		exits(0);
-	}
-
-	if(pid == -1) {
-		fprint(2, "prof: could not fork\n");
-		exit(1);
-	}
-	if(ctlproc(pid, "attached") < 0 || ctlproc(pid, "waitstop") < 0) {
-		fprint(2, "prof: could not attach to child process: %r\n");
-		exit(1);
-	}
-	return pid;
-}
-
-void
-detach(void)
-{
-	int i;
-
-	for(i = 0; i < nthread; i++)
-		detachproc(map[i]);
-}
-
-int
-main(int argc, char *argv[])
-{
-	int i;
-	char *ppfile;
-
-	ARGBEGIN{
-	case 'P':
-		pprof =1;
-		ppfile = EARGF(Usage());
-		pproffd = Bopen(ppfile, OWRITE);
-		if(pproffd == nil) {
-			fprint(2, "prof: cannot open %s: %r\n", ppfile);
-			exit(2);
-		}
-		break;
-	case 'd':
-		delta_msec = atoi(EARGF(Usage()));
-		break;
-	case 't':
-		total_sec = atoi(EARGF(Usage()));
-		break;
-	case 'p':
-		pid = atoi(EARGF(Usage()));
-		break;
-	case 'f':
-		functions = 1;
-		break;
-	case 'h':
-		histograms = 1;
-		break;
-	case 'l':
-		linenums = 1;
-		break;
-	case 'r':
-		registers = 1;
-		break;
-	case 's':
-		stacks++;
-		break;
-	default:
-		Usage();
-	}ARGEND
-	if(pid <= 0 && argc == 0)
-		Usage();
-	if(functions+linenums+registers+stacks+pprof == 0)
-		histograms = 1;
-	if(!machbyname("amd64")) {
-		fprint(2, "prof: no amd64 support\n", pid);
-		exit(1);
-	}
-	if(argc > 0)
-		file = argv[0];
-	else if(pid) {
-		file = proctextfile(pid);
-		if (file == NULL) {
-			fprint(2, "prof: can't find file for pid %d: %r\n", pid);
-			fprint(2, "prof: on Darwin, need to provide file name explicitly\n");
-			exit(1);
-		}
-	}
-	fd = open(file, 0);
-	if(fd < 0) {
-		fprint(2, "prof: can't open %s: %r\n", file);
-		exit(1);
-	}
-	if(crackhdr(fd, &fhdr)) {
-		have_syms = syminit(fd, &fhdr);
-		if(!have_syms) {
-			fprint(2, "prof: no symbols for %s: %r\n", file);
-		}
-	} else {
-		fprint(2, "prof: crack header for %s: %r\n", file);
-		exit(1);
-	}
-	if(pid <= 0)
-		pid = startprocess(argv);
-	attachproc(pid, &fhdr);	// initializes thread list
-	if(setarch() < 0) {
-		detach();
-		fprint(2, "prof: can't identify binary architecture for pid %d\n", pid);
-		exit(1);
-	}
-	if(getthreads() <= 0) {
-		detach();
-		fprint(2, "prof: can't find threads for pid %d\n", pid);
-		exit(1);
-	}
-	for(i = 0; i < nthread; i++)
-		ctlproc(thread[i], "start");
-	samples();
-	detach();
-	dumphistogram();
-	dumppprof();
-	exit(0);
-}